From 9a8e197d7e03298fce9cec030ae961ca7814419e Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 18 Jul 2016 15:01:32 +0300 Subject: Initial version based on XML generator --- src/cyrsasl.erl | 16 +- src/cyrsasl_digest.erl | 12 +- src/cyrsasl_oauth.erl | 4 +- src/cyrsasl_plain.erl | 4 +- src/cyrsasl_scram.erl | 32 +- src/ejabberd_c2s.erl | 2306 ++-- src/ejabberd_frontend_socket.erl | 17 + src/ejabberd_local.erl | 137 +- src/ejabberd_router.erl | 105 +- src/ejabberd_sm.erl | 182 +- src/ejabberd_socket.erl | 15 + src/ejabberd_system_monitor.erl | 32 +- src/gen_iq_handler.erl | 55 +- src/jid.erl | 15 +- src/mod_caps.erl | 296 +- src/mod_carboncopy.erl | 172 +- src/mod_client_state.erl | 136 +- src/mod_disco.erl | 403 +- src/mod_echo.erl | 50 +- src/mod_last.erl | 129 +- src/mod_ping.erl | 35 +- src/mod_privacy.erl | 565 +- src/mod_privacy_mnesia.erl | 24 +- src/mod_privacy_riak.erl | 25 +- src/mod_privacy_sql.erl | 27 +- src/mod_private.erl | 126 +- src/mod_roster.erl | 581 +- src/mod_time.erl | 51 +- src/mod_vcard.erl | 592 +- src/mod_vcard_xupdate.erl | 43 +- src/mod_version.erl | 51 +- src/translate.erl | 4 +- src/xmpp.erl | 712 ++ src/xmpp_codec.erl | 23222 +++++++++++++++++++++++++++++++++++++ src/xmpp_util.erl | 81 + 35 files changed, 26607 insertions(+), 3650 deletions(-) create mode 100644 src/xmpp.erl create mode 100644 src/xmpp_codec.erl create mode 100644 src/xmpp_util.erl (limited to 'src') diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl index a101e1380..46b23384e 100644 --- a/src/cyrsasl.erl +++ b/src/cyrsasl.erl @@ -73,8 +73,8 @@ -callback mech_step(any(), binary()) -> {ok, props()} | {ok, props(), binary()} | {continue, binary(), any()} | - {error, binary()} | - {error, binary(), binary()}. + {error, atom()} | + {error, atom(), binary()}. start() -> ets:new(sasl_mechanism, @@ -129,8 +129,8 @@ register_mechanism(Mechanism, Module, PasswordType) -> check_credentials(_State, Props) -> User = proplists:get_value(authzid, Props, <<>>), case jid:nodeprep(User) of - error -> {error, <<"not-authorized">>}; - <<"">> -> {error, <<"not-authorized">>}; + error -> {error, 'not-authorized'}; + <<"">> -> {error, 'not-authorized'}; _LUser -> ok end. @@ -159,6 +159,8 @@ server_new(Service, ServerFQDN, UserRealm, _SecFlags, check_password = CheckPassword, check_password_digest = CheckPasswordDigest}. +server_start(State, Mech, undefined) -> + server_start(State, Mech, <<"">>); server_start(State, Mech, ClientIn) -> case lists:member(Mech, listmech(State#sasl_state.myname)) @@ -174,11 +176,13 @@ server_start(State, Mech, ClientIn) -> server_step(State#sasl_state{mech_mod = Module, mech_state = MechState}, ClientIn); - _ -> {error, <<"no-mechanism">>} + _ -> {error, 'no-mechanism'} end; - false -> {error, <<"no-mechanism">>} + false -> {error, 'no-mechanism'} end. +server_step(State, undefined) -> + server_step(State, <<"">>); server_step(State, ClientIn) -> Module = State#sasl_state.mech_mod, MechState = State#sasl_state.mech_state, diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index 0d408fc48..150aa854c 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -80,7 +80,7 @@ mech_step(#state{step = 1, nonce = Nonce} = State, _) -> mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) -> case parse(ClientIn) of - bad -> {error, <<"bad-protocol">>}; + bad -> {error, 'bad-protocol'}; KeyVals -> DigestURI = proplists:get_value(<<"digest-uri">>, KeyVals, <<>>), UserName = proplists:get_value(<<"username">>, KeyVals, <<>>), @@ -92,11 +92,11 @@ mech_step(#state{step = 3, nonce = Nonce} = State, "seems invalid: ~p (checking for Host " "~p, FQDN ~p)", [DigestURI, State#state.host, State#state.hostfqdn]), - {error, <<"not-authorized">>, UserName}; + {error, 'not-authorized', UserName}; true -> AuthzId = proplists:get_value(<<"authzid">>, KeyVals, <<>>), case (State#state.get_password)(UserName) of - {false, _} -> {error, <<"not-authorized">>, UserName}; + {false, _} -> {error, 'not-authorized', UserName}; {Passwd, AuthModule} -> case (State#state.check_password)(UserName, UserName, <<"">>, proplists:get_value(<<"response">>, KeyVals, <<>>), @@ -116,8 +116,8 @@ mech_step(#state{step = 3, nonce = Nonce} = State, State#state{step = 5, auth_module = AuthModule, username = UserName, authzid = AuthzId}}; - false -> {error, <<"not-authorized">>, UserName}; - {false, _} -> {error, <<"not-authorized">>, UserName} + false -> {error, 'not-authorized', UserName}; + {false, _} -> {error, 'not-authorized', UserName} end end end @@ -134,7 +134,7 @@ mech_step(#state{step = 5, auth_module = AuthModule, {auth_module, AuthModule}]}; mech_step(A, B) -> ?DEBUG("SASL DIGEST: A ~p B ~p", [A, B]), - {error, <<"bad-protocol">>}. + {error, 'bad-protocol'}. parse(S) -> parse1(binary_to_list(S), "", []). diff --git a/src/cyrsasl_oauth.erl b/src/cyrsasl_oauth.erl index 16f1e3dfb..09d143ef5 100644 --- a/src/cyrsasl_oauth.erl +++ b/src/cyrsasl_oauth.erl @@ -52,9 +52,9 @@ mech_step(State, ClientIn) -> [{username, User}, {authzid, AuthzId}, {auth_module, ejabberd_oauth}]}; false -> - {error, <<"not-authorized">>, User} + {error, 'not-authorized', User} end; - _ -> {error, <<"bad-protocol">>} + _ -> {error, 'bad-protocol'} end. prepare(ClientIn) -> diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl index 82d68f87f..8e9b32b99 100644 --- a/src/cyrsasl_plain.erl +++ b/src/cyrsasl_plain.erl @@ -50,9 +50,9 @@ mech_step(State, ClientIn) -> {ok, [{username, User}, {authzid, AuthzId}, {auth_module, AuthModule}]}; - _ -> {error, <<"not-authorized">>, User} + _ -> {error, 'not-authorized', User} end; - _ -> {error, <<"bad-protocol">>} + _ -> {error, 'bad-protocol'} end. prepare(ClientIn) -> diff --git a/src/cyrsasl_scram.erl b/src/cyrsasl_scram.erl index 18f52b48f..8643a8924 100644 --- a/src/cyrsasl_scram.erl +++ b/src/cyrsasl_scram.erl @@ -67,21 +67,21 @@ mech_step(#state{step = 2} = State, ClientIn) -> case re:split(ClientIn, <<",">>, [{return, binary}]) of [_CBind, _AuthorizationIdentity, _UserNameAttribute, _ClientNonceAttribute, ExtensionAttribute | _] when ExtensionAttribute /= [] -> - {error, <<"protocol-error-extension-not-supported">>}; + {error, 'protocol-error-extension-not-supported'}; [CBind, _AuthorizationIdentity, UserNameAttribute, ClientNonceAttribute | _] when (CBind == <<"y">>) or (CBind == <<"n">>) -> case parse_attribute(UserNameAttribute) of {error, Reason} -> {error, Reason}; {_, EscapedUserName} -> case unescape_username(EscapedUserName) of - error -> {error, <<"protocol-error-bad-username">>}; + error -> {error, 'protocol-error-bad-username'}; UserName -> case parse_attribute(ClientNonceAttribute) of {$r, ClientNonce} -> {Ret, _AuthModule} = (State#state.get_password)(UserName), case {Ret, jid:resourceprep(Ret)} of - {false, _} -> {error, <<"not-authorized">>, UserName}; - {_, error} when is_binary(Ret) -> ?WARNING_MSG("invalid plain password", []), {error, <<"not-authorized">>, UserName}; + {false, _} -> {error, 'not-authorized', UserName}; + {_, error} when is_binary(Ret) -> ?WARNING_MSG("invalid plain password", []), {error, 'not-authorized', UserName}; {Ret, _} -> {StoredKey, ServerKey, Salt, IterationCount} = if is_tuple(Ret) -> Ret; @@ -121,11 +121,11 @@ mech_step(#state{step = 2} = State, ClientIn) -> server_nonce = ServerNonce, username = UserName}} end; - _Else -> {error, <<"not-supported">>} + _Else -> {error, 'not-supported'} end end end; - _Else -> {error, <<"bad-protocol">>} + _Else -> {error, 'bad-protocol'} end; mech_step(#state{step = 4} = State, ClientIn) -> case str:tokens(ClientIn, <<",">>) of @@ -163,18 +163,18 @@ mech_step(#state{step = 4} = State, ClientIn) -> {authzid, State#state.username}], <<"v=", (jlib:encode_base64(ServerSignature))/binary>>}; - true -> {error, <<"bad-auth">>, State#state.username} + true -> {error, 'bad-auth', State#state.username} end; - _Else -> {error, <<"bad-protocol">>} + _Else -> {error, 'bad-protocol'} end; - {$r, _} -> {error, <<"bad-nonce">>}; - _Else -> {error, <<"bad-protocol">>} + {$r, _} -> {error, 'bad-nonce'}; + _Else -> {error, 'bad-protocol'} end; - true -> {error, <<"bad-channel-binding">>} + true -> {error, 'bad-channel-binding'} end; - _Else -> {error, <<"bad-protocol">>} + _Else -> {error, 'bad-protocol'} end; - _Else -> {error, <<"bad-protocol">>} + _Else -> {error, 'bad-protocol'} end. parse_attribute(Attribute) -> @@ -187,11 +187,11 @@ parse_attribute(Attribute) -> if SecondChar == $= -> String = str:substr(Attribute, 3), {lists:nth(1, AttributeS), String}; - true -> {error, <<"bad-format second char not equal sign">>} + true -> {error, 'bad-format-second-char-not-equal-sign'} end; - _Else -> {error, <<"bad-format first char not a letter">>} + _Else -> {error, 'bad-format-first-char-not-a-letter'} end; - true -> {error, <<"bad-format attribute too short">>} + true -> {error, 'bad-format-attribute-too-short'} end. unescape_username(<<"">>) -> <<"">>; diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 9ddb8511d..8d217a354 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -67,7 +67,8 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). +%%-include("legacy.hrl"). -include("mod_privacy.hrl"). @@ -117,6 +118,16 @@ ask_offline = true, lang = <<"">>}). +-type state_name() :: wait_for_stream | wait_for_auth | + wait_for_feature_request | wait_for_bind | + wait_for_sasl_response | wait_for_resume | + session_established. +-type state() :: #state{}. +-type fsm_stop() :: {stop, normal, state()}. +-type fsm_next() :: {next_state, state_name(), state(), non_neg_integer()}. +-type fsm_transition() :: fsm_stop() | fsm_next(). +-export_type([state/0]). + %-define(DBGFSM, true). -ifdef(DBGFSM). @@ -143,55 +154,13 @@ -define(STREAM_TRAILER, <<"">>). --define(INVALID_NS_ERR, ?SERR_INVALID_NAMESPACE). - --define(INVALID_XML_ERR, ?SERR_XML_NOT_WELL_FORMED). - --define(HOST_UNKNOWN_ERR, ?SERR_HOST_UNKNOWN). - --define(POLICY_VIOLATION_ERR(Lang, Text), - ?SERRT_POLICY_VIOLATION(Lang, Text)). - --define(INVALID_FROM, ?SERR_INVALID_FROM). - %% XEP-0198: --define(IS_STREAM_MGMT_TAG(Name), - (Name == <<"enable">>) or - (Name == <<"resume">>) or - (Name == <<"a">>) or - (Name == <<"r">>)). - --define(IS_SUPPORTED_MGMT_XMLNS(Xmlns), - (Xmlns == ?NS_STREAM_MGMT_2) or - (Xmlns == ?NS_STREAM_MGMT_3)). - --define(MGMT_FAILED(Condition, Attrs), - #xmlel{name = <<"failed">>, - attrs = Attrs, - children = [#xmlel{name = Condition, - attrs = [{<<"xmlns">>, ?NS_STANZAS}], - children = []}]}). - --define(MGMT_BAD_REQUEST(Xmlns), - ?MGMT_FAILED(<<"bad-request">>, [{<<"xmlns">>, Xmlns}])). - --define(MGMT_SERVICE_UNAVAILABLE(Xmlns), - ?MGMT_FAILED(<<"service-unavailable">>, [{<<"xmlns">>, Xmlns}])). - --define(MGMT_UNEXPECTED_REQUEST(Xmlns), - ?MGMT_FAILED(<<"unexpected-request">>, [{<<"xmlns">>, Xmlns}])). - --define(MGMT_UNSUPPORTED_VERSION(Xmlns), - ?MGMT_FAILED(<<"unsupported-version">>, [{<<"xmlns">>, Xmlns}])). - --define(MGMT_ITEM_NOT_FOUND(Xmlns), - ?MGMT_FAILED(<<"item-not-found">>, [{<<"xmlns">>, Xmlns}])). - --define(MGMT_ITEM_NOT_FOUND_H(Xmlns, NumStanzasIn), - ?MGMT_FAILED(<<"item-not-found">>, - [{<<"xmlns">>, Xmlns}, - {<<"h">>, jlib:integer_to_binary(NumStanzasIn)}])). +-define(IS_STREAM_MGMT_PACKET(Pkt), + is_record(Pkt, sm_enable) or + is_record(Pkt, sm_resume) or + is_record(Pkt, sm_a) or + is_record(Pkt, sm_r)). %%%---------------------------------------------------------------------- %%% API @@ -213,21 +182,25 @@ get_presence(FsmRef) -> (?GEN_FSM):sync_send_all_state_event(FsmRef, {get_presence}, 1000). +-spec get_aux_field(any(), state()) -> {ok, any()} | error. get_aux_field(Key, #state{aux_fields = Opts}) -> case lists:keysearch(Key, 1, Opts) of {value, {_, Val}} -> {ok, Val}; _ -> error end. +-spec set_aux_field(any(), any(), state()) -> state(). set_aux_field(Key, Val, #state{aux_fields = Opts} = State) -> Opts1 = lists:keydelete(Key, 1, Opts), State#state{aux_fields = [{Key, Val} | Opts1]}. +-spec del_aux_field(any(), state()) -> state(). del_aux_field(Key, #state{aux_fields = Opts} = State) -> Opts1 = lists:keydelete(Key, 1, Opts), State#state{aux_fields = Opts1}. +-spec get_subscription(jid() | ljid(), state()) -> both | from | to | none. get_subscription(From = #jid{}, StateData) -> get_subscription(jid:tolower(From), StateData); get_subscription(LFrom, StateData) -> @@ -244,14 +217,19 @@ get_subscription(LFrom, StateData) -> true -> none end. +-spec send_filtered(pid(), binary(), jid(), jid(), stanza()) -> any(). send_filtered(FsmRef, Feature, From, To, Packet) -> FsmRef ! {send_filtered, Feature, From, To, Packet}. +-spec broadcast(pid(), any(), jid(), stanza()) -> any(). broadcast(FsmRef, Type, From, Packet) -> FsmRef ! {broadcast, Type, From, Packet}. +-spec stop(pid()) -> any(). stop(FsmRef) -> (?GEN_FSM):send_event(FsmRef, stop). +-spec close(pid()) -> any(). +%% What is the difference between stop and close??? close(FsmRef) -> (?GEN_FSM):send_event(FsmRef, closed). %%%---------------------------------------------------------------------- @@ -336,6 +314,7 @@ init([{SockMod, Socket}, Opts]) -> mgmt_resend = ResendOnTimeout}, {ok, wait_for_stream, StateData, ?C2S_OPEN_TIMEOUT}. +-spec get_subscribed(pid()) -> [ljid()]. %% Return list of all available resources of contacts, get_subscribed(FsmRef) -> (?GEN_FSM):sync_send_all_state_event(FsmRef, @@ -399,15 +378,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> Mechs = case TLSEnabled or not TLSRequired of true -> - Ms = lists:map(fun (S) -> - #xmlel{name = <<"mechanism">>, - attrs = [], - children = [{xmlcdata, S}]} - end, - cyrsasl:listmech(Server)), - [#xmlel{name = <<"mechanisms">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = Ms}]; + [#sasl_mechanisms{list = cyrsasl:listmech(Server)}]; false -> [] end, @@ -417,11 +388,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> CompressFeature = case Zlib andalso ((SockMod == gen_tcp) orelse (SockMod == fast_tls)) of true -> - [#xmlel{name = <<"compression">>, - attrs = [{<<"xmlns">>, ?NS_FEATURE_COMPRESS}], - children = [#xmlel{name = <<"method">>, - attrs = [], - children = [{xmlcdata, <<"zlib">>}]}]}]; + [#compression{methods = [<<"zlib">>]}]; _ -> [] end, @@ -430,18 +397,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> (TLSEnabled == false) andalso (SockMod == gen_tcp) of true -> - case TLSRequired of - true -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = [#xmlel{name = <<"required">>, - attrs = [], - children = []}]}]; - _ -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = []}] - end; + [#starttls{required = TLSRequired}]; false -> [] end, @@ -449,9 +405,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features, Server, StreamFeatures1, [Server]), send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = StreamFeatures}), + #stream_features{sub_els = StreamFeatures}), fsm_next_state(wait_for_feature_request, StateData#state{server = Server, sasl_state = SASLState, @@ -466,12 +420,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> StreamManagementFeature = case stream_mgmt_enabled(StateData) of true -> - [#xmlel{name = <<"sm">>, - attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_2}], - children = []}, - #xmlel{name = <<"sm">>, - attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_3}], - children = []}]; + [#feature_sm{xmlns = ?NS_STREAM_MGMT_2}, + #feature_sm{xmlns = ?NS_STREAM_MGMT_3}]; false -> [] end, @@ -483,21 +433,12 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> case Zlib andalso ((SockMod == gen_tcp) orelse (SockMod == fast_tls)) of true -> - [#xmlel{name = <<"compression">>, - attrs = [{<<"xmlns">>, ?NS_FEATURE_COMPRESS}], - children = [#xmlel{name = <<"method">>, - attrs = [], - children = [{xmlcdata, <<"zlib">>}]}]}]; + [#compression{methods = [<<"zlib">>]}]; _ -> [] end, - StreamFeatures1 = [#xmlel{name = <<"bind">>, - attrs = [{<<"xmlns">>, ?NS_BIND}], - children = []}, - #xmlel{name = <<"session">>, - attrs = [{<<"xmlns">>, ?NS_SESSION}], - children = - [#xmlel{name = <<"optional">>}]}] + StreamFeatures1 = + [#bind{}, #xmpp_session{optional = true}] ++ RosterVersioningFeature ++ StreamManagementFeature ++ @@ -507,16 +448,11 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features, Server, StreamFeatures1, [Server]), send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = StreamFeatures}), + #stream_features{sub_els = StreamFeatures}), fsm_next_state(wait_for_bind, StateData#state{server = Server, lang = Lang}); _ -> - send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = []}), + send_element(StateData, #stream_features{}), fsm_next_state(session_established, StateData#state{server = Server, lang = Lang}) end @@ -525,9 +461,10 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> send_header(StateData, Server, <<"">>, DefaultLang), if not StateData#state.tls_enabled and StateData#state.tls_required -> - send_element(StateData, - ?POLICY_VIOLATION_ERR(Lang, - <<"Use of STARTTLS required">>)), + send_element( + StateData, + xmpp:serr_policy_violation( + <<"Use of STARTTLS required">>, Lang)), {stop, normal, StateData}; true -> fsm_next_state(wait_for_auth, @@ -541,183 +478,151 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> ?INFO_MSG("Connection attempt from blacklisted IP ~s: ~s", [jlib:ip_to_list(IP), LogReason]), send_header(StateData, Server, StreamVersion, DefaultLang), - send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, ReasonT)), + send_element(StateData, xmpp:serr_policy_violation(ReasonT, Lang)), {stop, normal, StateData}; _ -> send_header(StateData, ?MYNAME, StreamVersion, DefaultLang), - send_element(StateData, ?HOST_UNKNOWN_ERR), + send_element(StateData, xmpp:serr_host_unknown()), {stop, normal, StateData} end; _ -> send_header(StateData, ?MYNAME, <<"">>, DefaultLang), - send_element(StateData, ?INVALID_NS_ERR), + send_element(StateData, xmpp:serr_invalid_namespace()), {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> {stop, normal, StateData}; wait_for_stream({xmlstreamelement, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream({xmlstreamend, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream({xmlstreamerror, _}, StateData) -> send_header(StateData, ?MYNAME, <<"1.0">>, <<"">>), - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}; wait_for_stream(stop, StateData) -> {stop, normal, StateData}. -wait_for_auth({xmlstreamelement, #xmlel{name = Name} = El}, StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> - fsm_next_state(wait_for_auth, dispatch_stream_mgmt(El, StateData)); -wait_for_auth({xmlstreamelement, El}, StateData) -> - case is_auth_packet(El) of - {auth, _ID, get, {U, _, _, _}} -> - #xmlel{name = Name, attrs = Attrs} = jlib:make_result_iq_reply(El), - case U of - <<"">> -> UCdata = []; - _ -> UCdata = [{xmlcdata, U}] - end, - Res = case - ejabberd_auth:plain_password_required(StateData#state.server) - of - false -> - #xmlel{name = Name, attrs = Attrs, - children = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_AUTH}], - children = - [#xmlel{name = <<"username">>, - attrs = [], - children = UCdata}, - #xmlel{name = <<"password">>, - attrs = [], children = []}, - #xmlel{name = <<"digest">>, - attrs = [], children = []}, - #xmlel{name = <<"resource">>, - attrs = [], - children = []}]}]}; - true -> - #xmlel{name = Name, attrs = Attrs, - children = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_AUTH}], - children = - [#xmlel{name = <<"username">>, - attrs = [], - children = UCdata}, - #xmlel{name = <<"password">>, - attrs = [], children = []}, - #xmlel{name = <<"resource">>, - attrs = [], - children = []}]}]} - end, - send_element(StateData, Res), +wait_for_auth({xmlstreamelement, #xmlel{} = El}, StateData) -> + decode_element(El, wait_for_auth, StateData); +wait_for_auth(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> + fsm_next_state(wait_for_auth, dispatch_stream_mgmt(Pkt, StateData)); +wait_for_auth(#iq{type = get, + sub_els = [#legacy_auth{username = U}]} = IQ, StateData) -> + Username = case U of + undefined -> none; + _ -> U + end, + Auth = #legacy_auth{username = Username, password = none, resource = none}, + Res = case ejabberd_auth:plain_password_required(StateData#state.server) of + false -> + xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = none}); + true -> + xmpp:make_iq_result(IQ, Auth) + end, + send_element(StateData, Res), + fsm_next_state(wait_for_auth, StateData); +wait_for_auth(#iq{type = set, sub_els = [#legacy_auth{resource = <<"">>}]} = IQ, + StateData) -> + Lang = StateData#state.lang, + Txt = <<"No resource provided">>, + Err = xmpp:make_error(IQ, xmpp:err_not_acceptable(Txt, Lang)), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData); +wait_for_auth(#iq{type = set, sub_els = [#legacy_auth{username = U, + password = P0, + digest = D0, + resource = R}]} = IQ, + StateData) when is_binary(U), is_binary(R) -> + JID = jid:make(U, StateData#state.server, R), + case (JID /= error) andalso + acl:access_matches(StateData#state.access, + #{usr => jid:split(JID), ip => StateData#state.ip}, + StateData#state.server) == allow of + true -> + DGen = fun (PW) -> + p1_sha:sha(<<(StateData#state.streamid)/binary, PW/binary>>) + end, + P = if is_binary(P0) -> P0; true -> <<>> end, + D = if is_binary(D0) -> D0; true -> <<>> end, + case ejabberd_auth:check_password_with_authmodule( + U, U, StateData#state.server, P, D, DGen) of + {true, AuthModule} -> + ?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s", + [StateData#state.socket, + jid:to_string(JID), AuthModule, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [true, U, StateData#state.server, + StateData#state.ip]), + Conn = get_conn_type(StateData), + Info = [{ip, StateData#state.ip}, {conn, Conn}, + {auth_module, AuthModule}], + Res = xmpp:make_iq_result(IQ), + send_element(StateData, Res), + ejabberd_sm:open_session(StateData#state.sid, U, + StateData#state.server, R, + Info), + change_shaper(StateData, JID), + {Fs, Ts} = ejabberd_hooks:run_fold( + roster_get_subscription_lists, + StateData#state.server, + {[], []}, + [U, StateData#state.server]), + LJID = jid:tolower(jid:remove_resource(JID)), + Fs1 = [LJID | Fs], + Ts1 = [LJID | Ts], + PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, + StateData#state.server, + #userlist{}, + [U, StateData#state.server]), + NewStateData = StateData#state{ + user = U, + resource = R, + jid = JID, + conn = Conn, + auth_module = AuthModule, + pres_f = (?SETS):from_list(Fs1), + pres_t = (?SETS):from_list(Ts1), + privacy_list = PrivList}, + fsm_next_state(session_established, NewStateData); + _ -> + ?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s", + [StateData#state.socket, + jid:to_string(JID), + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, U, StateData#state.server, + StateData#state.ip]), + Lang = StateData#state.lang, + Txt = <<"Legacy authentication failed">>, + Err = xmpp:make_error(IQ, xmpp:err_not_authorized(Txt, Lang)), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData) + end; + false when JID == error -> + ?INFO_MSG("(~w) Forbidden legacy authentication " + "for username '~s' with resource '~s'", + [StateData#state.socket, U, R]), + Err = xmpp:make_error(IQ, xmpp:err_jid_malformed()), + send_element(StateData, Err), fsm_next_state(wait_for_auth, StateData); - {auth, _ID, set, {_U, _P, _D, <<"">>}} -> + false -> + ?INFO_MSG("(~w) Forbidden legacy authentication for ~s from ~s", + [StateData#state.socket, + jid:to_string(JID), + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, U, StateData#state.server, + StateData#state.ip]), Lang = StateData#state.lang, - Txt = <<"No resource provided">>, - Err = jlib:make_error_reply(El, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)), + Txt = <<"Legacy authentication forbidden">>, + Err = xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)), send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData); - {auth, _ID, set, {U, P, D, R}} -> - JID = jid:make(U, StateData#state.server, R), - case JID /= error andalso - acl:access_matches(StateData#state.access, - #{usr => jid:split(JID), ip => StateData#state.ip}, - StateData#state.server) == allow - of - true -> - DGen = fun (PW) -> - p1_sha:sha(<<(StateData#state.streamid)/binary, PW/binary>>) - end, - case ejabberd_auth:check_password_with_authmodule(U, U, - StateData#state.server, - P, D, DGen) - of - {true, AuthModule} -> - ?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s", - [StateData#state.socket, - jid:to_string(JID), AuthModule, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [true, U, StateData#state.server, - StateData#state.ip]), - Conn = get_conn_type(StateData), - Info = [{ip, StateData#state.ip}, {conn, Conn}, - {auth_module, AuthModule}], - Res = jlib:make_result_iq_reply( - El#xmlel{children = []}), - send_element(StateData, Res), - ejabberd_sm:open_session(StateData#state.sid, U, - StateData#state.server, R, - Info), - change_shaper(StateData, JID), - {Fs, Ts} = - ejabberd_hooks:run_fold(roster_get_subscription_lists, - StateData#state.server, - {[], []}, - [U, StateData#state.server]), - LJID = jid:tolower(jid:remove_resource(JID)), - Fs1 = [LJID | Fs], - Ts1 = [LJID | Ts], - PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, - StateData#state.server, - #userlist{}, - [U, StateData#state.server]), - NewStateData = StateData#state{user = U, - resource = R, - jid = JID, - conn = Conn, - auth_module = AuthModule, - pres_f = (?SETS):from_list(Fs1), - pres_t = (?SETS):from_list(Ts1), - privacy_list = PrivList}, - fsm_next_state(session_established, NewStateData); - _ -> - ?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s", - [StateData#state.socket, - jid:to_string(JID), - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, U, StateData#state.server, - StateData#state.ip]), - Lang = StateData#state.lang, - Txt = <<"Legacy authentication failed">>, - Err = jlib:make_error_reply( - El, ?ERRT_NOT_AUTHORIZED(Lang, Txt)), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData) - end; - _ -> - if JID == error -> - ?INFO_MSG("(~w) Forbidden legacy authentication " - "for username '~s' with resource '~s'", - [StateData#state.socket, U, R]), - Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData); - true -> - ?INFO_MSG("(~w) Forbidden legacy authentication " - "for ~s from ~s", - [StateData#state.socket, - jid:to_string(JID), - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, U, StateData#state.server, - StateData#state.ip]), - Lang = StateData#state.lang, - Txt = <<"Legacy authentication forbidden">>, - Err = jlib:make_error_reply(El, ?ERRT_NOT_ALLOWED(Lang, Txt)), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData) - end - end; - _ -> - process_unauthenticated_stanza(StateData, El), fsm_next_state(wait_for_auth, StateData) end; wait_for_auth(timeout, StateData) -> @@ -725,127 +630,97 @@ wait_for_auth(timeout, StateData) -> wait_for_auth({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; wait_for_auth({xmlstreamerror, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_auth(closed, StateData) -> {stop, normal, StateData}; wait_for_auth(stop, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +wait_for_auth(Pkt, StateData) -> + process_unauthenticated_stanza(StateData, Pkt), + fsm_next_state(wait_for_auth, StateData). -wait_for_feature_request({xmlstreamelement, #xmlel{name = Name} = El}, - StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> +wait_for_feature_request({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_feature_request, StateData); +wait_for_feature_request(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> fsm_next_state(wait_for_feature_request, - dispatch_stream_mgmt(El, StateData)); -wait_for_feature_request({xmlstreamelement, El}, - StateData) -> - #xmlel{name = Name, attrs = Attrs, children = Els} = El, + dispatch_stream_mgmt(Pkt, StateData)); +wait_for_feature_request(#sasl_auth{mechanism = Mech, + text = ClientIn}, + #state{tls_enabled = TLSEnabled, + tls_required = TLSRequired} = StateData) + when TLSEnabled or not TLSRequired -> + case cyrsasl:server_start(StateData#state.sasl_state, Mech, ClientIn) of + {ok, Props} -> + (StateData#state.sockmod):reset_stream(StateData#state.socket), + U = identity(Props), + AuthModule = proplists:get_value(auth_module, Props, undefined), + ?INFO_MSG("(~w) Accepted authentication for ~s by ~p from ~s", + [StateData#state.socket, U, AuthModule, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [true, U, StateData#state.server, + StateData#state.ip]), + send_element(StateData, #sasl_success{}), + fsm_next_state(wait_for_stream, + StateData#state{streamid = new_id(), + authenticated = true, + auth_module = AuthModule, + sasl_state = undefined, + user = U}); + {continue, ServerOut, NewSASLState} -> + send_element(StateData, #sasl_challenge{text = ServerOut}), + fsm_next_state(wait_for_sasl_response, + StateData#state{sasl_state = NewSASLState}); + {error, Error, Username} -> + ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", + [StateData#state.socket, + Username, StateData#state.server, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, Username, StateData#state.server, + StateData#state.ip]), + send_element(StateData, #sasl_failure{reason = Error}), + fsm_next_state(wait_for_feature_request, StateData); + {error, Error} -> + send_element(StateData, #sasl_failure{reason = Error}), + fsm_next_state(wait_for_feature_request, StateData) + end; +wait_for_feature_request(#starttls{}, + #state{tls = true, tls_enabled = false} = StateData) -> + case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of + gen_tcp -> + TLSOpts = case ejabberd_config:get_option( + {domain_certfile, StateData#state.server}, + fun iolist_to_binary/1) of + undefined -> + StateData#state.tls_options; + CertFile -> + lists:keystore(certfile, 1, + StateData#state.tls_options, + {certfile, CertFile}) + end, + Socket = StateData#state.socket, + BProceed = fxml:element_to_binary(xmpp:encode(#starttls_proceed{})), + TLSSocket = (StateData#state.sockmod):starttls(Socket, TLSOpts, BProceed), + fsm_next_state(wait_for_stream, + StateData#state{socket = TLSSocket, + streamid = new_id(), + tls_enabled = true}); + _ -> + Lang = StateData#state.lang, + Txt = <<"Unsupported TLS transport">>, + send_element(StateData, xmpp:serr_policy_violation(Txt, Lang)), + {stop, normal, StateData} + end; +wait_for_feature_request(#compress{} = Comp, StateData) -> Zlib = StateData#state.zlib, - TLS = StateData#state.tls, - TLSEnabled = StateData#state.tls_enabled, - TLSRequired = StateData#state.tls_required, - SockMod = - (StateData#state.sockmod):get_sockmod(StateData#state.socket), - case {fxml:get_attr_s(<<"xmlns">>, Attrs), Name} of - {?NS_SASL, <<"auth">>} - when TLSEnabled or not TLSRequired -> - Mech = fxml:get_attr_s(<<"mechanism">>, Attrs), - ClientIn = jlib:decode_base64(fxml:get_cdata(Els)), - case cyrsasl:server_start(StateData#state.sasl_state, - Mech, ClientIn) - of - {ok, Props} -> - (StateData#state.sockmod):reset_stream(StateData#state.socket), - U = identity(Props), - AuthModule = proplists:get_value(auth_module, Props, undefined), - ?INFO_MSG("(~w) Accepted authentication for ~s " - "by ~p from ~s", - [StateData#state.socket, U, AuthModule, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [true, U, StateData#state.server, - StateData#state.ip]), - send_element(StateData, - #xmlel{name = <<"success">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = []}), - fsm_next_state(wait_for_stream, - StateData#state{streamid = new_id(), - authenticated = true, - auth_module = AuthModule, - sasl_state = undefined, - user = U}); - {continue, ServerOut, NewSASLState} -> - send_element(StateData, - #xmlel{name = <<"challenge">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [{xmlcdata, - jlib:encode_base64(ServerOut)}]}), - fsm_next_state(wait_for_sasl_response, - StateData#state{sasl_state = NewSASLState}); - {error, Error, Username} -> - ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", - [StateData#state.socket, - Username, StateData#state.server, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, Username, StateData#state.server, - StateData#state.ip]), - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = Error, attrs = [], - children = []}]}), - fsm_next_state(wait_for_feature_request, StateData); - {error, Error} -> - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = Error, attrs = [], - children = []}]}), - fsm_next_state(wait_for_feature_request, StateData) - end; - {?NS_TLS, <<"starttls">>} - when TLS == true, TLSEnabled == false, - SockMod == gen_tcp -> - TLSOpts = case - ejabberd_config:get_option( - {domain_certfile, StateData#state.server}, - fun iolist_to_binary/1) - of - undefined -> StateData#state.tls_options; - CertFile -> - [{certfile, CertFile} | lists:keydelete(certfile, 1, - StateData#state.tls_options)] - end, - Socket = StateData#state.socket, - BProceed = fxml:element_to_binary(#xmlel{name = <<"proceed">>, - attrs = [{<<"xmlns">>, ?NS_TLS}]}), - TLSSocket = (StateData#state.sockmod):starttls(Socket, - TLSOpts, - BProceed), - fsm_next_state(wait_for_stream, - StateData#state{socket = TLSSocket, - streamid = new_id(), - tls_enabled = true}); - {?NS_COMPRESS, <<"compress">>} - when Zlib == true, - (SockMod == gen_tcp) or (SockMod == fast_tls) -> - process_compression_request(El, wait_for_feature_request, StateData); - _ -> - if TLSRequired and not TLSEnabled -> - Lang = StateData#state.lang, - send_element(StateData, - ?POLICY_VIOLATION_ERR(Lang, - <<"Use of STARTTLS required">>)), - {stop, normal, StateData}; - true -> - process_unauthenticated_stanza(StateData, El), - fsm_next_state(wait_for_feature_request, StateData) - end + SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket), + if Zlib == true, (SockMod == gen_tcp) or (SockMod == fast_tls) -> + process_compression_request(Comp, wait_for_feature_request, StateData); + true -> + send_element(StateData, #compress_failure{reason = 'setup-failed'}), + fsm_next_state(wait_for_feature_request, StateData) end; wait_for_feature_request(timeout, StateData) -> {stop, normal, StateData}; @@ -854,106 +729,82 @@ wait_for_feature_request({xmlstreamend, _Name}, {stop, normal, StateData}; wait_for_feature_request({xmlstreamerror, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_feature_request(closed, StateData) -> {stop, normal, StateData}; wait_for_feature_request(stop, StateData) -> - {stop, normal, StateData}. - -wait_for_sasl_response({xmlstreamelement, #xmlel{name = Name} = El}, StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> - fsm_next_state(wait_for_sasl_response, dispatch_stream_mgmt(El, StateData)); -wait_for_sasl_response({xmlstreamelement, El}, - StateData) -> - #xmlel{name = Name, attrs = Attrs, children = Els} = El, - case {fxml:get_attr_s(<<"xmlns">>, Attrs), Name} of - {?NS_SASL, <<"response">>} -> - ClientIn = jlib:decode_base64(fxml:get_cdata(Els)), - case cyrsasl:server_step(StateData#state.sasl_state, - ClientIn) - of - {ok, Props} -> - catch - (StateData#state.sockmod):reset_stream(StateData#state.socket), - U = identity(Props), - AuthModule = proplists:get_value(auth_module, Props, <<>>), - ?INFO_MSG("(~w) Accepted authentication for ~s " - "by ~p from ~s", - [StateData#state.socket, U, AuthModule, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [true, U, StateData#state.server, - StateData#state.ip]), - send_element(StateData, - #xmlel{name = <<"success">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = []}), - fsm_next_state(wait_for_stream, - StateData#state{streamid = new_id(), - authenticated = true, - auth_module = AuthModule, - sasl_state = undefined, - user = U}); - {ok, Props, ServerOut} -> - (StateData#state.sockmod):reset_stream(StateData#state.socket), - U = identity(Props), - AuthModule = proplists:get_value(auth_module, Props, undefined), - ?INFO_MSG("(~w) Accepted authentication for ~s " - "by ~p from ~s", - [StateData#state.socket, U, AuthModule, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [true, U, StateData#state.server, - StateData#state.ip]), - send_element(StateData, - #xmlel{name = <<"success">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [{xmlcdata, - jlib:encode_base64(ServerOut)}]}), - fsm_next_state(wait_for_stream, - StateData#state{streamid = new_id(), - authenticated = true, - auth_module = AuthModule, - sasl_state = undefined, - user = U}); - {continue, ServerOut, NewSASLState} -> - send_element(StateData, - #xmlel{name = <<"challenge">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [{xmlcdata, - jlib:encode_base64(ServerOut)}]}), - fsm_next_state(wait_for_sasl_response, - StateData#state{sasl_state = NewSASLState}); - {error, Error, Username} -> - ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", - [StateData#state.socket, - Username, StateData#state.server, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, Username, StateData#state.server, - StateData#state.ip]), - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = Error, attrs = [], - children = []}]}), - fsm_next_state(wait_for_feature_request, StateData); - {error, Error} -> - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = Error, attrs = [], - children = []}]}), - fsm_next_state(wait_for_feature_request, StateData) - end; - _ -> - process_unauthenticated_stanza(StateData, El), - fsm_next_state(wait_for_feature_request, StateData) + {stop, normal, StateData}; +wait_for_feature_request(_Pkt, + #state{tls_required = TLSRequired, + tls_enabled = TLSEnabled} = StateData) + when TLSRequired and not TLSEnabled -> + Lang = StateData#state.lang, + Txt = <<"Use of STARTTLS required">>, + send_element(StateData, xmpp:serr_policy_violation(Txt, Lang)), + {stop, normal, StateData}; +wait_for_feature_request(Pkt, StateData) -> + process_unauthenticated_stanza(StateData, Pkt), + fsm_next_state(wait_for_feature_request, StateData). + +wait_for_sasl_response({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_sasl_response, StateData); +wait_for_sasl_response(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> + fsm_next_state(wait_for_sasl_response, + dispatch_stream_mgmt(Pkt, StateData)); +wait_for_sasl_response(#sasl_response{text = ClientIn}, StateData) -> + case cyrsasl:server_step(StateData#state.sasl_state, ClientIn) of + {ok, Props} -> + catch (StateData#state.sockmod):reset_stream(StateData#state.socket), + U = identity(Props), + AuthModule = proplists:get_value(auth_module, Props, <<>>), + ?INFO_MSG("(~w) Accepted authentication for ~s by ~p from ~s", + [StateData#state.socket, U, AuthModule, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [true, U, StateData#state.server, + StateData#state.ip]), + send_element(StateData, #sasl_success{}), + fsm_next_state(wait_for_stream, + StateData#state{streamid = new_id(), + authenticated = true, + auth_module = AuthModule, + sasl_state = undefined, + user = U}); + {ok, Props, ServerOut} -> + (StateData#state.sockmod):reset_stream(StateData#state.socket), + U = identity(Props), + AuthModule = proplists:get_value(auth_module, Props, undefined), + ?INFO_MSG("(~w) Accepted authentication for ~s by ~p from ~s", + [StateData#state.socket, U, AuthModule, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [true, U, StateData#state.server, + StateData#state.ip]), + send_element(StateData, #sasl_success{text = ServerOut}), + fsm_next_state(wait_for_stream, + StateData#state{streamid = new_id(), + authenticated = true, + auth_module = AuthModule, + sasl_state = undefined, + user = U}); + {continue, ServerOut, NewSASLState} -> + send_element(StateData, #sasl_challenge{text = ServerOut}), + fsm_next_state(wait_for_sasl_response, + StateData#state{sasl_state = NewSASLState}); + {error, Error, Username} -> + ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", + [StateData#state.socket, + Username, StateData#state.server, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, Username, StateData#state.server, + StateData#state.ip]), + send_element(StateData, #sasl_failure{reason = Error}), + fsm_next_state(wait_for_feature_request, StateData); + {error, Error} -> + send_element(StateData, #sasl_failure{reason = Error}), + fsm_next_state(wait_for_feature_request, StateData) end; wait_for_sasl_response(timeout, StateData) -> {stop, normal, StateData}; @@ -962,13 +813,18 @@ wait_for_sasl_response({xmlstreamend, _Name}, {stop, normal, StateData}; wait_for_sasl_response({xmlstreamerror, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_sasl_response(closed, StateData) -> {stop, normal, StateData}; wait_for_sasl_response(stop, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +wait_for_sasl_response(Pkt, StateData) -> + process_unauthenticated_stanza(StateData, Pkt), + fsm_next_state(wait_for_feature_request, StateData). +-spec resource_conflict_action(binary(), binary(), binary()) -> + {accept_resource, binary()} | closenew. resource_conflict_action(U, S, R) -> OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of true -> @@ -998,108 +854,116 @@ resource_conflict_action(U, S, R) -> {accept_resource, Rnew} end. -wait_for_bind({xmlstreamelement, #xmlel{name = Name, attrs = Attrs} = El}, - StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> - case Name of - <<"resume">> -> - case handle_resume(StateData, Attrs) of - {ok, ResumedState} -> - fsm_next_state(session_established, ResumedState); - error -> - fsm_next_state(wait_for_bind, StateData) - end; - _ -> - fsm_next_state(wait_for_bind, dispatch_stream_mgmt(El, StateData)) - end; -wait_for_bind({xmlstreamelement, El}, StateData) -> - case jlib:iq_query_info(El) of - #iq{type = set, lang = Lang, xmlns = ?NS_BIND, sub_el = SubEl} = - IQ -> - U = StateData#state.user, - R1 = fxml:get_path_s(SubEl, - [{elem, <<"resource">>}, cdata]), - R = case jid:resourceprep(R1) of - error -> error; - <<"">> -> new_uniq_id(); - Resource -> Resource - end, - case R of - error -> - Txt = <<"Malformed resource">>, - Err = jlib:make_error_reply(El, ?ERRT_BAD_REQUEST(Lang, Txt)), - send_element(StateData, Err), - fsm_next_state(wait_for_bind, StateData); - _ -> - case resource_conflict_action(U, StateData#state.server, - R) - of - closenew -> - Err = jlib:make_error_reply(El, - ?STANZA_ERROR(<<"409">>, - <<"modify">>, - <<"conflict">>)), - send_element(StateData, Err), - fsm_next_state(wait_for_bind, StateData); - {accept_resource, R2} -> - JID = jid:make(U, StateData#state.server, R2), - StateData2 = - StateData#state{resource = R2, jid = JID}, - case open_session(StateData2) of - {ok, StateData3} -> - Res = - IQ#iq{ - type = result, - sub_el = - [#xmlel{name = <<"bind">>, - attrs = [{<<"xmlns">>, ?NS_BIND}], - children = - [#xmlel{name = <<"jid">>, - attrs = [], - children = - [{xmlcdata, - jid:to_string(JID)}]}]}]}, - try - send_element(StateData3, jlib:iq_to_xml(Res)) - catch exit:normal -> - close(self()) - end, - fsm_next_state_pack( - session_established, - StateData3); - {error, Error} -> - Err = jlib:make_error_reply(El, Error), - send_element(StateData, Err), - fsm_next_state(wait_for_bind, StateData) - end - end - end; - _ -> - #xmlel{name = Name, attrs = Attrs, children = _Els} = El, - Zlib = StateData#state.zlib, - SockMod = - (StateData#state.sockmod):get_sockmod(StateData#state.socket), - case {fxml:get_attr_s(<<"xmlns">>, Attrs), Name} of - {?NS_COMPRESS, <<"compress">>} - when Zlib == true, - (SockMod == gen_tcp) or (SockMod == fast_tls) -> - process_compression_request(El, wait_for_bind, StateData); +-spec decode_subels(stanza()) -> stanza(). +decode_subels(#iq{sub_els = [El], type = T} = IQ) when T == set; T == get -> + NewEl = case xmpp:get_ns(El) of + ?NS_BIND when T == set -> xmpp:decode(El); + ?NS_AUTH -> xmpp:decode(El); + ?NS_PRIVACY -> xmpp:decode(El); + ?NS_BLOCKING -> xmpp:decode(El); + _ -> El + end, + IQ#iq{sub_els = [NewEl]}; +decode_subels(Pkt) -> + Pkt. + +-spec decode_element(xmlel(), state_name(), state()) -> fsm_next(). +decode_element(#xmlel{} = El, StateName, StateData) -> + try + Pkt0 = xmpp:decode(El, [ignore_els]), + Pkt = decode_subels(Pkt0), + ?MODULE:StateName(Pkt, StateData) + catch error:{xmpp_codec, Why} -> + Type = xmpp:get_type(El), + NS = xmpp:get_ns(El), + case xmpp:is_stanza(El) of + true when Type /= <<"result">>, Type /= <<"error">> -> + Lang = xmpp:get_lang(El), + Txt = xmpp:format_error(Why), + Err = xmpp:make_error(El, xmpp:err_bad_request(Txt, Lang)), + send_element(StateData, Err); + _ when NS == ?NS_STREAM_MGMT_2; NS == ?NS_STREAM_MGMT_3 -> + Err = #sm_failed{reason = 'bad-request', xmlns = NS}, + send_element(StateData, Err); _ -> + ok + end, + fsm_next_state(StateName, StateData) + end. + +wait_for_bind({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_bind, StateData); +wait_for_bind(#sm_resume{} = Pkt, StateData) -> + case handle_resume(StateData, Pkt) of + {ok, ResumedState} -> + fsm_next_state(session_established, ResumedState); + error -> + fsm_next_state(wait_for_bind, StateData) + end; +wait_for_bind(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> + fsm_next_state(wait_for_bind, dispatch_stream_mgmt(Pkt, StateData)); +wait_for_bind(#iq{type = set, + sub_els = [#bind{resource = R}]} = IQ, StateData) -> + U = StateData#state.user, + case resource_conflict_action(U, StateData#state.server, R) of + closenew -> + Err = xmpp:make_error(IQ, xmpp:err_conflict()), + send_element(StateData, Err), + fsm_next_state(wait_for_bind, StateData); + {accept_resource, R2} -> + JID = jid:make(U, StateData#state.server, R2), + StateData2 = StateData#state{resource = R2, jid = JID}, + case open_session(StateData2) of + {ok, StateData3} -> + Res = xmpp:make_iq_result(IQ, #bind{jid = JID}), + try + send_element(StateData3, Res) + catch + exit:normal -> close(self()) + end, + fsm_next_state_pack(session_established,StateData3); + {error, Error} -> + Err = xmpp:make_error(IQ, Error), + send_element(StateData, Err), fsm_next_state(wait_for_bind, StateData) end end; +wait_for_bind(#compress{} = Comp, StateData) -> + Zlib = StateData#state.zlib, + SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket), + if Zlib == true, (SockMod == gen_tcp) or (SockMod == fast_tls) -> + process_compression_request(Comp, wait_for_bind, StateData); + true -> + send_element(StateData, #compress_failure{reason = 'setup-failed'}), + fsm_next_state(wait_for_bind, StateData) + end; wait_for_bind(timeout, StateData) -> {stop, normal, StateData}; wait_for_bind({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; wait_for_bind({xmlstreamerror, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_bind(closed, StateData) -> {stop, normal, StateData}; wait_for_bind(stop, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +wait_for_bind(Pkt, StateData) -> + case xmpp:is_stanza(Pkt) of + true -> + Type = xmpp:get_type(Pkt), + if Type /= error, Type /= result -> + Err = xmpp:make_error(Pkt, xmpp:err_not_acceptable()), + send_element(StateData, Err); + true -> + ok + end; + false -> + ok + end, + fsm_next_state(wait_for_bind, StateData). +-spec open_session(state()) -> {ok, state()} | {error, error()}. open_session(StateData) -> U = StateData#state.user, R = StateData#state.resource, @@ -1145,33 +1009,18 @@ open_session(StateData) -> ?INFO_MSG("(~w) Forbidden session for ~s", [StateData#state.socket, jid:to_string(JID)]), Txt = <<"Denied by ACL">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)} + {error, xmpp:err_not_allowed(Txt, Lang)} end. -session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> - fsm_next_state(session_established, dispatch_stream_mgmt(El, StateData)); -session_established({xmlstreamelement, - #xmlel{name = <<"active">>, - attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}]}}, - StateData) -> +session_established({xmlstreamelement, El}, StateData) -> + decode_element(El, session_established, StateData); +session_established(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> + fsm_next_state(session_established, dispatch_stream_mgmt(Pkt, StateData)); +session_established(#csi{type = active}, StateData) -> NewStateData = csi_flush_queue(StateData), fsm_next_state(session_established, NewStateData#state{csi_state = active}); -session_established({xmlstreamelement, - #xmlel{name = <<"inactive">>, - attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}]}}, - StateData) -> +session_established(#csi{type = inactive}, StateData) -> fsm_next_state(session_established, StateData#state{csi_state = inactive}); -session_established({xmlstreamelement, El}, - StateData) -> - FromJID = StateData#state.jid, - case check_from(El, FromJID) of - 'invalid-from' -> - send_element(StateData, ?INVALID_FROM), - {stop, normal, StateData}; - _NewEl -> - session_established2(El, StateData) - end; %% We hibernate the process to reduce memory consumption after a %% configurable activity timeout session_established(timeout, StateData) -> @@ -1185,10 +1034,10 @@ session_established({xmlstreamerror, <<"XML stanza is too big">> = E}, StateData) -> send_element(StateData, - ?POLICY_VIOLATION_ERR((StateData#state.lang), E)), + xmpp:serr_policy_violation(E, StateData#state.lang)), {stop, normal, StateData}; session_established({xmlstreamerror, _}, StateData) -> - send_element(StateData, ?INVALID_XML_ERR), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; session_established(closed, #state{mgmt_state = active} = StateData) -> catch (StateData#state.sockmod):close(StateData#state.socket), @@ -1196,92 +1045,82 @@ session_established(closed, #state{mgmt_state = active} = StateData) -> session_established(closed, StateData) -> {stop, normal, StateData}; session_established(stop, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +session_established(Pkt, StateData) -> + FromJID = StateData#state.jid, + case check_from(Pkt, FromJID) of + 'invalid-from' -> + send_element(StateData, xmpp:serr_invalid_from()), + {stop, normal, StateData}; + _ -> + NewStateData = update_num_stanzas_in(StateData, Pkt), + session_established2(Pkt, NewStateData) + end. +-spec session_established2(xmpp_element(), state()) -> fsm_next(). %% Process packets sent by user (coming from user on c2s XMPP connection) -session_established2(El, StateData) -> - #xmlel{name = Name, attrs = Attrs} = El, - NewStateData = update_num_stanzas_in(StateData, El), - User = NewStateData#state.user, - Server = NewStateData#state.server, - FromJID = NewStateData#state.jid, - To = fxml:get_attr_s(<<"to">>, Attrs), - ToJID = case To of - <<"">> -> jid:make(User, Server, <<"">>); - _ -> jid:from_string(To) - end, - NewEl1 = jlib:remove_attr(<<"xmlns">>, El), - NewEl = case fxml:get_attr_s(<<"xml:lang">>, Attrs) of - <<"">> -> - case NewStateData#state.lang of - <<"">> -> NewEl1; - Lang -> - fxml:replace_tag_attr(<<"xml:lang">>, Lang, NewEl1) - end; - _ -> NewEl1 +session_established2(Pkt, StateData) when ?is_stanza(Pkt) -> + User = StateData#state.user, + Server = StateData#state.server, + FromJID = StateData#state.jid, + ToJID = case xmpp:get_to(Pkt) of + undefined -> jid:make(User, Server, <<"">>); + J -> J end, - NewState = case ToJID of - error -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> NewStateData; - <<"result">> -> NewStateData; - _ -> - Err = jlib:make_error_reply(NewEl, - ?ERR_JID_MALFORMED), - send_packet(NewStateData, Err) - end; - _ -> - case Name of - <<"presence">> -> - PresenceEl0 = - ejabberd_hooks:run_fold(c2s_update_presence, - Server, NewEl, - [User, Server]), - PresenceEl = - ejabberd_hooks:run_fold( - user_send_packet, Server, PresenceEl0, - [NewStateData, FromJID, ToJID]), - case ToJID of - #jid{user = User, server = Server, - resource = <<"">>} -> - ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)", - [FromJID, PresenceEl, NewStateData]), - presence_update(FromJID, PresenceEl, - NewStateData); - _ -> - presence_track(FromJID, ToJID, PresenceEl, - NewStateData) - end; - <<"iq">> -> - case jlib:iq_query_info(NewEl) of - #iq{xmlns = Xmlns} = IQ - when Xmlns == (?NS_PRIVACY); - Xmlns == (?NS_BLOCKING) -> - process_privacy_iq(FromJID, ToJID, IQ, - NewStateData); - #iq{xmlns = ?NS_SESSION} -> - Res = jlib:make_result_iq_reply( - NewEl#xmlel{children = []}), - send_stanza(NewStateData, Res); - _ -> - NewEl0 = ejabberd_hooks:run_fold( - user_send_packet, Server, NewEl, - [NewStateData, FromJID, ToJID]), - check_privacy_route(FromJID, NewStateData, - FromJID, ToJID, NewEl0) - end; - <<"message">> -> - NewEl0 = ejabberd_hooks:run_fold( - user_send_packet, Server, NewEl, - [NewStateData, FromJID, ToJID]), - check_privacy_route(FromJID, NewStateData, FromJID, - ToJID, NewEl0); - _ -> NewStateData - end - end, + Lang = case xmpp:get_lang(Pkt) of + undefined -> StateData#state.lang; + <<"">> -> StateData#state.lang; + L -> L + end, + NewPkt = xmpp:set_lang(Pkt, Lang), + NewState = + case NewPkt of + #presence{} -> + Presence0 = ejabberd_hooks:run_fold( + c2s_update_presence, Server, NewPkt, + [User, Server]), + Presence = ejabberd_hooks:run_fold( + user_send_packet, Server, Presence0, + [StateData, FromJID, ToJID]), + case ToJID of + #jid{user = User, server = Server, resource = <<"">>} -> + ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)", + [FromJID, Presence, StateData]), + presence_update(FromJID, Presence, + StateData); + _ -> + presence_track(FromJID, ToJID, Presence, + StateData) + end; + #iq{type = T, sub_els = [El]} when T == set; T == get -> + NS = xmpp:get_ns(El), + if NS == ?NS_BLOCKING; NS == ?NS_PRIVACY -> + IQ = xmpp:set_from_to(Pkt, FromJID, ToJID), + process_privacy_iq(IQ, StateData); + NS == ?NS_SESSION -> + Res = xmpp:make_iq_result(Pkt), + send_stanza(StateData, Res); + true -> + NewPkt0 = ejabberd_hooks:run_fold( + user_send_packet, Server, NewPkt, + [StateData, FromJID, ToJID]), + check_privacy_route(FromJID, StateData, FromJID, + ToJID, NewPkt0) + end; + _ -> + NewPkt0 = ejabberd_hooks:run_fold( + user_send_packet, Server, NewPkt, + [StateData, FromJID, ToJID]), + check_privacy_route(FromJID, StateData, FromJID, + ToJID, NewPkt0) + end, + ejabberd_hooks:run(c2s_loop_debug, + [{xmlstreamelement, Pkt}]), + fsm_next_state(session_established, NewState); +session_established2(Pkt, StateData) -> ejabberd_hooks:run(c2s_loop_debug, - [{xmlstreamelement, El}]), - fsm_next_state(session_established, NewState). + [{xmlstreamelement, Pkt}]), + fsm_next_state(session_established, StateData). wait_for_resume({xmlstreamelement, _El} = Event, StateData) -> Result = session_established(Event, StateData), @@ -1335,14 +1174,14 @@ handle_info({send_text, Text}, StateName, StateData) -> fsm_next_state(StateName, StateData); handle_info(replaced, StateName, StateData) -> Lang = StateData#state.lang, - Xmlelement = ?SERRT_CONFLICT(Lang, <<"Replaced by new connection">>), - handle_info({kick, replaced, Xmlelement}, StateName, StateData); + Pkt = xmpp:serr_conflict(<<"Replaced by new connection">>, Lang), + handle_info({kick, replaced, Pkt}, StateName, StateData); handle_info(kick, StateName, StateData) -> Lang = StateData#state.lang, - Xmlelement = ?SERRT_POLICY_VIOLATION(Lang, <<"has been kicked">>), - handle_info({kick, kicked_by_admin, Xmlelement}, StateName, StateData); -handle_info({kick, Reason, Xmlelement}, _StateName, StateData) -> - send_element(StateData, Xmlelement), + Pkt = xmpp:serr_policy_violation(<<"has been kicked">>, Lang), + handle_info({kick, kicked_by_admin, Pkt}, StateName, StateData); +handle_info({kick, Reason, Pkt}, _StateName, StateData) -> + send_element(StateData, Pkt), {stop, normal, StateData#state{authenticated = Reason}}; handle_info({route, _From, _To, {broadcast, Data}}, @@ -1354,7 +1193,7 @@ handle_info({route, _From, _To, {broadcast, Data}}, roster_change(IJID, ISubscription, StateData)); {exit, Reason} -> Lang = StateData#state.lang, - send_element(StateData, ?SERRT_CONFLICT(Lang, Reason)), + send_element(StateData, xmpp:serr_conflict(Reason, Lang)), {stop, normal, StateData}; {privacy_list, PrivList, PrivListName} -> case ejabberd_hooks:run_fold(privacy_updated_list, @@ -1365,24 +1204,15 @@ handle_info({route, _From, _To, {broadcast, Data}}, false -> fsm_next_state(StateName, StateData); NewPL -> - PrivPushIQ = #iq{type = set, - id = <<"push", - (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, - ?NS_PRIVACY}], - children = - [#xmlel{name = <<"list">>, - attrs = [{<<"name">>, - PrivListName}], - children = []}]}]}, - PrivPushEl = jlib:replace_from_to( - jid:remove_resource(StateData#state.jid), - StateData#state.jid, - jlib:iq_to_xml(PrivPushIQ)), - NewState = send_stanza( - StateData, PrivPushEl), + PrivPushIQ = + #iq{type = set, + from = jid:remove_resource(StateData#state.jid), + to = StateData#state.jid, + id = <<"push", (randoms:get_string())/binary>>, + sub_els = [#privacy_query{ + lists = [#privacy_list{ + name = PrivListName}]}]}, + NewState = send_stanza(StateData, PrivPushIQ), fsm_next_state(StateName, NewState#state{privacy_list = NewPL}) end; @@ -1393,265 +1223,147 @@ handle_info({route, _From, _To, {broadcast, Data}}, fsm_next_state(StateName, StateData) end; %% Process Packets that are to be send to the user -handle_info({route, From, To, - #xmlel{name = Name, attrs = Attrs, children = Els} = Packet}, - StateName, StateData) -> - {Pass, NewAttrs, NewState} = case Name of - <<"presence">> -> - State = - ejabberd_hooks:run_fold(c2s_presence_in, - StateData#state.server, - StateData, - [{From, To, - Packet}]), - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"probe">> -> - LFrom = jid:tolower(From), - LBFrom = - jid:remove_resource(LFrom), - NewStateData = case - (?SETS):is_element(LFrom, - State#state.pres_a) - orelse - (?SETS):is_element(LBFrom, - State#state.pres_a) - of - true -> State; - false -> - case - (?SETS):is_element(LFrom, - State#state.pres_f) - of - true -> - A = - (?SETS):add_element(LFrom, - State#state.pres_a), - State#state{pres_a - = - A}; - false -> - case - (?SETS):is_element(LBFrom, - State#state.pres_f) - of - true -> - A = - (?SETS):add_element(LBFrom, - State#state.pres_a), - State#state{pres_a - = - A}; - false -> - State - end - end - end, - process_presence_probe(From, To, - NewStateData), - {false, Attrs, NewStateData}; - <<"error">> -> - NewA = - remove_element(jid:tolower(From), - State#state.pres_a), - {true, Attrs, - State#state{pres_a = NewA}}; - <<"subscribe">> -> - SRes = is_privacy_allow(State, - From, To, - Packet, - in), - {SRes, Attrs, State}; - <<"subscribed">> -> - SRes = is_privacy_allow(State, - From, To, - Packet, - in), - {SRes, Attrs, State}; - <<"unsubscribe">> -> - SRes = is_privacy_allow(State, - From, To, - Packet, - in), - {SRes, Attrs, State}; - <<"unsubscribed">> -> - SRes = is_privacy_allow(State, - From, To, - Packet, - in), - {SRes, Attrs, State}; - _ -> - case privacy_check_packet(State, - From, To, - Packet, - in) - of - allow -> - LFrom = - jid:tolower(From), - LBFrom = - jid:remove_resource(LFrom), - case - (?SETS):is_element(LFrom, - State#state.pres_a) - orelse - (?SETS):is_element(LBFrom, - State#state.pres_a) - of - true -> - {true, Attrs, State}; - false -> - case - (?SETS):is_element(LFrom, - State#state.pres_f) - of - true -> - A = - (?SETS):add_element(LFrom, - State#state.pres_a), - {true, Attrs, - State#state{pres_a - = - A}}; - false -> - case - (?SETS):is_element(LBFrom, - State#state.pres_f) - of - true -> - A = - (?SETS):add_element(LBFrom, - State#state.pres_a), - {true, - Attrs, - State#state{pres_a - = - A}}; - false -> - {true, - Attrs, - State} - end - end - end; - deny -> {false, Attrs, State} - end - end; - <<"iq">> -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{xmlns = ?NS_LAST} -> - LFrom = jid:tolower(From), - LBFrom = - jid:remove_resource(LFrom), - HasFromSub = - ((?SETS):is_element(LFrom, - StateData#state.pres_f) - orelse - (?SETS):is_element(LBFrom, - StateData#state.pres_f)) - andalso - is_privacy_allow(StateData, - To, From, - #xmlel{name - = - <<"presence">>, - attrs - = - [], - children - = - []}, - out), - case HasFromSub of - true -> - case - privacy_check_packet(StateData, - From, - To, - Packet, - in) - of - allow -> - {true, Attrs, - StateData}; - deny -> - Err = - jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, - From, - Err), - {false, Attrs, - StateData} - end; - _ -> - Err = - jlib:make_error_reply(Packet, - ?ERR_FORBIDDEN), - ejabberd_router:route(To, - From, - Err), - {false, Attrs, StateData} - end; - IQ - when is_record(IQ, iq) or - (IQ == reply) -> - case - privacy_check_packet(StateData, - From, To, - Packet, in) - of - allow -> - {true, Attrs, StateData}; - deny when is_record(IQ, iq) -> - Err = - jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, - From, - Err), - {false, Attrs, StateData}; - deny when IQ == reply -> - {false, Attrs, StateData} - end; - IQ - when (IQ == invalid) or - (IQ == not_iq) -> - {false, Attrs, StateData} - end; - <<"message">> -> - case privacy_check_packet(StateData, - From, To, - Packet, in) - of - allow -> - {true, Attrs, StateData}; - deny -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - <<"groupchat">> -> ok; - <<"headline">> -> ok; - _ -> - Err = - jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, - Err) - end, - {false, Attrs, StateData} - end; - _ -> {true, Attrs, StateData} - end, +handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Packet) -> + {Pass, NewState} = + case Packet of + #presence{type = T} -> + State = ejabberd_hooks:run_fold(c2s_presence_in, + StateData#state.server, + StateData, + [{From, To, Packet}]), + case T of + probe -> + LFrom = jid:tolower(From), + LBFrom = jid:remove_resource(LFrom), + NewStateData = + case (?SETS):is_element(LFrom, State#state.pres_a) + orelse (?SETS):is_element(LBFrom, State#state.pres_a) of + true -> State; + false -> + case (?SETS):is_element(LFrom, State#state.pres_f) of + true -> + A = (?SETS):add_element(LFrom, State#state.pres_a), + State#state{pres_a = A}; + false -> + case (?SETS):is_element(LBFrom, State#state.pres_f) of + true -> + A = (?SETS):add_element(LBFrom, State#state.pres_a), + State#state{pres_a = A}; + false -> + State + end + end + end, + process_presence_probe(From, To, NewStateData), + {false, NewStateData}; + error -> + NewA = remove_element(jid:tolower(From), State#state.pres_a), + {true, State#state{pres_a = NewA}}; + subscribe -> + SRes = is_privacy_allow(State, From, To, Packet, in), + {SRes, State}; + subscribed -> + SRes = is_privacy_allow(State, From, To, Packet, in), + {SRes, State}; + unsubscribe -> + SRes = is_privacy_allow(State, From, To, Packet, in), + {SRes, State}; + unsubscribed -> + SRes = is_privacy_allow(State, From, To, Packet, in), + {SRes, State}; + _ -> + case privacy_check_packet(State, From, To, Packet, in) of + allow -> + LFrom = jid:tolower(From), + LBFrom = jid:remove_resource(LFrom), + case (?SETS):is_element(LFrom, State#state.pres_a) + orelse (?SETS):is_element(LBFrom, State#state.pres_a) of + true -> + {true, State}; + false -> + case (?SETS):is_element(LFrom, State#state.pres_f) of + true -> + A = (?SETS):add_element(LFrom, State#state.pres_a), + {true, State#state{pres_a = A}}; + false -> + case (?SETS):is_element(LBFrom, + State#state.pres_f) of + true -> + A = (?SETS):add_element( + LBFrom, + State#state.pres_a), + {true, State#state{pres_a = A}}; + false -> + {true, State} + end + end + end; + deny -> {false, State} + end + end; + #iq{type = T} -> + case xmpp:has_subtag(Packet, #last{}) of + true when T == get; T == set -> + LFrom = jid:tolower(From), + LBFrom = jid:remove_resource(LFrom), + HasFromSub = ((?SETS):is_element(LFrom, StateData#state.pres_f) + orelse (?SETS):is_element(LBFrom, StateData#state.pres_f)) + andalso is_privacy_allow(StateData, To, From, #presence{}, out), + case HasFromSub of + true -> + case privacy_check_packet( + StateData, From, To, Packet, in) of + allow -> + {true, StateData}; + deny -> + Err = xmpp:make_error( + Packet, + xmpp:err_service_unavailable()), + ejabberd_router:route(To, From, Err), + {false, StateData} + end; + _ -> + Err = xmpp:make_error(Packet, xmpp:err_forbidden()), + ejabberd_router:route(To, From, Err), + {false, StateData} + end; + _ -> + case privacy_check_packet(StateData, From, To, Packet, in) of + allow -> + {true, StateData}; + deny when T == get; T == set -> + Err = xmpp:make_error( + Packet, xmpp:err_service_unavailable()), + ejabberd_router:route(To, From, Err), + {false, StateData}; + deny -> + {false, StateData} + end + end; + #message{type = T} -> + case privacy_check_packet(StateData, From, To, Packet, in) of + allow -> + {true, StateData}; + deny -> + case T of + error -> ok; + groupchat -> ok; + headline -> ok; + _ -> + Err = xmpp:make_error( + Packet, xmpp:err_service_unavailable()), + ejabberd_router:route(To, From, Err) + end, + {false, StateData} + end + end, if Pass -> - Attrs2 = - jlib:replace_from_to_attrs(jid:to_string(From), - jid:to_string(To), NewAttrs), - FixedPacket0 = #xmlel{name = Name, attrs = Attrs2, children = Els}, + FixedPacket0 = xmpp:set_from_to(Packet, From, To), FixedPacket = ejabberd_hooks:run_fold( - user_receive_packet, - NewState#state.server, - FixedPacket0, - [NewState, NewState#state.jid, From, To]), + user_receive_packet, + NewState#state.server, + FixedPacket0, + [NewState, NewState#state.jid, From, To]), SentStateData = send_packet(NewState, FixedPacket), ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), fsm_next_state(StateName, SentStateData); @@ -1672,10 +1384,10 @@ handle_info(system_shutdown, StateName, StateData) -> case StateName of wait_for_stream -> send_header(StateData, ?MYNAME, <<"1.0">>, <<"en">>), - send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), + send_element(StateData, xmpp:serr_system_shutdown()), ok; _ -> - send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), + send_element(StateData, xmpp:serr_system_shutdown()), ok end, {stop, normal, StateData}; @@ -1686,17 +1398,17 @@ handle_info({route_xmlstreamelement, El}, _StateName, StateData) -> handle_info({force_update_presence, LUser, LServer}, StateName, #state{jid = #jid{luser = LUser, lserver = LServer}} = StateData) -> NewStateData = case StateData#state.pres_last of - #xmlel{name = <<"presence">>} -> - PresenceEl = - ejabberd_hooks:run_fold(c2s_update_presence, - LServer, - StateData#state.pres_last, - [LUser, LServer]), - StateData2 = StateData#state{pres_last = PresenceEl}, - presence_update(StateData2#state.jid, PresenceEl, - StateData2), - StateData2; - _ -> StateData + #presence{} -> + Presence = + ejabberd_hooks:run_fold(c2s_update_presence, + LServer, + StateData#state.pres_last, + [LUser, LServer]), + StateData2 = StateData#state{pres_last = Presence}, + presence_update(StateData2#state.jid, Presence, + StateData2), + StateData2; + undefined -> StateData end, fsm_next_state(StateName, NewStateData); handle_info({send_filtered, Feature, From, To, Packet}, StateName, StateData) -> @@ -1709,7 +1421,7 @@ handle_info({send_filtered, Feature, From, To, Packet}, StateName, StateData) -> jid:to_string(To)]), StateData; true -> - FinalPacket = jlib:replace_from_to(From, To, Packet), + FinalPacket = xmpp:set_from_to(Packet, From, To), case StateData#state.jid of To -> case privacy_check_packet(StateData, From, To, @@ -1742,6 +1454,7 @@ handle_info(Info, StateName, StateData) -> ?ERROR_MSG("Unexpected info: ~p", [Info]), fsm_next_state(StateName, StateData). +-spec print_state(state()) -> state(). print_state(State = #state{pres_t = T, pres_f = F, pres_a = A}) -> State#state{pres_t = {pres_t, (?SETS):size(T)}, pres_f = {pres_f, (?SETS):size(F)}, @@ -1761,18 +1474,16 @@ terminate(_Reason, StateName, StateData) -> [StateData#state.socket, jid:to_string(StateData#state.jid)]), From = StateData#state.jid, - Packet = #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"unavailable">>}], - children = - [#xmlel{name = <<"status">>, attrs = [], - children = - [{xmlcdata, - <<"Replaced by new connection">>}]}]}, + Lang = StateData#state.lang, + Status = <<"Replaced by new connection">>, + Packet = #presence{ + type = unavailable, + status = xmpp:mk_text(Status, Lang)}, ejabberd_sm:close_session_unset_presence(StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource, - <<"Replaced by new connection">>), + Status), presence_broadcast(StateData, From, StateData#state.pres_a, Packet); _ -> @@ -1788,9 +1499,7 @@ terminate(_Reason, StateName, StateData) -> StateData#state.resource); _ -> From = StateData#state.jid, - Packet = #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"unavailable">>}], - children = []}, + Packet = #presence{type = unavailable}, ejabberd_sm:close_session_unset_presence(StateData#state.sid, StateData#state.user, StateData#state.server, @@ -1825,7 +1534,7 @@ terminate(_Reason, StateName, StateData) -> %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- - +-spec change_shaper(state(), jid()) -> ok. change_shaper(StateData, JID) -> Shaper = acl:access_matches(StateData#state.shaper, #{usr => jid:split(JID), ip => StateData#state.ip}, @@ -1833,6 +1542,7 @@ change_shaper(StateData, JID) -> (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper). +-spec send_text(state(), iodata()) -> ok | {error, any()}. send_text(StateData, Text) when StateData#state.mgmt_state == pending -> ?DEBUG("Cannot send text while waiting for resumption: ~p", [Text]); send_text(StateData, Text) when StateData#state.xml_socket -> @@ -1852,14 +1562,18 @@ send_text(StateData, Text) -> ?DEBUG("Send XML on stream = ~p", [Text]), (StateData#state.sockmod):send(StateData#state.socket, Text). +-spec send_element(state(), xmlel() | xmpp_element()) -> ok | {error, any()}. send_element(StateData, El) when StateData#state.mgmt_state == pending -> ?DEBUG("Cannot send element while waiting for resumption: ~p", [El]); -send_element(StateData, El) when StateData#state.xml_socket -> +send_element(StateData, #xmlel{} = El) when StateData#state.xml_socket -> (StateData#state.sockmod):send_xml(StateData#state.socket, {xmlstreamelement, El}); -send_element(StateData, El) -> - send_text(StateData, fxml:element_to_binary(El)). +send_element(StateData, #xmlel{} = El) -> + send_text(StateData, fxml:element_to_binary(El)); +send_element(StateData, Pkt) -> + send_element(StateData, xmpp:encode(Pkt)). +-spec send_stanza(state(), xmpp_element()) -> state(). send_stanza(StateData, Stanza) when StateData#state.csi_state == inactive -> csi_filter_stanza(StateData, Stanza); send_stanza(StateData, Stanza) when StateData#state.mgmt_state == pending -> @@ -1871,8 +1585,9 @@ send_stanza(StateData, Stanza) -> send_element(StateData, Stanza), StateData. +-spec send_packet(state(), xmpp_element()) -> state(). send_packet(StateData, Packet) -> - case is_stanza(Packet) of + case xmpp:is_stanza(Packet) of true -> send_stanza(StateData, Packet); false -> @@ -1880,6 +1595,7 @@ send_packet(StateData, Packet) -> StateData end. +-spec send_header(state(), binary(), binary(), binary()) -> ok | {error, any()}. send_header(StateData, Server, Version, Lang) when StateData#state.xml_socket -> VersionAttr = case Version of @@ -1914,6 +1630,7 @@ send_header(StateData, Server, Version, Lang) -> LangStr]), send_text(StateData, iolist_to_binary(Header)). +-spec send_trailer(state()) -> ok | {error, any()}. send_trailer(StateData) when StateData#state.mgmt_state == pending -> ?DEBUG("Cannot send stream trailer while waiting for resumption", []); @@ -1924,64 +1641,24 @@ send_trailer(StateData) send_trailer(StateData) -> send_text(StateData, ?STREAM_TRAILER). +-spec new_id() -> binary(). new_id() -> randoms:get_string(). +-spec new_uniq_id() -> binary(). new_uniq_id() -> iolist_to_binary([randoms:get_string(), jlib:integer_to_binary(p1_time_compat:unique_integer([positive]))]). -is_auth_packet(El) -> - case jlib:iq_query_info(El) of - #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} -> - #xmlel{children = Els} = SubEl, - {auth, ID, Type, - get_auth_tags(Els, <<"">>, <<"">>, <<"">>, <<"">>)}; - _ -> false - end. - -is_stanza(#xmlel{name = Name, attrs = Attrs}) when Name == <<"message">>; - Name == <<"presence">>; - Name == <<"iq">> -> - case fxml:get_attr(<<"xmlns">>, Attrs) of - {value, NS} when NS /= <<"jabber:client">>, - NS /= <<"jabber:server">> -> - false; - _ -> - true - end; -is_stanza(_El) -> - false. - -get_auth_tags([#xmlel{name = Name, children = Els} | L], - U, P, D, R) -> - CData = fxml:get_cdata(Els), - case Name of - <<"username">> -> get_auth_tags(L, CData, P, D, R); - <<"password">> -> get_auth_tags(L, U, CData, D, R); - <<"digest">> -> get_auth_tags(L, U, P, CData, R); - <<"resource">> -> get_auth_tags(L, U, P, D, CData); - _ -> get_auth_tags(L, U, P, D, R) - end; -get_auth_tags([_ | L], U, P, D, R) -> - get_auth_tags(L, U, P, D, R); -get_auth_tags([], U, P, D, R) -> - {U, P, D, R}. - -%% Copied from ejabberd_socket.erl --record(socket_state, {sockmod, socket, receiver}). - +-spec get_conn_type(state()) -> c2s | c2s_tls | c2s_compressed | websocket | + c2s_compressed_tls | http_bind. get_conn_type(StateData) -> - case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of - gen_tcp -> c2s; - fast_tls -> c2s_tls; - ezlib -> - case ezlib:get_sockmod((StateData#state.socket)#socket_state.socket) of - gen_tcp -> c2s_compressed; - fast_tls -> c2s_compressed_tls - end; - ejabberd_http_bind -> http_bind; - ejabberd_http_ws -> websocket; - _ -> unknown + case (StateData#state.sockmod):get_transport(StateData#state.socket) of + tcp -> c2s; + tls -> c2s_tls; + tcp_zlib -> c2s_compressed; + tls_zlib -> c2s_compressed_tls; + http_bind -> http_bind; + websocket -> websocket end. process_presence_probe(From, To, StateData) -> @@ -1997,8 +1674,9 @@ process_presence_probe(From, To, StateData) -> (?SETS):is_element(LBFrom, StateData#state.pres_f))), if Cond -> %% To is the one sending the presence (the probe target) - Packet = jlib:add_delay_info(StateData#state.pres_last, To, - StateData#state.pres_timestamp), + Packet = xmpp_util:add_delay_info( + StateData#state.pres_last, To, + StateData#state.pres_timestamp), case privacy_check_packet(StateData, To, From, Packet, out) of deny -> ok; @@ -2020,13 +1698,10 @@ process_presence_probe(From, To, StateData) -> %% User updates his presence (non-directed presence packet) presence_update(From, Packet, StateData) -> - #xmlel{attrs = Attrs} = Packet, - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"unavailable">> -> - Status = case fxml:get_subtag(Packet, <<"status">>) of - false -> <<"">>; - StatusTag -> fxml:get_tag_cdata(StatusTag) - end, + #presence{type = Type} = Packet, + case Type of + unavailable -> + Status = xmpp:get_text(Packet#presence.status), Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn}, {auth_module, StateData#state.auth_module}], @@ -2038,12 +1713,12 @@ presence_update(From, Packet, StateData) -> StateData#state.pres_a, Packet), StateData#state{pres_last = undefined, pres_timestamp = undefined, pres_a = (?SETS):new()}; - <<"error">> -> StateData; - <<"probe">> -> StateData; - <<"subscribe">> -> StateData; - <<"subscribed">> -> StateData; - <<"unsubscribe">> -> StateData; - <<"unsubscribed">> -> StateData; + error -> StateData; + probe -> StateData; + subscribe -> StateData; + subscribed -> StateData; + unsubscribe -> StateData; + unsubscribed -> StateData; _ -> OldPriority = case StateData#state.pres_last of undefined -> 0; @@ -2082,31 +1757,31 @@ presence_update(From, Packet, StateData) -> %% User sends a directed presence packet presence_track(From, To, Packet, StateData) -> - #xmlel{attrs = Attrs} = Packet, + #presence{type = Type} = Packet, LTo = jid:tolower(To), User = StateData#state.user, Server = StateData#state.server, - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"unavailable">> -> + case Type of + unavailable -> A = remove_element(LTo, StateData#state.pres_a), check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet); - <<"subscribe">> -> + subscribe -> try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData); - <<"subscribed">> -> + subscribed -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, subscribed]), check_privacy_route(From, StateData, jid:remove_resource(From), To, Packet); - <<"unsubscribe">> -> + unsubscribe -> try_roster_subscribe(unsubscribe, User, Server, From, To, Packet, StateData); - <<"unsubscribed">> -> + unsubscribed -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, unsubscribed]), check_privacy_route(From, StateData, jid:remove_resource(From), To, Packet); - <<"error">> -> + error -> check_privacy_route(From, StateData, From, To, Packet); - <<"probe">> -> + probe -> check_privacy_route(From, StateData, From, To, Packet); _ -> A = (?SETS):add_element(LTo, StateData#state.pres_a), @@ -2122,12 +1797,12 @@ check_privacy_route(From, StateData, FromRoute, To, Lang = StateData#state.lang, ErrText = <<"Your active privacy list has denied " "the routing of this stanza.">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), - Err2 = jlib:replace_from_to(To, From, Err), - send_stanza(StateData, Err2); + Err = xmpp:make_error( + xmpp:set_from_to(Packet, From, To), + xmpp:err_not_acceptable(ErrText, Lang)), + send_stanza(StateData, Err); allow -> - ejabberd_router:route(FromRoute, To, Packet), + ejabberd_router:route(FromRoute, To, Packet), StateData end. @@ -2182,7 +1857,7 @@ presence_broadcast_first(From, StateData, Packet) -> fun(JID, L) -> [JID | L] end, [], StateData#state.pres_t), - PacketProbe = #xmlel{name = <<"presence">>, attrs = [{<<"type">>,<<"probe">>}], children = []}, + PacketProbe = #presence{type = probe}, JIDs2Probe = format_and_check_privacy(From, StateData, PacketProbe, JIDsProbe, out), Server = StateData#state.server, send_multiple(From, Server, JIDs2Probe, PacketProbe), @@ -2260,9 +1935,7 @@ roster_change(IJID, ISubscription, StateData) -> pres_t = TSet}; Cond2 -> ?DEBUG("C2: ~p~n", [LIJID]), - PU = #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"unavailable">>}], - children = []}, + PU = #presence{type = unavailable}, case privacy_check_packet(StateData, From, To, PU, out) of deny -> ok; @@ -2282,20 +1955,14 @@ update_priority(Priority, Packet, StateData) -> StateData#state.user, StateData#state.server, StateData#state.resource, Priority, Packet, Info). -get_priority_from_presence(PresencePacket) -> - case fxml:get_subtag(PresencePacket, <<"priority">>) of - false -> 0; - SubEl -> - case catch - jlib:binary_to_integer(fxml:get_tag_cdata(SubEl)) - of - P when is_integer(P) -> P; - _ -> 0 - end +get_priority_from_presence(#presence{priority = Prio}) -> + case Prio of + undefined -> 0; + _ -> Prio end. -process_privacy_iq(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ, StateData) -> +process_privacy_iq(#iq{from = From, to = To, + type = Type, lang = Lang} = IQ, StateData) -> Txt = <<"No module is handling this query">>, {Res, NewStateData} = case Type of @@ -2303,16 +1970,15 @@ process_privacy_iq(From, To, R = ejabberd_hooks:run_fold( privacy_iq_get, StateData#state.server, - {error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}, - [From, To, IQ, - StateData#state.privacy_list]), + {error, xmpp:err_feature_not_implemented(Txt, Lang)}, + [IQ, StateData#state.privacy_list]), {R, StateData}; set -> case ejabberd_hooks:run_fold( privacy_iq_set, StateData#state.server, - {error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}, - [From, To, IQ]) + {error, xmpp:err_feature_not_implemented(Txt, Lang)}, + [IQ]) of {result, R, NewPrivList} -> {{result, R}, @@ -2323,11 +1989,11 @@ process_privacy_iq(From, To, end, IQRes = case Res of {result, Result} -> - IQ#iq{type = result, sub_el = Result}; + xmpp:make_iq_result(IQ, Result); {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} + xmpp:make_error(IQ, Error) end, - ejabberd_router:route(To, From, jlib:iq_to_xml(IQRes)), + ejabberd_router:route(To, From, IQRes), NewStateData. resend_offline_messages(#state{ask_offline = true} = StateData) -> @@ -2336,8 +2002,7 @@ resend_offline_messages(#state{ask_offline = true} = StateData) -> [StateData#state.user, StateData#state.server]) of Rs -> %%when is_list(Rs) -> - lists:foreach(fun ({route, From, To, - #xmlel{} = Packet}) -> + lists:foreach(fun ({route, From, To, Packet}) -> Pass = case privacy_check_packet(StateData, From, To, Packet, in) @@ -2367,50 +2032,35 @@ resend_subscription_requests(#state{user = User, PendingSubscriptions). get_showtag(undefined) -> <<"unavailable">>; -get_showtag(Presence) -> - case fxml:get_path_s(Presence, [{elem, <<"show">>}, cdata]) of - <<"">> -> <<"available">>; - ShowTag -> ShowTag - end. +get_showtag(#presence{show = undefined}) -> <<"available">>; +get_showtag(#presence{show = Show}) -> atom_to_binary(Show, utf8). -get_statustag(undefined) -> <<"">>; -get_statustag(Presence) -> - fxml:get_path_s(Presence, [{elem, <<"status">>}, cdata]). - -process_unauthenticated_stanza(StateData, El) -> - NewEl = case fxml:get_tag_attr_s(<<"xml:lang">>, El) of - <<"">> -> - case StateData#state.lang of - <<"">> -> El; - Lang -> fxml:replace_tag_attr(<<"xml:lang">>, Lang, El) - end; - _ -> El - end, - case jlib:iq_query_info(NewEl) of - #iq{lang = L} = IQ -> - Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq, - StateData#state.server, empty, - [StateData#state.server, IQ, - StateData#state.ip]), - case Res of - empty -> - Txt = <<"Authentication required">>, - ResIQ = IQ#iq{type = error, - sub_el = [?ERRT_SERVICE_UNAVAILABLE(L, Txt)]}, - Res1 = jlib:replace_from_to(jid:make(<<"">>, - StateData#state.server, - <<"">>), - jid:make(<<"">>, <<"">>, - <<"">>), - jlib:iq_to_xml(ResIQ)), - send_element(StateData, - jlib:remove_attr(<<"to">>, Res1)); - _ -> send_element(StateData, Res) - end; - _ -> - % Drop any stanza, which isn't IQ stanza - ok - end. +get_statustag(#presence{status = [#text{data = Status}|_]}) -> Status; +get_statustag(_) -> <<"">>. + +process_unauthenticated_stanza(StateData, #iq{type = T, lang = L} = IQ) + when T == set; T == get -> + Lang = if L == undefined; L == <<"">> -> StateData#state.lang; + true -> L + end, + NewIQ = IQ#iq{lang = Lang}, + Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq, + StateData#state.server, empty, + [StateData#state.server, NewIQ, + StateData#state.ip]), + case Res of + empty -> + Txt = <<"Authentication required">>, + Err0 = xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)), + Err1 = Err0#iq{from = jid:make(<<>>, StateData#state.server, <<>>), + to = undefined}, + send_element(StateData, Err1); + _ -> + send_element(StateData, Res) + end; +process_unauthenticated_stanza(_StateData, _) -> + %% Drop any stanza, which isn't IQ stanza + ok. peerip(SockMod, Socket) -> IP = case SockMod of @@ -2424,9 +2074,11 @@ peerip(SockMod, Socket) -> %% fsm_next_state_pack: Pack the StateData structure to improve %% sharing. +-spec fsm_next_state_pack(state_name(), state()) -> fsm_transition(). fsm_next_state_pack(StateName, StateData) -> fsm_next_state_gc(StateName, pack(StateData)). +-spec fsm_next_state_gc(state_name(), state()) -> fsm_transition(). %% fsm_next_state_gc: Garbage collect the process heap to make use of %% the newly packed StateData structure. fsm_next_state_gc(StateName, PackedStateData) -> @@ -2435,12 +2087,13 @@ fsm_next_state_gc(StateName, PackedStateData) -> %% fsm_next_state: Generate the next_state FSM tuple with different %% timeout, depending on the future state +-spec fsm_next_state(state_name(), state()) -> fsm_transition(). fsm_next_state(session_established, #state{mgmt_max_queue = exceeded} = StateData) -> ?WARNING_MSG("ACK queue too long, terminating session for ~s", [jid:to_string(StateData#state.jid)]), - Err = ?SERRT_POLICY_VIOLATION(StateData#state.lang, - <<"Too many unacked stanzas">>), + Err = xmpp:serr_policy_violation(<<"Too many unacked stanzas">>, + StateData#state.lang), send_element(StateData, Err), {stop, normal, StateData#state{mgmt_resend = false}}; fsm_next_state(session_established, #state{mgmt_state = pending} = StateData) -> @@ -2483,25 +2136,25 @@ is_ip_blacklisted({IP, _Port}, Lang) -> %% Check from attributes %% returns invalid-from|NewElement -check_from(El, FromJID) -> - case fxml:get_tag_attr(<<"from">>, El) of +check_from(Pkt, FromJID) -> + case xmpp:is_stanza(Pkt) of false -> - El; - {value, SJID} -> - JID = jid:from_string(SJID), + Pkt; + true -> + JID = xmpp:get_from(Pkt), case JID of - error -> - 'invalid-from'; + undefined -> + Pkt; #jid{} -> if (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == FromJID#jid.lresource) -> - El; + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == FromJID#jid.lresource) -> + Pkt; (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == <<"">>) -> - El; + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == <<"">>) -> + Pkt; true -> 'invalid-from' end @@ -2527,39 +2180,22 @@ bounce_messages() -> after 0 -> ok end. -process_compression_request(El, StateName, StateData) -> - case fxml:get_subtag(El, <<"method">>) of +process_compression_request(#compress{methods = []}, StateName, StateData) -> + send_element(StateData, #compress_failure{reason = 'setup-failed'}), + fsm_next_state(StateName, StateData); +process_compression_request(#compress{methods = Ms}, StateName, StateData) -> + case lists:member(<<"zlib">>, Ms) of + true -> + Socket = StateData#state.socket, + BCompressed = fxml:element_to_binary(xmpp:encode(#compressed{})), + ZlibSocket = (StateData#state.sockmod):compress(Socket, BCompressed), + fsm_next_state(wait_for_stream, + StateData#state{socket = ZlibSocket, + streamid = new_id()}); false -> send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_COMPRESS}], - children = - [#xmlel{name = <<"setup-failed">>, - attrs = [], children = []}]}), - fsm_next_state(StateName, StateData); - Method -> - case fxml:get_tag_cdata(Method) of - <<"zlib">> -> - Socket = StateData#state.socket, - BCompressed = fxml:element_to_binary( - #xmlel{name = <<"compressed">>, - attrs = [{<<"xmlns">>, - ?NS_COMPRESS}]}), - ZlibSocket = (StateData#state.sockmod):compress( - Socket, BCompressed), - fsm_next_state(wait_for_stream, - StateData#state{socket = ZlibSocket, - streamid = new_id()}); - _ -> - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_COMPRESS}], - children = - [#xmlel{name = <<"unsupported-method">>, - attrs = [], - children = []}]}), - fsm_next_state(StateName, StateData) - end + #compress_failure{reason = 'unsupported-method'}), + fsm_next_state(StateName, StateData) end. %%%---------------------------------------------------------------------- @@ -2568,42 +2204,20 @@ process_compression_request(El, StateName, StateData) -> route_blocking(What, StateData) -> SubEl = case What of - {block, JIDs} -> - #xmlel{name = <<"block">>, - attrs = [{<<"xmlns">>, ?NS_BLOCKING}], - children = - lists:map(fun (JID) -> - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - jid:to_string(JID)}], - children = []} - end, - JIDs)}; - {unblock, JIDs} -> - #xmlel{name = <<"unblock">>, - attrs = [{<<"xmlns">>, ?NS_BLOCKING}], - children = - lists:map(fun (JID) -> - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - jid:to_string(JID)}], - children = []} - end, - JIDs)}; - unblock_all -> - #xmlel{name = <<"unblock">>, - attrs = [{<<"xmlns">>, ?NS_BLOCKING}], children = []} + {block, JIDs} -> + #block{items = JIDs}; + {unblock, JIDs} -> + #unblock{items = JIDs}; + unblock_all -> + #unblock{} end, - PrivPushIQ = #iq{type = set, id = <<"push">>, sub_el = [SubEl]}, - PrivPushEl = - jlib:replace_from_to(jid:remove_resource(StateData#state.jid), - StateData#state.jid, jlib:iq_to_xml(PrivPushIQ)), + PrivPushIQ = #iq{type = set, id = <<"push">>, sub_els = [SubEl], + from = jid:remove_resource(StateData#state.jid), + to = StateData#state.jid}, %% No need to replace active privacy list here, %% blocking pushes are always accompanied by %% Privacy List pushes - send_stanza(StateData, PrivPushEl). + send_stanza(StateData, PrivPushIQ). %%%---------------------------------------------------------------------- %%% XEP-0198 @@ -2627,164 +2241,131 @@ negotiate_stream_mgmt(_El, #state{resource = <<"">>} = StateData) -> %% Binding unless it is resuming a previous session". However, it also %% says: "Stream management errors SHOULD be considered recoverable", so we %% won't bail out. - send_element(StateData, ?MGMT_UNEXPECTED_REQUEST(?NS_STREAM_MGMT_3)), + send_element(StateData, #sm_failed{reason = 'unexpected-request', + xmlns = ?NS_STREAM_MGMT_3}), StateData; -negotiate_stream_mgmt(#xmlel{name = Name, attrs = Attrs}, StateData) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - Xmlns when ?IS_SUPPORTED_MGMT_XMLNS(Xmlns) -> - case stream_mgmt_enabled(StateData) of - true -> - case Name of - <<"enable">> -> - handle_enable(StateData#state{mgmt_xmlns = Xmlns}, Attrs); - _ -> - Res = if Name == <<"a">>; - Name == <<"r">>; - Name == <<"resume">> -> - ?MGMT_UNEXPECTED_REQUEST(Xmlns); - true -> - ?MGMT_BAD_REQUEST(Xmlns) - end, - send_element(StateData, Res), - StateData - end; - false -> - send_element(StateData, ?MGMT_SERVICE_UNAVAILABLE(Xmlns)), - StateData - end; - _ -> - send_element(StateData, ?MGMT_UNSUPPORTED_VERSION(?NS_STREAM_MGMT_3)), - StateData +negotiate_stream_mgmt(Pkt, StateData) -> + Xmlns = xmpp:get_ns(Pkt), + case stream_mgmt_enabled(StateData) of + true -> + case Pkt of + #sm_enable{} -> + handle_enable(StateData#state{mgmt_xmlns = Xmlns}, Pkt); + _ -> + Res = if is_record(Pkt, sm_a); + is_record(Pkt, sm_r); + is_record(Pkt, sm_resume) -> + #sm_failed{reason = 'unexpected-request', + xmlns = Xmlns}; + true -> + #sm_failed{reason = 'bad-request', + xmlns = Xmlns} + end, + send_element(StateData, Res), + StateData + end; + false -> + send_element(StateData, + #sm_failed{reason = 'service-unavailable', + xmlns = Xmlns}), + StateData end. -perform_stream_mgmt(#xmlel{name = Name, attrs = Attrs}, StateData) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - Xmlns when Xmlns == StateData#state.mgmt_xmlns -> - case Name of - <<"r">> -> - handle_r(StateData); - <<"a">> -> - handle_a(StateData, Attrs); - _ -> - Res = if Name == <<"enable">>; - Name == <<"resume">> -> - ?MGMT_UNEXPECTED_REQUEST(Xmlns); - true -> - ?MGMT_BAD_REQUEST(Xmlns) - end, - send_element(StateData, Res), - StateData - end; - _ -> - send_element(StateData, - ?MGMT_UNSUPPORTED_VERSION(StateData#state.mgmt_xmlns)), - StateData +perform_stream_mgmt(Pkt, StateData) -> + case xmpp:get_ns(Pkt) of + Xmlns when Xmlns == StateData#state.mgmt_xmlns -> + case Pkt of + #sm_r{} -> + handle_r(StateData); + #sm_a{} -> + handle_a(StateData, Pkt); + _ -> + Res = if is_record(Pkt, sm_enable); + is_record(Pkt, sm_resume) -> + #sm_failed{reason = 'unexpected-request', + xmlns = Xmlns}; + true -> + #sm_failed{reason = 'bad-request', + xmlns = Xmlns} + end, + send_element(StateData, Res), + StateData + end; + _ -> + send_element(StateData, + #sm_failed{reason = 'unsupported-version', + xmlns = StateData#state.mgmt_xmlns}) end. handle_enable(#state{mgmt_timeout = DefaultTimeout, - mgmt_max_timeout = MaxTimeout} = StateData, Attrs) -> - Timeout = case fxml:get_attr_s(<<"resume">>, Attrs) of - ResumeAttr when ResumeAttr == <<"true">>; - ResumeAttr == <<"1">> -> - MaxAttr = fxml:get_attr_s(<<"max">>, Attrs), - case catch jlib:binary_to_integer(MaxAttr) of - Max when is_integer(Max), Max > 0, Max =< MaxTimeout -> - Max; - _ -> - DefaultTimeout - end; - _ -> - 0 + mgmt_max_timeout = MaxTimeout} = StateData, + #sm_enable{resume = Resume, max = Max}) -> + Timeout = if Resume == false -> + 0; + Max /= undefined, Max > 0, Max =< MaxTimeout -> + Max; + true -> + DefaultTimeout end, - ResAttrs = [{<<"xmlns">>, StateData#state.mgmt_xmlns}] ++ - if Timeout > 0 -> - ?INFO_MSG("Stream management with resumption enabled for ~s", - [jid:to_string(StateData#state.jid)]), - [{<<"id">>, make_resume_id(StateData)}, - {<<"resume">>, <<"true">>}, - {<<"max">>, jlib:integer_to_binary(Timeout)}]; - true -> - ?INFO_MSG("Stream management without resumption enabled for ~s", - [jid:to_string(StateData#state.jid)]), - [] - end, - Res = #xmlel{name = <<"enabled">>, - attrs = ResAttrs, - children = []}, + Res = if Timeout > 0 -> + ?INFO_MSG("Stream management with resumption enabled for ~s", + [jid:to_string(StateData#state.jid)]), + #sm_enabled{xmlns = StateData#state.mgmt_xmlns, + id = make_resume_id(StateData), + resume = true, + max = Timeout}; + true -> + ?INFO_MSG("Stream management without resumption enabled for ~s", + [jid:to_string(StateData#state.jid)]), + #sm_enabled{xmlns = StateData#state.mgmt_xmlns} + end, send_element(StateData, Res), StateData#state{mgmt_state = active, mgmt_queue = queue:new(), mgmt_timeout = Timeout * 1000}. handle_r(StateData) -> - H = jlib:integer_to_binary(StateData#state.mgmt_stanzas_in), - Res = #xmlel{name = <<"a">>, - attrs = [{<<"xmlns">>, StateData#state.mgmt_xmlns}, - {<<"h">>, H}], - children = []}, + Res = #sm_a{xmlns = StateData#state.mgmt_xmlns, + h = StateData#state.mgmt_stanzas_in}, send_element(StateData, Res), StateData. -handle_a(StateData, Attrs) -> - case catch jlib:binary_to_integer(fxml:get_attr_s(<<"h">>, Attrs)) of - H when is_integer(H), H >= 0 -> - check_h_attribute(StateData, H); - _ -> - ?DEBUG("Ignoring invalid ACK element from ~s", - [jid:to_string(StateData#state.jid)]), - StateData - end. +handle_a(StateData, #sm_a{h = H}) -> + check_h_attribute(StateData, H). -handle_resume(StateData, Attrs) -> - R = case fxml:get_attr_s(<<"xmlns">>, Attrs) of - Xmlns when ?IS_SUPPORTED_MGMT_XMLNS(Xmlns) -> - case stream_mgmt_enabled(StateData) of - true -> - case {fxml:get_attr(<<"previd">>, Attrs), - catch jlib:binary_to_integer(fxml:get_attr_s(<<"h">>, Attrs))} - of - {{value, PrevID}, H} when is_integer(H), H >= 0 -> - case inherit_session_state(StateData, PrevID) of - {ok, InheritedState} -> - {ok, InheritedState, H}; - {error, Err, InH} -> - {error, ?MGMT_ITEM_NOT_FOUND_H(Xmlns, InH), Err}; - {error, Err} -> - {error, ?MGMT_ITEM_NOT_FOUND(Xmlns), Err} - end; - _ -> - {error, ?MGMT_BAD_REQUEST(Xmlns), - <<"Invalid request">>} - end; - false -> - {error, ?MGMT_SERVICE_UNAVAILABLE(Xmlns), - <<"XEP-0198 disabled">>} - end; - _ -> - {error, ?MGMT_UNSUPPORTED_VERSION(?NS_STREAM_MGMT_3), - <<"Invalid XMLNS">>} +handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) -> + R = case stream_mgmt_enabled(StateData) of + true -> + case inherit_session_state(StateData, PrevID) of + {ok, InheritedState} -> + {ok, InheritedState, H}; + {error, Err, InH} -> + {error, #sm_failed{reason = 'item-not-found', + h = InH, xmlns = Xmlns}, Err}; + {error, Err} -> + {error, #sm_failed{reason = 'item-not-found', + xmlns = Xmlns}, Err} + end; + false -> + {error, #sm_failed{reason = 'service-unavailable', + xmlns = Xmlns}, + <<"XEP-0198 disabled">>} end, case R of {ok, ResumedState, NumHandled} -> NewState = check_h_attribute(ResumedState, NumHandled), AttrXmlns = NewState#state.mgmt_xmlns, AttrId = make_resume_id(NewState), - AttrH = jlib:integer_to_binary(NewState#state.mgmt_stanzas_in), - send_element(NewState, - #xmlel{name = <<"resumed">>, - attrs = [{<<"xmlns">>, AttrXmlns}, - {<<"h">>, AttrH}, - {<<"previd">>, AttrId}], - children = []}), + AttrH = NewState#state.mgmt_stanzas_in, + send_element(NewState, #sm_resumed{xmlns = AttrXmlns, + h = AttrH, + previd = AttrId}), SendFun = fun(_F, _T, El, Time) -> NewEl = add_resent_delay_info(NewState, El, Time), send_element(NewState, NewEl) end, handle_unacked_stanzas(NewState, SendFun), - send_element(NewState, - #xmlel{name = <<"r">>, - attrs = [{<<"xmlns">>, AttrXmlns}], - children = []}), + send_element(NewState, #sm_r{xmlns = AttrXmlns}), FlushedState = csi_flush_queue(NewState), NewStateData = FlushedState#state{csi_state = active}, ?INFO_MSG("Resumed session for ~s", @@ -2810,7 +2391,7 @@ check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H) -> update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El) when MgmtState == active; MgmtState == pending -> - NewNum = case {is_stanza(El), StateData#state.mgmt_stanzas_in} of + NewNum = case {xmpp:is_stanza(El), StateData#state.mgmt_stanzas_in} of {true, 4294967295} -> 0; {true, Num} -> @@ -2823,9 +2404,7 @@ update_num_stanzas_in(StateData, _El) -> StateData. send_stanza_and_ack_req(StateData, Stanza) -> - AckReq = #xmlel{name = <<"r">>, - attrs = [{<<"xmlns">>, StateData#state.mgmt_xmlns}], - children = []}, + AckReq = #sm_r{xmlns = StateData#state.mgmt_xmlns}, case send_element(StateData, Stanza) == ok andalso send_element(StateData, AckReq) == ok of true -> @@ -2876,12 +2455,10 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F) ?DEBUG("~B stanza(s) were not acknowledged by ~s", [N, jid:to_string(StateData#state.jid)]), lists:foreach( - fun({_, Time, #xmlel{attrs = Attrs} = El}) -> - From_s = fxml:get_attr_s(<<"from">>, Attrs), - From = jid:from_string(From_s), - To_s = fxml:get_attr_s(<<"to">>, Attrs), - To = jid:from_string(To_s), - F(From, To, El, Time) + fun({_, Time, Pkt}) -> + From = xmpp:get_from(Pkt), + To = xmpp:get_to(Pkt), + F(From, To, Pkt, Time) end, queue:to_list(Queue)) end; handle_unacked_stanzas(_StateData, _F) -> @@ -2917,20 +2494,18 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) false -> fun(From, To, El, _Time) -> Txt = <<"User session terminated">>, - Err = - jlib:make_error_reply( - El, - ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)), + Err = xmpp:make_error( + El, xmpp:err_service_unavailable(Txt, Lang)), ejabberd_router:route(To, From, Err) end end, - F = fun(From, _To, #xmlel{name = <<"presence">>}, _Time) -> + F = fun(From, _To, #presence{}, _Time) -> ?DEBUG("Dropping presence stanza from ~s", [jid:to_string(From)]); - (From, To, #xmlel{name = <<"iq">>} = El, _Time) -> + (From, To, #iq{} = El, _Time) -> Txt = <<"User session terminated">>, - Err = jlib:make_error_reply( - El, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)), + Err = xmpp:make_error( + El, xmpp:err_service_unavailable(Txt, Lang)), ejabberd_router:route(To, From, Err); (From, To, El, Time) -> %% We'll drop the stanza if it was by some @@ -2943,7 +2518,7 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) case is_encapsulated_forward(El) of true -> ?DEBUG("Dropping forwarded message stanza from ~s", - [fxml:get_attr_s(<<"from">>, El#xmlel.attrs)]); + [jid:to_string(From)]); false -> case ejabberd_hooks:run_fold(message_is_archived, StateData#state.server, @@ -2961,29 +2536,10 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) handle_unacked_stanzas(_StateData) -> ok. -is_encapsulated_forward(#xmlel{name = <<"message">>} = El) -> - SubTag = case {fxml:get_subtag(El, <<"sent">>), - fxml:get_subtag(El, <<"received">>), - fxml:get_subtag(El, <<"result">>)} of - {false, false, false} -> - false; - {Tag, false, false} -> - Tag; - {false, Tag, false} -> - Tag; - {_, _, Tag} -> - Tag - end, - if SubTag == false -> - false; - true -> - case fxml:get_subtag(SubTag, <<"forwarded">>) of - false -> - false; - _ -> - true - end - end; +is_encapsulated_forward(#message{} = Msg) -> + xmpp:has_subtag(Msg, #forwarded{}) orelse + xmpp:has_subtag(Msg, #carbons_sent{}) orelse + xmpp:has_subtag(Msg, #carbons_received{}); is_encapsulated_forward(_El) -> false. @@ -3054,10 +2610,10 @@ make_resume_id(StateData) -> {Time, _} = StateData#state.sid, jlib:term_to_base64({StateData#state.resource, Time}). -add_resent_delay_info(_State, #xmlel{name = <<"iq">>} = El, _Time) -> +add_resent_delay_info(_State, #iq{} = El, _Time) -> El; add_resent_delay_info(#state{server = From}, El, Time) -> - jlib:add_delay_info(El, From, Time, <<"Resent">>). + xmpp_util:add_delay_info(El, From, Time, <<"Resent">>). %%%---------------------------------------------------------------------- %%% XEP-0352 diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl index b8e706f23..ab5b6a701 100644 --- a/src/ejabberd_frontend_socket.erl +++ b/src/ejabberd_frontend_socket.erl @@ -42,6 +42,7 @@ change_shaper/2, monitor/1, get_sockmod/1, + get_transport/1, get_peer_certificate/1, get_verify_result/1, close/1, @@ -118,6 +119,9 @@ monitor(FsmRef) -> erlang:monitor(process, FsmRef). get_sockmod(FsmRef) -> gen_server:call(FsmRef, get_sockmod). +get_transport(FsmRef) -> + gen_server:call(FsmRef, get_transport). + get_peer_certificate(FsmRef) -> gen_server:call(FsmRef, get_peer_certificate). @@ -186,6 +190,19 @@ handle_call({change_shaper, Shaper}, _From, State) -> handle_call(get_sockmod, _From, State) -> Reply = State#state.sockmod, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; +handle_call(get_transport, _From, State) -> + Reply = case State#state.sockmod of + gen_tcp -> tcp; + fast_tls -> tls; + ezlib -> + case ezlib:get_sockmod(State#state.socket) of + tcp -> tcp_zlib; + tls -> tls_zlib + end; + ejabberd_http_bind -> http_bind; + ejabberd_http_ws -> websocket + end, + {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(get_peer_certificate, _From, State) -> Reply = fast_tls:get_peer_certificate(State#state.socket), {reply, Reply, State, ?HIBERNATE_TIMEOUT}; diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 2ba943693..dca456427 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -46,7 +46,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {}). @@ -60,6 +60,8 @@ %% This value is used in SIP and Megaco for a transaction lifetime. -define(IQ_TIMEOUT, 32000). +-type ping_timeout() :: non_neg_integer() | undefined. + %%==================================================================== %% API %%==================================================================== @@ -71,37 +73,38 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). -process_iq(From, To, Packet) -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{xmlns = XMLNS, lang = Lang} -> - Host = To#jid.lserver, - case ets:lookup(?IQTABLE, {XMLNS, Host}) of - [{_, Module, Function}] -> - ResIQ = Module:Function(From, To, IQ), - if ResIQ /= ignore -> - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); - true -> ok - end; - [{_, Module, Function, Opts}] -> - gen_iq_handler:handle(Host, Module, Function, Opts, - From, To, IQ); - [] -> - Txt = <<"No module is handling this query">>, - Err = jlib:make_error_reply( - Packet, - ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)), - ejabberd_router:route(To, From, Err) - end; - reply -> - IQReply = jlib:iq_query_or_response_info(Packet), - process_iq_reply(From, To, IQReply); - _ -> - Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), - ejabberd_router:route(To, From, Err), - ok +-spec process_iq(jid(), jid(), iq()) -> any(). +process_iq(From, To, #iq{type = T, lang = Lang, sub_els = [El]} = Packet) + when T == get; T == set -> + XMLNS = xmpp:get_ns(El), + Host = To#jid.lserver, + case ets:lookup(?IQTABLE, {XMLNS, Host}) of + [{_, Module, Function}] -> + gen_iq_handler:handle(Host, Module, Function, no_queue, + From, To, Packet); + [{_, Module, Function, Opts}] -> + gen_iq_handler:handle(Host, Module, Function, Opts, + From, To, Packet); + [] -> + Txt = <<"No module is handling this query">>, + Err = xmpp:make_error( + Packet, + xmpp:err_service_unavailable(Txt, Lang)), + ejabberd_router:route(To, From, Err) + end; +process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> + Err = xmpp:make_error(Packet, xmpp:err_bad_request()), + ejabberd_router:route(To, From, Err); +process_iq(From, To, #iq{type = T} = Packet) when T == result; T == error -> + try + NewPacket = xmpp:decode_els(Packet), + process_iq_reply(From, To, NewPacket) + catch _:{xmpp_codec, Why} -> + ?DEBUG("failed to decode iq-result ~p: ~s", + [Packet, xmpp:format_error(Why)]) end. +-spec process_iq_reply(jid(), jid(), iq()) -> any(). process_iq_reply(From, To, #iq{id = ID} = IQ) -> case get_iq_callback(ID) of {ok, undefined, Function} -> Function(IQ), ok; @@ -110,6 +113,7 @@ process_iq_reply(From, To, #iq{id = ID} = IQ) -> _ -> nothing end. +-spec route(jid(), jid(), stanza()) -> any(). route(From, To, Packet) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> @@ -118,26 +122,32 @@ route(From, To, Packet) -> _ -> ok end. +-spec route_iq(jid(), jid(), iq(), function()) -> any(). route_iq(From, To, IQ, F) -> route_iq(From, To, IQ, F, undefined). +-spec route_iq(jid(), jid(), iq(), function(), ping_timeout()) -> any(). route_iq(From, To, #iq{type = Type} = IQ, F, Timeout) when is_function(F) -> Packet = if Type == set; Type == get -> ID = randoms:get_string(), Host = From#jid.lserver, register_iq_response_handler(Host, ID, undefined, F, Timeout), - jlib:iq_to_xml(IQ#iq{id = ID}); + IQ#iq{id = ID}; true -> - jlib:iq_to_xml(IQ) + IQ end, ejabberd_router:route(From, To, Packet). +-spec register_iq_response_handler(binary(), binary(), module(), + atom() | function()) -> any(). register_iq_response_handler(Host, ID, Module, Function) -> register_iq_response_handler(Host, ID, Module, Function, undefined). +-spec register_iq_response_handler(binary(), binary(), module(), + atom() | function(), ping_timeout()) -> any(). register_iq_response_handler(_Host, ID, Module, Function, Timeout0) -> Timeout = case Timeout0 of @@ -150,28 +160,35 @@ register_iq_response_handler(_Host, ID, Module, function = Function, timer = TRef}). +-spec register_iq_handler(binary(), binary(), module(), function()) -> any(). register_iq_handler(Host, XMLNS, Module, Fun) -> ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun}. +-spec register_iq_handler(binary(), binary(), module(), function(), + gen_iq_handler:opts()) -> any(). register_iq_handler(Host, XMLNS, Module, Fun, Opts) -> ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}. +-spec unregister_iq_response_handler(binary(), binary()) -> ok. unregister_iq_response_handler(_Host, ID) -> catch get_iq_callback(ID), ok. +-spec unregister_iq_handler(binary(), binary()) -> any(). unregister_iq_handler(Host, XMLNS) -> ejabberd_local ! {unregister_iq_handler, Host, XMLNS}. +-spec refresh_iq_handlers() -> any(). refresh_iq_handlers() -> ejabberd_local ! refresh_iq_handlers. +-spec bounce_resource_packet(jid(), jid(), stanza()) -> stop. bounce_resource_packet(From, To, Packet) -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"No available resource found">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_ITEM_NOT_FOUND(Lang, Txt)), + Err = xmpp:make_error(Packet, + xmpp:err_item_not_found(Txt, Lang)), ejabberd_router:route(To, From, Err), stop. @@ -261,50 +278,45 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +-spec do_route(jid(), jid(), stanza()) -> any(). do_route(From, To, Packet) -> ?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket " "~P~n", [From, To, Packet, 8]), if To#jid.luser /= <<"">> -> - ejabberd_sm:route(From, To, Packet); + ejabberd_sm:route(From, To, Packet); To#jid.lresource == <<"">> -> - #xmlel{name = Name} = Packet, - case Name of - <<"iq">> -> process_iq(From, To, Packet); - <<"message">> -> - #xmlel{attrs = Attrs} = Packet, - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"headline">> -> ok; - <<"error">> -> ok; - _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err) - end; - <<"presence">> -> ok; - _ -> ok - end; + case Packet of + #iq{} -> + process_iq(From, To, Packet); + #message{type = T} when T /= headline, T /= error -> + Err = xmpp:make_error(Packet, xmpp:err_service_unavailable()), + ejabberd_router:route(To, From, Err); + _ -> ok + end; true -> - #xmlel{attrs = Attrs} = Packet, - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - <<"result">> -> ok; - _ -> - ejabberd_hooks:run(local_send_to_resource_hook, - To#jid.lserver, [From, To, Packet]) - end + case xmpp:get_type(Packet) of + error -> ok; + result -> ok; + _ -> + ejabberd_hooks:run(local_send_to_resource_hook, + To#jid.lserver, [From, To, Packet]) + end end. +-spec update_table() -> ok. update_table() -> case catch mnesia:table_info(iq_response, attributes) of [id, module, function] -> - mnesia:delete_table(iq_response); + mnesia:delete_table(iq_response), + ok; [id, module, function, timer] -> ok; {'EXIT', _} -> ok end. +-spec get_iq_callback(binary()) -> {ok, module(), atom() | function()} | error. get_iq_callback(ID) -> case mnesia:dirty_read(iq_response, ID) of [#iq_response{module = Module, timer = TRef, @@ -316,9 +328,11 @@ get_iq_callback(ID) -> error end. +-spec process_iq_timeout(binary()) -> any(). process_iq_timeout(ID) -> spawn(fun process_iq_timeout/0) ! ID. +-spec process_iq_timeout() -> any(). process_iq_timeout() -> receive ID -> @@ -332,6 +346,7 @@ process_iq_timeout() -> ok end. +-spec cancel_timer(reference()) -> ok. cancel_timer(TRef) -> case erlang:cancel_timer(TRef) of false -> diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index e29d6acfb..5924d92c0 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -39,6 +39,7 @@ register_route/3, register_routes/1, host_of_route/1, + process_iq/3, unregister_route/1, unregister_routes/1, dirty_get_all_routes/0, @@ -53,7 +54,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -type local_hint() :: undefined | integer() | {apply, atom(), atom()}. @@ -71,7 +72,7 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). --spec route(jid(), jid(), xmlel()) -> ok. +-spec route(jid(), jid(), xmlel() | xmpp_element()) -> ok. route(From, To, Packet) -> case catch do_route(From, To, Packet) of @@ -236,6 +237,28 @@ host_of_route(Domain) -> end end. +-spec process_iq(jid(), jid(), iq() | xmlel()) -> any(). +process_iq(From, To, #iq{} = IQ) -> + if To#jid.luser == <<"">> -> + ejabberd_local:process_iq(From, To, IQ); + true -> + ejabberd_sm:process_iq(From, To, IQ) + end; +process_iq(From, To, El) -> + try xmpp:decode(El, [ignore_els]) of + IQ -> process_iq(From, To, IQ) + catch _:{xmpp_codec, Why} -> + Type = xmpp:get_type(El), + if Type == <<"get">>; Type == <<"set">> -> + Txt = xmpp:format_error(Why), + Lang = xmpp:get_lang(El), + Err = xmpp:make_error(El, xmpp:err_bad_request(Txt, Lang)), + ejabberd_router:route(To, From, Err); + true -> + ok + end + end. + %%==================================================================== %% gen_server callbacks %%==================================================================== @@ -347,6 +370,7 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +-spec do_route(jid(), jid(), xmlel() | xmpp_element()) -> any(). do_route(OrigFrom, OrigTo, OrigPacket) -> ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket " "~p~n", @@ -359,67 +383,66 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> case mnesia:dirty_read(route, LDstDomain) of [] -> ejabberd_s2s:route(From, To, Packet); [R] -> - Pid = R#route.pid, - if node(Pid) == node() -> - case R#route.local_hint of - {apply, Module, Function} -> - Module:Function(From, To, Packet); - _ -> Pid ! {route, From, To, Packet} - end; - is_pid(Pid) -> Pid ! {route, From, To, Packet}; - true -> drop - end; + do_route(From, To, Packet, R); Rs -> - Value = case - ejabberd_config:get_option({domain_balancing, - LDstDomain}, fun(D) when is_atom(D) -> D end) - of - undefined -> p1_time_compat:monotonic_time(); - random -> p1_time_compat:monotonic_time(); - source -> jid:tolower(From); - destination -> jid:tolower(To); - bare_source -> - jid:remove_resource(jid:tolower(From)); - bare_destination -> - jid:remove_resource(jid:tolower(To)) - end, + Value = get_domain_balancing(From, To, LDstDomain), case get_component_number(LDstDomain) of undefined -> case [R || R <- Rs, node(R#route.pid) == node()] of [] -> R = lists:nth(erlang:phash(Value, length(Rs)), Rs), - Pid = R#route.pid, - if is_pid(Pid) -> Pid ! {route, From, To, Packet}; - true -> drop - end; + do_route(From, To, Packet, R); LRs -> - R = lists:nth(erlang:phash(Value, length(LRs)), - LRs), - Pid = R#route.pid, - case R#route.local_hint of - {apply, Module, Function} -> - Module:Function(From, To, Packet); - _ -> Pid ! {route, From, To, Packet} - end + R = lists:nth(erlang:phash(Value, length(LRs)), LRs), + do_route(From, To, Packet, R) end; _ -> SRs = lists:ukeysort(#route.local_hint, Rs), R = lists:nth(erlang:phash(Value, length(SRs)), SRs), - Pid = R#route.pid, - if is_pid(Pid) -> Pid ! {route, From, To, Packet}; - true -> drop - end + do_route(From, To, Packet, R) end end; drop -> ok end. +-spec do_route(jid(), jid(), xmlel() | xmpp_element(), #route{}) -> any(). +do_route(From, To, Packet, + #route{local_hint = {apply, Module, Function}, pid = Pid}) + when is_pid(Pid) andalso node(Pid) == node() -> + try + Module:Function(From, To, xmpp:decode(Packet, [ignore_els])) + catch error:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode xml element ~p when " + "routing from ~s to ~s: ~s", + [Packet, jid:to_string(From), jid:to_string(To), + xmpp:format_error(Why)]), + drop + end; +do_route(From, To, Packet, #route{pid = Pid}) when is_pid(Pid) -> + Pid ! {route, From, To, xmpp:encode(Packet)}; +do_route(_From, _To, _Packet, _Route) -> + drop. + +-spec get_component_number(binary()) -> pos_integer() | undefined. get_component_number(LDomain) -> ejabberd_config:get_option( {domain_balancing_component_number, LDomain}, fun(N) when is_integer(N), N > 1 -> N end, undefined). +-spec get_domain_balancing(jid(), jid(), binary()) -> any(). +get_domain_balancing(From, To, LDomain) -> + case ejabberd_config:get_option( + {domain_balancing, LDomain}, fun(D) when is_atom(D) -> D end) of + undefined -> p1_time_compat:monotonic_time(); + random -> p1_time_compat:monotonic_time(); + source -> jid:tolower(From); + destination -> jid:tolower(To); + bare_source -> jid:remove_resource(jid:tolower(From)); + bare_destination -> jid:remove_resource(jid:tolower(To)) + end. + +-spec update_tables() -> ok. update_tables() -> try mnesia:transform_table(route, ignore, record_info(fields, route)) diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 8d94bc6aa..ec9ef43c6 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -78,7 +78,8 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +%%-include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_commands.hrl"). -include("mod_privacy.hrl"). @@ -98,6 +99,15 @@ %% default value for the maximum number of user connections -define(MAX_USER_SESSIONS, infinity). +-type broadcast() :: {broadcast, broadcast_data()}. + +-type broadcast_data() :: + {rebind, pid(), binary()} | %% ejabberd_c2s + {item, ljid(), mod_roster:subscription()} | %% mod_roster/mod_shared_roster + {exit, binary()} | %% mod_roster/mod_shared_roster + {privacy_list, mod_privacy:userlist(), binary()} | %% mod_privacy + {blocking, unblock_all | {block | unblock, [ljid()]}}. %% mod_blocking + %%==================================================================== %% API %%==================================================================== @@ -111,7 +121,7 @@ start() -> start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). --spec route(jid(), jid(), xmlel() | broadcast()) -> ok. +-spec route(jid(), jid(), stanza() | broadcast()) -> ok. route(From, To, Packet) -> case catch do_route(From, To, Packet) of @@ -162,10 +172,10 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) -> -spec bounce_offline_message(jid(), jid(), xmlel()) -> stop. bounce_offline_message(From, To, Packet) -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"User session not found">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)), + Err = xmpp:make_error( + Packet, xmpp:err_service_unavailable(Txt, Lang)), ejabberd_router:route(To, From, Err), stop. @@ -432,7 +442,7 @@ online(Sessions) -> end, Sessions). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +-spec do_route(jid(), jid(), stanza() | broadcast()) -> any(). do_route(From, To, {broadcast, _} = Packet) -> case To#jid.lresource of <<"">> -> @@ -455,25 +465,20 @@ do_route(From, To, {broadcast, _} = Packet) -> Pid ! {route, From, To, Packet} end end; -do_route(From, To, #xmlel{} = Packet) -> +do_route(From, To, Packet) -> ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket " "~P~n", [From, To, Packet, 8]), #jid{user = User, server = Server, luser = LUser, lserver = LServer, lresource = LResource} = To, - #xmlel{name = Name, attrs = Attrs} = Packet, - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), + Lang = xmpp:get_lang(Packet), case LResource of <<"">> -> - case Name of - <<"presence">> -> - {Pass, _Subsc} = case fxml:get_attr_s(<<"type">>, Attrs) - of - <<"subscribe">> -> - Reason = fxml:get_path_s(Packet, - [{elem, - <<"status">>}, - cdata]), + case Packet of + #presence{type = T, status = Status} -> + {Pass, _Subsc} = case T of + subscribe -> + Reason = xmpp:get_text(Status), {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold(roster_in_subscription, @@ -484,7 +489,7 @@ do_route(From, To, #xmlel{} = Packet) -> subscribe, Reason]), true}; - <<"subscribed">> -> + subscribed -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold(roster_in_subscription, @@ -495,7 +500,7 @@ do_route(From, To, #xmlel{} = Packet) -> subscribed, <<"">>]), true}; - <<"unsubscribe">> -> + unsubscribe -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold(roster_in_subscription, @@ -506,7 +511,7 @@ do_route(From, To, #xmlel{} = Packet) -> unsubscribe, <<"">>]), true}; - <<"unsubscribed">> -> + unsubscribed -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold(roster_in_subscription, @@ -530,53 +535,36 @@ do_route(From, To, #xmlel{} = Packet) -> PResources); true -> ok end; - <<"message">> -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"chat">> -> route_message(From, To, Packet, chat); - <<"headline">> -> route_message(From, To, Packet, headline); - <<"error">> -> ok; - <<"groupchat">> -> - ErrTxt = <<"User session not found">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)), - ejabberd_router:route(To, From, Err); - _ -> - route_message(From, To, Packet, normal) - end; - <<"iq">> -> process_iq(From, To, Packet); - _ -> ok + #message{type = T} when T == chat; T == headline; T == normal -> + route_message(From, To, Packet, T); + #message{type = groupchat} -> + ErrTxt = <<"User session not found">>, + Err = xmpp:make_error( + Packet, xmpp:err_service_unavailable(ErrTxt, Lang)), + ejabberd_router:route(To, From, Err); + #iq{} -> process_iq(From, To, Packet); + _ -> ok end; _ -> Mod = get_sm_backend(LServer), case online(Mod:get_sessions(LUser, LServer, LResource)) of [] -> - case Name of - <<"message">> -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"chat">> -> route_message(From, To, Packet, chat); - <<"headline">> -> ok; - <<"error">> -> ok; - <<"groupchat">> -> - ErrTxt = <<"User session not found">>, - Err = jlib:make_error_reply( - Packet, - ?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)), - ejabberd_router:route(To, From, Err); - _ -> - route_message(From, To, Packet, normal) - end; - <<"iq">> -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - <<"result">> -> ok; - _ -> - ErrTxt = <<"User session not found">>, - Err = jlib:make_error_reply( - Packet, - ?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)), - ejabberd_router:route(To, From, Err) - end; - _ -> ?DEBUG("packet dropped~n", []) + case Packet of + #message{type = T} when T == chat; T == normal -> + route_message(From, To, Packet, T); + #message{type = groupchat} -> + ErrTxt = <<"User session not found">>, + Err = xmpp:make_error( + Packet, + xmpp:err_service_unavailable(ErrTxt, Lang)), + ejabberd_router:route(To, From, Err); + #iq{type = T} when T == get; T == set -> + ErrTxt = <<"User session not found">>, + Err = xmpp:make_error( + Packet, + xmpp:err_service_unavailable(ErrTxt, Lang)), + ejabberd_router:route(To, From, Err); + _ -> ?DEBUG("packet dropped~n", []) end; Ss -> Session = lists:max(Ss), @@ -590,6 +578,7 @@ do_route(From, To, #xmlel{} = Packet) -> %% and is processed if there is no active list set %% for the target session/resource to which a stanza is addressed, %% or if there are no current sessions for the user. +-spec is_privacy_allow(jid(), jid(), stanza()) -> boolean(). is_privacy_allow(From, To, Packet) -> User = To#jid.user, Server = To#jid.server, @@ -600,6 +589,7 @@ is_privacy_allow(From, To, Packet) -> %% Check if privacy rules allow this delivery %% Function copied from ejabberd_c2s.erl +-spec is_privacy_allow(jid(), jid(), stanza(), #userlist{}) -> boolean(). is_privacy_allow(From, To, Packet, PrivacyList) -> User = To#jid.user, Server = To#jid.server, @@ -609,6 +599,7 @@ is_privacy_allow(From, To, Packet, PrivacyList) -> [User, Server, PrivacyList, {From, To, Packet}, in]). +-spec route_message(jid(), jid(), message(), message_type()) -> any(). route_message(From, To, Packet, Type) -> LUser = To#jid.luser, LServer = To#jid.lserver, @@ -644,18 +635,19 @@ route_message(From, To, Packet, Type) -> ejabberd_hooks:run(offline_message_hook, LServer, [From, To, Packet]); false -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), + Err = xmpp:make_error(Packet, + xmpp:err_service_unavailable()), ejabberd_router:route(To, From, Err) end end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +-spec clean_session_list([#session{}]) -> [#session{}]. clean_session_list(Ss) -> clean_session_list(lists:keysort(#session.usr, Ss), []). +-spec clean_session_list([#session{}], [#session{}]) -> [#session{}]. clean_session_list([], Res) -> Res; clean_session_list([S], Res) -> [S | Res]; clean_session_list([S1, S2 | Rest], Res) -> @@ -670,6 +662,7 @@ clean_session_list([S1, S2 | Rest], Res) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% On new session, check if some existing connections need to be replace +-spec check_for_sessions_to_replace(binary(), binary(), binary()) -> ok | replaced. check_for_sessions_to_replace(User, Server, Resource) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -677,6 +670,7 @@ check_for_sessions_to_replace(User, Server, Resource) -> check_existing_resources(LUser, LServer, LResource), check_max_sessions(LUser, LServer). +-spec check_existing_resources(binary(), binary(), binary()) -> ok. check_existing_resources(LUser, LServer, LResource) -> SIDs = get_resource_sessions(LUser, LServer, LResource), if SIDs == [] -> ok; @@ -698,6 +692,7 @@ check_existing_resources(LUser, LServer, LResource) -> is_existing_resource(LUser, LServer, LResource) -> [] /= get_resource_sessions(LUser, LServer, LResource). +-spec get_resource_sessions(binary(), binary(), binary()) -> [sid()]. get_resource_sessions(User, Server, Resource) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -705,6 +700,7 @@ get_resource_sessions(User, Server, Resource) -> Mod = get_sm_backend(LServer), [S#session.sid || S <- online(Mod:get_sessions(LUser, LServer, LResource))]. +-spec check_max_sessions(binary(), binary()) -> ok | replaced. check_max_sessions(LUser, LServer) -> Mod = get_sm_backend(LServer), SIDs = [S#session.sid || S <- online(Mod:get_sessions(LUser, LServer))], @@ -717,6 +713,7 @@ check_max_sessions(LUser, LServer) -> %% This option defines the max number of time a given users are allowed to %% log in %% Defaults to infinity +-spec get_max_user_sessions(binary(), binary()) -> infinity | non_neg_integer(). get_max_user_sessions(LUser, Host) -> case acl:match_rule(Host, max_user_sessions, jid:make(LUser, Host, <<"">>)) @@ -728,34 +725,31 @@ get_max_user_sessions(LUser, Host) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -process_iq(From, To, Packet) -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{xmlns = XMLNS, lang = Lang} -> - Host = To#jid.lserver, - case ets:lookup(sm_iqtable, {XMLNS, Host}) of - [{_, Module, Function}] -> - ResIQ = Module:Function(From, To, IQ), - if ResIQ /= ignore -> - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); - true -> ok - end; - [{_, Module, Function, Opts}] -> - gen_iq_handler:handle(Host, Module, Function, Opts, - From, To, IQ); - [] -> - Txt = <<"No module is handling this query">>, - Err = jlib:make_error_reply( - Packet, - ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)), - ejabberd_router:route(To, From, Err) - end; - reply -> ok; - _ -> - Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), - ejabberd_router:route(To, From, Err), - ok - end. +-spec process_iq(jid(), jid(), iq()) -> any(). +process_iq(From, To, #iq{type = T, lang = Lang, sub_els = [El]} = Packet) + when T == get; T == set -> + XMLNS = xmpp:get_ns(El), + Host = To#jid.lserver, + case ets:lookup(sm_iqtable, {XMLNS, Host}) of + [{_, Module, Function}] -> + gen_iq_handler:handle(Host, Module, Function, no_queue, + From, To, Packet); + [{_, Module, Function, Opts}] -> + gen_iq_handler:handle(Host, Module, Function, Opts, + From, To, Packet); + [] -> + Txt = <<"No module is handling this query">>, + Err = xmpp:make_error( + Packet, + xmpp:err_service_unavailable(Txt, Lang)), + ejabberd_router:route(To, From, Err) + end; +process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> + Err = xmpp:make_error(Packet, xmpp:err_bad_request()), + ejabberd_router:route(To, From, Err), + ok; +process_iq(_From, _To, #iq{}) -> + ok. -spec force_update_presence({binary(), binary()}) -> any(). diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index 887b4a0f3..aa916867a 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -41,6 +41,7 @@ change_shaper/2, monitor/1, get_sockmod/1, + get_transport/1, get_peer_certificate/1, get_verify_result/1, close/1, @@ -215,6 +216,20 @@ monitor(SocketData) get_sockmod(SocketData) -> SocketData#socket_state.sockmod. +get_transport(#socket_state{sockmod = SockMod, + socket = Socket}) -> + case SockMod of + gen_tcp -> tcp; + fast_tls -> tls; + ezlib -> + case ezlib:get_sockmod(Socket) of + tcp -> tcp_zlib; + tls -> tls_zlib + end; + ejabberd_http_bind -> http_bind; + ejabberd_http_ws -> websocket + end. + get_peer_certificate(SocketData) -> fast_tls:get_peer_certificate(SocketData#socket_state.socket). diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index 3f6c05667..ae7cb2d88 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -41,7 +41,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {}). @@ -64,18 +64,16 @@ start_link() -> process_command(From, To, Packet) -> case To of #jid{luser = <<"">>, lresource = <<"watchdog">>} -> - #xmlel{name = Name} = Packet, - case Name of - <<"message">> -> + case Packet of + #message{body = Body} -> LFrom = jid:tolower(jid:remove_resource(From)), case lists:member(LFrom, get_admin_jids()) of true -> - Body = fxml:get_path_s(Packet, - [{elem, <<"body">>}, cdata]), + BodyText = xmpp:get_text(Body), spawn(fun () -> process_flag(priority, high), - process_command1(From, To, Body) + process_command1(From, To, BodyText) end), stop; false -> ok @@ -186,24 +184,20 @@ process_large_heap(Pid, Info) -> "much memory:~n~p~n~s", [node(), Pid, Info, DetailedInfo])), From = jid:make(<<"">>, Host, <<"watchdog">>), - Hint = [#xmlel{name = <<"no-permanent-store">>, - attrs = [{<<"xmlns">>, ?NS_HINTS}]}], - lists:foreach(fun (JID) -> - send_message(From, jid:make(JID), Body, Hint) - end, JIDs). + Hint = [#hint{type = 'no-permanent-store'}], + lists:foreach( + fun(JID) -> + send_message(From, jid:make(JID), Body, Hint) + end, JIDs). send_message(From, To, Body) -> send_message(From, To, Body, []). send_message(From, To, Body, ExtraEls) -> ejabberd_router:route(From, To, - #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"chat">>}], - children = - [#xmlel{name = <<"body">>, attrs = [], - children = - [{xmlcdata, Body}]} - | ExtraEls]}). + #message{type = chat, + body = xmpp:mk_text(Body), + sub_els = ExtraEls}). get_admin_jids() -> ejabberd_config:get_option( diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index c2b4252c9..f78ba7e40 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -40,7 +40,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {host, module, function}). @@ -59,6 +59,8 @@ start_link(Host, Module, Function) -> gen_server:start_link(?MODULE, [Host, Module, Function], []). +-spec add_iq_handler(module(), binary(), binary(), module(), atom(), type()) -> any(). + add_iq_handler(Component, Host, NS, Module, Function, Type) -> case Type of @@ -124,14 +126,49 @@ handle(Host, Module, Function, Opts, From, To, IQ) -> -spec process_iq(binary(), atom(), atom(), jid(), jid(), iq()) -> any(). -process_iq(_Host, Module, Function, From, To, IQ) -> - case catch Module:Function(From, To, IQ) of - {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); - ResIQ -> - if ResIQ /= ignore -> - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); - true -> ok - end +process_iq(_Host, Module, Function, From, To, IQ0) -> + IQ = xmpp:set_from_to(IQ0, From, To), + try + ResIQ = case erlang:function_exported(Module, Function, 1) of + true -> + process_iq(Module, Function, IQ); + false -> + process_iq(Module, Function, From, To, + jlib:iq_query_info(xmpp:encode(IQ))) + end, + if ResIQ /= ignore -> + ejabberd_router:route(To, From, ResIQ); + true -> + ok + end + catch E:R -> + ?ERROR_MSG("failed to process iq:~n~s~nReason = ~p", + [xmpp_codec:pp(IQ), {E, {R, erlang:get_stacktrace()}}]), + Txt = <<"Module failed to handle the query">>, + Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang), + ejabberd_router:route(To, From, xmpp:make_error(IQ, Err)) + end. + +-spec process_iq(module(), atom(), iq()) -> ignore | iq(). +process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) -> + try + %% TODO: move this 'conditional' decoding somewhere + %% IQ handler should know *nothing* about vCards. + Pkt = case xmpp:get_ns(El) of + ?NS_VCARD -> El; + _ -> xmpp:decode(El) + end, + Module:Function(IQ#iq{sub_els = [Pkt]}) + catch error:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)) + end. + +-spec process_iq(module(), atom(), jid(), jid(), term()) -> iq(). +process_iq(Module, Function, From, To, IQ) -> + case Module:Function(From, To, IQ) of + ignore -> ignore; + ResIQ -> xmpp:decode(jlib:iq_to_xml(ResIQ), [ignore_els]) end. -spec check_type(type()) -> type(). diff --git a/src/jid.erl b/src/jid.erl index 0c3ac77c0..d81cbcefd 100644 --- a/src/jid.erl +++ b/src/jid.erl @@ -28,6 +28,7 @@ %% API -export([start/0, make/1, + make/2, make/3, split/1, from_string/1, @@ -40,7 +41,7 @@ remove_resource/1, replace_resource/2]). --include("jlib.hrl"). +-include("jid.hrl"). -export_type([jid/0]). @@ -74,10 +75,16 @@ make(User, Server, Resource) -> end end. --spec make({binary(), binary(), binary()}) -> jid() | error. +-spec make(binary(), binary()) -> jid() | error. +make(User, Server) -> + make(User, Server, <<"">>). + +-spec make({binary(), binary(), binary()} | binary()) -> jid() | error. make({User, Server, Resource}) -> - make(User, Server, Resource). + make(User, Server, Resource); +make(Server) -> + make(<<"">>, Server, <<"">>). %% This is the reverse of make_jid/1 -spec split(jid()) -> {binary(), binary(), binary()} | error. @@ -93,6 +100,8 @@ from_string(S) when is_list(S) -> %% using binaries for string. However, we do not let it crash to avoid %% losing associated ets table. {error, need_jid_as_binary}; +from_string(<<>>) -> + error; from_string(S) when is_binary(S) -> SplitPattern = ets:lookup_element(jlib, string_to_jid_pattern, 2), Size = size(S), diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 3ed3149bb..7c7ebf7b3 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -35,6 +35,8 @@ -behaviour(gen_mod). +-compile(export_all). + -export([read_caps/1, caps_stream_features/2, disco_features/5, disco_identity/5, disco_info/5, get_features/2, export/1, import_info/0, import/5, @@ -54,24 +56,12 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PROCNAME, ejabberd_mod_caps). -define(BAD_HASH_LIFETIME, 600). --record(caps, -{ - node = <<"">> :: binary(), - version = <<"">> :: binary(), - hash = <<"">> :: binary(), - exts = [] :: [binary()] -}). - --type caps() :: #caps{}. - --export_type([caps/0]). - -record(caps_features, { node_pair = {<<"">>, <<"">>} :: {binary(), binary()}, @@ -103,6 +93,7 @@ stop(Host) -> supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). +-spec get_features(binary(), nothing | caps()) -> [binary()]. get_features(_Host, nothing) -> []; get_features(Host, #caps{node = Node, version = Version, exts = Exts}) -> @@ -119,65 +110,37 @@ get_features(Host, #caps{node = Node, version = Version, end, [], SubNodes). --spec read_caps([xmlel()]) -> nothing | caps(). - -read_caps(Els) -> read_caps(Els, nothing). - -read_caps([#xmlel{name = <<"c">>, attrs = Attrs} - | Tail], - Result) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_CAPS -> - Node = fxml:get_attr_s(<<"node">>, Attrs), - Version = fxml:get_attr_s(<<"ver">>, Attrs), - Hash = fxml:get_attr_s(<<"hash">>, Attrs), - Exts = str:tokens(fxml:get_attr_s(<<"ext">>, Attrs), - <<" ">>), - read_caps(Tail, - #caps{node = Node, hash = Hash, version = Version, - exts = Exts}); - _ -> read_caps(Tail, Result) - end; -read_caps([#xmlel{name = <<"x">>, attrs = Attrs} - | Tail], - Result) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MUC_USER -> nothing; - _ -> read_caps(Tail, Result) - end; -read_caps([_ | Tail], Result) -> - read_caps(Tail, Result); -read_caps([], Result) -> Result. +-spec read_caps(#presence{}) -> nothing | caps(). +read_caps(Presence) -> + case xmpp:get_subtag(Presence, #caps{}) of + false -> nothing; + Caps -> Caps + end. -user_send_packet(#xmlel{name = <<"presence">>, attrs = Attrs, - children = Els} = Pkt, +-spec user_send_packet(stanza(), ejabberd_c2s:state(), jid(), jid()) -> stanza(). +user_send_packet(#presence{type = available} = Pkt, _C2SState, #jid{luser = User, lserver = Server} = From, #jid{luser = User, lserver = Server, lresource = <<"">>}) -> - Type = fxml:get_attr_s(<<"type">>, Attrs), - if Type == <<"">>; Type == <<"available">> -> - case read_caps(Els) of - nothing -> ok; - #caps{version = Version, exts = Exts} = Caps -> - feature_request(Server, From, Caps, [Version | Exts]) - end; - true -> ok + case read_caps(Pkt) of + nothing -> ok; + #caps{version = Version, exts = Exts} = Caps -> + feature_request(Server, From, Caps, [Version | Exts]) end, Pkt; user_send_packet(Pkt, _C2SState, _From, _To) -> Pkt. -user_receive_packet(#xmlel{name = <<"presence">>, attrs = Attrs, - children = Els} = Pkt, +-spec user_receive_packet(stanza(), ejabberd_c2s:state(), + jid(), jid(), jid()) -> stanza(). +user_receive_packet(#presence{type = available} = Pkt, _C2SState, #jid{lserver = Server}, From, _To) -> - Type = fxml:get_attr_s(<<"type">>, Attrs), IsRemote = not lists:member(From#jid.lserver, ?MYHOSTS), - if IsRemote and - ((Type == <<"">>) or (Type == <<"available">>)) -> - case read_caps(Els) of + if IsRemote -> + case read_caps(Pkt) of nothing -> ok; #caps{version = Version, exts = Exts} = Caps -> feature_request(Server, From, Caps, [Version | Exts]) @@ -188,58 +151,62 @@ user_receive_packet(#xmlel{name = <<"presence">>, attrs = Attrs, user_receive_packet(Pkt, _C2SState, _JID, _From, _To) -> Pkt. --spec caps_stream_features([xmlel()], binary()) -> [xmlel()]. +-spec caps_stream_features([xmpp_element()], binary()) -> [xmpp_element()]. caps_stream_features(Acc, MyHost) -> case make_my_disco_hash(MyHost) of <<"">> -> Acc; Hash -> - [#xmlel{name = <<"c">>, - attrs = - [{<<"xmlns">>, ?NS_CAPS}, {<<"hash">>, <<"sha-1">>}, - {<<"node">>, ?EJABBERD_URI}, {<<"ver">>, Hash}], - children = []} - | Acc] + [#caps{hash = <<"sha-1">>, node = ?EJABBERD_URI, version = Hash}|Acc] end. +-spec disco_features({error, error()} | {result, [binary()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [binary()]}. disco_features(Acc, From, To, Node, Lang) -> case is_valid_node(Node) of true -> ejabberd_hooks:run_fold(disco_local_features, To#jid.lserver, empty, - [From, To, <<"">>, Lang]); + [From, To, undefined, Lang]); false -> Acc end. +-spec disco_identity([identity()], jid(), jid(), + undefined | binary(), undefined | binary()) -> + [identity()]. disco_identity(Acc, From, To, Node, Lang) -> case is_valid_node(Node) of true -> ejabberd_hooks:run_fold(disco_local_identity, To#jid.lserver, [], - [From, To, <<"">>, Lang]); + [From, To, undefined, Lang]); false -> Acc end. +-spec disco_info([xdata()], binary(), module(), + undefined | binary(), undefined | binary()) -> [xdata()]. disco_info(Acc, Host, Module, Node, Lang) -> case is_valid_node(Node) of true -> ejabberd_hooks:run_fold(disco_info, Host, [], - [Host, Module, <<"">>, Lang]); + [Host, Module, undefined, Lang]); false -> Acc end. +-spec c2s_presence_in(ejabberd_c2s:state(), {jid(), jid(), presence()}) -> + ejabberd_c2s:state(). c2s_presence_in(C2SState, - {From, To, {_, _, Attrs, Els}}) -> - Type = fxml:get_attr_s(<<"type">>, Attrs), + {From, To, #presence{type = Type} = Presence}) -> Subscription = ejabberd_c2s:get_subscription(From, C2SState), - Insert = ((Type == <<"">>) or (Type == <<"available">>)) + Insert = (Type == available) and ((Subscription == both) or (Subscription == to)), - Delete = (Type == <<"unavailable">>) or - (Type == <<"error">>), + Delete = (Type == unavailable) or (Type == error), if Insert or Delete -> LFrom = jid:tolower(From), Rs = case ejabberd_c2s:get_aux_field(caps_resources, @@ -248,7 +215,7 @@ c2s_presence_in(C2SState, {ok, Rs1} -> Rs1; error -> gb_trees:empty() end, - Caps = read_caps(Els), + Caps = read_caps(Presence), NewRs = case Caps of nothing when Insert == true -> Rs; _ when Insert == true -> @@ -272,6 +239,9 @@ c2s_presence_in(C2SState, true -> C2SState end. +-spec c2s_filter_packet(boolean(), binary(), ejabberd_c2s:state(), + {pep_message, binary()}, jid(), stanza()) -> + boolean(). c2s_filter_packet(InAcc, Host, C2SState, {pep_message, Feature}, To, _Packet) -> case ejabberd_c2s:get_aux_field(caps_resources, C2SState) of {ok, Rs} -> @@ -287,6 +257,9 @@ c2s_filter_packet(InAcc, Host, C2SState, {pep_message, Feature}, To, _Packet) -> end; c2s_filter_packet(Acc, _, _, _, _, _) -> Acc. +-spec c2s_broadcast_recipients([ljid()], binary(), ejabberd_c2s:state(), + {pep_message, binary()}, jid(), stanza()) -> + [ljid()]. c2s_broadcast_recipients(InAcc, Host, C2SState, {pep_message, Feature}, _From, _Packet) -> case ejabberd_c2s:get_aux_field(caps_resources, @@ -377,6 +350,7 @@ terminate(_Reason, State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +-spec feature_request(binary(), jid(), caps(), [binary()]) -> any(). feature_request(Host, From, Caps, [SubNode | Tail] = SubNodes) -> Node = Caps#caps.node, @@ -392,15 +366,9 @@ feature_request(Host, From, Caps, _ -> true end, if NeedRequest -> - IQ = #iq{type = get, xmlns = ?NS_DISCO_INFO, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_DISCO_INFO}, - {<<"node">>, - <>}], - children = []}]}, + IQ = #iq{type = get, + sub_els = [#disco_info{node = <>}]}, cache_tab:insert(caps_features, NodePair, now_ts(), caps_write_fun(Host, NodePair, now_ts())), F = fun (IQReply) -> @@ -415,39 +383,41 @@ feature_request(Host, From, Caps, end; feature_request(_Host, _From, _Caps, []) -> ok. -feature_response(#iq{type = result, - sub_el = [#xmlel{children = Els}]}, +-spec feature_response(iq(), binary(), jid(), caps(), [binary()]) -> any(). +feature_response(#iq{type = result, sub_els = [El]}, Host, From, Caps, [SubNode | SubNodes]) -> NodePair = {Caps#caps.node, SubNode}, - case check_hash(Caps, Els) of - true -> - Features = lists:flatmap(fun (#xmlel{name = - <<"feature">>, - attrs = FAttrs}) -> - [fxml:get_attr_s(<<"var">>, FAttrs)]; - (_) -> [] - end, - Els), - cache_tab:insert(caps_features, NodePair, - Features, - caps_write_fun(Host, NodePair, Features)); - false -> ok + try + DiscoInfo = xmpp:decode(El), + case check_hash(Caps, DiscoInfo) of + true -> + Features = DiscoInfo#disco_info.features, + cache_tab:insert(caps_features, NodePair, + Features, + caps_write_fun(Host, NodePair, Features)); + false -> ok + end + catch _:{xmpp_codec, _Why} -> + ok end, feature_request(Host, From, Caps, SubNodes); feature_response(_IQResult, Host, From, Caps, [_SubNode | SubNodes]) -> feature_request(Host, From, Caps, SubNodes). +-spec caps_read_fun(binary(), binary()) -> function(). caps_read_fun(Host, Node) -> LServer = jid:nameprep(Host), Mod = gen_mod:db_mod(LServer, ?MODULE), fun() -> Mod:caps_read(LServer, Node) end. +-spec caps_write_fun(binary(), binary(), [binary()]) -> function(). caps_write_fun(Host, Node, Features) -> LServer = jid:nameprep(Host), Mod = gen_mod:db_mod(LServer, ?MODULE), fun() -> Mod:caps_write(LServer, Node, Features) end. +-spec make_my_disco_hash(binary()) -> binary(). make_my_disco_hash(Host) -> JID = jid:make(<<"">>, Host, <<"">>), case {ejabberd_hooks:run_fold(disco_local_features, @@ -458,119 +428,70 @@ make_my_disco_hash(Host) -> [Host, undefined, <<"">>, <<"">>])} of {{result, Features}, Identities, Info} -> - Feats = lists:map(fun ({{Feat, _Host}}) -> - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, Feat}], - children = []}; - (Feat) -> - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, Feat}], - children = []} + Feats = lists:map(fun ({{Feat, _Host}}) -> Feat; + (Feat) -> Feat end, Features), - make_disco_hash(Identities ++ Info ++ Feats, sha1); + DiscoInfo = #disco_info{identities = Identities, + features = Feats, + xdata = Info}, + make_disco_hash(DiscoInfo, sha); _Err -> <<"">> end. -make_disco_hash(DiscoEls, Algo) -> - Concat = list_to_binary([concat_identities(DiscoEls), - concat_features(DiscoEls), concat_info(DiscoEls)]), +-spec make_disco_hash(disco_info(), crypto:digest_type()) -> binary(). + +make_disco_hash(DiscoInfo, Algo) -> + Concat = list_to_binary([concat_identities(DiscoInfo), + concat_features(DiscoInfo), concat_info(DiscoInfo)]), jlib:encode_base64(case Algo of md5 -> erlang:md5(Concat); - sha1 -> p1_sha:sha1(Concat); + sha -> p1_sha:sha1(Concat); sha224 -> p1_sha:sha224(Concat); sha256 -> p1_sha:sha256(Concat); sha384 -> p1_sha:sha384(Concat); sha512 -> p1_sha:sha512(Concat) end). -check_hash(Caps, Els) -> +-spec check_hash(caps(), disco_info()) -> boolean(). +check_hash(Caps, DiscoInfo) -> case Caps#caps.hash of <<"md5">> -> - Caps#caps.version == make_disco_hash(Els, md5); + Caps#caps.version == make_disco_hash(DiscoInfo, md5); <<"sha-1">> -> - Caps#caps.version == make_disco_hash(Els, sha1); + Caps#caps.version == make_disco_hash(DiscoInfo, sha); <<"sha-224">> -> - Caps#caps.version == make_disco_hash(Els, sha224); + Caps#caps.version == make_disco_hash(DiscoInfo, sha224); <<"sha-256">> -> - Caps#caps.version == make_disco_hash(Els, sha256); + Caps#caps.version == make_disco_hash(DiscoInfo, sha256); <<"sha-384">> -> - Caps#caps.version == make_disco_hash(Els, sha384); + Caps#caps.version == make_disco_hash(DiscoInfo, sha384); <<"sha-512">> -> - Caps#caps.version == make_disco_hash(Els, sha512); + Caps#caps.version == make_disco_hash(DiscoInfo, sha512); _ -> true end. -concat_features(Els) -> - lists:usort(lists:flatmap(fun (#xmlel{name = - <<"feature">>, - attrs = Attrs}) -> - [[fxml:get_attr_s(<<"var">>, Attrs), $<]]; - (_) -> [] - end, - Els)). - -concat_identities(Els) -> - lists:sort(lists:flatmap(fun (#xmlel{name = - <<"identity">>, - attrs = Attrs}) -> - [[fxml:get_attr_s(<<"category">>, Attrs), - $/, fxml:get_attr_s(<<"type">>, Attrs), - $/, - fxml:get_attr_s(<<"xml:lang">>, Attrs), - $/, fxml:get_attr_s(<<"name">>, Attrs), - $<]]; - (_) -> [] - end, - Els)). - -concat_info(Els) -> - lists:sort(lists:flatmap(fun (#xmlel{name = <<"x">>, - attrs = Attrs, children = Fields}) -> - case {fxml:get_attr_s(<<"xmlns">>, Attrs), - fxml:get_attr_s(<<"type">>, Attrs)} - of - {?NS_XDATA, <<"result">>} -> - [concat_xdata_fields(Fields)]; - _ -> [] - end; - (_) -> [] - end, - Els)). +concat_features(#disco_info{features = Features}) -> + lists:usort([[Feat, $<] || Feat <- Features]). + +concat_identities(#disco_info{identities = Identities}) -> + lists:sort( + [[Cat, $/, T, $/, Lang, $/, Name, $<] || + #identity{category = Cat, type = T, + lang = Lang, name = Name} <- Identities]). + +concat_info(#disco_info{xdata = Xs}) -> + lists:sort( + [concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]). concat_xdata_fields(Fields) -> - [Form, Res] = lists:foldl(fun (#xmlel{name = - <<"field">>, - attrs = Attrs, children = Els} = - El, - [FormType, VarFields] = Acc) -> - case fxml:get_attr_s(<<"var">>, Attrs) of - <<"">> -> Acc; - <<"FORM_TYPE">> -> - [fxml:get_subtag_cdata(El, - <<"value">>), - VarFields]; - Var -> - [FormType, - [[[Var, $<], - lists:sort(lists:flatmap(fun - (#xmlel{name - = - <<"value">>, - children - = - VEls}) -> - [[fxml:get_cdata(VEls), - $<]]; - (_) -> - [] - end, - Els))] - | VarFields]] - end; - (_, Acc) -> Acc - end, - [<<"">>, []], Fields), + Form = case lists:keysearch(<<"FORM_TYPE">>, #xdata_field.var, Fields) of + #xdata_field{values = Values} -> Values; + false -> [] + end, + Res = [[Var, $<, lists:sort([[Val, $<] || Val <- Values])] + || #xdata_field{var = Var, values = Values} <- Fields, + is_binary(Var), Var /= <<"FORM_TYPE">>], [Form, $<, lists:sort(Res)]. gb_trees_fold(F, Acc, Tree) -> @@ -588,6 +509,9 @@ gb_trees_fold_iter(F, Acc, Iter) -> now_ts() -> p1_time_compat:system_time(seconds). +-spec is_valid_node(undefined | binary()) -> boolean(). +is_valid_node(undefined) -> + false; is_valid_node(Node) -> case str:tokens(Node, <<"#">>) of [?EJABBERD_URI|_] -> diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index de8d8e1a7..b70ccbc2a 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -36,37 +36,28 @@ stop/1]). -export([user_send_packet/4, user_receive_packet/5, - iq_handler2/3, iq_handler1/3, remove_connection/4, + iq_handler/1, remove_connection/4, is_carbon_copy/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PROCNAME, ?MODULE). +-type direction() :: sent | received. + -callback init(binary(), gen_mod:opts()) -> any(). -callback enable(binary(), binary(), binary(), binary()) -> ok | {error, any()}. -callback disable(binary(), binary(), binary()) -> ok | {error, any()}. -callback list(binary(), binary()) -> [{binary(), binary()}]. +-spec is_carbon_copy(stanza()) -> boolean(). is_carbon_copy(Packet) -> - is_carbon_copy(Packet, <<"sent">>) orelse - is_carbon_copy(Packet, <<"received">>). - -is_carbon_copy(Packet, Direction) -> - case fxml:get_subtag(Packet, Direction) of - #xmlel{name = Direction, attrs = Attrs} -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_CARBONS_2 -> true; - ?NS_CARBONS_1 -> true; - _ -> false - end; - _ -> false - end. + xmpp:has_subtag(Packet, #carbons_sent{}) orelse + xmpp:has_subtag(Packet, #carbons_received{}). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts,fun gen_iq_handler:check_type/1, one_queue), - mod_disco:register_feature(Host, ?NS_CARBONS_1), mod_disco:register_feature(Host, ?NS_CARBONS_2), Mod = gen_mod:db_mod(Host, ?MODULE), Mod:init(Host, Opts), @@ -74,54 +65,53 @@ start(Host, Opts) -> %% why priority 89: to define clearly that we must run BEFORE mod_logdb hook (90) ejabberd_hooks:add(user_send_packet,Host, ?MODULE, user_send_packet, 89), ejabberd_hooks:add(user_receive_packet,Host, ?MODULE, user_receive_packet, 89), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2, ?MODULE, iq_handler2, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_1, ?MODULE, iq_handler1, IQDisc). + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2, ?MODULE, iq_handler, IQDisc). stop(Host) -> - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_1), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2), mod_disco:unregister_feature(Host, ?NS_CARBONS_2), - mod_disco:unregister_feature(Host, ?NS_CARBONS_1), %% why priority 89: to define clearly that we must run BEFORE mod_logdb hook (90) ejabberd_hooks:delete(user_send_packet,Host, ?MODULE, user_send_packet, 89), ejabberd_hooks:delete(user_receive_packet,Host, ?MODULE, user_receive_packet, 89), ejabberd_hooks:delete(unset_presence_hook,Host, ?MODULE, remove_connection, 10). -iq_handler2(From, To, IQ) -> - iq_handler(From, To, IQ, ?NS_CARBONS_2). -iq_handler1(From, To, IQ) -> - iq_handler(From, To, IQ, ?NS_CARBONS_1). - -iq_handler(From, _To, - #iq{type=set, lang = Lang, - sub_el = #xmlel{name = Operation} = SubEl} = IQ, CC)-> - ?DEBUG("carbons IQ received: ~p", [IQ]), +-spec iq_handler(iq()) -> iq(). +iq_handler(#iq{type = set, lang = Lang, from = From, + sub_els = [El]} = IQ) when is_record(El, carbons_enable); + is_record(El, carbons_disable) -> {U, S, R} = jid:tolower(From), - Result = case Operation of - <<"enable">>-> - ?INFO_MSG("carbons enabled for user ~s@~s/~s", [U,S,R]), - enable(S,U,R,CC); - <<"disable">>-> - ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]), - disable(S, U, R) - end, + Result = case El of + #carbons_enable{} -> + ?INFO_MSG("carbons enabled for user ~s@~s/~s", [U,S,R]), + enable(S, U, R, ?NS_CARBONS_2); + #carbons_disable{} -> + ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]), + disable(S, U, R) + end, case Result of - ok -> + ok -> ?DEBUG("carbons IQ result: ok", []), - IQ#iq{type=result, sub_el=[]}; + xmpp:make_iq_result(IQ); {error,_Error} -> ?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]), Txt = <<"Database failure">>, - IQ#iq{type=error,sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]} + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)) end; - -iq_handler(_From, _To, #iq{lang = Lang, sub_el = SubEl} = IQ, _CC)-> +iq_handler(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Only or tags are allowed">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); +iq_handler(#iq{type = get, lang = Lang} = IQ)-> Txt = <<"Value 'get' of 'type' attribute is not allowed">>, - IQ#iq{type=error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}. + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). +-spec user_send_packet(stanza(), ejabberd_c2s:state(), jid(), jid()) -> + stanza() | {stop, stanza()}. user_send_packet(Packet, _C2SState, From, To) -> check_and_forward(From, To, Packet, sent). +-spec user_receive_packet(stanza(), ejabberd_c2s:state(), + jid(), jid(), jid()) -> + stanza() | {stop, stanza()}. user_receive_packet(Packet, _C2SState, JID, _From, To) -> check_and_forward(JID, To, Packet, received). @@ -129,10 +119,12 @@ user_receive_packet(Packet, _C2SState, JID, _From, To) -> % - registered to the user_send_packet hook, to be called only once even for multicast % - do not support "private" message mode, and do not modify the original packet in any way % - we also replicate "read" notifications +-spec check_and_forward(jid(), jid(), stanza(), direction()) -> + stanza() | {stop, stanza()}. check_and_forward(JID, To, Packet, Direction)-> case is_chat_message(Packet) andalso - fxml:get_subtag(Packet, <<"private">>) == false andalso - fxml:get_subtag(Packet, <<"no-copy">>) == false of + xmpp:has_subtag(Packet, #carbons_private{}) == false andalso + xmpp:has_subtag(Packet, #hint{type = 'no-copy'}) == false of true -> case is_carbon_copy(Packet) of false -> @@ -147,6 +139,7 @@ check_and_forward(JID, To, Packet, Direction)-> Packet end. +-spec remove_connection(binary(), binary(), binary(), binary()) -> ok. remove_connection(User, Server, Resource, _Status)-> disable(Server, User, Resource), ok. @@ -154,6 +147,7 @@ remove_connection(User, Server, Resource, _Status)-> %%% Internal %% Direction = received | sent +-spec send_copies(jid(), jid(), message(), direction()) -> ok. send_copies(JID, To, Packet, Direction)-> {U, S, R} = jid:tolower(JID), PrioRes = ejabberd_sm:get_user_present_resources(U, S), @@ -191,88 +185,54 @@ send_copies(JID, To, Packet, Direction)-> %TargetJIDs = lists:delete(JID, [ jid:make({U, S, CCRes}) || CCRes <- list(U, S) ]), end, - lists:map(fun({Dest,Version}) -> + lists:map(fun({Dest, _Version}) -> {_, _, Resource} = jid:tolower(Dest), ?DEBUG("Sending: ~p =/= ~p", [R, Resource]), Sender = jid:make({U, S, <<>>}), %{xmlelement, N, A, C} = Packet, - New = build_forward_packet(JID, Packet, Sender, Dest, Direction, Version), + New = build_forward_packet(JID, Packet, Sender, Dest, Direction), ejabberd_router:route(Sender, Dest, New) end, TargetJIDs), ok. -build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_2) -> - #xmlel{name = <<"message">>, - attrs = [{<<"xmlns">>, <<"jabber:client">>}, - {<<"type">>, message_type(Packet)}, - {<<"from">>, jid:to_string(Sender)}, - {<<"to">>, jid:to_string(Dest)}], - children = [ - #xmlel{name = list_to_binary(atom_to_list(Direction)), - attrs = [{<<"xmlns">>, ?NS_CARBONS_2}], - children = [ - #xmlel{name = <<"forwarded">>, - attrs = [{<<"xmlns">>, ?NS_FORWARD}], - children = [ - complete_packet(JID, Packet, Direction)]} - ]} - ]}; -build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_1) -> - #xmlel{name = <<"message">>, - attrs = [{<<"xmlns">>, <<"jabber:client">>}, - {<<"type">>, message_type(Packet)}, - {<<"from">>, jid:to_string(Sender)}, - {<<"to">>, jid:to_string(Dest)}], - children = [ - #xmlel{name = list_to_binary(atom_to_list(Direction)), - attrs = [{<<"xmlns">>, ?NS_CARBONS_1}]}, - #xmlel{name = <<"forwarded">>, - attrs = [{<<"xmlns">>, ?NS_FORWARD}], - children = [complete_packet(JID, Packet, Direction)]} - ]}. - +-spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message(). +build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) -> + Forwarded = #forwarded{sub_els = complete_packet(JID, Msg, Direction)}, + Carbon = case Direction of + sent -> #carbons_sent{forwarded = Forwarded}; + received -> #carbons_received{forwarded = Forwarded} + end, + #message{from = Sender, to = Dest, type = T, sub_els = [Carbon]}. +-spec enable(binary(), binary(), binary(), binary()) -> ok | {error, any()}. enable(Host, U, R, CC)-> ?DEBUG("enabling for ~p", [U]), Mod = gen_mod:db_mod(Host, ?MODULE), Mod:enable(U, Host, R, CC). +-spec disable(binary(), binary(), binary()) -> ok | {error, any()}. disable(Host, U, R)-> ?DEBUG("disabling for ~p", [U]), Mod = gen_mod:db_mod(Host, ?MODULE), Mod:disable(U, Host, R). -complete_packet(From, #xmlel{name = <<"message">>, attrs = OrigAttrs} = Packet, sent) -> +-spec complete_packet(jid(), message(), direction()) -> message(). +complete_packet(From, #message{from = undefined} = Msg, sent) -> %% if this is a packet sent by user on this host, then Packet doesn't %% include the 'from' attribute. We must add it. - Attrs = lists:keystore(<<"xmlns">>, 1, OrigAttrs, {<<"xmlns">>, <<"jabber:client">>}), - case proplists:get_value(<<"from">>, Attrs) of - undefined -> - Packet#xmlel{attrs = [{<<"from">>, jid:to_string(From)}|Attrs]}; - _ -> - Packet#xmlel{attrs = Attrs} - end; -complete_packet(_From, #xmlel{name = <<"message">>, attrs=OrigAttrs} = Packet, received) -> - Attrs = lists:keystore(<<"xmlns">>, 1, OrigAttrs, {<<"xmlns">>, <<"jabber:client">>}), - Packet#xmlel{attrs = Attrs}. - -message_type(#xmlel{attrs = Attrs}) -> - case fxml:get_attr(<<"type">>, Attrs) of - {value, Type} -> Type; - false -> <<"normal">> - end. - -is_chat_message(#xmlel{name = <<"message">>} = Packet) -> - case message_type(Packet) of - <<"chat">> -> true; - <<"normal">> -> has_non_empty_body(Packet); - _ -> false - end; -is_chat_message(_Packet) -> false. - -has_non_empty_body(Packet) -> - fxml:get_subtag_cdata(Packet, <<"body">>) =/= <<"">>. - + Msg#message{from = From}; +complete_packet(_From, Msg, _Direction) -> + Msg. + +-spec is_chat_message(stanza()) -> boolean(). +is_chat_message(#message{type = chat}) -> + true; +is_chat_message(#message{type = normal, body = Body}) -> + xmpp:get_text(Body) /= <<"">>; +is_chat_message(_) -> + false. + +-spec list(binary(), binary()) -> [{binary(), binary()}]. %% list {resource, cc_version} with carbons enabled for given user and host list(User, Server) -> Mod = gen_mod:db_mod(Server, ?MODULE), diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index 036175cce..a6a6ddc20 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -39,7 +39,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(CSI_QUEUE_MAX, 100). @@ -151,66 +151,62 @@ depends(_Host, _Opts) -> %% ejabberd_hooks callbacks. %%-------------------------------------------------------------------- --spec filter_presence({term(), [xmlel()]}, binary(), xmlel()) - -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}. +-spec filter_presence({term(), [stanza()]}, binary(), stanza()) + -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}. filter_presence({C2SState, _OutStanzas} = Acc, Host, - #xmlel{name = <<"presence">>, attrs = Attrs} = Stanza) -> - case fxml:get_attr(<<"type">>, Attrs) of - {value, Type} when Type /= <<"unavailable">> -> - Acc; - _ -> - ?DEBUG("Got availability presence stanza", []), - queue_add(presence, Stanza, Host, C2SState) + #presence{type = Type} = Stanza) -> + if Type == available, Type == unavailable -> + ?DEBUG("Got availability presence stanza", []), + queue_add(presence, Stanza, Host, C2SState); + true -> + Acc end; filter_presence(Acc, _Host, _Stanza) -> Acc. --spec filter_chat_states({term(), [xmlel()]}, binary(), xmlel()) - -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}. +-spec filter_chat_states({term(), [stanza()]}, binary(), stanza()) + -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}. filter_chat_states({C2SState, _OutStanzas} = Acc, Host, - #xmlel{name = <<"message">>} = Stanza) -> - case jlib:is_standalone_chat_state(Stanza) of - true -> - From = fxml:get_tag_attr_s(<<"from">>, Stanza), - To = fxml:get_tag_attr_s(<<"to">>, Stanza), - case {jid:from_string(From), jid:from_string(To)} of - {#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}} -> - %% Don't queue (carbon copies of) chat states from other - %% resources, as they might be used to sync the state of - %% conversations across clients. - Acc; - _ -> - ?DEBUG("Got standalone chat state notification", []), - queue_add(chatstate, Stanza, Host, C2SState) - end; - false -> - Acc + #message{from = From, to = To} = Stanza) -> + case xmpp_util:is_standalone_chat_state(Stanza) of + true -> + case {From, To} of + {#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}} -> + %% Don't queue (carbon copies of) chat states from other + %% resources, as they might be used to sync the state of + %% conversations across clients. + Acc; + _ -> + ?DEBUG("Got standalone chat state notification", []), + queue_add(chatstate, Stanza, Host, C2SState) + end; + false -> + Acc end; filter_chat_states(Acc, _Host, _Stanza) -> Acc. --spec filter_pep({term(), [xmlel()]}, binary(), xmlel()) - -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}. +-spec filter_pep({term(), [stanza()]}, binary(), stanza()) + -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}. -filter_pep({C2SState, _OutStanzas} = Acc, Host, - #xmlel{name = <<"message">>} = Stanza) -> +filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) -> case get_pep_node(Stanza) of - {value, Node} -> - ?DEBUG("Got PEP notification", []), - queue_add({pep, Node}, Stanza, Host, C2SState); - false -> - Acc + undefined -> + Acc; + Node -> + ?DEBUG("Got PEP notification", []), + queue_add({pep, Node}, Stanza, Host, C2SState) end; filter_pep(Acc, _Host, _Stanza) -> Acc. --spec filter_other({term(), [xmlel()]}, binary(), xmlel()) - -> {stop, {term(), [xmlel()]}}. +-spec filter_other({term(), [stanza()]}, binary(), stanza()) + -> {stop, {term(), [stanza()]}}. filter_other({C2SState, _OutStanzas}, Host, Stanza) -> ?DEBUG("Won't add stanza to CSI queue", []), queue_take(Stanza, Host, C2SState). --spec flush_queue({term(), [xmlel()]}, binary()) -> {term(), [xmlel()]}. +-spec flush_queue({term(), [stanza()]}, binary()) -> {term(), [stanza()]}. flush_queue({C2SState, _OutStanzas}, Host) -> ?DEBUG("Going to flush CSI queue", []), @@ -218,20 +214,17 @@ flush_queue({C2SState, _OutStanzas}, Host) -> NewState = set_queue([], C2SState), {NewState, get_stanzas(Queue, Host)}. --spec add_stream_feature([xmlel()], binary) -> [xmlel()]. +-spec add_stream_feature([stanza()], binary) -> [stanza()]. add_stream_feature(Features, _Host) -> - Feature = #xmlel{name = <<"csi">>, - attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}], - children = []}, - [Feature | Features]. + [#feature_csi{xmlns = <<"urn:xmpp:csi:0">>} | Features]. %%-------------------------------------------------------------------- %% Internal functions. %%-------------------------------------------------------------------- --spec queue_add(csi_type(), xmlel(), binary(), term()) - -> {stop, {term(), [xmlel()]}}. +-spec queue_add(csi_type(), stanza(), binary(), term()) + -> {stop, {term(), [stanza()]}}. queue_add(Type, Stanza, Host, C2SState) -> case get_queue(C2SState) of @@ -241,19 +234,19 @@ queue_add(Type, Stanza, Host, C2SState) -> {stop, {NewState, get_stanzas(Queue, Host) ++ [Stanza]}}; Queue -> ?DEBUG("Adding stanza to CSI queue", []), - From = fxml:get_tag_attr_s(<<"from">>, Stanza), - Key = {jid:tolower(jid:from_string(From)), Type}, + From = xmpp:get_from(Stanza), + Key = {jid:tolower(From), Type}, Entry = {Key, p1_time_compat:timestamp(), Stanza}, NewQueue = lists:keystore(Key, 1, Queue, Entry), NewState = set_queue(NewQueue, C2SState), {stop, {NewState, []}} end. --spec queue_take(xmlel(), binary(), term()) -> {stop, {term(), [xmlel()]}}. +-spec queue_take(stanza(), binary(), term()) -> {stop, {term(), [stanza()]}}. queue_take(Stanza, Host, C2SState) -> - From = fxml:get_tag_attr_s(<<"from">>, Stanza), - {LUser, LServer, _LResource} = jid:tolower(jid:from_string(From)), + From = xmpp:get_from(Stanza), + {LUser, LServer, _LResource} = jid:tolower(From), {Selected, Rest} = lists:partition( fun({{{U, S, _R}, _Type}, _Time, _Stanza}) -> U == LUser andalso S == LServer @@ -276,32 +269,23 @@ get_queue(C2SState) -> [] end. --spec get_stanzas(csi_queue(), binary()) -> [xmlel()]. +-spec get_stanzas(csi_queue(), binary()) -> [stanza()]. get_stanzas(Queue, Host) -> lists:map(fun({_Key, Time, Stanza}) -> - jlib:add_delay_info(Stanza, Host, Time, - <<"Client Inactive">>) + xmpp_util:add_delay_info(Stanza, Host, Time, + <<"Client Inactive">>) end, Queue). --spec get_pep_node(xmlel()) -> {value, binary()} | false. - -get_pep_node(#xmlel{name = <<"message">>} = Stanza) -> - From = fxml:get_tag_attr_s(<<"from">>, Stanza), - case jid:from_string(From) of - #jid{luser = <<>>} -> % It's not PEP. - false; - _ -> - case fxml:get_subtag_with_xmlns(Stanza, <<"event">>, - ?NS_PUBSUB_EVENT) of - #xmlel{children = Els} -> - case fxml:remove_cdata(Els) of - [#xmlel{name = <<"items">>, attrs = ItemsAttrs}] -> - fxml:get_attr(<<"node">>, ItemsAttrs); - _ -> - false - end; - false -> - false - end +-spec get_pep_node(message()) -> binary() | undefined. + +get_pep_node(#message{from = #jid{luser = <<>>}}) -> + %% It's not PEP. + undefined; +get_pep_node(#message{} = Msg) -> + case xmpp:get_subtag(Msg, #pubsub_event{}) of + #pubsub_event{items = [#pubsub_event_item{node = Node}]} -> + Node; + _ -> + undefined end. diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 2e7b80c18..03fdab209 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -32,10 +32,10 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq_items/3, - process_local_iq_info/3, get_local_identity/5, +-export([start/2, stop/1, process_local_iq_items/1, + process_local_iq_info/1, get_local_identity/5, get_local_features/5, get_local_services/5, - process_sm_iq_items/3, process_sm_iq_info/3, + process_sm_iq_items/1, process_sm_iq_info/1, get_sm_identity/5, get_sm_features/5, get_sm_items/5, get_info/5, register_feature/2, unregister_feature/2, register_extra_domain/2, unregister_extra_domain/2, @@ -44,8 +44,8 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). - +-include("xmpp.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). -include("mod_roster.hrl"). start(Host, Opts) -> @@ -126,158 +126,133 @@ stop(Host) -> {{'_', Host}}), ok. +-spec register_feature(binary(), binary()) -> true. register_feature(Host, Feature) -> catch ets:new(disco_features, [named_table, ordered_set, public]), ets:insert(disco_features, {{Feature, Host}}). +-spec unregister_feature(binary(), binary()) -> true. unregister_feature(Host, Feature) -> catch ets:new(disco_features, [named_table, ordered_set, public]), ets:delete(disco_features, {Feature, Host}). +-spec register_extra_domain(binary(), binary()) -> true. register_extra_domain(Host, Domain) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), ets:insert(disco_extra_domains, {{Domain, Host}}). +-spec unregister_extra_domain(binary(), binary()) -> true. unregister_extra_domain(Host, Domain) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), ets:delete(disco_extra_domains, {Domain, Host}). -process_local_iq_items(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - Node = fxml:get_tag_attr_s(<<"node">>, SubEl), - Host = To#jid.lserver, - case ejabberd_hooks:run_fold(disco_local_items, Host, - empty, [From, To, Node, Lang]) - of - {result, Items} -> - ANode = case Node of - <<"">> -> []; - _ -> [{<<"node">>, Node}] - end, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_DISCO_ITEMS} | ANode], - children = Items}]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end +-spec process_local_iq_items(iq()) -> iq(). +process_local_iq_items(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq_items(#iq{type = get, lang = Lang, + from = From, to = To, + sub_els = [#disco_items{node = Node}]} = IQ) -> + Host = To#jid.lserver, + case ejabberd_hooks:run_fold(disco_local_items, Host, + empty, [From, To, Node, Lang]) of + {result, Items} -> + xmpp:make_iq_result(IQ, #disco_items{node = Node, items = Items}); + {error, Error} -> + xmpp:make_error(IQ, Error) end. -process_local_iq_info(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - Host = To#jid.lserver, - Node = fxml:get_tag_attr_s(<<"node">>, SubEl), - Identity = ejabberd_hooks:run_fold(disco_local_identity, - Host, [], [From, To, Node, Lang]), - Info = ejabberd_hooks:run_fold(disco_info, Host, [], - [Host, ?MODULE, Node, Lang]), - case ejabberd_hooks:run_fold(disco_local_features, Host, - empty, [From, To, Node, Lang]) - of - {result, Features} -> - ANode = case Node of - <<"">> -> []; - _ -> [{<<"node">>, Node}] - end, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_DISCO_INFO} | ANode], - children = - Identity ++ - Info ++ features_to_xml(Features)}]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end +-spec process_local_iq_info(iq()) -> iq(). +process_local_iq_info(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq_info(#iq{type = get, lang = Lang, + from = From, to = To, + sub_els = [#disco_info{node = Node}]} = IQ) -> + Host = To#jid.lserver, + Identity = ejabberd_hooks:run_fold(disco_local_identity, + Host, [], [From, To, Node, Lang]), + Info = ejabberd_hooks:run_fold(disco_info, Host, [], + [Host, ?MODULE, Node, Lang]), + case ejabberd_hooks:run_fold(disco_local_features, Host, + empty, [From, To, Node, Lang]) of + {result, Features} -> + xmpp:make_iq_result(IQ, #disco_info{node = Node, + identities = Identity, + xdata = Info, + features = Features}); + {error, Error} -> + xmpp:make_error(IQ, Error) end. -get_local_identity(Acc, _From, _To, <<>>, _Lang) -> - Acc ++ - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"server">>}, {<<"type">>, <<"im">>}, - {<<"name">>, <<"ejabberd">>}], - children = []}]; +-spec get_local_identity([identity()], jid(), jid(), + undefined | binary(), undefined | binary()) -> + [identity()]. +get_local_identity(Acc, _From, _To, undefined, _Lang) -> + Acc ++ [#identity{category = <<"server">>, + type = <<"im">>, + name = <<"ejabberd">>}]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. +-spec get_local_features({error, error()} | {result, [binary()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [binary()]}. get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; -get_local_features(Acc, _From, To, <<>>, _Lang) -> +get_local_features(Acc, _From, To, undefined, _Lang) -> Feats = case Acc of - {result, Features} -> Features; - empty -> [] + {result, Features} -> Features; + empty -> [] end, Host = To#jid.lserver, {result, ets:select(disco_features, - [{{{'_', Host}}, [], ['$_']}]) - ++ Feats}; + ets:fun2ms(fun({{F, H}}) when H == Host -> F end)) + ++ Feats}; get_local_features(Acc, _From, _To, _Node, Lang) -> case Acc of {result, _Features} -> Acc; empty -> Txt = <<"No features available">>, - {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)} + {error, xmpp:err_item_not_found(Txt, Lang)} end. -features_to_xml(FeatureList) -> - [#xmlel{name = <<"feature">>, - attrs = [{<<"var">>, Feat}], children = []} - || Feat - <- lists:usort(lists:map(fun ({{Feature, _Host}}) -> - Feature; - (Feature) when is_binary(Feature) -> - Feature - end, - FeatureList))]. - -domain_to_xml({Domain}) -> - #xmlel{name = <<"item">>, attrs = [{<<"jid">>, Domain}], - children = []}; -domain_to_xml(Domain) -> - #xmlel{name = <<"item">>, attrs = [{<<"jid">>, Domain}], - children = []}. - +-spec get_local_services({error, error()} | {result, [disco_item()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [disco_item()]}. get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; -get_local_services(Acc, _From, To, <<>>, _Lang) -> +get_local_services(Acc, _From, To, undefined, _Lang) -> Items = case Acc of {result, Its} -> Its; empty -> [] end, Host = To#jid.lserver, {result, - lists:usort(lists:map(fun domain_to_xml/1, - get_vh_services(Host) ++ - ets:select(disco_extra_domains, - [{{{'$1', Host}}, [], ['$1']}]))) - ++ Items}; + lists:usort( + lists:map( + fun(Domain) -> #disco_item{jid = jid:make(Domain)} end, + get_vh_services(Host) ++ + ets:select(disco_extra_domains, + ets:fun2ms( + fun({{D, H}}) when H == Host -> D end)))) + ++ Items}; get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) -> Acc; get_local_services(empty, _From, _To, _Node, Lang) -> - {error, ?ERRT_ITEM_NOT_FOUND(Lang, <<"No services available">>)}. + {error, xmpp:err_item_not_found(<<"No services available">>, Lang)}. +-spec get_vh_services(binary()) -> [binary()]. get_vh_services(Host) -> Hosts = lists:sort(fun (H1, H2) -> byte_size(H1) >= byte_size(H2) @@ -300,47 +275,38 @@ get_vh_services(Host) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -process_sm_iq_items(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - case is_presence_subscribed(From, To) of - true -> - Host = To#jid.lserver, - Node = fxml:get_tag_attr_s(<<"node">>, SubEl), - case ejabberd_hooks:run_fold(disco_sm_items, Host, - empty, [From, To, Node, Lang]) - of - {result, Items} -> - ANode = case Node of - <<"">> -> []; - _ -> [{<<"node">>, Node}] - end, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_DISCO_ITEMS} - | ANode], - children = Items}]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; - false -> - Txt = <<"Not subscribed">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]} - end +-spec process_sm_iq_items(iq()) -> iq(). +process_sm_iq_items(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_sm_iq_items(#iq{type = get, lang = Lang, + from = From, to = To, + sub_els = [#disco_items{node = Node}]} = IQ) -> + case is_presence_subscribed(From, To) of + true -> + Host = To#jid.lserver, + case ejabberd_hooks:run_fold(disco_sm_items, Host, + empty, [From, To, Node, Lang]) of + {result, Items} -> + xmpp:make_iq_result( + IQ, #disco_items{node = Node, items = Items}); + {error, Error} -> + xmpp:make_error(IQ, Error) + end; + false -> + Txt = <<"Not subscribed">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)) end. +-spec get_sm_items({error, error()} | {result, [disco_item()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [disco_item()]}. get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_items(Acc, From, - #jid{user = User, server = Server} = To, <<>>, _Lang) -> + #jid{user = User, server = Server} = To, undefined, _Lang) -> Items = case Acc of {result, Its} -> Its; empty -> [] @@ -357,12 +323,13 @@ get_sm_items(empty, From, To, _Node, Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of - {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; + {LTo, LSTo} -> {error, xmpp:err_item_not_found()}; _ -> Txt = <<"Query to another users is forbidden">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)} + {error, xmpp:err_not_allowed(Txt, Lang)} end. +-spec is_presence_subscribed(jid(), jid()) -> boolean(). is_presence_subscribed(#jid{luser = User, lserver = Server}, #jid{luser = User, lserver = Server}) -> true; is_presence_subscribed(#jid{luser = FromUser, lserver = FromServer}, @@ -377,86 +344,70 @@ is_presence_subscribed(#jid{luser = FromUser, lserver = FromServer}, ejabberd_hooks:run_fold(roster_get, ToServer, [], [{ToUser, ToServer}])). -process_sm_iq_info(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - case is_presence_subscribed(From, To) of - true -> - Host = To#jid.lserver, - Node = fxml:get_tag_attr_s(<<"node">>, SubEl), - Identity = ejabberd_hooks:run_fold(disco_sm_identity, - Host, [], - [From, To, Node, Lang]), - Info = ejabberd_hooks:run_fold(disco_info, Host, [], +-spec process_sm_iq_info(iq()) -> iq(). +process_sm_iq_info(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_sm_iq_info(#iq{type = get, lang = Lang, + from = From, to = To, + sub_els = [#disco_info{node = Node}]} = IQ) -> + case is_presence_subscribed(From, To) of + true -> + Host = To#jid.lserver, + Identity = ejabberd_hooks:run_fold(disco_sm_identity, + Host, [], [From, To, Node, Lang]), - case ejabberd_hooks:run_fold(disco_sm_features, Host, - empty, [From, To, Node, Lang]) - of - {result, Features} -> - ANode = case Node of - <<"">> -> []; - _ -> [{<<"node">>, Node}] - end, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_DISCO_INFO} - | ANode], - children = - Identity ++ Info ++ - features_to_xml(Features)}]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; - false -> - Txt = <<"Not subscribed">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]} - end + Info = ejabberd_hooks:run_fold(disco_info, Host, [], + [From, To, Node, Lang]), + case ejabberd_hooks:run_fold(disco_sm_features, Host, + empty, [From, To, Node, Lang]) of + {result, Features} -> + xmpp:make_iq_result(IQ, #disco_info{node = Node, + identities = Identity, + xdata = Info, + features = Features}); + {error, Error} -> + xmpp:make_error(IQ, Error) + end; + false -> + Txt = <<"Not subscribed">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)) end. +-spec get_sm_identity([identity()], jid(), jid(), + undefined | binary(), undefined | binary()) -> + [identity()]. get_sm_identity(Acc, _From, #jid{luser = LUser, lserver = LServer}, _Node, _Lang) -> Acc ++ case ejabberd_auth:is_user_exists(LUser, LServer) of true -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"account">>}, - {<<"type">>, <<"registered">>}], - children = []}]; + [#identity{category = <<"account">>, type = <<"registered">>}]; _ -> [] end. +-spec get_sm_features({error, error()} | {result, [binary()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [binary()]}. get_sm_features(empty, From, To, _Node, Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of - {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; + {LTo, LSTo} -> {error, xmpp:err_item_not_found()}; _ -> Txt = <<"Query to another users is forbidden">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)} + {error, xmpp:err_not_allowed(Txt, Lang)} end; get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. +-spec get_user_resources(binary(), binary()) -> [disco_item()]. get_user_resources(User, Server) -> Rs = ejabberd_sm:get_user_resources(User, Server), - lists:map(fun (R) -> - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - <>}, - {<<"name">>, User}], - children = []} - end, - lists:sort(Rs)). + [#disco_item{jid = jid:make(User, Server, Resource), name = User} + || Resource <- lists:sort(Rs)]. +-spec transform_module_options(gen_mod:opts()) -> gen_mod:opts(). transform_module_options(Opts) -> lists:map( fun({server_info, Infos}) -> @@ -477,27 +428,23 @@ transform_module_options(Opts) -> %%% Support for: XEP-0157 Contact Addresses for XMPP Services -get_info(_A, Host, Mod, Node, _Lang) when Node == <<>> -> +-spec get_info([xdata()], binary(), module(), + undefined | binary(), undefined | binary()) -> + [xdata()]. +get_info(_A, Host, Mod, Node, _Lang) when Node == undefined -> Module = case Mod of undefined -> ?MODULE; _ -> Mod end, - Serverinfo_fields = get_fields_xml(Host, Module), - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}], - children = - [#xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, ?NS_SERVERINFO}]}]}] - ++ Serverinfo_fields}]; + [#xdata{type = result, + fields = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [?NS_SERVERINFO]} + | get_fields(Host, Module)]}]; get_info(Acc, _, _, _Node, _) -> Acc. -get_fields_xml(Host, Module) -> +-spec get_fields(binary(), module()) -> [xdata_field()]. +get_fields(Host, Module) -> Fields = gen_mod:get_module_opt( Host, ?MODULE, server_info, fun(L) -> @@ -509,31 +456,17 @@ get_fields_xml(Host, Module) -> {Mods, Name, URLs} end, L) end, []), - Fields_good = lists:filter(fun ({Modules, _, _}) -> - case Modules of - all -> true; - Modules -> - lists:member(Module, Modules) - end - end, - Fields), - fields_to_xml(Fields_good). - -fields_to_xml(Fields) -> - [field_to_xml(Field) || Field <- Fields]. - -field_to_xml({_, Var, Values}) -> - Values_xml = values_to_xml(Values), - #xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}], - children = Values_xml}. - -values_to_xml(Values) -> - lists:map(fun (Value) -> - #xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Value}]} - end, - Values). - + Fields1 = lists:filter(fun ({Modules, _, _}) -> + case Modules of + all -> true; + Modules -> + lists:member(Module, Modules) + end + end, + Fields), + [#xdata_field{var = Var, values = Values} || {_, Var, Values} <- Fields1]. + +-spec depends(binary(), gen_mod:opts()) -> []. depends(_Host, _Opts) -> []. diff --git a/src/mod_echo.erl b/src/mod_echo.erl index ee904d798..fe4b8d90d 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -42,7 +42,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {host = <<"">> :: binary()}). @@ -118,10 +118,10 @@ handle_cast(_Msg, State) -> {noreply, State}. handle_info({route, From, To, Packet}, State) -> Packet2 = case From#jid.user of <<"">> -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"User part of JID in 'from' is empty">>, - jlib:make_error_reply( - Packet, ?ERRT_BAD_REQUEST(Lang, Txt)); + xmpp:make_error( + Packet, xmpp:err_bad_request(Txt, Lang)); _ -> Packet end, do_client_version(disabled, To, From), @@ -168,37 +168,27 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %% using exactly the same JID. We add a (mostly) random resource to %% try to guarantee that the received response matches the request sent. %% Finally, the received response is printed in the ejabberd log file. + +%% THIS IS **NOT** HOW TO WRITE ejabberd CODE. THIS CODE IS RETARDED. + do_client_version(disabled, _From, _To) -> ok; do_client_version(enabled, From, To) -> - ToS = jid:to_string(To), - Random_resource = - iolist_to_binary(integer_to_list(random:uniform(100000))), + Random_resource = randoms:get_string(), From2 = From#jid{resource = Random_resource, lresource = Random_resource}, - Packet = #xmlel{name = <<"iq">>, - attrs = [{<<"to">>, ToS}, {<<"type">>, <<"get">>}], - children = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_VERSION}], - children = []}]}, + ID = randoms:get_string(), + Packet = #iq{from = From, to = To, type = get, + id = randoms:get_string(), + sub_els = [#version{}]}, ejabberd_router:route(From2, To, Packet), - Els = receive - {route, To, From2, IQ} -> - #xmlel{name = <<"query">>, children = List} = - fxml:get_subtag(IQ, <<"query">>), - List - after 5000 -> % Timeout in miliseconds: 5 seconds - [] - end, - Values = [{Name, Value} - || #xmlel{name = Name, attrs = [], - children = [{xmlcdata, Value}]} - <- Els], - Values_string1 = [io_lib:format("~n~s: ~p", [N, V]) - || {N, V} <- Values], - Values_string2 = iolist_to_binary(Values_string1), - ?INFO_MSG("Information of the client: ~s~s", - [ToS, Values_string2]). + receive + {route, To, From2, + #iq{id = ID, type = result, sub_els = [#version{} = V]}} -> + ?INFO_MSG("Version of the client ~s:~n~s", + [jid:to_string(To), xmpp:pp(V)]) + after 5000 -> % Timeout in miliseconds: 5 seconds + [] + end. depends(_Host, _Opts) -> []. diff --git a/src/mod_last.erl b/src/mod_last.erl index ce9148841..b267aa89b 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -33,8 +33,8 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, export/1, - process_sm_iq/3, on_presence_update/4, import/1, +-export([start/2, stop/1, process_local_iq/1, export/1, + process_sm_iq/1, on_presence_update/4, import/1, import/3, store_last_info/4, get_last_info/2, remove_user/2, transform_options/1, mod_opt_type/1, opt_type/1, register_user/2, depends/2]). @@ -42,7 +42,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). -include("mod_last.hrl"). @@ -87,25 +87,14 @@ stop(Host) -> %%% Uptime of ejabberd node %%% -process_local_iq(_From, _To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - Sec = get_node_uptime(), - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_LAST}, - {<<"seconds">>, - iolist_to_binary(integer_to_list(Sec))}], - children = []}]} - end. +-spec process_local_iq(iq()) -> iq(). +process_local_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq(#iq{type = get} = IQ) -> + xmpp:make_iq_result(IQ, #last{seconds = get_node_uptime()}). -%% @spec () -> integer() +-spec get_node_uptime() -> non_neg_integer(). %% @doc Get the uptime of the ejabberd node, expressed in seconds. %% When ejabberd is starting, ejabberd_config:start/0 stores the datetime. get_node_uptime() -> @@ -118,6 +107,7 @@ get_node_uptime() -> p1_time_compat:system_time(seconds) - Now end. +-spec now_to_seconds(erlang:timestamp()) -> non_neg_integer(). now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> MegaSecs * 1000000 + Secs. @@ -125,83 +115,63 @@ now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> %%% Serve queries about user last online %%% -process_sm_iq(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - User = To#jid.luser, - Server = To#jid.lserver, - {Subscription, _Groups} = - ejabberd_hooks:run_fold(roster_get_jid_info, Server, - {none, []}, [User, Server, From]), - if (Subscription == both) or (Subscription == from) or - (From#jid.luser == To#jid.luser) and - (From#jid.lserver == To#jid.lserver) -> - UserListRecord = - ejabberd_hooks:run_fold(privacy_get_user_list, Server, - #userlist{}, [User, Server]), - case ejabberd_hooks:run_fold(privacy_check_packet, - Server, allow, - [User, Server, UserListRecord, - {To, From, - #xmlel{name = <<"presence">>, - attrs = [], - children = []}}, - out]) - of - allow -> get_last_iq(IQ, SubEl, User, Server); - deny -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} - end; - true -> - Txt = <<"Not subscribed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]} - end +-spec process_sm_iq(iq()) -> iq(). +process_sm_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_sm_iq(#iq{from = From, to = To, lang = Lang} = IQ) -> + User = To#jid.luser, + Server = To#jid.lserver, + {Subscription, _Groups} = + ejabberd_hooks:run_fold(roster_get_jid_info, Server, + {none, []}, [User, Server, From]), + if (Subscription == both) or (Subscription == from) or + (From#jid.luser == To#jid.luser) and + (From#jid.lserver == To#jid.lserver) -> + UserListRecord = + ejabberd_hooks:run_fold(privacy_get_user_list, Server, + #userlist{}, [User, Server]), + case ejabberd_hooks:run_fold(privacy_check_packet, + Server, allow, + [User, Server, UserListRecord, + {To, From, #presence{}}, out]) of + allow -> get_last_iq(IQ, User, Server); + deny -> xmpp:make_error(IQ, xmpp:err_forbidden()) + end; + true -> + Txt = <<"Not subscribed">>, + xmpp:make_error(IQ, xmpp:err_not_subscribed(Txt, Lang)) end. %% @spec (LUser::string(), LServer::string()) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason} +-spec get_last(binary(), binary()) -> {ok, non_neg_integer(), binary()} | + not_found | {error, any()}. get_last(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_last(LUser, LServer). -get_last_iq(#iq{lang = Lang} = IQ, SubEl, LUser, LServer) -> +-spec get_last_iq(iq(), binary(), binary()) -> iq(). +get_last_iq(#iq{lang = Lang} = IQ, LUser, LServer) -> case ejabberd_sm:get_user_resources(LUser, LServer) of [] -> case get_last(LUser, LServer) of {error, _Reason} -> Txt = <<"Database failure">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}; + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)); not_found -> Txt = <<"No info about last activity found">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}; + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)); {ok, TimeStamp, Status} -> TimeStamp2 = p1_time_compat:system_time(seconds), Sec = TimeStamp2 - TimeStamp, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_LAST}, - {<<"seconds">>, - iolist_to_binary(integer_to_list(Sec))}], - children = [{xmlcdata, Status}]}]} + xmpp:make_iq_result(IQ, #last{seconds = Sec, status = Status}) end; _ -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_LAST}, - {<<"seconds">>, <<"0">>}], - children = []}]} + xmpp:make_iq_result(IQ, #last{seconds = 0}) end. +-spec register_user(binary(), binary()) -> {atomic, any()}. register_user(User, Server) -> on_presence_update( User, @@ -209,18 +179,21 @@ register_user(User, Server) -> <<"RegisterResource">>, <<"Registered but didn't login">>). +-spec on_presence_update(binary(), binary(), binary(), binary()) -> {atomic, any()}. on_presence_update(User, Server, _Resource, Status) -> TimeStamp = p1_time_compat:system_time(seconds), store_last_info(User, Server, TimeStamp, Status). +-spec store_last_info(binary(), binary(), non_neg_integer(), binary()) -> + {atomic, any()}. store_last_info(User, Server, TimeStamp, Status) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:store_last_info(LUser, LServer, TimeStamp, Status). -%% @spec (LUser::string(), LServer::string()) -> -%% {ok, TimeStamp::integer(), Status::string()} | not_found +-spec get_last_info(binary(), binary()) -> {ok, non_neg_integer(), binary()} | + not_found. get_last_info(LUser, LServer) -> case get_last(LUser, LServer) of {error, _Reason} -> not_found; diff --git a/src/mod_ping.erl b/src/mod_ping.erl index d1b3f9322..b09ca9ab2 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -36,7 +36,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(SUPERVISOR, ejabberd_sup). @@ -54,7 +54,7 @@ -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3]). --export([iq_ping/3, user_online/3, user_offline/3, +-export([iq_ping/1, user_online/3, user_offline/3, user_send/4, mod_opt_type/1, depends/2]). -record(state, @@ -73,10 +73,12 @@ start_link(Host, Opts) -> gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). +-spec start_ping(binary(), jid()) -> ok. start_ping(Host, JID) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:cast(Proc, {start_ping, JID}). +-spec stop_ping(binary(), jid()) -> ok. stop_ping(Host, JID) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:cast(Proc, {stop_ping, JID}). @@ -181,10 +183,7 @@ handle_cast({iq_pong, JID, timeout}, State) -> handle_cast(_Msg, State) -> {noreply, State}. handle_info({timeout, _TRef, {ping, JID}}, State) -> - IQ = #iq{type = get, - sub_el = - [#xmlel{name = <<"ping">>, - attrs = [{<<"xmlns">>, ?NS_PING}], children = []}]}, + IQ = #iq{type = get, sub_els = [#ping{}]}, Pid = self(), F = fun (Response) -> gen_server:cast(Pid, {iq_pong, JID, Response}) @@ -201,23 +200,22 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%==================================================================== %% Hook callbacks %%==================================================================== -iq_ping(_From, _To, - #iq{type = Type, sub_el = SubEl, lang = Lang} = IQ) -> - case {Type, SubEl} of - {get, #xmlel{name = <<"ping">>}} -> - IQ#iq{type = result, sub_el = []}; - _ -> - Txt = <<"Ping query is incorrect">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]} - end. - +-spec iq_ping(iq()) -> iq(). +iq_ping(#iq{type = get, sub_els = [#ping{}]} = IQ) -> + xmpp:make_iq_result(IQ); +iq_ping(#iq{lang = Lang} = IQ) -> + Txt = <<"Ping query is incorrect">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)). + +-spec user_online(ejabberd_sm:sid(), jid(), any()) -> ok. user_online(_SID, JID, _Info) -> start_ping(JID#jid.lserver, JID). +-spec user_offline(ejabberd_sm:sid(), jid(), any()) -> ok. user_offline(_SID, JID, _Info) -> stop_ping(JID#jid.lserver, JID). +-spec user_send(stanza(), ejabberd_c2s:state(), jid(), jid()) -> stanza(). user_send(Packet, _C2SState, JID, _From) -> start_ping(JID#jid.lserver, JID), Packet. @@ -225,6 +223,7 @@ user_send(Packet, _C2SState, JID, _From) -> %%==================================================================== %% Internal functions %%==================================================================== +-spec add_timer(jid(), non_neg_integer(), map()) -> map(). add_timer(JID, Interval, Timers) -> LJID = jid:tolower(JID), NewTimers = case maps:find(LJID, Timers) of @@ -237,6 +236,7 @@ add_timer(JID, Interval, Timers) -> {ping, JID}), maps:put(LJID, TRef, NewTimers). +-spec del_timer(jid(), map()) -> map(). del_timer(JID, Timers) -> LJID = jid:tolower(JID), case maps:find(LJID, Timers) of @@ -246,6 +246,7 @@ del_timer(JID, Timers) -> _ -> Timers end. +-spec cancel_timer(reference()) -> ok. cancel_timer(TRef) -> case erlang:cancel_timer(TRef) of false -> diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 18ff78371..e88c1fb5b 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -31,8 +31,8 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_iq/3, export/1, import/1, - process_iq_set/4, process_iq_get/5, get_user_list/3, +-export([start/2, stop/1, process_iq/1, export/1, import/1, + process_iq_set/2, process_iq_get/3, get_user_list/3, check_packet/6, remove_user/2, is_list_needdb/1, updated_list/3, item_to_xml/1, get_user_lists/2, import/3, @@ -41,15 +41,15 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). -callback import(binary(), #privacy{}) -> ok | pass. --callback process_lists_get(binary(), binary()) -> {none | binary(), [xmlel()]} | error. +-callback process_lists_get(binary(), binary()) -> {none | binary(), [binary()]} | error. -callback process_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found. --callback process_default_set(binary(), binary(), {value, binary()} | false) -> {atomic, any()}. +-callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}. -callback process_active_set(binary(), binary(), binary()) -> [listitem()] | error. -callback remove_privacy_list(binary(), binary(), binary()) -> {atomic, any()}. -callback set_privacy_list(#privacy{}) -> any(). @@ -96,335 +96,276 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY). -process_iq(_From, _To, IQ) -> - SubEl = IQ#iq.sub_el, - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. +-spec process_iq(iq()) -> iq(). +process_iq(IQ) -> + xmpp:make_error(IQ, xmpp:err_not_allowed()). -process_iq_get(_, From, _To, #iq{lang = Lang, sub_el = SubEl}, +-spec process_iq_get({error, error()} | iq(), + iq(), userlist()) -> {error, error()} | {result, privacy_query()}. +process_iq_get(_, #iq{from = From, lang = Lang, + sub_els = [#privacy_query{lists = Lists}]}, #userlist{name = Active}) -> #jid{luser = LUser, lserver = LServer} = From, - #xmlel{children = Els} = SubEl, - case fxml:remove_cdata(Els) of - [] -> process_lists_get(LUser, LServer, Active, Lang); - [#xmlel{name = Name, attrs = Attrs}] -> - case Name of - <<"list">> -> - ListName = fxml:get_attr(<<"name">>, Attrs), - process_list_get(LUser, LServer, ListName, Lang); - _ -> - Txt = <<"Unsupported tag name">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} - end; - _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Too many elements">>)} + case Lists of + [] -> + process_lists_get(LUser, LServer, Active, Lang); + [#privacy_list{name = ListName}] -> + process_list_get(LUser, LServer, ListName, Lang); + _ -> + Txt = <<"Too many elements">>, + {error, xmpp:err_bad_request(Txt, Lang)} end. +-spec process_lists_get(binary(), binary(), binary(), undefined | binary()) -> + {error, error()} | {result, privacy_query()}. process_lists_get(LUser, LServer, Active, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_lists_get(LUser, LServer) of - error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}; - {_Default, []} -> - {result, - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_PRIVACY}], children = []}]}; - {Default, LItems} -> - DItems = case Default of - none -> LItems; - _ -> - [#xmlel{name = <<"default">>, - attrs = [{<<"name">>, Default}], children = []} - | LItems] - end, - ADItems = case Active of - none -> DItems; - _ -> - [#xmlel{name = <<"active">>, - attrs = [{<<"name">>, Active}], children = []} - | DItems] - end, - {result, - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_PRIVACY}], - children = ADItems}]} + error -> + Txt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(Txt, Lang)}; + {_Default, []} -> + {result, #privacy_query{}}; + {Default, ListNames} -> + {result, + #privacy_query{active = Active, + default = Default, + lists = [#privacy_list{name = ListName} + || ListName <- ListNames]}} end. -process_list_get(LUser, LServer, {value, Name}, Lang) -> +-spec process_list_get(binary(), binary(), binary(), undefined | binary()) -> + {error, error()} | {result, privacy_query()}. +process_list_get(LUser, LServer, Name, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_list_get(LUser, LServer, Name) of - error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}; - not_found -> {error, ?ERR_ITEM_NOT_FOUND}; - Items -> - LItems = lists:map(fun item_to_xml/1, Items), - {result, - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_PRIVACY}], - children = - [#xmlel{name = <<"list">>, attrs = [{<<"name">>, Name}], - children = LItems}]}]} - end; -process_list_get(_LUser, _LServer, false, _Lang) -> - {error, ?ERR_BAD_REQUEST}. - -item_to_xml(Item) -> - Attrs1 = [{<<"action">>, - action_to_list(Item#listitem.action)}, - {<<"order">>, order_to_list(Item#listitem.order)}], - Attrs2 = case Item#listitem.type of - none -> Attrs1; - Type -> - [{<<"type">>, type_to_list(Item#listitem.type)}, - {<<"value">>, value_to_list(Type, Item#listitem.value)} - | Attrs1] - end, - SubEls = case Item#listitem.match_all of - true -> []; - false -> - SE1 = case Item#listitem.match_iq of - true -> - [#xmlel{name = <<"iq">>, attrs = [], - children = []}]; - false -> [] - end, - SE2 = case Item#listitem.match_message of - true -> - [#xmlel{name = <<"message">>, attrs = [], - children = []} - | SE1]; - false -> SE1 - end, - SE3 = case Item#listitem.match_presence_in of - true -> - [#xmlel{name = <<"presence-in">>, attrs = [], - children = []} - | SE2]; - false -> SE2 - end, - SE4 = case Item#listitem.match_presence_out of - true -> - [#xmlel{name = <<"presence-out">>, attrs = [], - children = []} - | SE3]; - false -> SE3 - end, - SE4 - end, - #xmlel{name = <<"item">>, attrs = Attrs2, - children = SubEls}. - -action_to_list(Action) -> - case Action of - allow -> <<"allow">>; - deny -> <<"deny">> + error -> + Txt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(Txt, Lang)}; + not_found -> + Txt = <<"No privacy list with this name found">>, + {error, xmpp:err_item_not_found(Txt, Lang)}; + Items -> + LItems = lists:map(fun encode_list_item/1, Items), + {result, + #privacy_query{ + lists = [#privacy_list{name = Name, items = LItems}]}} end. -order_to_list(Order) -> - iolist_to_binary(integer_to_list(Order)). - -type_to_list(Type) -> - case Type of - jid -> <<"jid">>; - group -> <<"group">>; - subscription -> <<"subscription">> +-spec item_to_xml(listitem()) -> xmlel(). +item_to_xml(ListItem) -> + xmpp:encode(encode_list_item(ListItem)). + +-spec encode_list_item(listitem()) -> privacy_item(). +encode_list_item(#listitem{action = Action, + order = Order, + type = Type, + match_all = MatchAll, + match_iq = MatchIQ, + match_message = MatchMessage, + match_presence_in = MatchPresenceIn, + match_presence_out = MatchPresenceOut, + value = Value}) -> + Item = #privacy_item{action = Action, + order = Order, + type = case Type of + none -> undefined; + Type -> Type + end, + value = encode_value(Type, Value)}, + case MatchAll of + true -> + Item; + false -> + Item#privacy_item{message = MatchMessage, + iq = MatchIQ, + presence_in = MatchPresenceIn, + presence_out = MatchPresenceOut} end. -value_to_list(Type, Val) -> +-spec encode_value(listitem_type(), listitem_value()) -> undefined | binary(). +encode_value(Type, Val) -> case Type of - jid -> jid:to_string(Val); - group -> Val; - subscription -> - case Val of - both -> <<"both">>; - to -> <<"to">>; - from -> <<"from">>; - none -> <<"none">> - end + jid -> jid:to_string(Val); + group -> Val; + subscription -> + case Val of + both -> <<"both">>; + to -> <<"to">>; + from -> <<"from">>; + none -> <<"none">> + end; + none -> undefined end. -list_to_action(S) -> - case S of - <<"allow">> -> allow; - <<"deny">> -> deny +-spec decode_value(jid | subscription | group | undefined, binary()) -> + listitem_value(). +decode_value(Type, Value) -> + case Type of + jid -> jid:from_string(Value); + subscription -> + case Value of + <<"from">> -> from; + <<"to">> -> to; + <<"both">> -> both; + <<"none">> -> none + end; + group -> Value; + undefined -> none end. -process_iq_set(_, From, _To, #iq{lang = Lang, sub_el = SubEl}) -> +-spec process_iq_set({error, error()} | + {result, privacy_query() | undefined, userlist()}, + iq()) -> {error, error()} | + {result, undefined, userlist()}. +process_iq_set(_, #iq{from = From, lang = Lang, + sub_els = [#privacy_query{default = Default, + active = Active, + lists = Lists}]}) -> #jid{luser = LUser, lserver = LServer} = From, - #xmlel{children = Els} = SubEl, - case fxml:remove_cdata(Els) of - [#xmlel{name = Name, attrs = Attrs, - children = SubEls}] -> - ListName = fxml:get_attr(<<"name">>, Attrs), - case Name of - <<"list">> -> - process_list_set(LUser, LServer, ListName, - fxml:remove_cdata(SubEls), Lang); - <<"active">> -> - process_active_set(LUser, LServer, ListName); - <<"default">> -> - process_default_set(LUser, LServer, ListName, Lang); - _ -> - Txt = <<"Unsupported tag name">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} - end; - _ -> {error, ?ERR_BAD_REQUEST} + case Lists of + [#privacy_list{items = Items, name = ListName}] + when Default == undefined, Active == undefined -> + process_lists_set(LUser, LServer, ListName, Items, Lang); + [] when Default == undefined, Active /= undefined -> + process_active_set(LUser, LServer, Active, Lang); + [] when Active == undefined, Default /= undefined -> + process_default_set(LUser, LServer, Default, Lang); + _ -> + Txt = <<"There should be exactly one element in this query: " + ", or ">>, + {error, xmpp:err_bad_request(Txt, Lang)} end. +-spec process_default_set(binary(), binary(), none | binary(), + undefined | binary()) -> {error, error()} | + {result, undefined}. process_default_set(LUser, LServer, Value, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_default_set(LUser, LServer, Value) of - {atomic, error} -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}; - {atomic, not_found} -> {error, ?ERR_ITEM_NOT_FOUND}; - {atomic, ok} -> {result, []}; - _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} + {atomic, error} -> + Txt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(Txt, Lang)}; + {atomic, not_found} -> + Txt = <<"No privacy list with this name found">>, + {error, xmpp:err_item_not_found(Txt, Lang)}; + {atomic, ok} -> + {result, undefined}; + Err -> + ?ERROR_MSG("failed to set default list '~s' for user ~s@~s: ~p", + [Value, LUser, LServer, Err]), + {error, xmpp:err_internal_server_error()} end. -process_active_set(LUser, LServer, {value, Name}) -> +-spec process_active_set(binary(), binary(), none | binary(), + undefined | binary()) -> + {error, error()} | + {result, undefined, userlist()}. +process_active_set(_LUser, _LServer, none, _Lang) -> + {result, undefined, #userlist{}}; +process_active_set(LUser, LServer, Name, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_active_set(LUser, LServer, Name) of - error -> {error, ?ERR_ITEM_NOT_FOUND}; - Items -> - NeedDb = is_list_needdb(Items), - {result, [], - #userlist{name = Name, list = Items, needdb = NeedDb}} - end; -process_active_set(_LUser, _LServer, false) -> - {result, [], #userlist{}}. + error -> + Txt = <<"No privacy list with this name found">>, + {error, xmpp:err_item_not_found(Txt, Lang)}; + Items -> + NeedDb = is_list_needdb(Items), + {result, undefined, + #userlist{name = Name, list = Items, needdb = NeedDb}} + end. +-spec set_privacy_list(privacy()) -> any(). set_privacy_list(#privacy{us = {_, LServer}} = Privacy) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:set_privacy_list(Privacy). -process_list_set(LUser, LServer, {value, Name}, Els, Lang) -> - case parse_items(Els) of - false -> {error, ?ERR_BAD_REQUEST}; - remove -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - case Mod:remove_privacy_list(LUser, LServer, Name) of - {atomic, conflict} -> - Txt = <<"Cannot remove default list">>, - {error, ?ERRT_CONFLICT(Lang, Txt)}; - {atomic, ok} -> - ejabberd_sm:route(jid:make(LUser, LServer, - <<"">>), - jid:make(LUser, LServer, <<"">>), - {broadcast, {privacy_list, - #userlist{name = Name, - list = []}, - Name}}), - {result, []}; - _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)} - end; - List -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - case Mod:set_privacy_list(LUser, LServer, Name, List) of - {atomic, ok} -> - NeedDb = is_list_needdb(List), - ejabberd_sm:route(jid:make(LUser, LServer, - <<"">>), - jid:make(LUser, LServer, <<"">>), - {broadcast, {privacy_list, - #userlist{name = Name, - list = List, - needdb = NeedDb}, - Name}}), - {result, []}; - _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)} - end +-spec process_lists_set(binary(), binary(), binary(), [privacy_item()], + undefined | binary()) -> {error, error()} | + {result, undefined}. +process_lists_set(LUser, LServer, Name, [], Lang) -> + Mod = gen_mod:db_mod(LServer, ?MODULE), + case Mod:remove_privacy_list(LUser, LServer, Name) of + {atomic, conflict} -> + Txt = <<"Cannot remove default list">>, + {error, xmpp:err_conflict(Txt, Lang)}; + {atomic, ok} -> + ejabberd_sm:route(jid:make(LUser, LServer, + <<"">>), + jid:make(LUser, LServer, <<"">>), + {broadcast, {privacy_list, + #userlist{name = Name, + list = []}, + Name}}), + {result, undefined}; + Err -> + ?ERROR_MSG("failed to remove privacy list '~s' for user ~s@~s: ~p", + [Name, LUser, LServer, Err]), + Txt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(Txt, Lang)} end; -process_list_set(_LUser, _LServer, false, _Els, _Lang) -> - {error, ?ERR_BAD_REQUEST}. - -parse_items([]) -> remove; -parse_items(Els) -> parse_items(Els, []). - -parse_items([], Res) -> - lists:keysort(#listitem.order, Res); -parse_items([#xmlel{name = <<"item">>, attrs = Attrs, - children = SubEls} - | Els], - Res) -> - Type = fxml:get_attr(<<"type">>, Attrs), - Value = fxml:get_attr(<<"value">>, Attrs), - SAction = fxml:get_attr(<<"action">>, Attrs), - SOrder = fxml:get_attr(<<"order">>, Attrs), - Action = case catch list_to_action(element(2, SAction)) - of - {'EXIT', _} -> false; - Val -> Val - end, - Order = case catch jlib:binary_to_integer(element(2, - SOrder)) - of - {'EXIT', _} -> false; - IntVal -> - if IntVal >= 0 -> IntVal; - true -> false - end +process_lists_set(LUser, LServer, Name, Items, Lang) -> + case catch lists:map(fun decode_item/1, Items) of + {error, Why} -> + Txt = xmpp:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)}; + List -> + Mod = gen_mod:db_mod(LServer, ?MODULE), + case Mod:set_privacy_list(LUser, LServer, Name, List) of + {atomic, ok} -> + NeedDb = is_list_needdb(List), + ejabberd_sm:route(jid:make(LUser, LServer, + <<"">>), + jid:make(LUser, LServer, <<"">>), + {broadcast, {privacy_list, + #userlist{name = Name, + list = List, + needdb = NeedDb}, + Name}}), + {result, undefined}; + Err -> + ?ERROR_MSG("failed to set privacy list '~s' " + "for user ~s@~s: ~p", + [Name, LUser, LServer, Err]), + Txt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(Txt, Lang)} + end + end. + +-spec decode_item(privacy_item()) -> listitem(). +decode_item(#privacy_item{order = Order, + action = Action, + type = T, + value = V, + message = MatchMessage, + iq = MatchIQ, + presence_in = MatchPresenceIn, + presence_out = MatchPresenceOut}) -> + Value = try decode_value(T, V) + catch _:_ -> + throw({error, {bad_attr_value, <<"value">>, + <<"item">>, ?NS_PRIVACY}}) end, - if (Action /= false) and (Order /= false) -> - I1 = #listitem{action = Action, order = Order}, - I2 = case {Type, Value} of - {{value, T}, {value, V}} -> - case T of - <<"jid">> -> - case jid:from_string(V) of - error -> false; - JID -> - I1#listitem{type = jid, - value = jid:tolower(JID)} - end; - <<"group">> -> I1#listitem{type = group, value = V}; - <<"subscription">> -> - case V of - <<"none">> -> - I1#listitem{type = subscription, - value = none}; - <<"both">> -> - I1#listitem{type = subscription, - value = both}; - <<"from">> -> - I1#listitem{type = subscription, - value = from}; - <<"to">> -> - I1#listitem{type = subscription, value = to}; - _ -> false - end - end; - {{value, _}, false} -> false; - _ -> I1 - end, - case I2 of - false -> false; - _ -> - case parse_matches(I2, fxml:remove_cdata(SubEls)) of - false -> false; - I3 -> parse_items(Els, [I3 | Res]) - end - end; - true -> false - end; -parse_items(_, _Res) -> false. - -parse_matches(Item, []) -> - Item#listitem{match_all = true}; -parse_matches(Item, Els) -> parse_matches1(Item, Els). - -parse_matches1(Item, []) -> Item; -parse_matches1(Item, - [#xmlel{name = <<"message">>} | Els]) -> - parse_matches1(Item#listitem{match_message = true}, - Els); -parse_matches1(Item, [#xmlel{name = <<"iq">>} | Els]) -> - parse_matches1(Item#listitem{match_iq = true}, Els); -parse_matches1(Item, - [#xmlel{name = <<"presence-in">>} | Els]) -> - parse_matches1(Item#listitem{match_presence_in = true}, - Els); -parse_matches1(Item, - [#xmlel{name = <<"presence-out">>} | Els]) -> - parse_matches1(Item#listitem{match_presence_out = true}, - Els); -parse_matches1(_Item, [#xmlel{} | _Els]) -> false. + Type = case T of + undefined -> none; + _ -> T + end, + ListItem = #listitem{order = Order, + action = Action, + type = Type, + value = Value}, + if MatchMessage and MatchIQ and MatchPresenceIn and MatchPresenceOut -> + ListItem#listitem{match_all = true}; + not (MatchMessage or MatchIQ or MatchPresenceIn or MatchPresenceOut) -> + ListItem#listitem{match_all = true}; + true -> + ListItem#listitem{match_iq = MatchIQ, + match_message = MatchMessage, + match_presence_in = MatchPresenceIn, + match_presence_out = MatchPresenceOut} + end. +-spec is_list_needdb([listitem()]) -> boolean(). is_list_needdb(Items) -> lists:any(fun (X) -> case X#listitem.type of @@ -435,6 +376,7 @@ is_list_needdb(Items) -> end, Items). +-spec get_user_list(userlist(), binary(), binary()) -> userlist(). get_user_list(_Acc, User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -444,6 +386,7 @@ get_user_list(_Acc, User, Server) -> #userlist{name = Default, list = Items, needdb = NeedDb}. +-spec get_user_lists(binary(), binary()) -> {ok, privacy()} | error. get_user_lists(User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -453,6 +396,8 @@ get_user_lists(User, Server) -> %% From is the sender, To is the destination. %% If Dir = out, User@Server is the sender account (From). %% If Dir = in, User@Server is the destination account (To). +-spec check_packet(allow | deny, binary(), binary(), userlist(), + {jid(), jid(), stanza()}, in | out) -> allow | deny. check_packet(_, _User, _Server, _UserList, {#jid{luser = <<"">>, lserver = Server} = _From, #jid{lserver = Server} = _To, _}, @@ -470,22 +415,16 @@ check_packet(_, _User, _Server, _UserList, allow; check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, - {From, To, #xmlel{name = PName, attrs = Attrs}}, Dir) -> + {From, To, Packet}, Dir) -> case List of [] -> allow; _ -> - PType = case PName of - <<"message">> -> message; - <<"iq">> -> iq; - <<"presence">> -> - case fxml:get_attr_s(<<"type">>, Attrs) of - %% notification - <<"">> -> presence; - <<"unavailable">> -> presence; - %% subscribe, subscribed, unsubscribe, - %% unsubscribed, error, probe, or other - _ -> other - end + PType = case Packet of + #message{} -> message; + #iq{} -> iq; + #presence{type = available} -> presence; + #presence{type = unavailable} -> presence; + _ -> other end, PType2 = case {PType, Dir} of {message, in} -> message; @@ -511,6 +450,10 @@ check_packet(_, User, Server, Groups) end. +-spec check_packet_aux([listitem()], + message | iq | presence_in | presence_out | other, + ljid(), none | both | from | to, [binary()]) -> + allow | deny. %% Ptype = mesage | iq | presence_in | presence_out | other check_packet_aux([], _PType, _JID, _Subscription, _Groups) -> @@ -536,6 +479,9 @@ check_packet_aux([Item | List], PType, JID, check_packet_aux(List, PType, JID, Subscription, Groups) end. +-spec is_ptype_match(listitem(), + message | iq | presence_in | presence_out | other) -> + boolean(). is_ptype_match(Item, PType) -> case Item#listitem.match_all of true -> true; @@ -549,6 +495,8 @@ is_ptype_match(Item, PType) -> end end. +-spec is_type_match(jid | subscription | group, listitem_value(), + ljid(), none | both | from | to, [binary()]) -> boolean(). is_type_match(Type, Value, JID, Subscription, Groups) -> case Type of jid -> @@ -575,6 +523,7 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:remove_user(LUser, LServer). +-spec updated_list(userlist(), userlist(), userlist()) -> userlist(). updated_list(_, #userlist{name = OldName} = Old, #userlist{name = NewName} = New) -> if OldName == NewName -> New; diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl index 4026b7f64..1a9172b5a 100644 --- a/src/mod_privacy_mnesia.erl +++ b/src/mod_privacy_mnesia.erl @@ -35,11 +35,7 @@ process_lists_get(LUser, LServer) -> {'EXIT', _Reason} -> error; [] -> {none, []}; [#privacy{default = Default, lists = Lists}] -> - LItems = lists:map(fun ({N, _}) -> - #xmlel{name = <<"list">>, - attrs = [{<<"name">>, N}], - children = []} - end, Lists), + LItems = lists:map(fun ({N, _}) -> N end, Lists), {Default, LItems} end. @@ -54,7 +50,15 @@ process_list_get(LUser, LServer, Name) -> end end. -process_default_set(LUser, LServer, {value, Name}) -> +process_default_set(LUser, LServer, none) -> + F = fun () -> + case mnesia:read({privacy, {LUser, LServer}}) of + [] -> ok; + [R] -> mnesia:write(R#privacy{default = none}) + end + end, + mnesia:transaction(F); +process_default_set(LUser, LServer, Name) -> F = fun () -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> not_found; @@ -68,14 +72,6 @@ process_default_set(LUser, LServer, {value, Name}) -> end end end, - mnesia:transaction(F); -process_default_set(LUser, LServer, false) -> - F = fun () -> - case mnesia:read({privacy, {LUser, LServer}}) of - [] -> ok; - [R] -> mnesia:write(R#privacy{default = none}) - end - end, mnesia:transaction(F). process_active_set(LUser, LServer, Name) -> diff --git a/src/mod_privacy_riak.erl b/src/mod_privacy_riak.erl index 0c43e74f9..40e92005c 100644 --- a/src/mod_privacy_riak.erl +++ b/src/mod_privacy_riak.erl @@ -31,12 +31,7 @@ init(_Host, _Opts) -> process_lists_get(LUser, LServer) -> case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of {ok, #privacy{default = Default, lists = Lists}} -> - LItems = lists:map(fun ({N, _}) -> - #xmlel{name = <<"list">>, - attrs = [{<<"name">>, N}], - children = []} - end, - Lists), + LItems = lists:map(fun ({N, _}) -> N end, Lists), {Default, LItems}; {error, notfound} -> {none, []}; @@ -57,7 +52,15 @@ process_list_get(LUser, LServer, Name) -> error end. -process_default_set(LUser, LServer, {value, Name}) -> +process_default_set(LUser, LServer, none) -> + {atomic, + case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of + {ok, R} -> + ejabberd_riak:put(R#privacy{default = none}, privacy_schema()); + {error, _} -> + ok + end}; +process_default_set(LUser, LServer, Name) -> {atomic, case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of {ok, #privacy{lists = Lists} = P} -> @@ -71,14 +74,6 @@ process_default_set(LUser, LServer, {value, Name}) -> end; {error, _} -> not_found - end}; -process_default_set(LUser, LServer, false) -> - {atomic, - case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of - {ok, R} -> - ejabberd_riak:put(R#privacy{default = none}, privacy_schema()); - {error, _} -> - ok end}. process_active_set(LUser, LServer, Name) -> diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index 6da917e9d..66926f236 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -47,12 +47,7 @@ process_lists_get(LUser, LServer) -> end, case catch sql_get_privacy_list_names(LUser, LServer) of {selected, Names} -> - LItems = lists:map(fun ({N}) -> - #xmlel{name = <<"list">>, - attrs = [{<<"name">>, N}], - children = []} - end, - Names), + LItems = lists:map(fun ({N}) -> N end, Names), {Default, LItems}; _ -> error end. @@ -69,7 +64,15 @@ process_list_get(LUser, LServer, Name) -> _ -> error end. -process_default_set(LUser, LServer, {value, Name}) -> +process_default_set(LUser, LServer, none) -> + case catch sql_unset_default_privacy_list(LUser, + LServer) + of + {'EXIT', _Reason} -> {atomic, error}; + {error, _Reason} -> {atomic, error}; + _ -> {atomic, ok} + end; +process_default_set(LUser, LServer, Name) -> F = fun () -> case sql_get_privacy_list_names_t(LUser) of {selected, []} -> not_found; @@ -80,15 +83,7 @@ process_default_set(LUser, LServer, {value, Name}) -> end end end, - sql_queries:sql_transaction(LServer, F); -process_default_set(LUser, LServer, false) -> - case catch sql_unset_default_privacy_list(LUser, - LServer) - of - {'EXIT', _Reason} -> {atomic, error}; - {error, _Reason} -> {atomic, error}; - _ -> {atomic, ok} - end. + sql_queries:sql_transaction(LServer, F). process_active_set(LUser, LServer, Name) -> case catch sql_get_privacy_list_id(LUser, LServer, Name) of diff --git a/src/mod_private.erl b/src/mod_private.erl index f0e4632f6..28d49bb3f 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -31,14 +31,14 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_sm_iq/3, import/3, +-export([start/2, stop/1, process_sm_iq/1, import/3, remove_user/2, get_data/2, export/1, import/1, mod_opt_type/1, set_data/3, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_private.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). @@ -46,10 +46,7 @@ -callback set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}. -callback get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error. -callback get_all_data(binary(), binary()) -> [xmlel()]. - --define(Xmlel_Query(Attrs, Children), - #xmlel{name = <<"query">>, attrs = Attrs, - children = Children}). +-callback remove_user(binary(), binary()) -> {atomic, any()}. start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, @@ -67,90 +64,55 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE). -process_sm_iq(#jid{luser = LUser, lserver = LServer}, - #jid{luser = LUser, lserver = LServer}, #iq{lang = Lang} = IQ) - when IQ#iq.type == set -> - case IQ#iq.sub_el of - #xmlel{name = <<"query">>, children = Xmlels} -> - case filter_xmlels(Xmlels) of - [] -> - Txt = <<"No private data found in this query">>, - IQ#iq{type = error, - sub_el = [IQ#iq.sub_el, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)]}; - Data -> - set_data(LUser, LServer, Data), - IQ#iq{type = result, sub_el = []} - end; - _ -> - Txt = <<"No query found">>, - IQ#iq{type = error, - sub_el = [IQ#iq.sub_el, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)]} +-spec process_sm_iq(iq()) -> iq(). +process_sm_iq(#iq{type = Type, lang = Lang, + from = #jid{luser = LUser, lserver = LServer}, + to = #jid{luser = LUser, lserver = LServer}, + sub_els = [#private{xml_els = Els0}]} = IQ) -> + case filter_xmlels(Els0) of + [] -> + Txt = <<"No private data found in this query">>, + xmpp:make_error(IQ, xmpp:err_bad_format(Txt, Lang)); + Data when Type == set -> + set_data(LUser, LServer, Data), + xmpp:make_iq_result(IQ); + Data when Type == get -> + StorageEls = get_data(LUser, LServer, Data), + xmpp:make_iq_result(IQ, #private{xml_els = StorageEls}) end; -%% -process_sm_iq(#jid{luser = LUser, lserver = LServer}, - #jid{luser = LUser, lserver = LServer}, #iq{lang = Lang} = IQ) - when IQ#iq.type == get -> - case IQ#iq.sub_el of - #xmlel{name = <<"query">>, attrs = Attrs, - children = Xmlels} -> - case filter_xmlels(Xmlels) of - [] -> - Txt = <<"No private data found in this query">>, - IQ#iq{type = error, - sub_el = [IQ#iq.sub_el, ?ERRT_BAD_FORMAT(Lang, Txt)]}; - Data -> - case catch get_data(LUser, LServer, Data) of - {'EXIT', _Reason} -> - Txt = <<"Database failure">>, - IQ#iq{type = error, - sub_el = - [IQ#iq.sub_el, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}; - Storage_Xmlels -> - IQ#iq{type = result, - sub_el = [?Xmlel_Query(Attrs, Storage_Xmlels)]} - end - end; - _ -> - Txt = <<"No query found">>, - IQ#iq{type = error, - sub_el = [IQ#iq.sub_el, ?ERRT_BAD_FORMAT(Lang, Txt)]} - end; -%% -process_sm_iq(_From, _To, #iq{lang = Lang} = IQ) -> +process_sm_iq(#iq{lang = Lang} = IQ) -> Txt = <<"Query to another users is forbidden">>, - IQ#iq{type = error, - sub_el = [IQ#iq.sub_el, ?ERRT_FORBIDDEN(Lang, Txt)]}. - -filter_xmlels(Xmlels) -> filter_xmlels(Xmlels, []). - -filter_xmlels([], Data) -> lists:reverse(Data); -filter_xmlels([#xmlel{attrs = Attrs} = Xmlel | Xmlels], - Data) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - <<"">> -> []; - XmlNS -> filter_xmlels(Xmlels, [{XmlNS, Xmlel} | Data]) - end; -filter_xmlels([_ | Xmlels], Data) -> - filter_xmlels(Xmlels, Data). - + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)). + +-spec filter_xmlels([xmlel()]) -> [{binary(), xmlel()}]. +filter_xmlels(Els) -> + lists:flatmap( + fun(#xmlel{} = El) -> + case fxml:get_tag_attr_s(<<"xmlns">>, El) of + <<"">> -> []; + NS -> [{NS, El}] + end + end, Els). + +-spec set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}. set_data(LUser, LServer, Data) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:set_data(LUser, LServer, Data). +-spec get_data(binary(), binary(), [{binary(), xmlel()}]) -> [xmlel()]. get_data(LUser, LServer, Data) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - get_data(LUser, LServer, Data, Mod, []). - -get_data(_LUser, _LServer, [], _Mod, Storage_Xmlels) -> - lists:reverse(Storage_Xmlels); -get_data(LUser, LServer, [{XmlNS, Xmlel} | Data], Mod, Storage_Xmlels) -> - case Mod:get_data(LUser, LServer, XmlNS) of - {ok, Storage_Xmlel} -> - get_data(LUser, LServer, Data, Mod, [Storage_Xmlel | Storage_Xmlels]); - error -> - get_data(LUser, LServer, Data, Mod, [Xmlel | Storage_Xmlels]) - end. - + lists:map( + fun({NS, El}) -> + case Mod:get_data(LUser, LServer, NS) of + {ok, StorageEl} -> + StorageEl; + error -> + El + end + end, Data). + +-spec get_data(binary(), binary()) -> [xmlel()]. get_data(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_all_data(LUser, LServer). diff --git a/src/mod_roster.erl b/src/mod_roster.erl index a75041bc7..58dc51983 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -41,12 +41,12 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_iq/3, export/1, - import/1, process_local_iq/3, get_user_roster/2, +-export([start/2, stop/1, process_iq/1, export/1, + import/1, process_local_iq/1, get_user_roster/2, import/3, get_subscription_lists/3, get_roster/2, get_in_pending_subscriptions/3, in_subscription/6, out_subscription/4, set_items/3, remove_user/2, - get_jid_info/4, item_to_xml/1, webadmin_page/3, + get_jid_info/4, encode_item/1, webadmin_page/3, webadmin_user/4, get_versioning_feature/2, roster_versioning_enabled/1, roster_version/2, mod_opt_type/1, set_roster/1, depends/2]). @@ -54,7 +54,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_roster.hrl"). @@ -139,24 +139,23 @@ stop(Host) -> depends(_Host, _Opts) -> []. -process_iq(From, To, IQ) when ((From#jid.luser == <<"">>) andalso (From#jid.resource == <<"">>)) -> - process_iq_manager(From, To, IQ); +process_iq(#iq{from = #jid{luser = <<"">>}, + to = #jid{resource = <<"">>}} = IQ) -> + process_iq_manager(IQ); -process_iq(From, To, IQ) -> - #iq{sub_el = SubEl, lang = Lang} = IQ, +process_iq(#iq{from = From, lang = Lang} = IQ) -> #jid{lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of - true -> process_local_iq(From, To, IQ); + true -> process_local_iq(IQ); _ -> Txt = <<"The query is only allowed from local users">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]} + xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)) end. -process_local_iq(From, To, #iq{type = Type} = IQ) -> +process_local_iq(#iq{type = Type} = IQ) -> case Type of - set -> try_process_iq_set(From, To, IQ); - get -> process_iq_get(From, To, IQ) + set -> try_process_iq_set(IQ); + get -> process_iq_get(IQ) end. roster_hash(Items) -> @@ -179,10 +178,7 @@ roster_version_on_db(Host) -> get_versioning_feature(Acc, Host) -> case roster_versioning_enabled(Host) of true -> - Feature = #xmlel{name = <<"ver">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER_VER}], - children = []}, - [Feature | Acc]; + [#rosterver_feature{}|Acc]; false -> [] end. @@ -221,82 +217,61 @@ write_roster_version(LUser, LServer, InTransaction) -> %% - roster versioning is not used by the client OR %% - roster versioning is used by server and client, BUT the server isn't storing versions on db OR %% - the roster version from client don't match current version. -process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) -> +process_iq_get(#iq{from = From, to = To, lang = Lang, + sub_els = [#roster_query{ver = RequestedVersion}]} = IQ) -> LUser = From#jid.luser, LServer = From#jid.lserver, US = {LUser, LServer}, - try {ItemsToSend, VersionToSend} = case - {fxml:get_tag_attr(<<"ver">>, SubEl), - roster_versioning_enabled(LServer), - roster_version_on_db(LServer)} - of - {{value, RequestedVersion}, true, - true} -> - case read_roster_version(LUser, - LServer) - of - error -> - RosterVersion = - write_roster_version(LUser, - LServer), - {lists:map(fun item_to_xml/1, - ejabberd_hooks:run_fold(roster_get, - To#jid.lserver, - [], - [US])), - RosterVersion}; - RequestedVersion -> - {false, false}; - NewVersion -> - {lists:map(fun item_to_xml/1, - ejabberd_hooks:run_fold(roster_get, - To#jid.lserver, - [], - [US])), - NewVersion} - end; - {{value, RequestedVersion}, true, - false} -> - RosterItems = - ejabberd_hooks:run_fold(roster_get, - To#jid.lserver, - [], - [US]), - case roster_hash(RosterItems) of - RequestedVersion -> - {false, false}; - New -> - {lists:map(fun item_to_xml/1, - RosterItems), - New} - end; - _ -> - {lists:map(fun item_to_xml/1, - ejabberd_hooks:run_fold(roster_get, - To#jid.lserver, - [], - [US])), - false} - end, - IQ#iq{type = result, - sub_el = - case {ItemsToSend, VersionToSend} of - {false, false} -> []; - {Items, false} -> - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER}], - children = Items}]; - {Items, Version} -> - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, ?NS_ROSTER}, - {<<"ver">>, Version}], - children = Items}] - end} - catch - _:_ -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} + try {ItemsToSend, VersionToSend} = + case {roster_versioning_enabled(LServer), + roster_version_on_db(LServer)} of + {true, true} when RequestedVersion /= undefined -> + case read_roster_version(LUser, LServer) of + error -> + RosterVersion = write_roster_version(LUser, LServer), + {lists:map(fun encode_item/1, + ejabberd_hooks:run_fold( + roster_get, To#jid.lserver, [], [US])), + RosterVersion}; + RequestedVersion -> + {false, false}; + NewVersion -> + {lists:map(fun encode_item/1, + ejabberd_hooks:run_fold( + roster_get, To#jid.lserver, [], [US])), + NewVersion} + end; + {true, false} when RequestedVersion /= undefined -> + RosterItems = ejabberd_hooks:run_fold( + roster_get, To#jid.lserver, [], [US]), + case roster_hash(RosterItems) of + RequestedVersion -> + {false, false}; + New -> + {lists:map(fun encode_item/1, RosterItems), New} + end; + _ -> + {lists:map(fun encode_item/1, + ejabberd_hooks:run_fold( + roster_get, To#jid.lserver, [], [US])), + false} + end, + xmpp:make_iq_result( + IQ, + case {ItemsToSend, VersionToSend} of + {false, false} -> + undefined; + {Items, false} -> + #roster_query{items = Items}; + {Items, Version} -> + #roster_query{items = Items, + ver = Version} + end) + catch E:R -> + ?ERROR_MSG("failed to process roster get for ~s: ~p", + [jid:to_string(From), {E, {R, erlang:get_stacktrace()}}]), + Txt = <<"Roster module has failed">>, + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)) end. get_user_roster(Acc, {LUser, LServer}) -> @@ -320,143 +295,82 @@ set_roster(#roster{us = {LUser, LServer}, jid = LJID} = Item) -> roster_subscribe_t(LUser, LServer, LJID, Item) end). -item_to_xml(Item) -> - Attrs1 = [{<<"jid">>, - jid:to_string(Item#roster.jid)}], - Attrs2 = case Item#roster.name of - <<"">> -> Attrs1; - Name -> [{<<"name">>, Name} | Attrs1] - end, - Attrs3 = case Item#roster.subscription of - none -> [{<<"subscription">>, <<"none">>} | Attrs2]; - from -> [{<<"subscription">>, <<"from">>} | Attrs2]; - to -> [{<<"subscription">>, <<"to">>} | Attrs2]; - both -> [{<<"subscription">>, <<"both">>} | Attrs2]; - remove -> [{<<"subscription">>, <<"remove">>} | Attrs2] - end, - Attrs4 = case ask_to_pending(Item#roster.ask) of - out -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - both -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - _ -> Attrs3 - end, - SubEls1 = lists:map(fun (G) -> - #xmlel{name = <<"group">>, attrs = [], - children = [{xmlcdata, G}]} - end, - Item#roster.groups), - SubEls = SubEls1 ++ Item#roster.xs, - #xmlel{name = <<"item">>, attrs = Attrs4, - children = SubEls}. +encode_item(Item) -> + #roster_item{jid = jid:make(Item#roster.jid), + name = Item#roster.name, + subscription = Item#roster.subscription, + ask = case ask_to_pending(Item#roster.ask) of + out -> subscribe; + both -> subscribe; + _ -> undefined + end, + groups = Item#roster.groups}. + +decode_item(#roster_item{} = Item, R, Managed) -> + R#roster{jid = jid:tolower(Item#roster_item.jid), + name = Item#roster_item.name, + subscription = case Item#roster_item.subscription of + remove -> remove; + Sub when Managed -> Sub; + _ -> undefined + end, + groups = Item#roster_item.groups}. get_roster_by_jid_t(LUser, LServer, LJID) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_roster_by_jid(LUser, LServer, LJID). -try_process_iq_set(From, To, #iq{sub_el = SubEl, lang = Lang} = IQ) -> +try_process_iq_set(#iq{from = From, lang = Lang} = IQ) -> #jid{server = Server} = From, Access = gen_mod:get_module_opt(Server, ?MODULE, access, fun(A) -> A end, all), case acl:match_rule(Server, Access, From) of deny -> Txt = <<"Denied by ACL">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); allow -> - process_iq_set(From, To, IQ) + process_iq_set(IQ) end. -process_iq_set(From, To, #iq{sub_el = SubEl, id = Id} = IQ) -> - #xmlel{children = Els} = SubEl, +process_iq_set(#iq{from = From, to = To, id = Id, + sub_els = [#roster_query{items = Items}]} = IQ) -> Managed = is_managed_from_id(Id), - lists:foreach(fun (El) -> process_item_set(From, To, El, Managed) + lists:foreach(fun (Item) -> process_item_set(From, To, Item, Managed) end, - Els), - IQ#iq{type = result, sub_el = []}. - -process_item_set(From, To, - #xmlel{attrs = Attrs, children = Els}, Managed) -> - JID1 = jid:from_string(fxml:get_attr_s(<<"jid">>, - Attrs)), - #jid{user = User, luser = LUser, lserver = LServer} = - From, - case JID1 of - error -> ok; - _ -> - LJID = jid:tolower(JID1), - F = fun () -> - Item = get_roster_by_jid_t(LUser, LServer, LJID), - Item1 = process_item_attrs_managed(Item, Attrs, Managed), - Item2 = process_item_els(Item1, Els), - Item3 = ejabberd_hooks:run_fold(roster_process_item, - LServer, Item2, - [LServer]), - case Item3#roster.subscription of - remove -> del_roster_t(LUser, LServer, LJID); - _ -> update_roster_t(LUser, LServer, LJID, Item3) - end, - send_itemset_to_managers(From, Item3, Managed), - case roster_version_on_db(LServer) of - true -> write_roster_version_t(LUser, LServer); - false -> ok - end, - {Item, Item3} - end, - case transaction(LServer, F) of - {atomic, {OldItem, Item}} -> - push_item(User, LServer, To, Item), - case Item#roster.subscription of - remove -> - send_unsubscribing_presence(From, OldItem), ok; - _ -> ok - end; - E -> - ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok - end - end; -process_item_set(_From, _To, _, _Managed) -> ok. + Items), + xmpp:make_iq_result(IQ). -process_item_attrs(Item, [{Attr, Val} | Attrs]) -> - case Attr of - <<"jid">> -> - case jid:from_string(Val) of - error -> process_item_attrs(Item, Attrs); - JID1 -> - JID = {JID1#jid.luser, JID1#jid.lserver, - JID1#jid.lresource}, - process_item_attrs(Item#roster{jid = JID}, Attrs) - end; - <<"name">> -> - process_item_attrs(Item#roster{name = Val}, Attrs); - <<"subscription">> -> - case Val of - <<"remove">> -> - process_item_attrs(Item#roster{subscription = remove}, - Attrs); - _ -> process_item_attrs(Item, Attrs) - end; - <<"ask">> -> process_item_attrs(Item, Attrs); - _ -> process_item_attrs(Item, Attrs) - end; -process_item_attrs(Item, []) -> Item. - -process_item_els(Item, - [#xmlel{name = Name, attrs = Attrs, children = SEls} - | Els]) -> - case Name of - <<"group">> -> - Groups = [fxml:get_cdata(SEls) | Item#roster.groups], - process_item_els(Item#roster{groups = Groups}, Els); - _ -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - <<"">> -> process_item_els(Item, Els); - _ -> - XEls = [#xmlel{name = Name, attrs = Attrs, - children = SEls} - | Item#roster.xs], - process_item_els(Item#roster{xs = XEls}, Els) - end +process_item_set(From, To, #roster_item{jid = JID1} = QueryItem, Managed) -> + #jid{user = User, luser = LUser, lserver = LServer} = From, + LJID = jid:tolower(JID1), + F = fun () -> + Item = get_roster_by_jid_t(LUser, LServer, LJID), + Item2 = decode_item(QueryItem, Item, Managed), + Item3 = ejabberd_hooks:run_fold(roster_process_item, + LServer, Item2, + [LServer]), + case Item3#roster.subscription of + remove -> del_roster_t(LUser, LServer, LJID); + _ -> update_roster_t(LUser, LServer, LJID, Item3) + end, + send_itemset_to_managers(From, Item3, Managed), + case roster_version_on_db(LServer) of + true -> write_roster_version_t(LUser, LServer); + false -> ok + end, + {Item, Item3} + end, + case transaction(LServer, F) of + {atomic, {OldItem, Item}} -> + push_item(User, LServer, To, Item), + case Item#roster.subscription of + remove -> + send_unsubscribing_presence(From, OldItem), ok; + _ -> ok + end; + E -> + ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok end; -process_item_els(Item, [{xmlcdata, _} | Els]) -> - process_item_els(Item, Els); -process_item_els(Item, []) -> Item. +process_item_set(_From, _To, _, _Managed) -> ok. push_item(User, Server, From, Item) -> ejabberd_sm:route(jid:make(<<"">>, <<"">>, <<"">>), @@ -480,21 +394,19 @@ push_item(User, Server, Resource, From, Item) -> push_item(User, Server, Resource, From, Item, RosterVersion) -> - ExtraAttrs = case RosterVersion of - not_found -> []; - _ -> [{<<"ver">>, RosterVersion}] - end, - ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, + Ver = case RosterVersion of + not_found -> undefined; + _ -> RosterVersion + end, + ResIQ = #iq{type = set, %% @doc Roster push, calculate and include the version attribute. %% TODO: don't push to those who didn't load roster id = <<"push", (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER} | ExtraAttrs], - children = [item_to_xml(Item)]}]}, + sub_els = [#roster_query{ver = Ver, + items = [encode_item(Item)]}]}, ejabberd_router:route(From, jid:make(User, Server, Resource), - jlib:iq_to_xml(ResIQ)). + ResIQ). push_item_version(Server, User, From, Item, RosterVersion) -> @@ -598,16 +510,8 @@ process_subscription(Direction, User, Server, JID1, case AutoReply of none -> ok; _ -> - T = case AutoReply of - subscribed -> <<"subscribed">>; - unsubscribed -> <<"unsubscribed">> - end, - ejabberd_router:route(jid:make(User, Server, - <<"">>), - JID1, - #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, T}], - children = []}) + ejabberd_router:route(jid:make(User, Server, <<"">>), + JID1, #presence{type = AutoReply}) end, case Push of {push, Item} -> @@ -769,24 +673,19 @@ send_unsubscribing_presence(From, Item) -> _ -> false end, if IsTo -> - send_presence_type(jid:remove_resource(From), - jid:make(Item#roster.jid), - <<"unsubscribe">>); + ejabberd_router:route(jid:remove_resource(From), + jid:make(Item#roster.jid), + #presence{type = unsubscribe}); true -> ok end, if IsFrom -> - send_presence_type(jid:remove_resource(From), - jid:make(Item#roster.jid), - <<"unsubscribed">>); + ejabberd_router:route(jid:remove_resource(From), + jid:make(Item#roster.jid), + #presence{type = unsubscribed}); true -> ok end, ok. -send_presence_type(From, To, Type) -> - ejabberd_router:route(From, To, - #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, Type}], children = []}). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_items(User, Server, SubEl) -> @@ -809,65 +708,20 @@ del_roster_t(LUser, LServer, LJID) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:del_roster(LUser, LServer, LJID). -process_item_set_t(LUser, LServer, - #xmlel{attrs = Attrs, children = Els}) -> - JID1 = jid:from_string(fxml:get_attr_s(<<"jid">>, - Attrs)), - case JID1 of - error -> ok; - _ -> - JID = {JID1#jid.user, JID1#jid.server, - JID1#jid.resource}, - LJID = {JID1#jid.luser, JID1#jid.lserver, - JID1#jid.lresource}, - Item = #roster{usj = {LUser, LServer, LJID}, - us = {LUser, LServer}, jid = JID}, - Item1 = process_item_attrs_ws(Item, Attrs), - Item2 = process_item_els(Item1, Els), - case Item2#roster.subscription of - remove -> del_roster_t(LUser, LServer, LJID); - _ -> update_roster_t(LUser, LServer, LJID, Item2) - end +process_item_set_t(LUser, LServer, #roster_item{jid = JID1} = QueryItem) -> + JID = {JID1#jid.user, JID1#jid.server, + JID1#jid.resource}, + LJID = {JID1#jid.luser, JID1#jid.lserver, + JID1#jid.lresource}, + Item = #roster{usj = {LUser, LServer, LJID}, + us = {LUser, LServer}, jid = JID}, + Item2 = decode_item(QueryItem, Item, _Managed = true), + case Item2#roster.subscription of + remove -> del_roster_t(LUser, LServer, LJID); + _ -> update_roster_t(LUser, LServer, LJID, Item2) end; process_item_set_t(_LUser, _LServer, _) -> ok. -process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) -> - case Attr of - <<"jid">> -> - case jid:from_string(Val) of - error -> process_item_attrs_ws(Item, Attrs); - JID1 -> - JID = {JID1#jid.luser, JID1#jid.lserver, - JID1#jid.lresource}, - process_item_attrs_ws(Item#roster{jid = JID}, Attrs) - end; - <<"name">> -> - process_item_attrs_ws(Item#roster{name = Val}, Attrs); - <<"subscription">> -> - case Val of - <<"remove">> -> - process_item_attrs_ws(Item#roster{subscription = - remove}, - Attrs); - <<"none">> -> - process_item_attrs_ws(Item#roster{subscription = none}, - Attrs); - <<"both">> -> - process_item_attrs_ws(Item#roster{subscription = both}, - Attrs); - <<"from">> -> - process_item_attrs_ws(Item#roster{subscription = from}, - Attrs); - <<"to">> -> - process_item_attrs_ws(Item#roster{subscription = to}, - Attrs); - _ -> process_item_attrs_ws(Item, Attrs) - end; - <<"ask">> -> process_item_attrs_ws(Item, Attrs); - _ -> process_item_attrs_ws(Item, Attrs) - end; -process_item_attrs_ws(Item, []) -> Item. - get_in_pending_subscriptions(Ls, User, Server) -> LServer = jid:nameprep(Server), Mod = gen_mod:db_mod(LServer, ?MODULE), @@ -876,31 +730,18 @@ get_in_pending_subscriptions(Ls, User, Server) -> get_in_pending_subscriptions(Ls, User, Server, Mod) -> JID = jid:make(User, Server, <<"">>), Result = Mod:get_only_items(JID#jid.luser, JID#jid.lserver), - Ls ++ lists:map(fun (R) -> - Message = R#roster.askmessage, - Status = if is_binary(Message) -> (Message); - true -> <<"">> - end, - #xmlel{name = <<"presence">>, - attrs = - [{<<"from">>, - jid:to_string(R#roster.jid)}, - {<<"to">>, jid:to_string(JID)}, - {<<"type">>, <<"subscribe">>}], - children = - [#xmlel{name = <<"status">>, - attrs = [], - children = - [{xmlcdata, Status}]}]} - end, - lists:filter(fun (R) -> - case R#roster.ask of - in -> true; - both -> true; - _ -> false - end - end, - Result)). + Ls ++ lists:flatmap( + fun(#roster{ask = Ask} = R) when Ask == in; Ask == both -> + Message = R#roster.askmessage, + Status = if is_binary(Message) -> (Message); + true -> <<"">> + end, + [#presence{from = R#roster.jid, to = JID, + type = subscribe, + status = xmpp:mk_text(Status)}]; + (_) -> + [] + end, Result). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1070,10 +911,7 @@ user_roster_parse_query(User, Server, Items, Query) -> user_roster_subscribe_jid(User, Server, JID) -> out_subscription(User, Server, JID, subscribe), UJID = jid:make(User, Server, <<"">>), - ejabberd_router:route(UJID, JID, - #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"subscribe">>}], - children = []}). + ejabberd_router:route(UJID, JID, #presence{type = subscribe}). user_roster_item_parse_query(User, Server, Items, Query) -> @@ -1089,12 +927,7 @@ user_roster_item_parse_query(User, Server, Items, subscribed), UJID = jid:make(User, Server, <<"">>), ejabberd_router:route(UJID, JID1, - #xmlel{name = - <<"presence">>, - attrs = - [{<<"type">>, - <<"subscribed">>}], - children = []}), + #presence{type = subscribed}), throw(submitted); false -> case lists:keysearch(<<"remove", @@ -1102,29 +935,17 @@ user_roster_item_parse_query(User, Server, Items, 1, Query) of {value, _} -> - UJID = jid:make(User, Server, - <<"">>), - process_iq_set(UJID, UJID, - #iq{type = set, - sub_el = - #xmlel{name = - <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_ROSTER}], - children = - [#xmlel{name - = - <<"item">>, - attrs - = - [{<<"jid">>, - jid:to_string(JID)}, - {<<"subscription">>, - <<"remove">>}], - children - = - []}]}}), + UJID = jid:make(User, Server), + RosterItem = #roster_item{ + jid = jid:make(JID), + subscription = remove}, + process_iq_set( + #iq{type = set, + from = UJID, + to = UJID, + id = randoms:get_string(), + sub_els = [#roster_query{ + items = [RosterItem]}]}), throw(submitted); false -> ok end @@ -1144,24 +965,24 @@ webadmin_user(Acc, _User, _Server, Lang) -> %% Implement XEP-0321 Remote Roster Management -process_iq_manager(From, To, IQ) -> +process_iq_manager(#iq{from = From, to = To, lang = Lang} = IQ) -> %% Check what access is allowed for From to To MatchDomain = From#jid.lserver, case is_domain_managed(MatchDomain, To#jid.lserver) of true -> - process_iq_manager2(MatchDomain, To, IQ); + process_iq_manager2(MatchDomain, IQ); false -> - #iq{sub_el = SubEl, lang = Lang} = IQ, Txt = <<"Roster management is not allowed from this domain">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]} + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)) end. -process_iq_manager2(MatchDomain, To, IQ) -> +process_iq_manager2(MatchDomain, #iq{to = To} = IQ) -> %% If IQ is SET, filter the input IQ IQFiltered = maybe_filter_request(MatchDomain, IQ), %% Call the standard function with reversed JIDs IdInitial = IQFiltered#iq.id, - ResIQ = process_iq(To, To, IQFiltered#iq{id = <<"roster-remotely-managed">>}), + ResIQ = process_iq(IQFiltered#iq{from = To, to = To, + id = <<"roster-remotely-managed">>}), %% Filter the output IQ filter_stanza(MatchDomain, ResIQ#iq{id = IdInitial}). @@ -1176,37 +997,13 @@ maybe_filter_request(MatchDomain, IQ) when IQ#iq.type == set -> maybe_filter_request(_MatchDomain, IQ) -> IQ. -filter_stanza(_MatchDomain, #iq{sub_el = []} = IQ) -> - IQ; -filter_stanza(MatchDomain, #iq{sub_el = [SubEl | _]} = IQ) -> - #iq{sub_el = SubElFiltered} = IQRes = - filter_stanza(MatchDomain, IQ#iq{sub_el = SubEl}), - IQRes#iq{sub_el = [SubElFiltered]}; -filter_stanza(MatchDomain, #iq{sub_el = SubEl} = IQ) -> - #xmlel{name = Type, attrs = Attrs, children = Items} = SubEl, +filter_stanza(MatchDomain, + #iq{sub_els = [#roster_query{items = Items} = R]} = IQ) -> ItemsFiltered = lists:filter( - fun(Item) -> - is_item_of_domain(MatchDomain, Item) end, Items), - SubElFiltered = #xmlel{name=Type, attrs = Attrs, children = ItemsFiltered}, - IQ#iq{sub_el = SubElFiltered}. - -is_item_of_domain(MatchDomain, #xmlel{} = El) -> - lists:any(fun(Attr) -> is_jid_of_domain(MatchDomain, Attr) end, El#xmlel.attrs); -is_item_of_domain(_MatchDomain, {xmlcdata, _}) -> - false. - -is_jid_of_domain(MatchDomain, {<<"jid">>, JIDString}) -> - case jid:from_string(JIDString) of - JID when JID#jid.lserver == MatchDomain -> true; - _ -> false - end; -is_jid_of_domain(_, _) -> - false. - -process_item_attrs_managed(Item, Attrs, true) -> - process_item_attrs_ws(Item, Attrs); -process_item_attrs_managed(Item, _Attrs, false) -> - process_item_attrs(Item, _Attrs). + fun(#roster_item{jid = #jid{lserver = S}}) -> + S == MatchDomain + end, Items), + IQ#iq{sub_els = [R#roster_query{items = ItemsFiltered}]}. send_itemset_to_managers(_From, _Item, true) -> ok; diff --git a/src/mod_time.erl b/src/mod_time.erl index 90296f3d8..0aeb6831c 100644 --- a/src/mod_time.erl +++ b/src/mod_time.erl @@ -32,13 +32,13 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, +-export([start/2, stop/1, process_local_iq/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, @@ -50,41 +50,18 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME). -process_local_iq(_From, _To, - #iq{type = Type, sub_el = SubEl, lang = Lang} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - Now_universal = calendar:universal_time(), - Now_local = calendar:universal_time_to_local_time(Now_universal), - {UTC, UTC_diff} = jlib:timestamp_to_iso(Now_universal, - utc), - Seconds_diff = - calendar:datetime_to_gregorian_seconds(Now_local) - - calendar:datetime_to_gregorian_seconds(Now_universal), - {Hd, Md, _} = - calendar:seconds_to_time(abs(Seconds_diff)), - {_, TZO_diff} = jlib:timestamp_to_iso({{0, 1, 1}, - {0, 0, 0}}, - {sign(Seconds_diff), {Hd, Md}}), - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"time">>, - attrs = [{<<"xmlns">>, ?NS_TIME}], - children = - [#xmlel{name = <<"tzo">>, attrs = [], - children = [{xmlcdata, TZO_diff}]}, - #xmlel{name = <<"utc">>, attrs = [], - children = - [{xmlcdata, - <>}]}]}]} - end. - -sign(N) when N < 0 -> <<"-">>; -sign(_) -> <<"+">>. +process_local_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq(#iq{type = get} = IQ) -> + Now = p1_time_compat:timestamp(), + Now_universal = calendar:now_to_universal_time(Now), + Now_local = calendar:universal_time_to_local_time(Now_universal), + Seconds_diff = + calendar:datetime_to_gregorian_seconds(Now_local) - + calendar:datetime_to_gregorian_seconds(Now_universal), + {Hd, Md, _} = calendar:seconds_to_time(abs(Seconds_diff)), + xmpp:make_iq_result(IQ, #time{tzo = {Hd, Md}, utc = Now}). depends(_Host, _Opts) -> []. diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index aca9d7462..de9fce00d 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -33,13 +33,15 @@ -behaviour(gen_mod). -export([start/2, init/3, stop/1, get_sm_features/5, - process_local_iq/3, process_sm_iq/3, string2lower/1, + process_local_iq/1, process_sm_iq/1, string2lower/1, remove_user/2, export/1, import/1, import/3, depends/2, + process_search/1, process_vcard/1, + disco_items/5, disco_features/5, disco_identity/5, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_vcard.hrl"). -define(JUD_MATCHES, 30). @@ -68,11 +70,30 @@ start(Host, Opts) -> ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), - MyHost = gen_mod:get_opt_host(Host, Opts, - <<"vjud.@HOST@">>), + MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>), Search = gen_mod:get_opt(search, Opts, fun(B) when is_boolean(B) -> B end, false), + if Search -> + ejabberd_hooks:add( + disco_local_items, MyHost, ?MODULE, disco_items, 100), + ejabberd_hooks:add( + disco_local_features, MyHost, ?MODULE, disco_features, 100), + ejabberd_hooks:add( + disco_local_identity, MyHost, ?MODULE, disco_identity, 100), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_SEARCH, ?MODULE, process_search, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_VCARD, ?MODULE, process_vcard, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_DISCO_ITEMS, mod_disco, + process_local_iq_items, IQDisc), + gen_iq_handler:add_iq_handler( + ejabberd_local, MyHost, ?NS_DISCO_INFO, mod_disco, + process_local_iq_info, IQDisc); + true -> + ok + end, register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [MyHost, Host, Search])). @@ -87,12 +108,20 @@ init(Host, ServerHost, Search) -> loop(Host, ServerHost) -> receive {route, From, To, Packet} -> - case catch do_route(ServerHost, From, To, Packet) of + case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, loop(Host, ServerHost); - stop -> ejabberd_router:unregister_route(Host), ok; + stop -> + ejabberd_router:unregister_route(Host), + ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50), + ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50), + ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SEARCH), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO); _ -> loop(Host, ServerHost) end. @@ -109,12 +138,23 @@ stop(Host) -> Proc ! stop, {wait, Proc}. +do_route(From, To, #xmlel{name = <<"iq">>} = El) -> + ejabberd_router:process_iq(From, To, El); +do_route(From, To, #iq{} = IQ) -> + ejabberd_router:process_iq(From, To, IQ); +do_route(_, _, _) -> + ok. + +-spec get_sm_features({error, error()} | empty | {result, [binary()]}, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | empty | {result, [binary()]}. get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_features(Acc, _From, _To, Node, _Lang) -> case Node of - <<"">> -> + undefined -> case Acc of {result, Features} -> {result, [?NS_DISCO_INFO, ?NS_VCARD | Features]}; @@ -123,67 +163,113 @@ get_sm_features(Acc, _From, _To, Node, _Lang) -> _ -> Acc end. -process_local_iq(_From, _To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = - [#xmlel{name = <<"FN">>, attrs = [], - children = - [{xmlcdata, <<"ejabberd">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Erlang Jabber Server">>))/binary, - "\nCopyright (c) 2002-2016 ProcessOne">>}]}, - #xmlel{name = <<"BDAY">>, attrs = [], - children = - [{xmlcdata, <<"2002-11-16">>}]}]}]} - end. - -process_sm_iq(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - #jid{user = User, lserver = LServer} = From, - case lists:member(LServer, ?MYHOSTS) of - true -> - set_vcard(User, LServer, SubEl), - IQ#iq{type = result, sub_el = []}; - false -> - Txt = <<"The query is only allowed from local users">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]} - end; - get -> - #jid{luser = LUser, lserver = LServer} = To, - case get_vcard(LUser, LServer) of - error -> - Txt = <<"Database failure">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}; - [] -> - IQ#iq{type = result, - sub_el = [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = []}]}; - Els -> IQ#iq{type = result, sub_el = Els} - end +-spec process_local_iq(iq()) -> iq(). +process_local_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq(#iq{type = get, lang = Lang} = IQ) -> + Desc = translate:translate(Lang, <<"Erlang Jabber Server">>), + Copyright = <<"Copyright (c) 2002-2016 ProcessOne">>, + xmpp:make_iq_result( + IQ, #vcard_temp{fn = <<"ejabberd">>, + url = ?EJABBERD_URI, + desc = <>, + bday = <<"2002-11-16">>}). + +-spec process_sm_iq(iq()) -> iq(). +process_sm_iq(#iq{type = set, lang = Lang, from = From, + sub_els = [SubEl]} = IQ) -> + #jid{user = User, lserver = LServer} = From, + case lists:member(LServer, ?MYHOSTS) of + true -> + set_vcard(User, LServer, SubEl), + xmpp:make_iq_result(IQ); + false -> + Txt = <<"The query is only allowed from local users">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)) + end; +process_sm_iq(#iq{type = get, from = From, to = To, lang = Lang} = IQ) -> + #jid{luser = LUser, lserver = LServer} = To, + case get_vcard(LUser, LServer) of + error -> + Txt = <<"Database failure">>, + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)); + [] -> + xmpp:make_iq_result(IQ, #vcard_temp{}); + Els -> + IQ#iq{type = result, to = From, from = To, sub_els = Els} end. +-spec process_vcard(iq()) -> iq(). +process_vcard(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_vcard(#iq{type = get, lang = Lang} = IQ) -> + Desc = translate:translate(Lang, <<"ejabberd vCard module">>), + Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, + xmpp:make_iq_result( + IQ, #vcard_temp{fn = <<"ejabberd/mod_vcard">>, + url = ?EJABBERD_URI, + desc = <>}). + +-spec process_search(iq()) -> iq(). +process_search(#iq{type = get, to = To, lang = Lang} = IQ) -> + xmpp:make_iq_result(IQ, mk_search_form(To, Lang)); +process_search(#iq{type = set, to = To, lang = Lang, + sub_els = [#search{xdata = #xdata{type = submit, + fields = Fs}}]} = IQ) -> + ServerHost = ejabberd_router:host_of_route(To#jid.lserver), + ResultXData = search_result(Lang, To, ServerHost, Fs), + xmpp:make_iq_result(IQ, #search{xdata = ResultXData}); +process_search(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Incorrect data form">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)). + +-spec disco_items({error, error()} | {result, [disco_item()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [disco_item()]}. +disco_items(empty, _From, _To, undefined, _Lang) -> + {result, []}; +disco_items(empty, _From, _To, _Node, Lang) -> + {error, xmpp:err_item_not_found(<<"No services available">>, Lang)}; +disco_items(Acc, _From, _To, _Node, _Lang) -> + Acc. + +-spec disco_features({error, error()} | {result, [binary()]} | empty, + jid(), jid(), + undefined | binary(), undefined | binary()) -> + {error, error()} | {result, [binary()]}. +disco_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> + Acc; +disco_features(Acc, _From, _To, undefined, _Lang) -> + Features = case Acc of + {result, Fs} -> Fs; + empty -> [] + end, + {result, [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, + ?NS_VCARD, ?NS_SEARCH | Features]}; +disco_features(empty, _From, _To, _Node, Lang) -> + Txt = <<"No features available">>, + {error, xmpp:err_item_not_found(Txt, Lang)}; +disco_features(Acc, _From, _To, _Node, _Lang) -> + Acc. + +-spec disco_identity([identity()], jid(), jid(), undefined | binary(), + undefined | binary()) -> [identity()]. +disco_identity(Acc, _From, _To, undefined, Lang) -> + [#identity{category = <<"directory">>, + type = <<"user">>, + name = translate:translate(Lang, <<"vCard User Search">>)}|Acc]; +disco_identity(Acc, _From, _To, _Node, _Lang) -> + Acc. + +-spec get_vcard(binary(), binary()) -> [xmlel()] | error. get_vcard(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_vcard(LUser, LServer). +-spec make_vcard_search(binary(), binary(), binary(), xmlel()) -> #vcard_search{}. make_vcard_search(User, LUser, LServer, VCARD) -> FN = fxml:get_path_s(VCARD, [{elem, <<"FN">>}, cdata]), Family = fxml:get_path_s(VCARD, @@ -250,6 +336,7 @@ make_vcard_search(User, LUser, LServer, VCARD) -> orgunit = OrgUnit, lorgunit = LOrgUnit}. +-spec set_vcard(binary(), binary(), xmlel()) -> any(). set_vcard(User, LServer, VCARD) -> case jid:nodeprep(User) of error -> @@ -262,307 +349,108 @@ set_vcard(User, LServer, VCARD) -> [LUser, LServer, VCARD]) end. +-spec string2lower(binary()) -> binary(). string2lower(String) -> case stringprep:tolower(String) of Lower when is_binary(Lower) -> Lower; error -> str:to_lower(String) end. --define(TLFIELD(Type, Label, Var), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = []}). - --define(FORM(JID), - [#xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"You need an x:data capable client to " - "search">>)}]}, - #xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Search users in ">>))/binary, - (jid:to_string(JID))/binary>>}]}, - #xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Fill in the form to search for any matching " - "Jabber User (Add * to the end of field " - "to match substring)">>)}]}, - ?TLFIELD(<<"text-single">>, <<"User">>, <<"user">>), - ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>), - ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>), - ?TLFIELD(<<"text-single">>, <<"Middle Name">>, - <<"middle">>), - ?TLFIELD(<<"text-single">>, <<"Family Name">>, - <<"last">>), - ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>), - ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>), - ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>), - ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>), - ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>), - ?TLFIELD(<<"text-single">>, <<"Organization Name">>, - <<"orgname">>), - ?TLFIELD(<<"text-single">>, <<"Organization Unit">>, - <<"orgunit">>)]}]). - -do_route(ServerHost, From, To, Packet) -> - #jid{user = User, resource = Resource} = To, - if (User /= <<"">>) or (Resource /= <<"">>) -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err); - true -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, - sub_el = SubEl} -> - case Type of - set -> - XDataEl = find_xdata_el(SubEl), - case XDataEl of - false -> - Txt = <<"Data form not found">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_BAD_REQUEST(Lang, Txt)), - ejabberd_router:route(To, From, Err); - _ -> - XData = jlib:parse_xdata_submit(XDataEl), - case XData of - invalid -> - Txt = <<"Incorrect data form">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_BAD_REQUEST(Lang, Txt)), - ejabberd_router:route(To, From, Err); - _ -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_SEARCH}], - children = - [#xmlel{name = - <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_XDATA}, - {<<"type">>, - <<"result">>}], - children - = - search_result(Lang, - To, - ServerHost, - XData)}]}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(ResIQ)) - end - end; - get -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_SEARCH}], - children = ?FORM(To)}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)), - ejabberd_router:route(To, From, Err); - get -> - Info = ejabberd_hooks:run_fold(disco_info, ServerHost, - [], - [ServerHost, ?MODULE, - <<"">>, <<"">>]), - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_DISCO_INFO}], - children = - [#xmlel{name = - <<"identity">>, - attrs = - [{<<"category">>, - <<"directory">>}, - {<<"type">>, - <<"user">>}, - {<<"name">>, - translate:translate(Lang, - <<"vCard User Search">>)}], - children = []}, - #xmlel{name = - <<"feature">>, - attrs = - [{<<"var">>, - ?NS_DISCO_INFO}], - children = []}, - #xmlel{name = - <<"feature">>, - attrs = - [{<<"var">>, - ?NS_SEARCH}], - children = []}, - #xmlel{name = - <<"feature">>, - attrs = - [{<<"var">>, - ?NS_VCARD}], - children = []}] - ++ Info}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, lang = Lang, xmlns = ?NS_DISCO_ITEMS} -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)), - ejabberd_router:route(To, From, Err); - get -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_DISCO_ITEMS}], - children = []}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = iq_get_vcard(Lang)}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); - _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err) - end - end. - -iq_get_vcard(Lang) -> - [#xmlel{name = <<"FN">>, attrs = [], - children = [{xmlcdata, <<"ejabberd/mod_vcard">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"ejabberd vCard module">>))/binary, - "\nCopyright (c) 2003-2016 ProcessOne">>}]}]. - -find_xdata_el(#xmlel{children = SubEls}) -> - find_xdata_el1(SubEls). - -find_xdata_el1([]) -> false; -find_xdata_el1([#xmlel{name = Name, attrs = Attrs, - children = SubEls} - | Els]) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_XDATA -> - #xmlel{name = Name, attrs = Attrs, children = SubEls}; - _ -> find_xdata_el1(Els) - end; -find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). - --define(LFIELD(Label, Var), - #xmlel{name = <<"field">>, - attrs = - [{<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = []}). - -search_result(Lang, JID, ServerHost, Data) -> - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Search Results for ">>))/binary, - (jid:to_string(JID))/binary>>}]}, - #xmlel{name = <<"reported">>, attrs = [], - children = - [?TLFIELD(<<"text-single">>, <<"Jabber ID">>, - <<"jid">>), - ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>), - ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>), - ?TLFIELD(<<"text-single">>, <<"Middle Name">>, - <<"middle">>), - ?TLFIELD(<<"text-single">>, <<"Family Name">>, - <<"last">>), - ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>), - ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>), - ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>), - ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>), - ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>), - ?TLFIELD(<<"text-single">>, <<"Organization Name">>, - <<"orgname">>), - ?TLFIELD(<<"text-single">>, <<"Organization Unit">>, - <<"orgunit">>)]}] - ++ - lists:map(fun (R) -> record_to_item(ServerHost, R) end, - search(ServerHost, Data)). - --define(FIELD(Var, Val), - #xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). - +-spec mk_tfield(binary(), binary(), undefined | binary()) -> xdata_field(). +mk_tfield(Label, Var, Lang) -> + #xdata_field{type = 'text-single', + label = translate:translate(Lang, Label), + var = Var}. + +-spec mk_field(binary(), binary()) -> xdata_field(). +mk_field(Var, Val) -> + #xdata_field{var = Var, values = [Val]}. + +-spec mk_search_form(jid(), undefined | binary()) -> search(). +mk_search_form(JID, Lang) -> + Title = <<(translate:translate(Lang, <<"Search users in ">>))/binary, + (jid:to_string(JID))/binary>>, + Fs = [mk_tfield(<<"User">>, <<"user">>, Lang), + mk_tfield(<<"Full Name">>, <<"fn">>, Lang), + mk_tfield(<<"Name">>, <<"first">>, Lang), + mk_tfield(<<"Middle Name">>, <<"middle">>, Lang), + mk_tfield(<<"Family Name">>, <<"last">>, Lang), + mk_tfield(<<"Nickname">>, <<"nick">>, Lang), + mk_tfield(<<"Birthday">>, <<"bday">>, Lang), + mk_tfield(<<"Country">>, <<"ctry">>, Lang), + mk_tfield(<<"City">>, <<"locality">>, Lang), + mk_tfield(<<"Email">>, <<"email">>, Lang), + mk_tfield(<<"Organization Name">>, <<"orgname">>, Lang), + mk_tfield(<<"Organization Unit">>, <<"orgunit">>, Lang)], + X = #xdata{type = form, + title = Title, + instructions = + [translate:translate( + Lang, + <<"Fill in the form to search for any matching " + "Jabber User (Add * to the end of field " + "to match substring)">>)], + fields = Fs}, + #search{instructions = + translate:translate( + Lang, <<"You need an x:data capable client to search">>), + xdata = X}. + +-spec search_result(undefined | binary(), jid(), binary(), [xdata_field()]) -> xdata(). +search_result(Lang, JID, ServerHost, XFields) -> + #xdata{type = result, + title = <<(translate:translate(Lang, + <<"Search Results for ">>))/binary, + (jid:to_string(JID))/binary>>, + reported = [mk_tfield(<<"Jabber ID">>, <<"jid">>, Lang), + mk_tfield(<<"Full Name">>, <<"fn">>, Lang), + mk_tfield(<<"Name">>, <<"first">>, Lang), + mk_tfield(<<"Middle Name">>, <<"middle">>, Lang), + mk_tfield(<<"Family Name">>, <<"last">>, Lang), + mk_tfield(<<"Nickname">>, <<"nick">>, Lang), + mk_tfield(<<"Birthday">>, <<"bday">>, Lang), + mk_tfield(<<"Country">>, <<"ctry">>, Lang), + mk_tfield(<<"City">>, <<"locality">>, Lang), + mk_tfield(<<"Email">>, <<"email">>, Lang), + mk_tfield(<<"Organization Name">>, <<"orgname">>, Lang), + mk_tfield(<<"Organization Unit">>, <<"orgunit">>, Lang)], + items = lists:map(fun (R) -> record_to_item(ServerHost, R) end, + search(ServerHost, XFields))}. + +-spec record_to_item(binary(), [binary()] | #vcard_search{}) -> [xdata_field()]. record_to_item(LServer, [Username, FN, Family, Given, Middle, Nickname, BDay, CTRY, Locality, EMail, OrgName, OrgUnit]) -> - #xmlel{name = <<"item">>, attrs = [], - children = - [?FIELD(<<"jid">>, - <>), - ?FIELD(<<"fn">>, FN), ?FIELD(<<"last">>, Family), - ?FIELD(<<"first">>, Given), - ?FIELD(<<"middle">>, Middle), - ?FIELD(<<"nick">>, Nickname), ?FIELD(<<"bday">>, BDay), - ?FIELD(<<"ctry">>, CTRY), - ?FIELD(<<"locality">>, Locality), - ?FIELD(<<"email">>, EMail), - ?FIELD(<<"orgname">>, OrgName), - ?FIELD(<<"orgunit">>, OrgUnit)]}; + [mk_field(<<"jid">>, <>), + mk_field(<<"fn">>, FN), + mk_field(<<"last">>, Family), + mk_field(<<"first">>, Given), + mk_field(<<"middle">>, Middle), + mk_field(<<"nick">>, Nickname), + mk_field(<<"bday">>, BDay), + mk_field(<<"ctry">>, CTRY), + mk_field(<<"locality">>, Locality), + mk_field(<<"email">>, EMail), + mk_field(<<"orgname">>, OrgName), + mk_field(<<"orgunit">>, OrgUnit)]; record_to_item(_LServer, #vcard_search{} = R) -> {User, Server} = R#vcard_search.user, - #xmlel{name = <<"item">>, attrs = [], - children = - [?FIELD(<<"jid">>, <>), - ?FIELD(<<"fn">>, (R#vcard_search.fn)), - ?FIELD(<<"last">>, (R#vcard_search.family)), - ?FIELD(<<"first">>, (R#vcard_search.given)), - ?FIELD(<<"middle">>, (R#vcard_search.middle)), - ?FIELD(<<"nick">>, (R#vcard_search.nickname)), - ?FIELD(<<"bday">>, (R#vcard_search.bday)), - ?FIELD(<<"ctry">>, (R#vcard_search.ctry)), - ?FIELD(<<"locality">>, (R#vcard_search.locality)), - ?FIELD(<<"email">>, (R#vcard_search.email)), - ?FIELD(<<"orgname">>, (R#vcard_search.orgname)), - ?FIELD(<<"orgunit">>, (R#vcard_search.orgunit))]}. - -search(LServer, Data) -> + [mk_field(<<"jid">>, <>), + mk_field(<<"fn">>, (R#vcard_search.fn)), + mk_field(<<"last">>, (R#vcard_search.family)), + mk_field(<<"first">>, (R#vcard_search.given)), + mk_field(<<"middle">>, (R#vcard_search.middle)), + mk_field(<<"nick">>, (R#vcard_search.nickname)), + mk_field(<<"bday">>, (R#vcard_search.bday)), + mk_field(<<"ctry">>, (R#vcard_search.ctry)), + mk_field(<<"locality">>, (R#vcard_search.locality)), + mk_field(<<"email">>, (R#vcard_search.email)), + mk_field(<<"orgname">>, (R#vcard_search.orgname)), + mk_field(<<"orgunit">>, (R#vcard_search.orgunit))]. + +-spec search(binary(), [xdata_field()]) -> [binary()]. +search(LServer, XFields) -> + Data = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- XFields], Mod = gen_mod:db_mod(LServer, ?MODULE), AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all, fun(B) when is_boolean(B) -> B end, diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index f2101df91..27ea8461a 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -17,8 +17,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("mod_vcard_xupdate.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). -callback import(binary(), #vcard_xupdate{}) -> ok | pass. @@ -53,12 +52,8 @@ depends(_Host, _Opts) -> %% Hooks %%==================================================================== -update_presence(#xmlel{name = <<"presence">>, attrs = Attrs} = Packet, - User, Host) -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<>> -> presence_with_xupdate(Packet, User, Host); - _ -> Packet - end; +update_presence(#presence{type = undefined} = Packet, User, Host) -> + presence_with_xupdate(Packet, User, Host); update_presence(Packet, _User, _Host) -> Packet. vcard_set(LUser, LServer, VCARD) -> @@ -93,36 +88,10 @@ remove_xupdate(LUser, LServer) -> %%% Presence stanza rebuilding %%%---------------------------------------------------------------------- -presence_with_xupdate(#xmlel{name = <<"presence">>, - attrs = Attrs, children = Els}, - User, Host) -> - XPhotoEl = build_xphotoel(User, Host), - Els2 = presence_with_xupdate2(Els, [], XPhotoEl), - #xmlel{name = <<"presence">>, attrs = Attrs, - children = Els2}. - -presence_with_xupdate2([], Els2, XPhotoEl) -> - lists:reverse([XPhotoEl | Els2]); -%% This clause assumes that the x element contains only the XMLNS attribute: -presence_with_xupdate2([#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_VCARD_UPDATE}]} - | Els], - Els2, XPhotoEl) -> - presence_with_xupdate2(Els, Els2, XPhotoEl); -presence_with_xupdate2([El | Els], Els2, XPhotoEl) -> - presence_with_xupdate2(Els, [El | Els2], XPhotoEl). - -build_xphotoel(User, Host) -> +presence_with_xupdate(Presence, User, Host) -> Hash = get_xupdate(User, Host), - PhotoSubEls = case Hash of - Hash when is_binary(Hash) -> [{xmlcdata, Hash}]; - _ -> [] - end, - PhotoEl = [#xmlel{name = <<"photo">>, attrs = [], - children = PhotoSubEls}], - #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_VCARD_UPDATE}], - children = PhotoEl}. + Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}), + xmpp:set_subtag(Presence1, #vcard_xupdate{hash = Hash}). export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), diff --git a/src/mod_version.erl b/src/mod_version.erl index 8a035763f..80b22554d 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -31,13 +31,13 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, +-export([start/2, stop/1, process_local_iq/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, @@ -50,35 +50,20 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VERSION). -process_local_iq(_From, To, - #iq{id = _ID, type = Type, xmlns = _XMLNS, - sub_el = SubEl, lang = Lang} = - IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - Host = To#jid.lserver, - OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, - fun(B) when is_boolean(B) -> B end, - true) - of - true -> [get_os()]; - false -> [] - end, - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_VERSION}], - children = - [#xmlel{name = <<"name">>, attrs = [], - children = - [{xmlcdata, <<"ejabberd">>}]}, - #xmlel{name = <<"version">>, attrs = [], - children = [{xmlcdata, ?VERSION}]}] - ++ OS}]} - end. +process_local_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_local_iq(#iq{type = get, to = To} = IQ) -> + Host = To#jid.lserver, + OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, + fun(B) when is_boolean(B) -> B end, + true) of + true -> get_os(); + false -> undefined + end, + xmpp:make_iq_result(IQ, #version{name = <<"ejabberd">>, + ver = ?VERSION, + os = OS}). get_os() -> {Osfamily, Osname} = os:type(), @@ -89,9 +74,7 @@ get_os() -> [Major, Minor, Release])); VersionString -> VersionString end, - OS = <>, - #xmlel{name = <<"os">>, attrs = [], - children = [{xmlcdata, OS}]}. + <>. depends(_Host, _Opts) -> []. diff --git a/src/translate.erl b/src/translate.erl index e9f61ab8c..c8a924585 100644 --- a/src/translate.erl +++ b/src/translate.erl @@ -126,8 +126,10 @@ load_file_loop(Fd, Line, File, Lang) -> ok end. --spec translate(binary(), binary()) -> binary(). +-spec translate(binary() | undefined, binary()) -> binary(). +translate(undefined, Msg) -> + translate(?MYLANG, Msg); translate(Lang, Msg) -> LLang = ascii_tolower(Lang), case ets:lookup(translations, {LLang, Msg}) of diff --git a/src/xmpp.erl b/src/xmpp.erl new file mode 100644 index 000000000..ca6ed5e4c --- /dev/null +++ b/src/xmpp.erl @@ -0,0 +1,712 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov +%%% @copyright (C) 2015, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 9 Dec 2015 by Evgeny Khramtsov +%%%------------------------------------------------------------------- +-module(xmpp). + +%% API +-export([make_iq_result/1, make_iq_result/2, make_error/2, + decode/1, decode/2, decode_tags_by_ns/2, encode/1, + get_type/1, get_to/1, get_from/1, get_id/1, + get_lang/1, get_error/1, get_els/1, get_ns/1, + set_type/2, set_to/2, set_from/2, set_id/2, + set_lang/2, set_error/2, set_els/2, set_from_to/3, + format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, + remove_subtag/2, has_subtag/2, decode_els/1, pp/1, + get_name/1, get_text/1, mk_text/1, mk_text/2]). + +%% XMPP errors +-export([err_bad_request/0, err_bad_request/2, + err_bad_format/0, err_bad_format/2, + err_not_allowed/0, err_not_allowed/2, + err_conflict/0, err_conflict/2, + err_forbidden/0, err_forbidden/2, + err_not_acceptable/0, err_not_acceptable/2, + err_internal_server_error/0, err_internal_server_error/2, + err_service_unavailable/0, err_service_unavailable/2, + err_item_not_found/0, err_item_not_found/2, + err_jid_malformed/0, err_jid_malformed/2, + err_not_authorized/0, err_not_authorized/2, + err_feature_not_implemented/0, err_feature_not_implemented/2]). + +%% XMPP stream errors +-export([serr_bad_format/0, serr_bad_format/2, + serr_bad_namespace_prefix/0, serr_bad_namespace_prefix/2, + serr_conflict/0, serr_conflict/2, + serr_connection_timeout/0, serr_connection_timeout/2, + serr_host_gone/0, serr_host_gone/2, + serr_host_unknown/0, serr_host_unknown/2, + serr_improper_addressing/0, serr_improper_addressing/2, + serr_internal_server_error/0, serr_internal_server_error/2, + serr_invalid_from/0, serr_invalid_from/2, + serr_invalid_id/0, serr_invalid_id/2, + serr_invalid_namespace/0, serr_invalid_namespace/2, + serr_invalid_xml/0, serr_invalid_xml/2, + serr_not_authorized/0, serr_not_authorized/2, + serr_not_well_formed/0, serr_not_well_formed/2, + serr_policy_violation/0, serr_policy_violation/2, + serr_remote_connection_failed/0, serr_remote_connection_failed/2, + serr_reset/0, serr_reset/2, + serr_resource_constraint/0, serr_resource_constraint/2, + serr_restricted_xml/0, serr_restricted_xml/2, + serr_see_other_host/0, serr_see_other_host/2, + serr_system_shutdown/0, serr_system_shutdown/2, + serr_undefined_condition/0, serr_undefined_condition/2, + serr_unsupported_encoding/0, serr_unsupported_encoding/2, + serr_unsupported_stanza_type/0, serr_unsupported_stanza_type/2, + serr_unsupported_version/0, serr_unsupported_version/2]). + +-ifndef(NS_CLIENT). +-define(NS_CLIENT, <<"jabber:client">>). +-endif. + +-include("xmpp.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +-spec make_iq_result(iq()) -> iq(). +make_iq_result(IQ) -> + make_iq_result(IQ, undefined). + +-spec make_iq_result(iq(), xmpp_element() | xmlel() | undefined) -> iq(). +make_iq_result(#iq{type = Type, from = From, to = To} = IQ, El) + when Type == get; Type == set -> + SubEls = if El == undefined -> []; + true -> [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(). +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]}; +make_error(#presence{type = Type, from = From, to = To, sub_els = Els} = Pres, + Err) when Type /= error -> + Pres#presence{type = error, from = To, to = From, sub_els = Els ++ [Err]}; +make_error(#iq{type = Type, from = From, to = To, sub_els = Els} = IQ, + Err) when Type /= result, Type /= error -> + IQ#iq{type = error, from = To, to = From, sub_els = Els ++ [Err]}; +make_error(#xmlel{attrs = Attrs, children = Els} = El, Err) -> + To = fxml:get_attr(<<"to">>, Attrs), + From = fxml:get_attr(<<"from">>, Attrs), + Attrs1 = case To of + {value, T} -> + lists:keystore(<<"from">>, 1, Attrs, {<<"from">>, T}); + _ -> + Attrs + end, + Attrs2 = case From of + {value, F} -> + lists:keystore(<<"to">>, 1, Attrs1, {<<"to">>, F}); + _ -> + Attrs + end, + Attrs3 = lists:keystore(<<"type">>, 1, Attrs2, {<<"type">>, <<"error">>}), + El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err)]}. + +-spec get_id(iq() | message() | presence() | xmlel()) -> undefined | binary(). +get_id(#iq{id = ID}) -> ID; +get_id(#message{id = ID}) -> ID; +get_id(#presence{id = ID}) -> ID; +get_id(#xmlel{attrs = Attrs}) -> + case fxml:get_attr(<<"id">>, Attrs) of + {value, ID} -> ID; + false -> undefined + end. + +-spec get_type(iq()) -> iq_type(); + (message()) -> message_type(); + (presence()) -> presence_type(); + (xmlel()) -> binary(). +get_type(#iq{type = T}) -> T; +get_type(#message{type = T}) -> T; +get_type(#presence{type = T}) -> T; +get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs). + +-spec get_lang(iq() | message() | presence()) -> undefined | binary(). +get_lang(#iq{lang = L}) -> L; +get_lang(#message{lang = L}) -> L; +get_lang(#presence{lang = L}) -> L; +get_lang(#xmlel{attrs = Attrs}) -> + case fxml:get_attr(<<"xml:lang">>, Attrs) of + {value, L} -> L; + false -> undefined + end. + +-spec get_from(iq() | message() | presence()) -> undefined | jid:jid(). +get_from(#iq{from = J}) -> J; +get_from(#message{from = J}) -> J; +get_from(#presence{from = J}) -> J. + +-spec get_to(iq() | message() | presence()) -> undefined | jid:jid(). +get_to(#iq{to = J}) -> J; +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. + +-spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()]. +get_els(#iq{sub_els = Els}) -> Els; +get_els(#message{sub_els = Els}) -> Els; +get_els(#presence{sub_els = Els}) -> Els. + +-spec set_id(iq(), binary()) -> iq(); + (message(), binary()) -> message(); + (presence(), binary()) -> presence(). +set_id(#iq{} = IQ, I) -> IQ#iq{id = I}; +set_id(#message{} = Msg, I) -> Msg#message{id = I}; +set_id(#presence{} = Pres, I) -> Pres#presence{id = I}. + +-spec set_type(iq(), iq_type()) -> iq(); + (message(), message_type()) -> message(); + (presence(), presence_type()) -> presence(). +set_type(#iq{} = IQ, T) -> IQ#iq{type = T}; +set_type(#message{} = Msg, T) -> Msg#message{type = T}; +set_type(#presence{} = Pres, T) -> Pres#presence{type = T}. + +-spec set_lang(iq(), binary()) -> iq(); + (message(), binary()) -> message(); + (presence(), binary()) -> presence(). +set_lang(#iq{} = IQ, L) -> IQ#iq{lang = L}; +set_lang(#message{} = Msg, L) -> Msg#message{lang = L}; +set_lang(#presence{} = Pres, L) -> Pres#presence{lang = L}. + +-spec set_from(iq(), jid:jid()) -> iq(); + (message(), jid:jid()) -> message(); + (presence(), jid:jid()) -> presence(). +set_from(#iq{} = IQ, J) -> IQ#iq{from = J}; +set_from(#message{} = Msg, J) -> Msg#message{from = J}; +set_from(#presence{} = Pres, J) -> Pres#presence{from = J}. + +-spec set_to(iq(), jid:jid()) -> iq(); + (message(), jid:jid()) -> message(); + (presence(), jid:jid()) -> presence(). +set_to(#iq{} = IQ, J) -> IQ#iq{to = J}; +set_to(#message{} = Msg, J) -> Msg#message{to = J}; +set_to(#presence{} = Pres, J) -> Pres#presence{to = J}. + +-spec set_from_to(iq(), jid:jid(), jid:jid()) -> iq(); + (message(), jid:jid(), jid:jid()) -> message(); + (presence(), jid:jid(), jid:jid()) -> presence(). +set_from_to(#iq{} = IQ, F, T) -> IQ#iq{from = F, to = T}; +set_from_to(#message{} = Msg, F, T) -> Msg#message{from = F, to = T}; +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}. + +-spec set_els(iq(), [xmpp_element() | xmlel()]) -> iq(); + (message(), [xmpp_element() | xmlel()]) -> message(); + (presence(), [xmpp_element() | xmlel()]) -> presence(). +set_els(#iq{} = IQ, Els) -> IQ#iq{sub_els = Els}; +set_els(#message{} = Msg, Els) -> Msg#message{sub_els = Els}; +set_els(#presence{} = Pres, Els) -> Pres#presence{sub_els = Els}. + +-spec get_ns(xmpp_element() | xmlel()) -> binary(). +get_ns(#xmlel{attrs = Attrs}) -> + fxml:get_attr_s(<<"xmlns">>, Attrs); +get_ns(Pkt) -> + xmpp_codec:get_ns(Pkt). + +-spec get_name(xmpp_element() | xmlel()) -> binary(). +get_name(#xmlel{name = Name}) -> + Name; +get_name(Pkt) -> + xmpp_codec:get_name(Pkt). + +-spec decode(xmlel() | xmpp_element()) -> {ok, xmpp_element()} | {error, any()}. +decode(El) -> + decode(El, []). + +-spec decode(xmlel() | xmpp_element(), [proplists:property()]) -> + {ok, xmpp_element()} | {error, any()}. +decode(#xmlel{} = El, Opts) -> + xmpp_codec:decode(add_ns(El), Opts); +decode(Pkt, _Opts) -> + Pkt. + +-spec decode_els(iq()) -> iq(); + (message()) -> message(); + (presence()) -> presence(). +decode_els(Stanza) -> + Els = lists:map( + fun(#xmlel{} = El) -> + case xmpp_codec:is_known_tag(El) of + true -> decode(El); + false -> El + end; + (Pkt) -> + Pkt + end, get_els(Stanza)), + set_els(Stanza, Els). + +-spec encode(xmpp_element() | xmlel()) -> xmlel(). +encode(Pkt) -> + xmpp_codec:encode(Pkt). + +-spec decode_tags_by_ns([xmpp_element() | xmlel()], [binary()]) -> [xmpp_element()]. +decode_tags_by_ns(Els, NSList) -> + [xmpp_codec:decode(El) || El <- Els, lists:member(get_ns(El), NSList)]. + +format_error(Reason) -> + xmpp_codec:format_error(Reason). + +-spec is_stanza(any()) -> boolean(). +is_stanza(#message{}) -> true; +is_stanza(#iq{}) -> true; +is_stanza(#presence{}) -> true; +is_stanza(#xmlel{name = Name}) -> + (Name == <<"iq">>) or (Name == <<"message">>) or (Name == <<"presence">>); +is_stanza(_) -> false. + +-spec set_subtag(iq(), xmpp_element()) -> iq(); + (message(), xmpp_element()) -> message(); + (presence(), xmpp_element()) -> presence(). +set_subtag(Stanza, Tag) -> + TagName = xmpp_codec:get_name(Tag), + XMLNS = xmpp_codec:get_ns(Tag), + Els = get_els(Stanza), + NewEls = set_subtag(Els, Tag, TagName, XMLNS), + set_els(Stanza, NewEls). + +set_subtag([El|Els], Tag, TagName, XMLNS) -> + case {get_name(El), get_ns(El)} of + {TagName, XMLNS} -> + [Tag|Els]; + _ -> + [El|set_subtag(Els, Tag, TagName, XMLNS)] + end; +set_subtag([], Tag, _, _) -> + [Tag]. + +-spec get_subtag(stanza(), xmpp_element()) -> xmpp_element() | false. +get_subtag(Stanza, Tag) -> + Els = get_els(Stanza), + TagName = xmpp_codec:get_name(Tag), + XMLNS = xmpp_codec:get_ns(Tag), + get_subtag(Els, TagName, XMLNS). + +get_subtag([El|Els], TagName, XMLNS) -> + case {get_name(El), get_ns(El)} of + {TagName, XMLNS} -> + try + decode(El) + catch _:{xmpp_codec, _Why} -> + get_subtag(Els, TagName, XMLNS) + end; + _ -> + get_subtag(Els, TagName, XMLNS) + end; +get_subtag([], _, _) -> + false. + +-spec remove_subtag(iq(), xmpp_element()) -> iq(); + (message(), xmpp_element()) -> message(); + (presence(), xmpp_element()) -> presence(). +remove_subtag(Stanza, Tag) -> + Els = get_els(Stanza), + TagName = xmpp_codec:get_name(Tag), + XMLNS = xmpp_codec:get_ns(Tag), + NewEls = remove_subtag(Els, TagName, XMLNS), + set_els(Stanza, NewEls). + +remove_subtag([El|Els], TagName, XMLNS) -> + case {get_name(El), get_ns(El)} of + {TagName, XMLNS} -> + remove_subtag(Els, TagName, XMLNS); + _ -> + [El|remove_subtag(Els, TagName, XMLNS)] + end; +remove_subtag([], _, _) -> + []. + +-spec has_subtag(stanza(), xmpp_element()) -> boolean(). +has_subtag(Stanza, Tag) -> + Els = get_els(Stanza), + TagName = xmpp_codec:get_name(Tag), + XMLNS = xmpp_codec:get_ns(Tag), + has_subtag(Els, TagName, XMLNS). + +has_subtag([El|Els], TagName, XMLNS) -> + case {get_name(El), get_ns(El)} of + {TagName, XMLNS} -> + true; + _ -> + has_subtag(Els, TagName, XMLNS) + end; +has_subtag([], _, _) -> + false. + +-spec get_text([text()]) -> binary(). +get_text([]) -> <<"">>; +get_text([#text{data = undefined}|_]) -> <<"">>; +get_text([#text{data = Data}|_]) -> Data. + +-spec mk_text(binary()) -> [text()]. +mk_text(Text) -> + mk_text(Text, undefined). + +-spec mk_text(binary(), binary() | undefined) -> [text()]. +mk_text(<<"">>, _) -> + []; +mk_text(Text, Lang) -> + [#text{lang = Lang, + data = translate:translate(Lang, Text)}]. + +-spec pp(any()) -> iodata(). +pp(Term) -> + xmpp_codec:pp(Term). + +%%%=================================================================== +%%% Functions to construct general XMPP errors +%%%=================================================================== +-spec err_bad_request() -> error(). +err_bad_request() -> + err(modify, 'bad-request', 400). + +-spec err_bad_request(binary(), binary() | undefined) -> error(). +err_bad_request(Text, Lang) -> + err(modify, 'bad-request', 400, Text, Lang). + +-spec err_bad_format() -> error(). +err_bad_format() -> + err(modify, 'bad-format', 406). + +-spec err_bad_format(binary(), binary() | undefined) -> error(). +err_bad_format(Text, Lang) -> + err(modify, 'bad-format', 406, Text, Lang). + +-spec err_conflict() -> error(). +err_conflict() -> + err(cancel, 'conflict', 409). + +-spec err_conflict(binary(), binary() | undefined) -> error(). +err_conflict(Text, Lang) -> + err(cancel, 'conflict', 409, Text, Lang). + +-spec err_not_allowed() -> error(). +err_not_allowed() -> + err(cancel, 'not-allowed', 405). + +-spec err_not_allowed(binary(), binary() | undefined) -> error(). +err_not_allowed(Text, Lang) -> + err(cancel, 'not-allowed', 405, Text, Lang). + +-spec err_feature_not_implemented() -> error(). +err_feature_not_implemented() -> + err(cancel, 'feature-not-implemented', 501). + +-spec err_feature_not_implemented(binary(), binary() | undefined) -> error(). +err_feature_not_implemented(Text, Lang) -> + err(cancel, 'feature-not-implemented', 501, Text, Lang). + +-spec err_item_not_found() -> error(). +err_item_not_found() -> + err(cancel, 'item-not-found', 404). + +-spec err_item_not_found(binary(), binary() | undefined) -> error(). +err_item_not_found(Text, Lang) -> + err(cancel, 'item-not-found', 404, Text, Lang). + +-spec err_forbidden() -> error(). +err_forbidden() -> + err(auth, 'forbidden', 403). + +-spec err_forbidden(binary(), binary() | undefined) -> error(). +err_forbidden(Text, Lang) -> + err(auth, 'forbidden', 403, Text, Lang). + +-spec err_not_acceptable() -> error(). +err_not_acceptable() -> + err(modify, 'not-acceptable', 406). + +-spec err_not_acceptable(binary(), binary() | undefined) -> error(). +err_not_acceptable(Text, Lang) -> + err(modify, 'not-acceptable', 406, Text, Lang). + +-spec err_internal_server_error() -> error(). +err_internal_server_error() -> + err(wait, 'internal-server-error', 500). + +-spec err_internal_server_error(binary(), binary() | undefined) -> error(). +err_internal_server_error(Text, Lang) -> + err(wait, 'internal-server-error', 500, Text, Lang). + +-spec err_service_unavailable() -> error(). +err_service_unavailable() -> + err(cancel, 'service-unavailable', 503). + +-spec err_service_unavailable(binary(), binary() | undefined) -> error(). +err_service_unavailable(Text, Lang) -> + err(cancel, 'service-unavailable', 503, Text, Lang). + +-spec err_jid_malformed() -> error(). +err_jid_malformed() -> + err(modify, 'jid-malformed', 400). + +-spec err_jid_malformed(binary(), binary() | undefined) -> error(). +err_jid_malformed(Text, Lang) -> + err(modify, 'jid-malformed', 400, Text, Lang). + +-spec err_not_authorized() -> error(). +err_not_authorized() -> + err(auth, 'not-authorized', 401). + +-spec err_not_authorized(binary(), binary() | undefined) -> error(). +err_not_authorized(Text, Lang) -> + err(auth, 'not-authorized', 401, Text, Lang). + +%%%=================================================================== +%%% Functions to construct stream errors +%%%=================================================================== +-spec serr_bad_format() -> stream_error(). +serr_bad_format() -> + serr('bad-format'). + +-spec serr_bad_format(binary(), binary() | undefined) -> stream_error(). +serr_bad_format(Text, Lang) -> + serr('bad-format', Text, Lang). + +-spec serr_bad_namespace_prefix() -> stream_error(). +serr_bad_namespace_prefix() -> + serr('bad-namespace-prefix'). + +-spec serr_bad_namespace_prefix(binary(), binary() | undefined) -> stream_error(). +serr_bad_namespace_prefix(Text, Lang) -> + serr('bad-namespace-prefix', Text, Lang). + +-spec serr_conflict() -> stream_error(). +serr_conflict() -> + serr('conflict'). + +-spec serr_conflict(binary(), binary() | undefined) -> stream_error(). +serr_conflict(Text, Lang) -> + serr('conflict', Text, Lang). + +-spec serr_connection_timeout() -> stream_error(). +serr_connection_timeout() -> + serr('connection-timeout'). + +-spec serr_connection_timeout(binary(), binary() | undefined) -> stream_error(). +serr_connection_timeout(Text, Lang) -> + serr('connection-timeout', Text, Lang). + +-spec serr_host_gone() -> stream_error(). +serr_host_gone() -> + serr('host-gone'). + +-spec serr_host_gone(binary(), binary() | undefined) -> stream_error(). +serr_host_gone(Text, Lang) -> + serr('host-gone', Text, Lang). + +-spec serr_host_unknown() -> stream_error(). +serr_host_unknown() -> + serr('host-unknown'). + +-spec serr_host_unknown(binary(), binary() | undefined) -> stream_error(). +serr_host_unknown(Text, Lang) -> + serr('host-unknown', Text, Lang). + +-spec serr_improper_addressing() -> stream_error(). +serr_improper_addressing() -> + serr('improper-addressing'). + +-spec serr_improper_addressing(binary(), binary() | undefined) -> stream_error(). +serr_improper_addressing(Text, Lang) -> + serr('improper-addressing', Text, Lang). + +-spec serr_internal_server_error() -> stream_error(). +serr_internal_server_error() -> + serr('internal-server-error'). + +-spec serr_internal_server_error(binary(), binary() | undefined) -> stream_error(). +serr_internal_server_error(Text, Lang) -> + serr('internal-server-error', Text, Lang). + +-spec serr_invalid_from() -> stream_error(). +serr_invalid_from() -> + serr('invalid-from'). + +-spec serr_invalid_from(binary(), binary() | undefined) -> stream_error(). +serr_invalid_from(Text, Lang) -> + serr('invalid-from', Text, Lang). + +-spec serr_invalid_id() -> stream_error(). +serr_invalid_id() -> + serr('invalid-id'). + +-spec serr_invalid_id(binary(), binary() | undefined) -> stream_error(). +serr_invalid_id(Text, Lang) -> + serr('invalid-id', Text, Lang). + +-spec serr_invalid_namespace() -> stream_error(). +serr_invalid_namespace() -> + serr('invalid-namespace'). + +-spec serr_invalid_namespace(binary(), binary() | undefined) -> stream_error(). +serr_invalid_namespace(Text, Lang) -> + serr('invalid-namespace', Text, Lang). + +-spec serr_invalid_xml() -> stream_error(). +serr_invalid_xml() -> + serr('invalid-xml'). + +-spec serr_invalid_xml(binary(), binary() | undefined) -> stream_error(). +serr_invalid_xml(Text, Lang) -> + serr('invalid-xml', Text, Lang). + +-spec serr_not_authorized() -> stream_error(). +serr_not_authorized() -> + serr('not-authorized'). + +-spec serr_not_authorized(binary(), binary() | undefined) -> stream_error(). +serr_not_authorized(Text, Lang) -> + serr('not-authorized', Text, Lang). + +-spec serr_not_well_formed() -> stream_error(). +serr_not_well_formed() -> + serr('not-well-formed'). + +-spec serr_not_well_formed(binary(), binary() | undefined) -> stream_error(). +serr_not_well_formed(Text, Lang) -> + serr('not-well-formed', Text, Lang). + +-spec serr_policy_violation() -> stream_error(). +serr_policy_violation() -> + serr('policy-violation'). + +-spec serr_policy_violation(binary(), binary() | undefined) -> stream_error(). +serr_policy_violation(Text, Lang) -> + serr('policy-violation', Text, Lang). + +-spec serr_remote_connection_failed() -> stream_error(). +serr_remote_connection_failed() -> + serr('remote-connection-failed'). + +-spec serr_remote_connection_failed(binary(), binary() | undefined) -> stream_error(). +serr_remote_connection_failed(Text, Lang) -> + serr('remote-connection-failed', Text, Lang). + +-spec serr_reset() -> stream_error(). +serr_reset() -> + serr('reset'). + +-spec serr_reset(binary(), binary() | undefined) -> stream_error(). +serr_reset(Text, Lang) -> + serr('reset', Text, Lang). + +-spec serr_resource_constraint() -> stream_error(). +serr_resource_constraint() -> + serr('resource-constraint'). + +-spec serr_resource_constraint(binary(), binary() | undefined) -> stream_error(). +serr_resource_constraint(Text, Lang) -> + serr('resource-constraint', Text, Lang). + +-spec serr_restricted_xml() -> stream_error(). +serr_restricted_xml() -> + serr('restricted-xml'). + +-spec serr_restricted_xml(binary(), binary() | undefined) -> stream_error(). +serr_restricted_xml(Text, Lang) -> + serr('restricted-xml', Text, Lang). + +-spec serr_see_other_host() -> stream_error(). +serr_see_other_host() -> + serr('see-other-host'). + +-spec serr_see_other_host(binary(), binary() | undefined) -> stream_error(). +serr_see_other_host(Text, Lang) -> + serr('see-other-host', Text, Lang). + +-spec serr_system_shutdown() -> stream_error(). +serr_system_shutdown() -> + serr('system-shutdown'). + +-spec serr_system_shutdown(binary(), binary() | undefined) -> stream_error(). +serr_system_shutdown(Text, Lang) -> + serr('system-shutdown', Text, Lang). + +-spec serr_undefined_condition() -> stream_error(). +serr_undefined_condition() -> + serr('undefined-condition'). + +-spec serr_undefined_condition(binary(), binary() | undefined) -> stream_error(). +serr_undefined_condition(Text, Lang) -> + serr('undefined-condition', Text, Lang). + +-spec serr_unsupported_encoding() -> stream_error(). +serr_unsupported_encoding() -> + serr('unsupported-encoding'). + +-spec serr_unsupported_encoding(binary(), binary() | undefined) -> stream_error(). +serr_unsupported_encoding(Text, Lang) -> + serr('unsupported-encoding', Text, Lang). + +-spec serr_unsupported_stanza_type() -> stream_error(). +serr_unsupported_stanza_type() -> + serr('unsupported-stanza-type'). + +-spec serr_unsupported_stanza_type(binary(), binary() | undefined) -> stream_error(). +serr_unsupported_stanza_type(Text, Lang) -> + serr('unsupported-stanza-type', Text, Lang). + +-spec serr_unsupported_version() -> stream_error(). +serr_unsupported_version() -> + serr('unsupported-version'). + +-spec serr_unsupported_version(binary(), binary() | undefined) -> stream_error(). +serr_unsupported_version(Text, Lang) -> + serr('unsupported-version', Text, Lang). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +-spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', + atom() | gone() | redirect(), non_neg_integer()) -> error(). +err(Type, Reason, Code) -> + #error{type = Type, reason = Reason, code = Code}. + +-spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', + atom() | gone() | redirect(), non_neg_integer(), + binary(), binary() | undefined) -> error(). +err(Type, Reason, Code, Text, Lang) -> + #error{type = Type, reason = Reason, code = Code, + text = #text{lang = Lang, + data = translate:translate(Lang, Text)}}. + +-spec serr(atom() | 'see-other-host'()) -> stream_error(). +serr(Reason) -> + #stream_error{reason = Reason}. + +-spec serr(atom() | 'see-other-host'(), binary(), + binary() | undefined) -> stream_error(). +serr(Reason, Text, Lang) -> + #stream_error{reason = Reason, + text = #text{lang = Lang, + data = translate:translate(Lang, Text)}}. + +-spec add_ns(xmlel()) -> xmlel(). +add_ns(#xmlel{name = Name} = El) when Name == <<"message">>; + Name == <<"presence">>; + Name == <<"iq">> -> + Attrs = lists:keystore(<<"xmlns">>, 1, El#xmlel.attrs, + {<<"xmlns">>, ?NS_CLIENT}), + El#xmlel{attrs = Attrs}; +add_ns(El) -> + El. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl new file mode 100644 index 000000000..568c5fbc7 --- /dev/null +++ b/src/xmpp_codec.erl @@ -0,0 +1,23222 @@ +%% Created automatically by XML generator (fxml_gen.erl) +%% Source: xmpp_codec.spec + +-module(xmpp_codec). + +-compile({nowarn_unused_function, + [{dec_int, 3}, {dec_int, 1}, {dec_enum, 2}, + {enc_int, 1}, {get_attr, 2}, {enc_enum, 1}]}). + +-export([pp/1, format_error/1, decode/1, decode/2, + is_known_tag/1, encode/1, get_name/1, get_ns/1]). + +decode(_el) -> decode(_el, []). + +decode({xmlel, _name, _attrs, _} = _el, Opts) -> + IgnoreEls = proplists:get_bool(ignore_els, Opts), + case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"query">>, <<"jabber:iq:search">>} -> + decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); + {<<"item">>, <<"jabber:iq:search">>} -> + decode_search_item(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"email">>, <<"jabber:iq:search">>} -> + decode_search_email(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"nick">>, <<"jabber:iq:search">>} -> + decode_search_nick(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"last">>, <<"jabber:iq:search">>} -> + decode_search_last(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"first">>, <<"jabber:iq:search">>} -> + decode_search_first(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"instructions">>, <<"jabber:iq:search">>} -> + decode_search_instructions(<<"jabber:iq:search">>, + IgnoreEls, _el); + {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> + decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, + IgnoreEls, _el); + {<<"store">>, <<"urn:xmpp:hints">>} -> + decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); + {<<"no-store">>, <<"urn:xmpp:hints">>} -> + decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, + _el); + {<<"no-copy">>, <<"urn:xmpp:hints">>} -> + decode_hint_no_copy(<<"urn:xmpp:hints">>, IgnoreEls, + _el); + {<<"participant">>, <<"urn:xmpp:mix:0">>} -> + decode_mix_participant(<<"urn:xmpp:mix:0">>, IgnoreEls, + _el); + {<<"leave">>, <<"urn:xmpp:mix:0">>} -> + decode_mix_leave(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); + {<<"join">>, <<"urn:xmpp:mix:0">>} -> + decode_mix_join(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); + {<<"subscribe">>, <<"urn:xmpp:mix:0">>} -> + decode_mix_subscribe(<<"urn:xmpp:mix:0">>, IgnoreEls, + _el); + {<<"offline">>, + <<"http://jabber.org/protocol/offline">>} -> + decode_offline(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/offline">>} -> + decode_offline_item(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"fetch">>, + <<"http://jabber.org/protocol/offline">>} -> + decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"purge">>, + <<"http://jabber.org/protocol/offline">>} -> + decode_offline_purge(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"failed">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"failed">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_failed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"a">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_a(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"a">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_a(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"r">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_r(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"r">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_r(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"resumed">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_resumed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"resumed">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_resumed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"resume">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_resume(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"resume">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_resume(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"enabled">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_enabled(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"enabled">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_enabled(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"enable">>, <<"urn:xmpp:sm:2">>} -> + decode_sm_enable(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"enable">>, <<"urn:xmpp:sm:3">>} -> + decode_sm_enable(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"sm">>, <<"urn:xmpp:sm:2">>} -> + decode_feature_sm(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"sm">>, <<"urn:xmpp:sm:3">>} -> + decode_feature_sm(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"inactive">>, <<"urn:xmpp:csi:0">>} -> + decode_csi_inactive(<<"urn:xmpp:csi:0">>, IgnoreEls, + _el); + {<<"active">>, <<"urn:xmpp:csi:0">>} -> + decode_csi_active(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); + {<<"csi">>, <<"urn:xmpp:csi:0">>} -> + decode_feature_csi(<<"urn:xmpp:csi:0">>, IgnoreEls, + _el); + {<<"sent">>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_sent(<<"urn:xmpp:carbons:2">>, IgnoreEls, + _el); + {<<"received">>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_received(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"private">>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_private(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"enable">>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_enable(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"disable">>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_disable(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"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:1">>} -> + decode_mam_prefs(<<"urn:xmpp:mam:1">>, 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:1">>} -> + decode_mam_result(<<"urn:xmpp:mam:1">>, 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:1">>} -> + decode_mam_query(<<"urn:xmpp:mam:1">>, 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); + {<<"query">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_admin_reason(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"continue">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"actor">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"query">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_owner_destroy(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_owner_reason(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"password">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_owner_password(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"status">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"continue">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"actor">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"invite">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_destroy(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"decline">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"reason">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> + decode_muc_history(<<"http://jabber.org/protocol/muc">>, + IgnoreEls, _el); + {<<"query">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + decode_bytestreams(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"activate">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"streamhost-used">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"streamhost">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"delay">>, <<"urn:xmpp:delay">>} -> + decode_delay(<<"urn:xmpp:delay">>, IgnoreEls, _el); + {<<"paused">>, + <<"http://jabber.org/protocol/chatstates">>} -> + decode_chatstate_paused(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"inactive">>, + <<"http://jabber.org/protocol/chatstates">>} -> + decode_chatstate_inactive(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"gone">>, + <<"http://jabber.org/protocol/chatstates">>} -> + decode_chatstate_gone(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"composing">>, + <<"http://jabber.org/protocol/chatstates">>} -> + decode_chatstate_composing(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"active">>, + <<"http://jabber.org/protocol/chatstates">>} -> + decode_chatstate_active(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"headers">>, + <<"http://jabber.org/protocol/shim">>} -> + decode_shim_headers(<<"http://jabber.org/protocol/shim">>, + IgnoreEls, _el); + {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> + decode_shim_header(<<"http://jabber.org/protocol/shim">>, + IgnoreEls, _el); + {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"retract">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"options">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"publish">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"unsubscribe">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscribe">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"event">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"items">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_event_items(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_event_item(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"retract">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"items">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"x">>, <<"jabber:x:data">>} -> + decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"item">>, <<"jabber:x:data">>} -> + decode_xdata_item(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"reported">>, <<"jabber:x:data">>} -> + decode_xdata_reported(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"title">>, <<"jabber:x:data">>} -> + decode_xdata_title(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"instructions">>, <<"jabber:x:data">>} -> + decode_xdata_instructions(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"field">>, <<"jabber:x:data">>} -> + decode_xdata_field(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"option">>, <<"jabber:x:data">>} -> + decode_xdata_field_option(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"value">>, <<"jabber:x:data">>} -> + decode_xdata_field_value(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"desc">>, <<"jabber:x:data">>} -> + decode_xdata_field_desc(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"required">>, <<"jabber:x:data">>} -> + decode_xdata_field_required(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"x">>, <<"vcard-temp:x:update">>} -> + decode_vcard_xupdate(<<"vcard-temp:x:update">>, + IgnoreEls, _el); + {<<"photo">>, <<"vcard-temp:x:update">>} -> + decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, + IgnoreEls, _el); + {<<"vCard">>, <<"vcard-temp">>} -> + decode_vcard_temp(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CLASS">>, <<"vcard-temp">>} -> + decode_vcard_CLASS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CATEGORIES">>, <<"vcard-temp">>} -> + decode_vcard_CATEGORIES(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"KEY">>, <<"vcard-temp">>} -> + decode_vcard_KEY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"SOUND">>, <<"vcard-temp">>} -> + decode_vcard_SOUND(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORG">>, <<"vcard-temp">>} -> + decode_vcard_ORG(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PHOTO">>, <<"vcard-temp">>} -> + decode_vcard_PHOTO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOGO">>, <<"vcard-temp">>} -> + decode_vcard_LOGO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"BINVAL">>, <<"vcard-temp">>} -> + decode_vcard_BINVAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"GEO">>, <<"vcard-temp">>} -> + decode_vcard_GEO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EMAIL">>, <<"vcard-temp">>} -> + decode_vcard_EMAIL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TEL">>, <<"vcard-temp">>} -> + decode_vcard_TEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LABEL">>, <<"vcard-temp">>} -> + decode_vcard_LABEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ADR">>, <<"vcard-temp">>} -> + decode_vcard_ADR(<<"vcard-temp">>, IgnoreEls, _el); + {<<"N">>, <<"vcard-temp">>} -> + decode_vcard_N(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CONFIDENTIAL">>, <<"vcard-temp">>} -> + decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"PRIVATE">>, <<"vcard-temp">>} -> + decode_vcard_PRIVATE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PUBLIC">>, <<"vcard-temp">>} -> + decode_vcard_PUBLIC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTVAL">>, <<"vcard-temp">>} -> + decode_vcard_EXTVAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TYPE">>, <<"vcard-temp">>} -> + decode_vcard_TYPE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"DESC">>, <<"vcard-temp">>} -> + decode_vcard_DESC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"URL">>, <<"vcard-temp">>} -> + decode_vcard_URL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"UID">>, <<"vcard-temp">>} -> + decode_vcard_UID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"SORT-STRING">>, <<"vcard-temp">>} -> + decode_vcard_SORT_STRING(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"REV">>, <<"vcard-temp">>} -> + decode_vcard_REV(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PRODID">>, <<"vcard-temp">>} -> + decode_vcard_PRODID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"NOTE">>, <<"vcard-temp">>} -> + decode_vcard_NOTE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"KEYWORD">>, <<"vcard-temp">>} -> + decode_vcard_KEYWORD(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ROLE">>, <<"vcard-temp">>} -> + decode_vcard_ROLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TITLE">>, <<"vcard-temp">>} -> + decode_vcard_TITLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TZ">>, <<"vcard-temp">>} -> + decode_vcard_TZ(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MAILER">>, <<"vcard-temp">>} -> + decode_vcard_MAILER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"JABBERID">>, <<"vcard-temp">>} -> + decode_vcard_JABBERID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"BDAY">>, <<"vcard-temp">>} -> + decode_vcard_BDAY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"NICKNAME">>, <<"vcard-temp">>} -> + decode_vcard_NICKNAME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FN">>, <<"vcard-temp">>} -> + decode_vcard_FN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"VERSION">>, <<"vcard-temp">>} -> + decode_vcard_VERSION(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CRED">>, <<"vcard-temp">>} -> + decode_vcard_CRED(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PHONETIC">>, <<"vcard-temp">>} -> + decode_vcard_PHONETIC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORGUNIT">>, <<"vcard-temp">>} -> + decode_vcard_ORGUNIT(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORGNAME">>, <<"vcard-temp">>} -> + decode_vcard_ORGNAME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LON">>, <<"vcard-temp">>} -> + decode_vcard_LON(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LAT">>, <<"vcard-temp">>} -> + decode_vcard_LAT(<<"vcard-temp">>, IgnoreEls, _el); + {<<"USERID">>, <<"vcard-temp">>} -> + decode_vcard_USERID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"NUMBER">>, <<"vcard-temp">>} -> + decode_vcard_NUMBER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LINE">>, <<"vcard-temp">>} -> + decode_vcard_LINE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CTRY">>, <<"vcard-temp">>} -> + decode_vcard_CTRY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCODE">>, <<"vcard-temp">>} -> + decode_vcard_PCODE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"REGION">>, <<"vcard-temp">>} -> + decode_vcard_REGION(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOCALITY">>, <<"vcard-temp">>} -> + decode_vcard_LOCALITY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"STREET">>, <<"vcard-temp">>} -> + decode_vcard_STREET(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTADD">>, <<"vcard-temp">>} -> + decode_vcard_EXTADD(<<"vcard-temp">>, IgnoreEls, _el); + {<<"POBOX">>, <<"vcard-temp">>} -> + decode_vcard_POBOX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"SUFFIX">>, <<"vcard-temp">>} -> + decode_vcard_SUFFIX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PREFIX">>, <<"vcard-temp">>} -> + decode_vcard_PREFIX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MIDDLE">>, <<"vcard-temp">>} -> + decode_vcard_MIDDLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"GIVEN">>, <<"vcard-temp">>} -> + decode_vcard_GIVEN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAMILY">>, <<"vcard-temp">>} -> + decode_vcard_FAMILY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"X400">>, <<"vcard-temp">>} -> + decode_vcard_X400(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTERNET">>, <<"vcard-temp">>} -> + decode_vcard_INTERNET(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PREF">>, <<"vcard-temp">>} -> + decode_vcard_PREF(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTL">>, <<"vcard-temp">>} -> + decode_vcard_INTL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"DOM">>, <<"vcard-temp">>} -> + decode_vcard_DOM(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PARCEL">>, <<"vcard-temp">>} -> + decode_vcard_PARCEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"POSTAL">>, <<"vcard-temp">>} -> + decode_vcard_POSTAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCS">>, <<"vcard-temp">>} -> + decode_vcard_PCS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ISDN">>, <<"vcard-temp">>} -> + decode_vcard_ISDN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MODEM">>, <<"vcard-temp">>} -> + decode_vcard_MODEM(<<"vcard-temp">>, IgnoreEls, _el); + {<<"BBS">>, <<"vcard-temp">>} -> + decode_vcard_BBS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"VIDEO">>, <<"vcard-temp">>} -> + decode_vcard_VIDEO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CELL">>, <<"vcard-temp">>} -> + decode_vcard_CELL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MSG">>, <<"vcard-temp">>} -> + decode_vcard_MSG(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PAGER">>, <<"vcard-temp">>} -> + decode_vcard_PAGER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAX">>, <<"vcard-temp">>} -> + decode_vcard_FAX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"VOICE">>, <<"vcard-temp">>} -> + decode_vcard_VOICE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"WORK">>, <<"vcard-temp">>} -> + decode_vcard_WORK(<<"vcard-temp">>, IgnoreEls, _el); + {<<"HOME">>, <<"vcard-temp">>} -> + decode_vcard_HOME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"stream:error">>, + <<"http://etherx.jabber.org/streams">>} -> + decode_stream_error(<<"http://etherx.jabber.org/streams">>, + IgnoreEls, _el); + {<<"unsupported-version">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"unsupported-stanza-type">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"unsupported-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"system-shutdown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"see-other-host">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"restricted-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"reset">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"remote-connection-failed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"not-well-formed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-namespace">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-id">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-from">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"improper-addressing">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"host-unknown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"host-gone">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"connection-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"bad-namespace-prefix">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"bad-format">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"text">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"time">>, <<"urn:xmpp:time">>} -> + decode_time(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"tzo">>, <<"urn:xmpp:time">>} -> + decode_time_tzo(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"utc">>, <<"urn:xmpp:time">>} -> + decode_time_utc(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"ping">>, <<"urn:xmpp:ping">>} -> + decode_ping(<<"urn:xmpp:ping">>, IgnoreEls, _el); + {<<"session">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>} -> + decode_session(<<"urn:ietf:params:xml:ns:xmpp-session">>, + IgnoreEls, _el); + {<<"optional">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>} -> + decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, + IgnoreEls, _el); + {<<"query">>, <<"jabber:iq:register">>} -> + decode_register(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"key">>, <<"jabber:iq:register">>} -> + decode_register_key(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"text">>, <<"jabber:iq:register">>} -> + decode_register_text(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"misc">>, <<"jabber:iq:register">>} -> + decode_register_misc(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"date">>, <<"jabber:iq:register">>} -> + decode_register_date(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"url">>, <<"jabber:iq:register">>} -> + decode_register_url(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"phone">>, <<"jabber:iq:register">>} -> + decode_register_phone(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"zip">>, <<"jabber:iq:register">>} -> + decode_register_zip(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"state">>, <<"jabber:iq:register">>} -> + decode_register_state(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"city">>, <<"jabber:iq:register">>} -> + decode_register_city(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"address">>, <<"jabber:iq:register">>} -> + decode_register_address(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"email">>, <<"jabber:iq:register">>} -> + decode_register_email(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"last">>, <<"jabber:iq:register">>} -> + decode_register_last(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"first">>, <<"jabber:iq:register">>} -> + decode_register_first(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"name">>, <<"jabber:iq:register">>} -> + decode_register_name(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"password">>, <<"jabber:iq:register">>} -> + decode_register_password(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"nick">>, <<"jabber:iq:register">>} -> + decode_register_nick(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"username">>, <<"jabber:iq:register">>} -> + decode_register_username(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"instructions">>, <<"jabber:iq:register">>} -> + decode_register_instructions(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"remove">>, <<"jabber:iq:register">>} -> + decode_register_remove(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"registered">>, <<"jabber:iq:register">>} -> + decode_register_registered(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"register">>, + <<"http://jabber.org/features/iq-register">>} -> + decode_feature_register(<<"http://jabber.org/features/iq-register">>, + IgnoreEls, _el); + {<<"c">>, <<"http://jabber.org/protocol/caps">>} -> + decode_caps(<<"http://jabber.org/protocol/caps">>, + IgnoreEls, _el); + {<<"ack">>, <<"p1:ack">>} -> + decode_p1_ack(<<"p1:ack">>, IgnoreEls, _el); + {<<"rebind">>, <<"p1:rebind">>} -> + decode_p1_rebind(<<"p1:rebind">>, IgnoreEls, _el); + {<<"push">>, <<"p1:push">>} -> + decode_p1_push(<<"p1:push">>, IgnoreEls, _el); + {<<"stream:features">>, + <<"http://etherx.jabber.org/streams">>} -> + decode_stream_features(<<"http://etherx.jabber.org/streams">>, + IgnoreEls, _el); + {<<"compression">>, + <<"http://jabber.org/features/compress">>} -> + decode_compression(<<"http://jabber.org/features/compress">>, + IgnoreEls, _el); + {<<"method">>, + <<"http://jabber.org/features/compress">>} -> + decode_compression_method(<<"http://jabber.org/features/compress">>, + IgnoreEls, _el); + {<<"compressed">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compressed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"compress">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"method">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress_method(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"failure">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress_failure(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"unsupported-method">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"processing-failed">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"setup-failed">>, + <<"http://jabber.org/protocol/compress">>} -> + decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"failure">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + decode_starttls_failure(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"proceed">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + decode_starttls_proceed(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"starttls">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + decode_starttls(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"required">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"mechanisms">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_mechanisms(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"temporary-auth-failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"bad-protocol">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"mechanism-too-weak">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"malformed-request">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"invalid-mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"invalid-authzid">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"incorrect-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"encryption-required">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"credentials-expired">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"account-disabled">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"aborted">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"success">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_success(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"response">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_response(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"challenge">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_challenge(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_abort(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + decode_sasl_auth(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"query">>, <<"jabber:iq:auth">>} -> + decode_legacy_auth(<<"jabber:iq:auth">>, IgnoreEls, + _el); + {<<"resource">>, <<"jabber:iq:auth">>} -> + decode_legacy_auth_resource(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"digest">>, <<"jabber:iq:auth">>} -> + decode_legacy_auth_digest(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"password">>, <<"jabber:iq:auth">>} -> + decode_legacy_auth_password(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"username">>, <<"jabber:iq:auth">>} -> + decode_legacy_auth_username(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + decode_bind(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"resource">>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"error">>, <<"jabber:client">>} -> + decode_error(<<"jabber:client">>, IgnoreEls, _el); + {<<"text">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"unexpected-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"subscription-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"service-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"remote-server-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"remote-server-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"registration-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"redirect">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"recipient-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-allowed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-acceptable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"jid-malformed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"item-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"gone">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"forbidden">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"feature-not-implemented">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"bad-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"presence">>, <<"jabber:client">>} -> + decode_presence(<<"jabber:client">>, IgnoreEls, _el); + {<<"priority">>, <<"jabber:client">>} -> + decode_presence_priority(<<"jabber:client">>, IgnoreEls, + _el); + {<<"status">>, <<"jabber:client">>} -> + decode_presence_status(<<"jabber:client">>, IgnoreEls, + _el); + {<<"show">>, <<"jabber:client">>} -> + decode_presence_show(<<"jabber:client">>, IgnoreEls, + _el); + {<<"message">>, <<"jabber:client">>} -> + decode_message(<<"jabber:client">>, IgnoreEls, _el); + {<<"thread">>, <<"jabber:client">>} -> + decode_message_thread(<<"jabber:client">>, IgnoreEls, + _el); + {<<"body">>, <<"jabber:client">>} -> + decode_message_body(<<"jabber:client">>, IgnoreEls, + _el); + {<<"subject">>, <<"jabber:client">>} -> + decode_message_subject(<<"jabber:client">>, IgnoreEls, + _el); + {<<"iq">>, <<"jabber:client">>} -> + decode_iq(<<"jabber:client">>, IgnoreEls, _el); + {<<"query">>, <<"http://jabber.org/protocol/stats">>} -> + decode_stats(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"stat">>, <<"http://jabber.org/protocol/stats">>} -> + decode_stat(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"error">>, <<"http://jabber.org/protocol/stats">>} -> + decode_stat_error(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"storage">>, <<"storage:bookmarks">>} -> + decode_bookmarks_storage(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"url">>, <<"storage:bookmarks">>} -> + decode_bookmark_url(<<"storage:bookmarks">>, IgnoreEls, + _el); + {<<"conference">>, <<"storage:bookmarks">>} -> + decode_bookmark_conference(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"password">>, <<"storage:bookmarks">>} -> + decode_conference_password(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"nick">>, <<"storage:bookmarks">>} -> + decode_conference_nick(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"query">>, <<"jabber:iq:private">>} -> + decode_private(<<"jabber:iq:private">>, IgnoreEls, _el); + {<<"query">>, + <<"http://jabber.org/protocol/disco#items">>} -> + decode_disco_items(<<"http://jabber.org/protocol/disco#items">>, + IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/disco#items">>} -> + decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, + IgnoreEls, _el); + {<<"query">>, + <<"http://jabber.org/protocol/disco#info">>} -> + decode_disco_info(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"feature">>, + <<"http://jabber.org/protocol/disco#info">>} -> + decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"identity">>, + <<"http://jabber.org/protocol/disco#info">>} -> + decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"blocklist">>, <<"urn:xmpp:blocking">>} -> + decode_block_list(<<"urn:xmpp:blocking">>, IgnoreEls, + _el); + {<<"unblock">>, <<"urn:xmpp:blocking">>} -> + decode_unblock(<<"urn:xmpp:blocking">>, IgnoreEls, _el); + {<<"block">>, <<"urn:xmpp:blocking">>} -> + decode_block(<<"urn:xmpp:blocking">>, IgnoreEls, _el); + {<<"item">>, <<"urn:xmpp:blocking">>} -> + decode_block_item(<<"urn:xmpp:blocking">>, IgnoreEls, + _el); + {<<"query">>, <<"jabber:iq:privacy">>} -> + decode_privacy(<<"jabber:iq:privacy">>, IgnoreEls, _el); + {<<"active">>, <<"jabber:iq:privacy">>} -> + decode_privacy_active_list(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"default">>, <<"jabber:iq:privacy">>} -> + decode_privacy_default_list(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"list">>, <<"jabber:iq:privacy">>} -> + decode_privacy_list(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"item">>, <<"jabber:iq:privacy">>} -> + decode_privacy_item(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"presence-out">>, <<"jabber:iq:privacy">>} -> + decode_privacy_presence_out(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"presence-in">>, <<"jabber:iq:privacy">>} -> + decode_privacy_presence_in(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"iq">>, <<"jabber:iq:privacy">>} -> + decode_privacy_iq(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"message">>, <<"jabber:iq:privacy">>} -> + decode_privacy_message(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"ver">>, <<"urn:xmpp:features:rosterver">>} -> + decode_rosterver_feature(<<"urn:xmpp:features:rosterver">>, + IgnoreEls, _el); + {<<"query">>, <<"jabber:iq:roster">>} -> + decode_roster_query(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"item">>, <<"jabber:iq:roster">>} -> + decode_roster_item(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"group">>, <<"jabber:iq:roster">>} -> + decode_roster_group(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"query">>, <<"jabber:iq:version">>} -> + decode_version(<<"jabber:iq:version">>, IgnoreEls, _el); + {<<"os">>, <<"jabber:iq:version">>} -> + decode_version_os(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"version">>, <<"jabber:iq:version">>} -> + decode_version_ver(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"name">>, <<"jabber:iq:version">>} -> + decode_version_name(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"query">>, <<"jabber:iq:last">>} -> + decode_last(<<"jabber:iq:last">>, IgnoreEls, _el); + {_name, _xmlns} -> + erlang:error({xmpp_codec, {unknown_tag, _name, _xmlns}}) + end. + +is_known_tag({xmlel, _name, _attrs, _} = _el) -> + case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"query">>, <<"jabber:iq:search">>} -> true; + {<<"item">>, <<"jabber:iq:search">>} -> true; + {<<"email">>, <<"jabber:iq:search">>} -> true; + {<<"nick">>, <<"jabber:iq:search">>} -> true; + {<<"last">>, <<"jabber:iq:search">>} -> true; + {<<"first">>, <<"jabber:iq:search">>} -> true; + {<<"instructions">>, <<"jabber:iq:search">>} -> true; + {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> + true; + {<<"store">>, <<"urn:xmpp:hints">>} -> true; + {<<"no-store">>, <<"urn:xmpp:hints">>} -> true; + {<<"no-copy">>, <<"urn:xmpp:hints">>} -> true; + {<<"participant">>, <<"urn:xmpp:mix:0">>} -> true; + {<<"leave">>, <<"urn:xmpp:mix:0">>} -> true; + {<<"join">>, <<"urn:xmpp:mix:0">>} -> true; + {<<"subscribe">>, <<"urn:xmpp:mix:0">>} -> true; + {<<"offline">>, + <<"http://jabber.org/protocol/offline">>} -> + true; + {<<"item">>, + <<"http://jabber.org/protocol/offline">>} -> + true; + {<<"fetch">>, + <<"http://jabber.org/protocol/offline">>} -> + true; + {<<"purge">>, + <<"http://jabber.org/protocol/offline">>} -> + true; + {<<"failed">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"failed">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"a">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"a">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"r">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"r">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"resumed">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"resumed">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"resume">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"resume">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"enabled">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"enabled">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"enable">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"enable">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"sm">>, <<"urn:xmpp:sm:2">>} -> true; + {<<"sm">>, <<"urn:xmpp:sm:3">>} -> true; + {<<"inactive">>, <<"urn:xmpp:csi:0">>} -> true; + {<<"active">>, <<"urn:xmpp:csi:0">>} -> true; + {<<"csi">>, <<"urn:xmpp:csi:0">>} -> true; + {<<"sent">>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"received">>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"private">>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"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:1">>} -> 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:1">>} -> true; + {<<"result">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"archived">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"query">>, <<"urn:xmpp:mam:0">>} -> true; + {<<"query">>, <<"urn:xmpp:mam:1">>} -> 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">>} -> + true; + {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + true; + {<<"continue">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + true; + {<<"actor">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + true; + {<<"item">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + true; + {<<"query">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; + {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; + {<<"password">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; + {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"item">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"status">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"continue">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"actor">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"invite">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"decline">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"reason">>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> + true; + {<<"query">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + true; + {<<"activate">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + true; + {<<"streamhost-used">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + true; + {<<"streamhost">>, + <<"http://jabber.org/protocol/bytestreams">>} -> + true; + {<<"delay">>, <<"urn:xmpp:delay">>} -> true; + {<<"paused">>, + <<"http://jabber.org/protocol/chatstates">>} -> + true; + {<<"inactive">>, + <<"http://jabber.org/protocol/chatstates">>} -> + true; + {<<"gone">>, + <<"http://jabber.org/protocol/chatstates">>} -> + true; + {<<"composing">>, + <<"http://jabber.org/protocol/chatstates">>} -> + true; + {<<"active">>, + <<"http://jabber.org/protocol/chatstates">>} -> + true; + {<<"headers">>, + <<"http://jabber.org/protocol/shim">>} -> + true; + {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> + true; + {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"retract">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"options">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"publish">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"unsubscribe">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"subscribe">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"event">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"items">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"item">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"retract">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"items">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"x">>, <<"jabber:x:data">>} -> true; + {<<"item">>, <<"jabber:x:data">>} -> true; + {<<"reported">>, <<"jabber:x:data">>} -> true; + {<<"title">>, <<"jabber:x:data">>} -> true; + {<<"instructions">>, <<"jabber:x:data">>} -> true; + {<<"field">>, <<"jabber:x:data">>} -> true; + {<<"option">>, <<"jabber:x:data">>} -> true; + {<<"value">>, <<"jabber:x:data">>} -> true; + {<<"desc">>, <<"jabber:x:data">>} -> true; + {<<"required">>, <<"jabber:x:data">>} -> true; + {<<"x">>, <<"vcard-temp:x:update">>} -> true; + {<<"photo">>, <<"vcard-temp:x:update">>} -> true; + {<<"vCard">>, <<"vcard-temp">>} -> true; + {<<"CLASS">>, <<"vcard-temp">>} -> true; + {<<"CATEGORIES">>, <<"vcard-temp">>} -> true; + {<<"KEY">>, <<"vcard-temp">>} -> true; + {<<"SOUND">>, <<"vcard-temp">>} -> true; + {<<"ORG">>, <<"vcard-temp">>} -> true; + {<<"PHOTO">>, <<"vcard-temp">>} -> true; + {<<"LOGO">>, <<"vcard-temp">>} -> true; + {<<"BINVAL">>, <<"vcard-temp">>} -> true; + {<<"GEO">>, <<"vcard-temp">>} -> true; + {<<"EMAIL">>, <<"vcard-temp">>} -> true; + {<<"TEL">>, <<"vcard-temp">>} -> true; + {<<"LABEL">>, <<"vcard-temp">>} -> true; + {<<"ADR">>, <<"vcard-temp">>} -> true; + {<<"N">>, <<"vcard-temp">>} -> true; + {<<"CONFIDENTIAL">>, <<"vcard-temp">>} -> true; + {<<"PRIVATE">>, <<"vcard-temp">>} -> true; + {<<"PUBLIC">>, <<"vcard-temp">>} -> true; + {<<"EXTVAL">>, <<"vcard-temp">>} -> true; + {<<"TYPE">>, <<"vcard-temp">>} -> true; + {<<"DESC">>, <<"vcard-temp">>} -> true; + {<<"URL">>, <<"vcard-temp">>} -> true; + {<<"UID">>, <<"vcard-temp">>} -> true; + {<<"SORT-STRING">>, <<"vcard-temp">>} -> true; + {<<"REV">>, <<"vcard-temp">>} -> true; + {<<"PRODID">>, <<"vcard-temp">>} -> true; + {<<"NOTE">>, <<"vcard-temp">>} -> true; + {<<"KEYWORD">>, <<"vcard-temp">>} -> true; + {<<"ROLE">>, <<"vcard-temp">>} -> true; + {<<"TITLE">>, <<"vcard-temp">>} -> true; + {<<"TZ">>, <<"vcard-temp">>} -> true; + {<<"MAILER">>, <<"vcard-temp">>} -> true; + {<<"JABBERID">>, <<"vcard-temp">>} -> true; + {<<"BDAY">>, <<"vcard-temp">>} -> true; + {<<"NICKNAME">>, <<"vcard-temp">>} -> true; + {<<"FN">>, <<"vcard-temp">>} -> true; + {<<"VERSION">>, <<"vcard-temp">>} -> true; + {<<"CRED">>, <<"vcard-temp">>} -> true; + {<<"PHONETIC">>, <<"vcard-temp">>} -> true; + {<<"ORGUNIT">>, <<"vcard-temp">>} -> true; + {<<"ORGNAME">>, <<"vcard-temp">>} -> true; + {<<"LON">>, <<"vcard-temp">>} -> true; + {<<"LAT">>, <<"vcard-temp">>} -> true; + {<<"USERID">>, <<"vcard-temp">>} -> true; + {<<"NUMBER">>, <<"vcard-temp">>} -> true; + {<<"LINE">>, <<"vcard-temp">>} -> true; + {<<"CTRY">>, <<"vcard-temp">>} -> true; + {<<"PCODE">>, <<"vcard-temp">>} -> true; + {<<"REGION">>, <<"vcard-temp">>} -> true; + {<<"LOCALITY">>, <<"vcard-temp">>} -> true; + {<<"STREET">>, <<"vcard-temp">>} -> true; + {<<"EXTADD">>, <<"vcard-temp">>} -> true; + {<<"POBOX">>, <<"vcard-temp">>} -> true; + {<<"SUFFIX">>, <<"vcard-temp">>} -> true; + {<<"PREFIX">>, <<"vcard-temp">>} -> true; + {<<"MIDDLE">>, <<"vcard-temp">>} -> true; + {<<"GIVEN">>, <<"vcard-temp">>} -> true; + {<<"FAMILY">>, <<"vcard-temp">>} -> true; + {<<"X400">>, <<"vcard-temp">>} -> true; + {<<"INTERNET">>, <<"vcard-temp">>} -> true; + {<<"PREF">>, <<"vcard-temp">>} -> true; + {<<"INTL">>, <<"vcard-temp">>} -> true; + {<<"DOM">>, <<"vcard-temp">>} -> true; + {<<"PARCEL">>, <<"vcard-temp">>} -> true; + {<<"POSTAL">>, <<"vcard-temp">>} -> true; + {<<"PCS">>, <<"vcard-temp">>} -> true; + {<<"ISDN">>, <<"vcard-temp">>} -> true; + {<<"MODEM">>, <<"vcard-temp">>} -> true; + {<<"BBS">>, <<"vcard-temp">>} -> true; + {<<"VIDEO">>, <<"vcard-temp">>} -> true; + {<<"CELL">>, <<"vcard-temp">>} -> true; + {<<"MSG">>, <<"vcard-temp">>} -> true; + {<<"PAGER">>, <<"vcard-temp">>} -> true; + {<<"FAX">>, <<"vcard-temp">>} -> true; + {<<"VOICE">>, <<"vcard-temp">>} -> true; + {<<"WORK">>, <<"vcard-temp">>} -> true; + {<<"HOME">>, <<"vcard-temp">>} -> true; + {<<"stream:error">>, + <<"http://etherx.jabber.org/streams">>} -> + true; + {<<"unsupported-version">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"unsupported-stanza-type">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"unsupported-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"system-shutdown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"see-other-host">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"restricted-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"reset">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"remote-connection-failed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"not-well-formed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"invalid-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"invalid-namespace">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"invalid-id">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"invalid-from">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"improper-addressing">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"host-unknown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"host-gone">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"connection-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"bad-namespace-prefix">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"bad-format">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"text">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> + true; + {<<"time">>, <<"urn:xmpp:time">>} -> true; + {<<"tzo">>, <<"urn:xmpp:time">>} -> true; + {<<"utc">>, <<"urn:xmpp:time">>} -> true; + {<<"ping">>, <<"urn:xmpp:ping">>} -> true; + {<<"session">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>} -> + true; + {<<"optional">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>} -> + true; + {<<"query">>, <<"jabber:iq:register">>} -> true; + {<<"key">>, <<"jabber:iq:register">>} -> true; + {<<"text">>, <<"jabber:iq:register">>} -> true; + {<<"misc">>, <<"jabber:iq:register">>} -> true; + {<<"date">>, <<"jabber:iq:register">>} -> true; + {<<"url">>, <<"jabber:iq:register">>} -> true; + {<<"phone">>, <<"jabber:iq:register">>} -> true; + {<<"zip">>, <<"jabber:iq:register">>} -> true; + {<<"state">>, <<"jabber:iq:register">>} -> true; + {<<"city">>, <<"jabber:iq:register">>} -> true; + {<<"address">>, <<"jabber:iq:register">>} -> true; + {<<"email">>, <<"jabber:iq:register">>} -> true; + {<<"last">>, <<"jabber:iq:register">>} -> true; + {<<"first">>, <<"jabber:iq:register">>} -> true; + {<<"name">>, <<"jabber:iq:register">>} -> true; + {<<"password">>, <<"jabber:iq:register">>} -> true; + {<<"nick">>, <<"jabber:iq:register">>} -> true; + {<<"username">>, <<"jabber:iq:register">>} -> true; + {<<"instructions">>, <<"jabber:iq:register">>} -> true; + {<<"remove">>, <<"jabber:iq:register">>} -> true; + {<<"registered">>, <<"jabber:iq:register">>} -> true; + {<<"register">>, + <<"http://jabber.org/features/iq-register">>} -> + true; + {<<"c">>, <<"http://jabber.org/protocol/caps">>} -> + true; + {<<"ack">>, <<"p1:ack">>} -> true; + {<<"rebind">>, <<"p1:rebind">>} -> true; + {<<"push">>, <<"p1:push">>} -> true; + {<<"stream:features">>, + <<"http://etherx.jabber.org/streams">>} -> + true; + {<<"compression">>, + <<"http://jabber.org/features/compress">>} -> + true; + {<<"method">>, + <<"http://jabber.org/features/compress">>} -> + true; + {<<"compressed">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"compress">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"method">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"failure">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"unsupported-method">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"processing-failed">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"setup-failed">>, + <<"http://jabber.org/protocol/compress">>} -> + true; + {<<"failure">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + true; + {<<"proceed">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + true; + {<<"starttls">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + true; + {<<"required">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> + true; + {<<"mechanisms">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"temporary-auth-failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"bad-protocol">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"mechanism-too-weak">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"malformed-request">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"invalid-mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"invalid-authzid">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"incorrect-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"encryption-required">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"credentials-expired">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"account-disabled">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"aborted">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"success">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"response">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"challenge">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"query">>, <<"jabber:iq:auth">>} -> true; + {<<"resource">>, <<"jabber:iq:auth">>} -> true; + {<<"digest">>, <<"jabber:iq:auth">>} -> true; + {<<"password">>, <<"jabber:iq:auth">>} -> true; + {<<"username">>, <<"jabber:iq:auth">>} -> true; + {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + true; + {<<"resource">>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + true; + {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + true; + {<<"error">>, <<"jabber:client">>} -> true; + {<<"text">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"unexpected-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"subscription-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"service-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"remote-server-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"remote-server-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"registration-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"redirect">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"recipient-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"not-allowed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"not-acceptable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"jid-malformed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"item-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"gone">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"forbidden">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"feature-not-implemented">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"bad-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; + {<<"presence">>, <<"jabber:client">>} -> true; + {<<"priority">>, <<"jabber:client">>} -> true; + {<<"status">>, <<"jabber:client">>} -> true; + {<<"show">>, <<"jabber:client">>} -> true; + {<<"message">>, <<"jabber:client">>} -> true; + {<<"thread">>, <<"jabber:client">>} -> true; + {<<"body">>, <<"jabber:client">>} -> true; + {<<"subject">>, <<"jabber:client">>} -> true; + {<<"iq">>, <<"jabber:client">>} -> true; + {<<"query">>, <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"stat">>, <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"error">>, <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"storage">>, <<"storage:bookmarks">>} -> true; + {<<"url">>, <<"storage:bookmarks">>} -> true; + {<<"conference">>, <<"storage:bookmarks">>} -> true; + {<<"password">>, <<"storage:bookmarks">>} -> true; + {<<"nick">>, <<"storage:bookmarks">>} -> true; + {<<"query">>, <<"jabber:iq:private">>} -> true; + {<<"query">>, + <<"http://jabber.org/protocol/disco#items">>} -> + true; + {<<"item">>, + <<"http://jabber.org/protocol/disco#items">>} -> + true; + {<<"query">>, + <<"http://jabber.org/protocol/disco#info">>} -> + true; + {<<"feature">>, + <<"http://jabber.org/protocol/disco#info">>} -> + true; + {<<"identity">>, + <<"http://jabber.org/protocol/disco#info">>} -> + true; + {<<"blocklist">>, <<"urn:xmpp:blocking">>} -> true; + {<<"unblock">>, <<"urn:xmpp:blocking">>} -> true; + {<<"block">>, <<"urn:xmpp:blocking">>} -> true; + {<<"item">>, <<"urn:xmpp:blocking">>} -> true; + {<<"query">>, <<"jabber:iq:privacy">>} -> true; + {<<"active">>, <<"jabber:iq:privacy">>} -> true; + {<<"default">>, <<"jabber:iq:privacy">>} -> true; + {<<"list">>, <<"jabber:iq:privacy">>} -> true; + {<<"item">>, <<"jabber:iq:privacy">>} -> true; + {<<"presence-out">>, <<"jabber:iq:privacy">>} -> true; + {<<"presence-in">>, <<"jabber:iq:privacy">>} -> true; + {<<"iq">>, <<"jabber:iq:privacy">>} -> true; + {<<"message">>, <<"jabber:iq:privacy">>} -> true; + {<<"ver">>, <<"urn:xmpp:features:rosterver">>} -> true; + {<<"query">>, <<"jabber:iq:roster">>} -> true; + {<<"item">>, <<"jabber:iq:roster">>} -> true; + {<<"group">>, <<"jabber:iq:roster">>} -> true; + {<<"query">>, <<"jabber:iq:version">>} -> true; + {<<"os">>, <<"jabber:iq:version">>} -> true; + {<<"version">>, <<"jabber:iq:version">>} -> true; + {<<"name">>, <<"jabber:iq:version">>} -> true; + {<<"query">>, <<"jabber:iq:last">>} -> true; + _ -> false + end. + +encode({xmlel, _, _, _} = El) -> El; +encode({last, _, _} = Query) -> + encode_last(Query, + [{<<"xmlns">>, <<"jabber:iq:last">>}]); +encode({version, _, _, _} = Query) -> + encode_version(Query, + [{<<"xmlns">>, <<"jabber:iq:version">>}]); +encode({roster_item, _, _, _, _, _} = Item) -> + encode_roster_item(Item, + [{<<"xmlns">>, <<"jabber:iq:roster">>}]); +encode({roster_query, _, _} = Query) -> + encode_roster_query(Query, + [{<<"xmlns">>, <<"jabber:iq:roster">>}]); +encode({rosterver_feature} = Ver) -> + encode_rosterver_feature(Ver, + [{<<"xmlns">>, + <<"urn:xmpp:features:rosterver">>}]); +encode({privacy_item, _, _, _, _, _, _, _, _} = Item) -> + encode_privacy_item(Item, + [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); +encode({privacy_list, _, _} = List) -> + encode_privacy_list(List, + [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); +encode({privacy_query, _, _, _} = Query) -> + encode_privacy(Query, + [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); +encode({block, _} = Block) -> + encode_block(Block, + [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); +encode({unblock, _} = Unblock) -> + encode_unblock(Unblock, + [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); +encode({block_list} = Blocklist) -> + encode_block_list(Blocklist, + [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); +encode({identity, _, _, _, _} = Identity) -> + encode_disco_identity(Identity, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/disco#info">>}]); +encode({disco_info, _, _, _, _} = Query) -> + encode_disco_info(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/disco#info">>}]); +encode({disco_item, _, _, _} = Item) -> + encode_disco_item(Item, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/disco#items">>}]); +encode({disco_items, _, _} = Query) -> + encode_disco_items(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/disco#items">>}]); +encode({private, _} = Query) -> + encode_private(Query, + [{<<"xmlns">>, <<"jabber:iq:private">>}]); +encode({bookmark_conference, _, _, _, _, _} = + Conference) -> + encode_bookmark_conference(Conference, + [{<<"xmlns">>, <<"storage:bookmarks">>}]); +encode({bookmark_url, _, _} = Url) -> + encode_bookmark_url(Url, + [{<<"xmlns">>, <<"storage:bookmarks">>}]); +encode({bookmark_storage, _, _} = Storage) -> + encode_bookmarks_storage(Storage, + [{<<"xmlns">>, <<"storage:bookmarks">>}]); +encode({stat, _, _, _, _} = Stat) -> + encode_stat(Stat, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/stats">>}]); +encode({stats, _} = Query) -> + encode_stats(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/stats">>}]); +encode({iq, _, _, _, _, _, _, _} = Iq) -> + encode_iq(Iq, [{<<"xmlns">>, <<"jabber:client">>}]); +encode({message, _, _, _, _, _, _, _, _, _, _} = + Message) -> + encode_message(Message, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({presence, _, _, _, _, _, _, _, _, _, _} = + Presence) -> + encode_presence(Presence, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({gone, _} = Gone) -> + encode_error_gone(Gone, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); +encode({redirect, _} = Redirect) -> + encode_error_redirect(Redirect, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); +encode({error, _, _, _, _, _} = Error) -> + encode_error(Error, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({bind, _, _} = Bind) -> + encode_bind(Bind, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>}]); +encode({legacy_auth, _, _, _, _} = Query) -> + encode_legacy_auth(Query, + [{<<"xmlns">>, <<"jabber:iq:auth">>}]); +encode({sasl_auth, _, _} = Auth) -> + encode_sasl_auth(Auth, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_abort} = Abort) -> + encode_sasl_abort(Abort, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_challenge, _} = Challenge) -> + encode_sasl_challenge(Challenge, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_response, _} = Response) -> + encode_sasl_response(Response, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_success, _} = Success) -> + encode_sasl_success(Success, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_failure, _, _} = Failure) -> + encode_sasl_failure(Failure, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({sasl_mechanisms, _} = Mechanisms) -> + encode_sasl_mechanisms(Mechanisms, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); +encode({starttls, _} = Starttls) -> + encode_starttls(Starttls, + [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); +encode({starttls_proceed} = Proceed) -> + encode_starttls_proceed(Proceed, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); +encode({starttls_failure} = Failure) -> + encode_starttls_failure(Failure, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); +encode({compress_failure, _} = Failure) -> + encode_compress_failure(Failure, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/compress">>}]); +encode({compress, _} = Compress) -> + encode_compress(Compress, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/compress">>}]); +encode({compressed} = Compressed) -> + encode_compressed(Compressed, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/compress">>}]); +encode({compression, _} = Compression) -> + encode_compression(Compression, + [{<<"xmlns">>, + <<"http://jabber.org/features/compress">>}]); +encode({stream_features, _} = Stream_features) -> + encode_stream_features(Stream_features, + [{<<"xmlns">>, + <<"http://etherx.jabber.org/streams">>}]); +encode({p1_push} = Push) -> + encode_p1_push(Push, [{<<"xmlns">>, <<"p1:push">>}]); +encode({p1_rebind} = Rebind) -> + encode_p1_rebind(Rebind, + [{<<"xmlns">>, <<"p1:rebind">>}]); +encode({p1_ack} = Ack) -> + encode_p1_ack(Ack, [{<<"xmlns">>, <<"p1:ack">>}]); +encode({caps, _, _, _, _} = C) -> + encode_caps(C, + [{<<"xmlns">>, <<"http://jabber.org/protocol/caps">>}]); +encode({feature_register} = Register) -> + encode_feature_register(Register, + [{<<"xmlns">>, + <<"http://jabber.org/features/iq-register">>}]); +encode({register, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _} = + Query) -> + encode_register(Query, + [{<<"xmlns">>, <<"jabber:iq:register">>}]); +encode({xmpp_session, _} = Session) -> + encode_session(Session, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>}]); +encode({ping} = Ping) -> + encode_ping(Ping, [{<<"xmlns">>, <<"urn:xmpp:ping">>}]); +encode({time, _, _} = Time) -> + encode_time(Time, [{<<"xmlns">>, <<"urn:xmpp:time">>}]); +encode({text, _, _} = Text) -> + encode_stream_error_text(Text, []); +encode({'see-other-host', _} = See_other_host) -> + encode_stream_error_see_other_host(See_other_host, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]); +encode({stream_error, _, _} = Stream_error) -> + encode_stream_error(Stream_error, + [{<<"xmlns">>, + <<"http://etherx.jabber.org/streams">>}]); +encode({vcard_name, _, _, _, _, _} = N) -> + encode_vcard_N(N, [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, + _, _} = + Adr) -> + encode_vcard_ADR(Adr, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_label, _, _, _, _, _, _, _, _} = Label) -> + encode_vcard_LABEL(Label, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, + _, _} = + Tel) -> + encode_vcard_TEL(Tel, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_email, _, _, _, _, _, _} = Email) -> + encode_vcard_EMAIL(Email, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_geo, _, _} = Geo) -> + encode_vcard_GEO(Geo, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_logo, _, _, _} = Logo) -> + encode_vcard_LOGO(Logo, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_photo, _, _, _} = Photo) -> + encode_vcard_PHOTO(Photo, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_org, _, _} = Org) -> + encode_vcard_ORG(Org, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_sound, _, _, _} = Sound) -> + encode_vcard_SOUND(Sound, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_key, _, _} = Key) -> + encode_vcard_KEY(Key, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = + Vcard) -> + encode_vcard_temp(Vcard, + [{<<"xmlns">>, <<"vcard-temp">>}]); +encode({vcard_xupdate, undefined, _} = X) -> + encode_vcard_xupdate(X, + [{<<"xmlns">>, <<"vcard-temp:x:update">>}]); +encode({xdata_field, _, _, _, _, _, _, _} = Field) -> + encode_xdata_field(Field, + [{<<"xmlns">>, <<"jabber:x:data">>}]); +encode({xdata, _, _, _, _, _, _} = X) -> + encode_xdata(X, [{<<"xmlns">>, <<"jabber:x:data">>}]); +encode({pubsub_subscription, _, _, _, _} = + Subscription) -> + encode_pubsub_subscription(Subscription, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_affiliation, _, _} = Affiliation) -> + encode_pubsub_affiliation(Affiliation, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_item, _, _} = Item) -> + encode_pubsub_item(Item, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_items, _, _, _, _} = Items) -> + encode_pubsub_items(Items, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_event_item, _, _, _, _} = Item) -> + encode_pubsub_event_item(Item, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#event">>}]); +encode({pubsub_event_items, _, _, _} = Items) -> + encode_pubsub_event_items(Items, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#event">>}]); +encode({pubsub_event, _} = Event) -> + encode_pubsub_event(Event, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#event">>}]); +encode({pubsub_subscribe, _, _} = Subscribe) -> + encode_pubsub_subscribe(Subscribe, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_unsubscribe, _, _, _} = Unsubscribe) -> + encode_pubsub_unsubscribe(Unsubscribe, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_publish, _, _} = Publish) -> + encode_pubsub_publish(Publish, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_options, _, _, _, _} = Options) -> + encode_pubsub_options(Options, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_retract, _, _, _} = Retract) -> + encode_pubsub_retract(Retract, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub, _, _, _, _, _, _, _, _} = Pubsub) -> + encode_pubsub(Pubsub, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub">>}]); +encode({shim, _} = Headers) -> + encode_shim_headers(Headers, + [{<<"xmlns">>, <<"http://jabber.org/protocol/shim">>}]); +encode({chatstate, active} = Active) -> + encode_chatstate_active(Active, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/chatstates">>}]); +encode({chatstate, composing} = Composing) -> + encode_chatstate_composing(Composing, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/chatstates">>}]); +encode({chatstate, gone} = Gone) -> + encode_chatstate_gone(Gone, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/chatstates">>}]); +encode({chatstate, inactive} = Inactive) -> + encode_chatstate_inactive(Inactive, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/chatstates">>}]); +encode({chatstate, paused} = Paused) -> + encode_chatstate_paused(Paused, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/chatstates">>}]); +encode({delay, _, _, _} = Delay) -> + encode_delay(Delay, + [{<<"xmlns">>, <<"urn:xmpp:delay">>}]); +encode({streamhost, _, _, _} = Streamhost) -> + encode_bytestreams_streamhost(Streamhost, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/bytestreams">>}]); +encode({bytestreams, _, _, _, _, _, _} = Query) -> + encode_bytestreams(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/bytestreams">>}]); +encode({muc_history, _, _, _, _} = History) -> + encode_muc_history(History, + [{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]); +encode({muc_decline, _, _, _} = Decline) -> + encode_muc_user_decline(Decline, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#user">>}]); +encode({muc_user_destroy, _, _} = Destroy) -> + encode_muc_user_destroy(Destroy, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#user">>}]); +encode({muc_invite, _, _, _} = Invite) -> + encode_muc_user_invite(Invite, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#user">>}]); +encode({muc_user, _, _, _, _, _, _} = X) -> + encode_muc_user(X, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#user">>}]); +encode({muc_owner_destroy, _, _, _} = Destroy) -> + encode_muc_owner_destroy(Destroy, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#owner">>}]); +encode({muc_owner, _, _} = Query) -> + encode_muc_owner(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#owner">>}]); +encode({muc_item, _, _, _, _, _, _, _} = Item) -> + encode_muc_admin_item(Item, []); +encode({muc_actor, _, _} = Actor) -> + encode_muc_admin_actor(Actor, []); +encode({muc_admin, _} = Query) -> + encode_muc_admin(Query, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#admin">>}]); +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">>}]); +encode({carbons_disable} = Disable) -> + encode_carbons_disable(Disable, + [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); +encode({carbons_enable} = Enable) -> + encode_carbons_enable(Enable, + [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); +encode({carbons_private} = Private) -> + encode_carbons_private(Private, + [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); +encode({carbons_received, _} = Received) -> + encode_carbons_received(Received, + [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); +encode({carbons_sent, _} = Sent) -> + encode_carbons_sent(Sent, + [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); +encode({feature_csi, _} = Csi) -> + encode_feature_csi(Csi, []); +encode({csi, active} = Active) -> + encode_csi_active(Active, + [{<<"xmlns">>, <<"urn:xmpp:csi:0">>}]); +encode({csi, inactive} = Inactive) -> + encode_csi_inactive(Inactive, + [{<<"xmlns">>, <<"urn:xmpp:csi:0">>}]); +encode({feature_sm, _} = Sm) -> + encode_feature_sm(Sm, []); +encode({sm_enable, _, _, _} = Enable) -> + encode_sm_enable(Enable, []); +encode({sm_enabled, _, _, _, _, _} = Enabled) -> + encode_sm_enabled(Enabled, []); +encode({sm_resume, _, _, _} = Resume) -> + encode_sm_resume(Resume, []); +encode({sm_resumed, _, _, _} = Resumed) -> + encode_sm_resumed(Resumed, []); +encode({sm_r, _} = R) -> encode_sm_r(R, []); +encode({sm_a, _, _} = A) -> encode_sm_a(A, []); +encode({sm_failed, _, _, _} = Failed) -> + encode_sm_failed(Failed, []); +encode({offline_item, _, _} = Item) -> + encode_offline_item(Item, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/offline">>}]); +encode({offline, _, _, _} = Offline) -> + encode_offline(Offline, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/offline">>}]); +encode({mix_join, _, _} = Join) -> + encode_mix_join(Join, + [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); +encode({mix_leave} = Leave) -> + encode_mix_leave(Leave, + [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); +encode({mix_participant, _, _} = Participant) -> + encode_mix_participant(Participant, + [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); +encode({hint, 'no-copy'} = No_copy) -> + encode_hint_no_copy(No_copy, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({hint, 'no-store'} = No_store) -> + encode_hint_no_store(No_store, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({hint, store} = Store) -> + encode_hint_store(Store, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({hint, 'no-permanent-store'} = + No_permanent_store) -> + encode_hint_no_permanent_store(No_permanent_store, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({search_item, _, _, _, _, _} = Item) -> + encode_search_item(Item, + [{<<"xmlns">>, <<"jabber:iq:search">>}]); +encode({search, _, _, _, _, _, _, _} = Query) -> + encode_search(Query, + [{<<"xmlns">>, <<"jabber:iq:search">>}]). + +get_name({last, _, _}) -> <<"query">>; +get_name({version, _, _, _}) -> <<"query">>; +get_name({roster_item, _, _, _, _, _}) -> <<"item">>; +get_name({roster_query, _, _}) -> <<"query">>; +get_name({rosterver_feature}) -> <<"ver">>; +get_name({privacy_item, _, _, _, _, _, _, _, _}) -> + <<"item">>; +get_name({privacy_list, _, _}) -> <<"list">>; +get_name({privacy_query, _, _, _}) -> <<"query">>; +get_name({block, _}) -> <<"block">>; +get_name({unblock, _}) -> <<"unblock">>; +get_name({block_list}) -> <<"blocklist">>; +get_name({identity, _, _, _, _}) -> <<"identity">>; +get_name({disco_info, _, _, _, _}) -> <<"query">>; +get_name({disco_item, _, _, _}) -> <<"item">>; +get_name({disco_items, _, _}) -> <<"query">>; +get_name({private, _}) -> <<"query">>; +get_name({bookmark_conference, _, _, _, _, _}) -> + <<"conference">>; +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, _, _, _, _, _, _, _, _, _, _}) -> + <<"message">>; +get_name({presence, _, _, _, _, _, _, _, _, _, _}) -> + <<"presence">>; +get_name({gone, _}) -> <<"gone">>; +get_name({redirect, _}) -> <<"redirect">>; +get_name({error, _, _, _, _, _}) -> <<"error">>; +get_name({bind, _, _}) -> <<"bind">>; +get_name({legacy_auth, _, _, _, _}) -> <<"query">>; +get_name({sasl_auth, _, _}) -> <<"auth">>; +get_name({sasl_abort}) -> <<"abort">>; +get_name({sasl_challenge, _}) -> <<"challenge">>; +get_name({sasl_response, _}) -> <<"response">>; +get_name({sasl_success, _}) -> <<"success">>; +get_name({sasl_failure, _, _}) -> <<"failure">>; +get_name({sasl_mechanisms, _}) -> <<"mechanisms">>; +get_name({starttls, _}) -> <<"starttls">>; +get_name({starttls_proceed}) -> <<"proceed">>; +get_name({starttls_failure}) -> <<"failure">>; +get_name({compress_failure, _}) -> <<"failure">>; +get_name({compress, _}) -> <<"compress">>; +get_name({compressed}) -> <<"compressed">>; +get_name({compression, _}) -> <<"compression">>; +get_name({stream_features, _}) -> <<"stream:features">>; +get_name({p1_push}) -> <<"push">>; +get_name({p1_rebind}) -> <<"rebind">>; +get_name({p1_ack}) -> <<"ack">>; +get_name({caps, _, _, _, _}) -> <<"c">>; +get_name({feature_register}) -> <<"register">>; +get_name({register, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _}) -> + <<"query">>; +get_name({xmpp_session, _}) -> <<"session">>; +get_name({ping}) -> <<"ping">>; +get_name({time, _, _}) -> <<"time">>; +get_name({text, _, _}) -> <<"text">>; +get_name({'see-other-host', _}) -> <<"see-other-host">>; +get_name({stream_error, _, _}) -> <<"stream:error">>; +get_name({vcard_name, _, _, _, _, _}) -> <<"N">>; +get_name({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"ADR">>; +get_name({vcard_label, _, _, _, _, _, _, _, _}) -> + <<"LABEL">>; +get_name({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"TEL">>; +get_name({vcard_email, _, _, _, _, _, _}) -> + <<"EMAIL">>; +get_name({vcard_geo, _, _}) -> <<"GEO">>; +get_name({vcard_logo, _, _, _}) -> <<"LOGO">>; +get_name({vcard_photo, _, _, _}) -> <<"PHOTO">>; +get_name({vcard_org, _, _}) -> <<"ORG">>; +get_name({vcard_sound, _, _, _}) -> <<"SOUND">>; +get_name({vcard_key, _, _}) -> <<"KEY">>; +get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _}) -> + <<"vCard">>; +get_name({vcard_xupdate, undefined, _}) -> <<"x">>; +get_name({xdata_field, _, _, _, _, _, _, _}) -> + <<"field">>; +get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; +get_name({pubsub_subscription, _, _, _, _}) -> + <<"subscription">>; +get_name({pubsub_affiliation, _, _}) -> + <<"affiliation">>; +get_name({pubsub_item, _, _}) -> <<"item">>; +get_name({pubsub_items, _, _, _, _}) -> <<"items">>; +get_name({pubsub_event_item, _, _, _, _}) -> <<"item">>; +get_name({pubsub_event_items, _, _, _}) -> <<"items">>; +get_name({pubsub_event, _}) -> <<"event">>; +get_name({pubsub_subscribe, _, _}) -> <<"subscribe">>; +get_name({pubsub_unsubscribe, _, _, _}) -> + <<"unsubscribe">>; +get_name({pubsub_publish, _, _}) -> <<"publish">>; +get_name({pubsub_options, _, _, _, _}) -> <<"options">>; +get_name({pubsub_retract, _, _, _}) -> <<"retract">>; +get_name({pubsub, _, _, _, _, _, _, _, _}) -> + <<"pubsub">>; +get_name({shim, _}) -> <<"headers">>; +get_name({chatstate, active}) -> <<"active">>; +get_name({chatstate, composing}) -> <<"composing">>; +get_name({chatstate, gone}) -> <<"gone">>; +get_name({chatstate, inactive}) -> <<"inactive">>; +get_name({chatstate, paused}) -> <<"paused">>; +get_name({delay, _, _, _}) -> <<"delay">>; +get_name({streamhost, _, _, _}) -> <<"streamhost">>; +get_name({bytestreams, _, _, _, _, _, _}) -> + <<"query">>; +get_name({muc_history, _, _, _, _}) -> <<"history">>; +get_name({muc_decline, _, _, _}) -> <<"decline">>; +get_name({muc_user_destroy, _, _}) -> <<"destroy">>; +get_name({muc_invite, _, _, _}) -> <<"invite">>; +get_name({muc_user, _, _, _, _, _, _}) -> <<"x">>; +get_name({muc_owner_destroy, _, _, _}) -> <<"destroy">>; +get_name({muc_owner, _, _}) -> <<"query">>; +get_name({muc_item, _, _, _, _, _, _, _}) -> <<"item">>; +get_name({muc_actor, _, _}) -> <<"actor">>; +get_name({muc_admin, _}) -> <<"query">>; +get_name({muc, _, _}) -> <<"x">>; +get_name({rsm_first, _, _}) -> <<"first">>; +get_name({rsm_set, _, _, _, _, _, _, _}) -> <<"set">>; +get_name({mam_query, _, _, _, _, _, _, _}) -> + <<"query">>; +get_name({mam_archived, _, _}) -> <<"archived">>; +get_name({mam_result, _, _, _, _}) -> <<"result">>; +get_name({mam_prefs, _, _, _, _}) -> <<"prefs">>; +get_name({mam_fin, _, _, _, _}) -> <<"fin">>; +get_name({forwarded, _, _}) -> <<"forwarded">>; +get_name({carbons_disable}) -> <<"disable">>; +get_name({carbons_enable}) -> <<"enable">>; +get_name({carbons_private}) -> <<"private">>; +get_name({carbons_received, _}) -> <<"received">>; +get_name({carbons_sent, _}) -> <<"sent">>; +get_name({feature_csi, _}) -> <<"csi">>; +get_name({csi, active}) -> <<"active">>; +get_name({csi, inactive}) -> <<"inactive">>; +get_name({feature_sm, _}) -> <<"sm">>; +get_name({sm_enable, _, _, _}) -> <<"enable">>; +get_name({sm_enabled, _, _, _, _, _}) -> <<"enabled">>; +get_name({sm_resume, _, _, _}) -> <<"resume">>; +get_name({sm_resumed, _, _, _}) -> <<"resumed">>; +get_name({sm_r, _}) -> <<"r">>; +get_name({sm_a, _, _}) -> <<"a">>; +get_name({sm_failed, _, _, _}) -> <<"failed">>; +get_name({offline_item, _, _}) -> <<"item">>; +get_name({offline, _, _, _}) -> <<"offline">>; +get_name({mix_join, _, _}) -> <<"join">>; +get_name({mix_leave}) -> <<"leave">>; +get_name({mix_participant, _, _}) -> <<"participant">>; +get_name({hint, 'no-copy'}) -> <<"no-copy">>; +get_name({hint, 'no-store'}) -> <<"no-store">>; +get_name({hint, store}) -> <<"store">>; +get_name({hint, 'no-permanent-store'}) -> + <<"no-permanent-store">>; +get_name({search_item, _, _, _, _, _}) -> <<"item">>; +get_name({search, _, _, _, _, _, _, _}) -> <<"query">>. + +get_ns({last, _, _}) -> <<"jabber:iq:last">>; +get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; +get_ns({roster_item, _, _, _, _, _}) -> + <<"jabber:iq:roster">>; +get_ns({roster_query, _, _}) -> <<"jabber:iq:roster">>; +get_ns({rosterver_feature}) -> + <<"urn:xmpp:features:rosterver">>; +get_ns({privacy_item, _, _, _, _, _, _, _, _}) -> + <<"jabber:iq:privacy">>; +get_ns({privacy_list, _, _}) -> <<"jabber:iq:privacy">>; +get_ns({privacy_query, _, _, _}) -> + <<"jabber:iq:privacy">>; +get_ns({block, _}) -> <<"urn:xmpp:blocking">>; +get_ns({unblock, _}) -> <<"urn:xmpp:blocking">>; +get_ns({block_list}) -> <<"urn:xmpp:blocking">>; +get_ns({identity, _, _, _, _}) -> + <<"http://jabber.org/protocol/disco#info">>; +get_ns({disco_info, _, _, _, _}) -> + <<"http://jabber.org/protocol/disco#info">>; +get_ns({disco_item, _, _, _}) -> + <<"http://jabber.org/protocol/disco#items">>; +get_ns({disco_items, _, _}) -> + <<"http://jabber.org/protocol/disco#items">>; +get_ns({private, _}) -> <<"jabber:iq:private">>; +get_ns({bookmark_conference, _, _, _, _, _}) -> + <<"storage:bookmarks">>; +get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>; +get_ns({bookmark_storage, _, _}) -> + <<"storage:bookmarks">>; +get_ns({stat, _, _, _, _}) -> + <<"http://jabber.org/protocol/stats">>; +get_ns({stats, _}) -> + <<"http://jabber.org/protocol/stats">>; +get_ns({iq, _, _, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({message, _, _, _, _, _, _, _, _, _, _}) -> + <<"jabber:client">>; +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({bind, _, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-bind">>; +get_ns({legacy_auth, _, _, _, _}) -> + <<"jabber:iq:auth">>; +get_ns({sasl_auth, _, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_abort}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_challenge, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_response, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_success, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_failure, _, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_mechanisms, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({starttls, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-tls">>; +get_ns({starttls_proceed}) -> + <<"urn:ietf:params:xml:ns:xmpp-tls">>; +get_ns({starttls_failure}) -> + <<"urn:ietf:params:xml:ns:xmpp-tls">>; +get_ns({compress_failure, _}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compress, _}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compressed}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compression, _}) -> + <<"http://jabber.org/features/compress">>; +get_ns({stream_features, _}) -> + <<"http://etherx.jabber.org/streams">>; +get_ns({p1_push}) -> <<"p1:push">>; +get_ns({p1_rebind}) -> <<"p1:rebind">>; +get_ns({p1_ack}) -> <<"p1:ack">>; +get_ns({caps, _, _, _, _}) -> + <<"http://jabber.org/protocol/caps">>; +get_ns({feature_register}) -> + <<"http://jabber.org/features/iq-register">>; +get_ns({register, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _}) -> + <<"jabber:iq:register">>; +get_ns({xmpp_session, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-session">>; +get_ns({ping}) -> <<"urn:xmpp:ping">>; +get_ns({time, _, _}) -> <<"urn:xmpp:time">>; +get_ns({'see-other-host', _}) -> + <<"urn:ietf:params:xml:ns:xmpp-streams">>; +get_ns({stream_error, _, _}) -> + <<"http://etherx.jabber.org/streams">>; +get_ns({vcard_name, _, _, _, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"vcard-temp">>; +get_ns({vcard_label, _, _, _, _, _, _, _, _}) -> + <<"vcard-temp">>; +get_ns({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"vcard-temp">>; +get_ns({vcard_email, _, _, _, _, _, _}) -> + <<"vcard-temp">>; +get_ns({vcard_geo, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_logo, _, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_photo, _, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_org, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_sound, _, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_key, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> + <<"vcard-temp">>; +get_ns({vcard_xupdate, undefined, _}) -> + <<"vcard-temp:x:update">>; +get_ns({xdata_field, _, _, _, _, _, _, _}) -> + <<"jabber:x:data">>; +get_ns({xdata, _, _, _, _, _, _}) -> + <<"jabber:x:data">>; +get_ns({pubsub_subscription, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_affiliation, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_item, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_items, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_event_item, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub#event">>; +get_ns({pubsub_event_items, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub#event">>; +get_ns({pubsub_event, _}) -> + <<"http://jabber.org/protocol/pubsub#event">>; +get_ns({pubsub_subscribe, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_unsubscribe, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_publish, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_options, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_retract, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub, _, _, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({shim, _}) -> + <<"http://jabber.org/protocol/shim">>; +get_ns({chatstate, active}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, composing}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, gone}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, inactive}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, paused}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({delay, _, _, _}) -> <<"urn:xmpp:delay">>; +get_ns({streamhost, _, _, _}) -> + <<"http://jabber.org/protocol/bytestreams">>; +get_ns({bytestreams, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/bytestreams">>; +get_ns({muc_history, _, _, _, _}) -> + <<"http://jabber.org/protocol/muc">>; +get_ns({muc_decline, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_user_destroy, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_invite, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_user, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_owner_destroy, _, _, _}) -> + <<"http://jabber.org/protocol/muc#owner">>; +get_ns({muc_owner, _, _}) -> + <<"http://jabber.org/protocol/muc#owner">>; +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_query, Xmlns, _, _, _, _, _, _}) -> Xmlns; +get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; +get_ns({mam_result, Xmlns, _, _, _}) -> Xmlns; +get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; +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">>; +get_ns({carbons_private}) -> <<"urn:xmpp:carbons:2">>; +get_ns({carbons_received, _}) -> + <<"urn:xmpp:carbons:2">>; +get_ns({carbons_sent, _}) -> <<"urn:xmpp:carbons:2">>; +get_ns({feature_csi, Xmlns}) -> Xmlns; +get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>; +get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>; +get_ns({feature_sm, Xmlns}) -> Xmlns; +get_ns({sm_enable, _, _, Xmlns}) -> Xmlns; +get_ns({sm_enabled, _, _, _, _, Xmlns}) -> Xmlns; +get_ns({sm_resume, _, _, Xmlns}) -> Xmlns; +get_ns({sm_resumed, _, _, Xmlns}) -> Xmlns; +get_ns({sm_r, Xmlns}) -> Xmlns; +get_ns({sm_a, _, Xmlns}) -> Xmlns; +get_ns({sm_failed, _, _, Xmlns}) -> Xmlns; +get_ns({offline_item, _, _}) -> + <<"http://jabber.org/protocol/offline">>; +get_ns({offline, _, _, _}) -> + <<"http://jabber.org/protocol/offline">>; +get_ns({mix_join, _, _}) -> <<"urn:xmpp:mix:0">>; +get_ns({mix_leave}) -> <<"urn:xmpp:mix:0">>; +get_ns({mix_participant, _, _}) -> <<"urn:xmpp:mix:0">>; +get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-store'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, store}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-permanent-store'}) -> + <<"urn:xmpp:hints">>; +get_ns({search_item, _, _, _, _, _}) -> + <<"jabber:iq:search">>; +get_ns({search, _, _, _, _, _, _, _}) -> + <<"jabber:iq:search">>. + +dec_int(Val) -> dec_int(Val, infinity, infinity). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> Int; + Int when Int =< Max, Int >= Min -> Int + end. + +enc_int(Int) -> list_to_binary(integer_to_list(Int)). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +format_error({bad_attr_value, Attr, Tag, XMLNS}) -> + <<"Bad value of attribute '", Attr/binary, "' in tag <", + Tag/binary, "/> qualified by namespace '", XMLNS/binary, + "'">>; +format_error({bad_cdata_value, <<>>, Tag, XMLNS}) -> + <<"Bad value of cdata in tag <", Tag/binary, + "/> qualified by namespace '", XMLNS/binary, "'">>; +format_error({missing_tag, Tag, XMLNS}) -> + <<"Missing tag <", Tag/binary, + "/> qualified by namespace '", XMLNS/binary, "'">>; +format_error({missing_attr, Attr, Tag, XMLNS}) -> + <<"Missing attribute '", Attr/binary, "' in tag <", + Tag/binary, "/> qualified by namespace '", XMLNS/binary, + "'">>; +format_error({missing_cdata, <<>>, Tag, XMLNS}) -> + <<"Missing cdata in tag <", Tag/binary, + "/> qualified by namespace '", XMLNS/binary, "'">>; +format_error({unknown_tag, Tag, XMLNS}) -> + <<"Unknown tag <", Tag/binary, + "/> qualified by namespace '", XMLNS/binary, "'">>. + +get_attr(Attr, Attrs) -> + case lists:keyfind(Attr, 1, Attrs) of + {_, Val} -> Val; + false -> <<>> + end. + +pp(Term) -> io_lib_pretty:print(Term, fun pp/2). + +pp(last, 2) -> [seconds, status]; +pp(version, 3) -> [name, ver, os]; +pp(roster_item, 5) -> + [jid, name, groups, subscription, ask]; +pp(roster_query, 2) -> [items, ver]; +pp(rosterver_feature, 0) -> []; +pp(privacy_item, 8) -> + [order, action, type, value, message, iq, presence_in, + presence_out]; +pp(privacy_list, 2) -> [name, items]; +pp(privacy_query, 3) -> [lists, default, active]; +pp(block, 1) -> [items]; +pp(unblock, 1) -> [items]; +pp(block_list, 0) -> []; +pp(identity, 4) -> [category, type, lang, name]; +pp(disco_info, 4) -> + [node, identities, features, xdata]; +pp(disco_item, 3) -> [jid, name, node]; +pp(disco_items, 2) -> [node, items]; +pp(private, 1) -> [xml_els]; +pp(bookmark_conference, 5) -> + [name, jid, autojoin, nick, password]; +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, + sub_els]; +pp(presence, 10) -> + [id, type, lang, from, to, show, status, priority, + error, sub_els]; +pp(gone, 1) -> [uri]; +pp(redirect, 1) -> [uri]; +pp(error, 5) -> [type, code, by, reason, text]; +pp(bind, 2) -> [jid, resource]; +pp(legacy_auth, 4) -> + [username, password, digest, resource]; +pp(sasl_auth, 2) -> [mechanism, text]; +pp(sasl_abort, 0) -> []; +pp(sasl_challenge, 1) -> [text]; +pp(sasl_response, 1) -> [text]; +pp(sasl_success, 1) -> [text]; +pp(sasl_failure, 2) -> [reason, text]; +pp(sasl_mechanisms, 1) -> [list]; +pp(starttls, 1) -> [required]; +pp(starttls_proceed, 0) -> []; +pp(starttls_failure, 0) -> []; +pp(compress_failure, 1) -> [reason]; +pp(compress, 1) -> [methods]; +pp(compressed, 0) -> []; +pp(compression, 1) -> [methods]; +pp(stream_features, 1) -> [sub_els]; +pp(p1_push, 0) -> []; +pp(p1_rebind, 0) -> []; +pp(p1_ack, 0) -> []; +pp(caps, 4) -> [node, version, hash, exts]; +pp(feature_register, 0) -> []; +pp(register, 21) -> + [registered, remove, instructions, username, nick, + password, name, first, last, email, address, city, + state, zip, phone, url, date, misc, text, key, xdata]; +pp(xmpp_session, 1) -> [optional]; +pp(ping, 0) -> []; +pp(time, 2) -> [tzo, utc]; +pp(text, 2) -> [lang, data]; +pp('see-other-host', 1) -> [host]; +pp(stream_error, 2) -> [reason, text]; +pp(vcard_name, 5) -> + [family, given, middle, prefix, suffix]; +pp(vcard_adr, 14) -> + [home, work, postal, parcel, dom, intl, pref, pobox, + extadd, street, locality, region, pcode, ctry]; +pp(vcard_label, 8) -> + [home, work, postal, parcel, dom, intl, pref, line]; +pp(vcard_tel, 14) -> + [home, work, voice, fax, pager, msg, cell, video, bbs, + modem, isdn, pcs, pref, number]; +pp(vcard_email, 6) -> + [home, work, internet, pref, x400, userid]; +pp(vcard_geo, 2) -> [lat, lon]; +pp(vcard_logo, 3) -> [type, binval, extval]; +pp(vcard_photo, 3) -> [type, binval, extval]; +pp(vcard_org, 2) -> [name, units]; +pp(vcard_sound, 3) -> [phonetic, binval, extval]; +pp(vcard_key, 2) -> [type, cred]; +pp(vcard_temp, 29) -> + [version, fn, n, nickname, photo, bday, adr, label, tel, + email, jabberid, mailer, tz, geo, title, role, logo, + org, categories, note, prodid, rev, sort_string, sound, + uid, url, class, key, desc]; +pp(vcard_xupdate, 2) -> [us, hash]; +pp(xdata_field, 7) -> + [label, type, var, required, desc, values, options]; +pp(xdata, 6) -> + [type, instructions, title, reported, items, fields]; +pp(pubsub_subscription, 4) -> [jid, node, subid, type]; +pp(pubsub_affiliation, 2) -> [node, type]; +pp(pubsub_item, 2) -> [id, xml_els]; +pp(pubsub_items, 4) -> [node, max_items, subid, items]; +pp(pubsub_event_item, 4) -> + [id, node, publisher, xml_els]; +pp(pubsub_event_items, 3) -> [node, retract, items]; +pp(pubsub_event, 1) -> [items]; +pp(pubsub_subscribe, 2) -> [node, jid]; +pp(pubsub_unsubscribe, 3) -> [node, jid, subid]; +pp(pubsub_publish, 2) -> [node, items]; +pp(pubsub_options, 4) -> [node, jid, subid, xdata]; +pp(pubsub_retract, 3) -> [node, notify, items]; +pp(pubsub, 8) -> + [subscriptions, affiliations, publish, subscribe, + unsubscribe, options, items, retract]; +pp(shim, 1) -> [headers]; +pp(chatstate, 1) -> [type]; +pp(delay, 3) -> [stamp, from, desc]; +pp(streamhost, 3) -> [jid, host, port]; +pp(bytestreams, 6) -> + [hosts, used, activate, dstaddr, mode, sid]; +pp(muc_history, 4) -> + [maxchars, maxstanzas, seconds, since]; +pp(muc_decline, 3) -> [reason, from, to]; +pp(muc_user_destroy, 2) -> [reason, jid]; +pp(muc_invite, 3) -> [reason, from, to]; +pp(muc_user, 6) -> + [decline, destroy, invites, items, status_codes, + password]; +pp(muc_owner_destroy, 3) -> [jid, reason, password]; +pp(muc_owner, 2) -> [destroy, config]; +pp(muc_item, 7) -> + [actor, continue, reason, affiliation, role, jid, nick]; +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, 4) -> [id, rsm, stable, complete]; +pp(forwarded, 2) -> [delay, sub_els]; +pp(carbons_disable, 0) -> []; +pp(carbons_enable, 0) -> []; +pp(carbons_private, 0) -> []; +pp(carbons_received, 1) -> [forwarded]; +pp(carbons_sent, 1) -> [forwarded]; +pp(feature_csi, 1) -> [xmlns]; +pp(csi, 1) -> [type]; +pp(feature_sm, 1) -> [xmlns]; +pp(sm_enable, 3) -> [max, resume, xmlns]; +pp(sm_enabled, 5) -> [id, location, max, resume, xmlns]; +pp(sm_resume, 3) -> [h, previd, xmlns]; +pp(sm_resumed, 3) -> [h, previd, xmlns]; +pp(sm_r, 1) -> [xmlns]; +pp(sm_a, 2) -> [h, xmlns]; +pp(sm_failed, 3) -> [reason, h, xmlns]; +pp(offline_item, 2) -> [node, action]; +pp(offline, 3) -> [items, purge, fetch]; +pp(mix_join, 2) -> [jid, subscribe]; +pp(mix_leave, 0) -> []; +pp(mix_participant, 2) -> [jid, nick]; +pp(hint, 1) -> [type]; +pp(search_item, 5) -> [jid, first, last, nick, email]; +pp(search, 7) -> + [instructions, first, last, nick, email, items, xdata]; +pp(_, _) -> no. + +join([], _Sep) -> <<>>; +join([H | T], Sep) -> + <> || X <- T >>/binary>>. + +enc_bool(false) -> <<"false">>; +enc_bool(true) -> <<"true">>. + +dec_bool(<<"false">>) -> false; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"1">>) -> true. + +resourceprep(R) -> + case jid:resourceprep(R) of + error -> erlang:error(badarg); + R1 -> R1 + end. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +enc_utc(Val) -> jlib:now_to_utc_string(Val). + +dec_utc(Val) -> + {_, _, _} = jlib:datetime_string_to_timestamp(Val). + +enc_tzo({H, M}) -> + Sign = if H >= 0 -> <<>>; + true -> <<"-">> + end, + list_to_binary([Sign, + io_lib:format("~2..0w:~2..0w", [H, M])]). + +dec_tzo(Val) -> + [H1, M1] = str:tokens(Val, <<":">>), + H = jlib:binary_to_integer(H1), + M = jlib:binary_to_integer(M1), + if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. + +decode_search(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Xdata, Items, Instructions, Last, First, Nick, Email} = + decode_search_els(__TopXMLNS, __IgnoreEls, _els, + undefined, [], undefined, undefined, undefined, + undefined, undefined), + {search, Instructions, First, Last, Nick, Email, Items, + Xdata}. + +decode_search_els(__TopXMLNS, __IgnoreEls, [], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + {Xdata, lists:reverse(Items), Instructions, Last, First, + Nick, Email}; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], + Xdata, Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, + decode_search_instructions(__TopXMLNS, __IgnoreEls, + _el), + Last, First, Nick, Email); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, + decode_search_instructions(<<"jabber:iq:search">>, + __IgnoreEls, _el), + Last, First, Nick, Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"first">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, + decode_search_first(__TopXMLNS, __IgnoreEls, _el), + Nick, Email); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, + decode_search_first(<<"jabber:iq:search">>, + __IgnoreEls, _el), + Nick, Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"last">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, + decode_search_last(__TopXMLNS, __IgnoreEls, _el), + First, Nick, Email); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, + decode_search_last(<<"jabber:iq:search">>, + __IgnoreEls, _el), + First, Nick, Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, + decode_search_nick(__TopXMLNS, __IgnoreEls, _el), + Email); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, + decode_search_nick(<<"jabber:iq:search">>, + __IgnoreEls, _el), + Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"email">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, + decode_search_email(__TopXMLNS, __IgnoreEls, _el)); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, + decode_search_email(<<"jabber:iq:search">>, + __IgnoreEls, _el)); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + [decode_search_item(__TopXMLNS, __IgnoreEls, _el) + | Items], + Instructions, Last, First, Nick, Email); + <<"jabber:iq:search">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + [decode_search_item(<<"jabber:iq:search">>, + __IgnoreEls, _el) + | Items], + Instructions, Last, First, Nick, Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, + Items, Instructions, Last, First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, __IgnoreEls, _el), + Items, Instructions, Last, First, Nick, Email); + _ -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email) + end; +decode_search_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Xdata, Items, Instructions, Last, First, Nick, Email) -> + decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, + Items, Instructions, Last, First, Nick, Email). + +encode_search({search, Instructions, First, Last, Nick, + Email, Items, Xdata}, + _xmlns_attrs) -> + _els = lists:reverse('encode_search_$xdata'(Xdata, + 'encode_search_$items'(Items, + 'encode_search_$instructions'(Instructions, + 'encode_search_$last'(Last, + 'encode_search_$first'(First, + 'encode_search_$nick'(Nick, + 'encode_search_$email'(Email, + [])))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_search_$xdata'(undefined, _acc) -> _acc; +'encode_search_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +'encode_search_$items'([], _acc) -> _acc; +'encode_search_$items'([Items | _els], _acc) -> + 'encode_search_$items'(_els, + [encode_search_item(Items, []) | _acc]). + +'encode_search_$instructions'(undefined, _acc) -> _acc; +'encode_search_$instructions'(Instructions, _acc) -> + [encode_search_instructions(Instructions, []) | _acc]. + +'encode_search_$last'(undefined, _acc) -> _acc; +'encode_search_$last'(Last, _acc) -> + [encode_search_last(Last, []) | _acc]. + +'encode_search_$first'(undefined, _acc) -> _acc; +'encode_search_$first'(First, _acc) -> + [encode_search_first(First, []) | _acc]. + +'encode_search_$nick'(undefined, _acc) -> _acc; +'encode_search_$nick'(Nick, _acc) -> + [encode_search_nick(Nick, []) | _acc]. + +'encode_search_$email'(undefined, _acc) -> _acc; +'encode_search_$email'(Email, _acc) -> + [encode_search_email(Email, []) | _acc]. + +decode_search_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Last, First, Nick, Email} = + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined), + Jid = decode_search_item_attrs(__TopXMLNS, _attrs, + undefined), + {search_item, Jid, First, Last, Nick, Email}. + +decode_search_item_els(__TopXMLNS, __IgnoreEls, [], + Last, First, Nick, Email) -> + {Last, First, Nick, Email}; +decode_search_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"first">>, _attrs, _} = _el | _els], Last, + First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, + decode_search_first(__TopXMLNS, __IgnoreEls, + _el), + Nick, Email); + <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, + decode_search_first(<<"jabber:iq:search">>, + __IgnoreEls, _el), + Nick, Email); + _ -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, Email) + end; +decode_search_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"last">>, _attrs, _} = _el | _els], Last, + First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_search_last(__TopXMLNS, __IgnoreEls, + _el), + First, Nick, Email); + <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_search_last(<<"jabber:iq:search">>, + __IgnoreEls, _el), + First, Nick, Email); + _ -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, Email) + end; +decode_search_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Last, + First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, + decode_search_nick(__TopXMLNS, __IgnoreEls, + _el), + Email); + <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, + decode_search_nick(<<"jabber:iq:search">>, + __IgnoreEls, _el), + Email); + _ -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, Email) + end; +decode_search_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"email">>, _attrs, _} = _el | _els], Last, + First, Nick, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, + decode_search_email(__TopXMLNS, __IgnoreEls, + _el)); + <<"jabber:iq:search">> -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, + decode_search_email(<<"jabber:iq:search">>, + __IgnoreEls, _el)); + _ -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, Email) + end; +decode_search_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Last, First, Nick, Email) -> + decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, + Last, First, Nick, Email). + +decode_search_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_search_item_attrs(__TopXMLNS, _attrs, _val); +decode_search_item_attrs(__TopXMLNS, [_ | _attrs], + Jid) -> + decode_search_item_attrs(__TopXMLNS, _attrs, Jid); +decode_search_item_attrs(__TopXMLNS, [], Jid) -> + decode_search_item_attr_jid(__TopXMLNS, Jid). + +encode_search_item({search_item, Jid, First, Last, Nick, + Email}, + _xmlns_attrs) -> + _els = lists:reverse('encode_search_item_$last'(Last, + 'encode_search_item_$first'(First, + 'encode_search_item_$nick'(Nick, + 'encode_search_item_$email'(Email, + []))))), + _attrs = encode_search_item_attr_jid(Jid, _xmlns_attrs), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_search_item_$last'(undefined, _acc) -> _acc; +'encode_search_item_$last'(Last, _acc) -> + [encode_search_last(Last, []) | _acc]. + +'encode_search_item_$first'(undefined, _acc) -> _acc; +'encode_search_item_$first'(First, _acc) -> + [encode_search_first(First, []) | _acc]. + +'encode_search_item_$nick'(undefined, _acc) -> _acc; +'encode_search_item_$nick'(Nick, _acc) -> + [encode_search_nick(Nick, []) | _acc]. + +'encode_search_item_$email'(undefined, _acc) -> _acc; +'encode_search_item_$email'(Email, _acc) -> + [encode_search_email(Email, []) | _acc]. + +decode_search_item_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); +decode_search_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_search_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_search_email(__TopXMLNS, __IgnoreEls, + {xmlel, <<"email">>, _attrs, _els}) -> + Cdata = decode_search_email_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_search_email_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_search_email_cdata(__TopXMLNS, Cdata); +decode_search_email_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_search_email_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_search_email_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_search_email_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_search_email(Cdata, _xmlns_attrs) -> + _els = encode_search_email_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"email">>, _attrs, _els}. + +decode_search_email_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_search_email_cdata(__TopXMLNS, _val) -> _val. + +encode_search_email_cdata(<<>>, _acc) -> _acc; +encode_search_email_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_search_nick(__TopXMLNS, __IgnoreEls, + {xmlel, <<"nick">>, _attrs, _els}) -> + Cdata = decode_search_nick_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_search_nick_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_search_nick_cdata(__TopXMLNS, Cdata); +decode_search_nick_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_search_nick_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_search_nick_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_search_nick_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_search_nick(Cdata, _xmlns_attrs) -> + _els = encode_search_nick_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"nick">>, _attrs, _els}. + +decode_search_nick_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_search_nick_cdata(__TopXMLNS, _val) -> _val. + +encode_search_nick_cdata(<<>>, _acc) -> _acc; +encode_search_nick_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_search_last(__TopXMLNS, __IgnoreEls, + {xmlel, <<"last">>, _attrs, _els}) -> + Cdata = decode_search_last_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_search_last_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_search_last_cdata(__TopXMLNS, Cdata); +decode_search_last_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_search_last_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_search_last_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_search_last_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_search_last(Cdata, _xmlns_attrs) -> + _els = encode_search_last_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"last">>, _attrs, _els}. + +decode_search_last_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_search_last_cdata(__TopXMLNS, _val) -> _val. + +encode_search_last_cdata(<<>>, _acc) -> _acc; +encode_search_last_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_search_first(__TopXMLNS, __IgnoreEls, + {xmlel, <<"first">>, _attrs, _els}) -> + Cdata = decode_search_first_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_search_first_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_search_first_cdata(__TopXMLNS, Cdata); +decode_search_first_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_search_first_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_search_first_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_search_first_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_search_first(Cdata, _xmlns_attrs) -> + _els = encode_search_first_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"first">>, _attrs, _els}. + +decode_search_first_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_search_first_cdata(__TopXMLNS, _val) -> _val. + +encode_search_first_cdata(<<>>, _acc) -> _acc; +encode_search_first_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_search_instructions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"instructions">>, _attrs, _els}) -> + Cdata = decode_search_instructions_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_search_instructions_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_search_instructions_cdata(__TopXMLNS, Cdata); +decode_search_instructions_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_search_instructions_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_search_instructions_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_search_instructions_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_search_instructions(Cdata, _xmlns_attrs) -> + _els = encode_search_instructions_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"instructions">>, _attrs, _els}. + +decode_search_instructions_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_search_instructions_cdata(__TopXMLNS, _val) -> + _val. + +encode_search_instructions_cdata(undefined, _acc) -> + _acc; +encode_search_instructions_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_hint_no_permanent_store(__TopXMLNS, __IgnoreEls, + {xmlel, <<"no-permanent-store">>, _attrs, + _els}) -> + {hint, 'no-permanent-store'}. + +encode_hint_no_permanent_store({hint, + 'no-permanent-store'}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"no-permanent-store">>, _attrs, _els}. + +decode_hint_store(__TopXMLNS, __IgnoreEls, + {xmlel, <<"store">>, _attrs, _els}) -> + {hint, store}. + +encode_hint_store({hint, store}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"store">>, _attrs, _els}. + +decode_hint_no_store(__TopXMLNS, __IgnoreEls, + {xmlel, <<"no-store">>, _attrs, _els}) -> + {hint, 'no-store'}. + +encode_hint_no_store({hint, 'no-store'}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"no-store">>, _attrs, _els}. + +decode_hint_no_copy(__TopXMLNS, __IgnoreEls, + {xmlel, <<"no-copy">>, _attrs, _els}) -> + {hint, 'no-copy'}. + +encode_hint_no_copy({hint, 'no-copy'}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"no-copy">>, _attrs, _els}. + +decode_mix_participant(__TopXMLNS, __IgnoreEls, + {xmlel, <<"participant">>, _attrs, _els}) -> + {Jid, Nick} = decode_mix_participant_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {mix_participant, Jid, Nick}. + +decode_mix_participant_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> + decode_mix_participant_attrs(__TopXMLNS, _attrs, _val, + Nick); +decode_mix_participant_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> + decode_mix_participant_attrs(__TopXMLNS, _attrs, Jid, + _val); +decode_mix_participant_attrs(__TopXMLNS, [_ | _attrs], + Jid, Nick) -> + decode_mix_participant_attrs(__TopXMLNS, _attrs, Jid, + Nick); +decode_mix_participant_attrs(__TopXMLNS, [], Jid, + Nick) -> + {decode_mix_participant_attr_jid(__TopXMLNS, Jid), + decode_mix_participant_attr_nick(__TopXMLNS, Nick)}. + +encode_mix_participant({mix_participant, Jid, Nick}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_mix_participant_attr_nick(Nick, + encode_mix_participant_attr_jid(Jid, + _xmlns_attrs)), + {xmlel, <<"participant">>, _attrs, _els}. + +decode_mix_participant_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"participant">>, + __TopXMLNS}}); +decode_mix_participant_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"participant">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_mix_participant_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_mix_participant_attr_nick(__TopXMLNS, + undefined) -> + undefined; +decode_mix_participant_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_mix_participant_attr_nick(undefined, _acc) -> + _acc; +encode_mix_participant_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_mix_leave(__TopXMLNS, __IgnoreEls, + {xmlel, <<"leave">>, _attrs, _els}) -> + {mix_leave}. + +encode_mix_leave({mix_leave}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"leave">>, _attrs, _els}. + +decode_mix_join(__TopXMLNS, __IgnoreEls, + {xmlel, <<"join">>, _attrs, _els}) -> + Subscribe = decode_mix_join_els(__TopXMLNS, __IgnoreEls, + _els, []), + Jid = decode_mix_join_attrs(__TopXMLNS, _attrs, + undefined), + {mix_join, Jid, Subscribe}. + +decode_mix_join_els(__TopXMLNS, __IgnoreEls, [], + Subscribe) -> + lists:reverse(Subscribe); +decode_mix_join_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], + Subscribe) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mix:0">> -> + decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, + [decode_mix_subscribe(__TopXMLNS, __IgnoreEls, + _el) + | Subscribe]); + <<"urn:xmpp:mix:0">> -> + decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, + [decode_mix_subscribe(<<"urn:xmpp:mix:0">>, + __IgnoreEls, _el) + | Subscribe]); + _ -> + decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, + Subscribe) + end; +decode_mix_join_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Subscribe) -> + decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, + Subscribe). + +decode_mix_join_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_mix_join_attrs(__TopXMLNS, _attrs, _val); +decode_mix_join_attrs(__TopXMLNS, [_ | _attrs], Jid) -> + decode_mix_join_attrs(__TopXMLNS, _attrs, Jid); +decode_mix_join_attrs(__TopXMLNS, [], Jid) -> + decode_mix_join_attr_jid(__TopXMLNS, Jid). + +encode_mix_join({mix_join, Jid, Subscribe}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_mix_join_$subscribe'(Subscribe, + [])), + _attrs = encode_mix_join_attr_jid(Jid, _xmlns_attrs), + {xmlel, <<"join">>, _attrs, _els}. + +'encode_mix_join_$subscribe'([], _acc) -> _acc; +'encode_mix_join_$subscribe'([Subscribe | _els], + _acc) -> + 'encode_mix_join_$subscribe'(_els, + [encode_mix_subscribe(Subscribe, []) | _acc]). + +decode_mix_join_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_mix_join_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"join">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mix_join_attr_jid(undefined, _acc) -> _acc; +encode_mix_join_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_mix_subscribe(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscribe">>, _attrs, _els}) -> + Node = decode_mix_subscribe_attrs(__TopXMLNS, _attrs, + undefined), + Node. + +decode_mix_subscribe_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_mix_subscribe_attrs(__TopXMLNS, _attrs, _val); +decode_mix_subscribe_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_mix_subscribe_attrs(__TopXMLNS, _attrs, Node); +decode_mix_subscribe_attrs(__TopXMLNS, [], Node) -> + decode_mix_subscribe_attr_node(__TopXMLNS, Node). + +encode_mix_subscribe(Node, _xmlns_attrs) -> + _els = [], + _attrs = encode_mix_subscribe_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"subscribe">>, _attrs, _els}. + +decode_mix_subscribe_attr_node(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"subscribe">>, + __TopXMLNS}}); +decode_mix_subscribe_attr_node(__TopXMLNS, _val) -> + _val. + +encode_mix_subscribe_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_offline(__TopXMLNS, __IgnoreEls, + {xmlel, <<"offline">>, _attrs, _els}) -> + {Items, Purge, Fetch} = decode_offline_els(__TopXMLNS, + __IgnoreEls, _els, [], false, + false), + {offline, Items, Purge, Fetch}. + +decode_offline_els(__TopXMLNS, __IgnoreEls, [], Items, + Purge, Fetch) -> + {lists:reverse(Items), Purge, Fetch}; +decode_offline_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"purge">>, _attrs, _} = _el | _els], Items, + Purge, Fetch) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + decode_offline_purge(__TopXMLNS, __IgnoreEls, _el), + Fetch); + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + decode_offline_purge(<<"http://jabber.org/protocol/offline">>, + __IgnoreEls, _el), + Fetch); + _ -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, Fetch) + end; +decode_offline_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"fetch">>, _attrs, _} = _el | _els], Items, + Purge, Fetch) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, + decode_offline_fetch(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, + decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, + __IgnoreEls, _el)); + _ -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, Fetch) + end; +decode_offline_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, + Purge, Fetch) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, + [decode_offline_item(__TopXMLNS, __IgnoreEls, _el) + | Items], + Purge, Fetch); + <<"http://jabber.org/protocol/offline">> -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, + [decode_offline_item(<<"http://jabber.org/protocol/offline">>, + __IgnoreEls, _el) + | Items], + Purge, Fetch); + _ -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, Fetch) + end; +decode_offline_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Items, Purge, Fetch) -> + decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, + Purge, Fetch). + +encode_offline({offline, Items, Purge, Fetch}, + _xmlns_attrs) -> + _els = lists:reverse('encode_offline_$items'(Items, + 'encode_offline_$purge'(Purge, + 'encode_offline_$fetch'(Fetch, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"offline">>, _attrs, _els}. + +'encode_offline_$items'([], _acc) -> _acc; +'encode_offline_$items'([Items | _els], _acc) -> + 'encode_offline_$items'(_els, + [encode_offline_item(Items, []) | _acc]). + +'encode_offline_$purge'(false, _acc) -> _acc; +'encode_offline_$purge'(Purge, _acc) -> + [encode_offline_purge(Purge, []) | _acc]. + +'encode_offline_$fetch'(false, _acc) -> _acc; +'encode_offline_$fetch'(Fetch, _acc) -> + [encode_offline_fetch(Fetch, []) | _acc]. + +decode_offline_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Node, Action} = decode_offline_item_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {offline_item, Node, Action}. + +decode_offline_item_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Action) -> + decode_offline_item_attrs(__TopXMLNS, _attrs, _val, + Action); +decode_offline_item_attrs(__TopXMLNS, + [{<<"action">>, _val} | _attrs], Node, _Action) -> + decode_offline_item_attrs(__TopXMLNS, _attrs, Node, + _val); +decode_offline_item_attrs(__TopXMLNS, [_ | _attrs], + Node, Action) -> + decode_offline_item_attrs(__TopXMLNS, _attrs, Node, + Action); +decode_offline_item_attrs(__TopXMLNS, [], Node, + Action) -> + {decode_offline_item_attr_node(__TopXMLNS, Node), + decode_offline_item_attr_action(__TopXMLNS, Action)}. + +encode_offline_item({offline_item, Node, Action}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_offline_item_attr_action(Action, + encode_offline_item_attr_node(Node, + _xmlns_attrs)), + {xmlel, <<"item">>, _attrs, _els}. + +decode_offline_item_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_offline_item_attr_node(__TopXMLNS, _val) -> _val. + +encode_offline_item_attr_node(undefined, _acc) -> _acc; +encode_offline_item_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_offline_item_attr_action(__TopXMLNS, + undefined) -> + undefined; +decode_offline_item_attr_action(__TopXMLNS, _val) -> + case catch dec_enum(_val, [view, remove]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"action">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_offline_item_attr_action(undefined, _acc) -> + _acc; +encode_offline_item_attr_action(_val, _acc) -> + [{<<"action">>, enc_enum(_val)} | _acc]. + +decode_offline_fetch(__TopXMLNS, __IgnoreEls, + {xmlel, <<"fetch">>, _attrs, _els}) -> + true. + +encode_offline_fetch(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"fetch">>, _attrs, _els}. + +decode_offline_purge(__TopXMLNS, __IgnoreEls, + {xmlel, <<"purge">>, _attrs, _els}) -> + true. + +encode_offline_purge(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"purge">>, _attrs, _els}. + +decode_sm_failed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"failed">>, _attrs, _els}) -> + Reason = decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + _els, undefined), + {H, Xmlns} = decode_sm_failed_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {sm_failed, Reason, H, Xmlns}. + +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, [], + Reason) -> + Reason; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"bad-request">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"feature-not-implemented">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"forbidden">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"gone">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"internal-server-error">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item-not-found">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"jid-malformed">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-acceptable">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-allowed">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"policy-violation">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"recipient-unavailable">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"registration-required">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remote-server-not-found">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remote-server-timeout">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"resource-constraint">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"service-unavailable">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscription-required">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"undefined-condition">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unexpected-request">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + __IgnoreEls, + _el)); + _ -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason) + end; +decode_sm_failed_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Reason) -> + decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, + Reason). + +decode_sm_failed_attrs(__TopXMLNS, + [{<<"h">>, _val} | _attrs], _H, Xmlns) -> + decode_sm_failed_attrs(__TopXMLNS, _attrs, _val, Xmlns); +decode_sm_failed_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], H, _Xmlns) -> + decode_sm_failed_attrs(__TopXMLNS, _attrs, H, _val); +decode_sm_failed_attrs(__TopXMLNS, [_ | _attrs], H, + Xmlns) -> + decode_sm_failed_attrs(__TopXMLNS, _attrs, H, Xmlns); +decode_sm_failed_attrs(__TopXMLNS, [], H, Xmlns) -> + {decode_sm_failed_attr_h(__TopXMLNS, H), + decode_sm_failed_attr_xmlns(__TopXMLNS, Xmlns)}. + +encode_sm_failed({sm_failed, Reason, H, Xmlns}, + _xmlns_attrs) -> + _els = lists:reverse('encode_sm_failed_$reason'(Reason, + [])), + _attrs = encode_sm_failed_attr_xmlns(Xmlns, + encode_sm_failed_attr_h(H, + _xmlns_attrs)), + {xmlel, <<"failed">>, _attrs, _els}. + +'encode_sm_failed_$reason'(undefined, _acc) -> _acc; +'encode_sm_failed_$reason'('bad-request' = Reason, + _acc) -> + [encode_error_bad_request(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'(conflict = Reason, _acc) -> + [encode_error_conflict(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('feature-not-implemented' = + Reason, + _acc) -> + [encode_error_feature_not_implemented(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'(forbidden = Reason, _acc) -> + [encode_error_forbidden(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'({gone, _} = Reason, _acc) -> + [encode_error_gone(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('internal-server-error' = + Reason, + _acc) -> + [encode_error_internal_server_error(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('item-not-found' = Reason, + _acc) -> + [encode_error_item_not_found(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('jid-malformed' = Reason, + _acc) -> + [encode_error_jid_malformed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('not-acceptable' = Reason, + _acc) -> + [encode_error_not_acceptable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('not-allowed' = Reason, + _acc) -> + [encode_error_not_allowed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('not-authorized' = Reason, + _acc) -> + [encode_error_not_authorized(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('policy-violation' = Reason, + _acc) -> + [encode_error_policy_violation(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('recipient-unavailable' = + Reason, + _acc) -> + [encode_error_recipient_unavailable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'({redirect, _} = Reason, + _acc) -> + [encode_error_redirect(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('registration-required' = + Reason, + _acc) -> + [encode_error_registration_required(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('remote-server-not-found' = + Reason, + _acc) -> + [encode_error_remote_server_not_found(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('remote-server-timeout' = + Reason, + _acc) -> + [encode_error_remote_server_timeout(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('resource-constraint' = + Reason, + _acc) -> + [encode_error_resource_constraint(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('service-unavailable' = + Reason, + _acc) -> + [encode_error_service_unavailable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('subscription-required' = + Reason, + _acc) -> + [encode_error_subscription_required(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('undefined-condition' = + Reason, + _acc) -> + [encode_error_undefined_condition(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_sm_failed_$reason'('unexpected-request' = + Reason, + _acc) -> + [encode_error_unexpected_request(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]. + +decode_sm_failed_attr_h(__TopXMLNS, undefined) -> + undefined; +decode_sm_failed_attr_h(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"h">>, <<"failed">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_failed_attr_h(undefined, _acc) -> _acc; +encode_sm_failed_attr_h(_val, _acc) -> + [{<<"h">>, enc_int(_val)} | _acc]. + +decode_sm_failed_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_failed_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_failed_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_failed_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_a(__TopXMLNS, __IgnoreEls, + {xmlel, <<"a">>, _attrs, _els}) -> + {H, Xmlns} = decode_sm_a_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {sm_a, H, Xmlns}. + +decode_sm_a_attrs(__TopXMLNS, + [{<<"h">>, _val} | _attrs], _H, Xmlns) -> + decode_sm_a_attrs(__TopXMLNS, _attrs, _val, Xmlns); +decode_sm_a_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], H, _Xmlns) -> + decode_sm_a_attrs(__TopXMLNS, _attrs, H, _val); +decode_sm_a_attrs(__TopXMLNS, [_ | _attrs], H, Xmlns) -> + decode_sm_a_attrs(__TopXMLNS, _attrs, H, Xmlns); +decode_sm_a_attrs(__TopXMLNS, [], H, Xmlns) -> + {decode_sm_a_attr_h(__TopXMLNS, H), + decode_sm_a_attr_xmlns(__TopXMLNS, Xmlns)}. + +encode_sm_a({sm_a, H, Xmlns}, _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_a_attr_xmlns(Xmlns, + encode_sm_a_attr_h(H, _xmlns_attrs)), + {xmlel, <<"a">>, _attrs, _els}. + +decode_sm_a_attr_h(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"h">>, <<"a">>, __TopXMLNS}}); +decode_sm_a_attr_h(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"h">>, <<"a">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_a_attr_h(_val, _acc) -> + [{<<"h">>, enc_int(_val)} | _acc]. + +decode_sm_a_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_a_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_a_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_a_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_r(__TopXMLNS, __IgnoreEls, + {xmlel, <<"r">>, _attrs, _els}) -> + Xmlns = decode_sm_r_attrs(__TopXMLNS, _attrs, + undefined), + {sm_r, Xmlns}. + +decode_sm_r_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_sm_r_attrs(__TopXMLNS, _attrs, _val); +decode_sm_r_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> + decode_sm_r_attrs(__TopXMLNS, _attrs, Xmlns); +decode_sm_r_attrs(__TopXMLNS, [], Xmlns) -> + decode_sm_r_attr_xmlns(__TopXMLNS, Xmlns). + +encode_sm_r({sm_r, Xmlns}, _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_r_attr_xmlns(Xmlns, _xmlns_attrs), + {xmlel, <<"r">>, _attrs, _els}. + +decode_sm_r_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_r_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_r_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_r_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_resumed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"resumed">>, _attrs, _els}) -> + {H, Xmlns, Previd} = decode_sm_resumed_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {sm_resumed, H, Previd, Xmlns}. + +decode_sm_resumed_attrs(__TopXMLNS, + [{<<"h">>, _val} | _attrs], _H, Xmlns, Previd) -> + decode_sm_resumed_attrs(__TopXMLNS, _attrs, _val, Xmlns, + Previd); +decode_sm_resumed_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], H, _Xmlns, Previd) -> + decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, _val, + Previd); +decode_sm_resumed_attrs(__TopXMLNS, + [{<<"previd">>, _val} | _attrs], H, Xmlns, _Previd) -> + decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, Xmlns, + _val); +decode_sm_resumed_attrs(__TopXMLNS, [_ | _attrs], H, + Xmlns, Previd) -> + decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, Xmlns, + Previd); +decode_sm_resumed_attrs(__TopXMLNS, [], H, Xmlns, + Previd) -> + {decode_sm_resumed_attr_h(__TopXMLNS, H), + decode_sm_resumed_attr_xmlns(__TopXMLNS, Xmlns), + decode_sm_resumed_attr_previd(__TopXMLNS, Previd)}. + +encode_sm_resumed({sm_resumed, H, Previd, Xmlns}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_resumed_attr_previd(Previd, + encode_sm_resumed_attr_xmlns(Xmlns, + encode_sm_resumed_attr_h(H, + _xmlns_attrs))), + {xmlel, <<"resumed">>, _attrs, _els}. + +decode_sm_resumed_attr_h(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"h">>, <<"resumed">>, __TopXMLNS}}); +decode_sm_resumed_attr_h(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"h">>, <<"resumed">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_resumed_attr_h(_val, _acc) -> + [{<<"h">>, enc_int(_val)} | _acc]. + +decode_sm_resumed_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_resumed_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_resumed_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_resumed_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_resumed_attr_previd(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"previd">>, <<"resumed">>, + __TopXMLNS}}); +decode_sm_resumed_attr_previd(__TopXMLNS, _val) -> _val. + +encode_sm_resumed_attr_previd(_val, _acc) -> + [{<<"previd">>, _val} | _acc]. + +decode_sm_resume(__TopXMLNS, __IgnoreEls, + {xmlel, <<"resume">>, _attrs, _els}) -> + {H, Xmlns, Previd} = decode_sm_resume_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {sm_resume, H, Previd, Xmlns}. + +decode_sm_resume_attrs(__TopXMLNS, + [{<<"h">>, _val} | _attrs], _H, Xmlns, Previd) -> + decode_sm_resume_attrs(__TopXMLNS, _attrs, _val, Xmlns, + Previd); +decode_sm_resume_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], H, _Xmlns, Previd) -> + decode_sm_resume_attrs(__TopXMLNS, _attrs, H, _val, + Previd); +decode_sm_resume_attrs(__TopXMLNS, + [{<<"previd">>, _val} | _attrs], H, Xmlns, _Previd) -> + decode_sm_resume_attrs(__TopXMLNS, _attrs, H, Xmlns, + _val); +decode_sm_resume_attrs(__TopXMLNS, [_ | _attrs], H, + Xmlns, Previd) -> + decode_sm_resume_attrs(__TopXMLNS, _attrs, H, Xmlns, + Previd); +decode_sm_resume_attrs(__TopXMLNS, [], H, Xmlns, + Previd) -> + {decode_sm_resume_attr_h(__TopXMLNS, H), + decode_sm_resume_attr_xmlns(__TopXMLNS, Xmlns), + decode_sm_resume_attr_previd(__TopXMLNS, Previd)}. + +encode_sm_resume({sm_resume, H, Previd, Xmlns}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_resume_attr_previd(Previd, + encode_sm_resume_attr_xmlns(Xmlns, + encode_sm_resume_attr_h(H, + _xmlns_attrs))), + {xmlel, <<"resume">>, _attrs, _els}. + +decode_sm_resume_attr_h(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"h">>, <<"resume">>, __TopXMLNS}}); +decode_sm_resume_attr_h(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"h">>, <<"resume">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_resume_attr_h(_val, _acc) -> + [{<<"h">>, enc_int(_val)} | _acc]. + +decode_sm_resume_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_resume_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_resume_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_resume_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_resume_attr_previd(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"previd">>, <<"resume">>, + __TopXMLNS}}); +decode_sm_resume_attr_previd(__TopXMLNS, _val) -> _val. + +encode_sm_resume_attr_previd(_val, _acc) -> + [{<<"previd">>, _val} | _acc]. + +decode_sm_enabled(__TopXMLNS, __IgnoreEls, + {xmlel, <<"enabled">>, _attrs, _els}) -> + {Id, Location, Xmlns, Max, Resume} = + decode_sm_enabled_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined, undefined), + {sm_enabled, Id, Location, Max, Resume, Xmlns}. + +decode_sm_enabled_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, Location, Xmlns, Max, + Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, _val, + Location, Xmlns, Max, Resume); +decode_sm_enabled_attrs(__TopXMLNS, + [{<<"location">>, _val} | _attrs], Id, _Location, Xmlns, + Max, Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, _val, + Xmlns, Max, Resume); +decode_sm_enabled_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Id, Location, _Xmlns, + Max, Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, + Location, _val, Max, Resume); +decode_sm_enabled_attrs(__TopXMLNS, + [{<<"max">>, _val} | _attrs], Id, Location, Xmlns, _Max, + Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, + Location, Xmlns, _val, Resume); +decode_sm_enabled_attrs(__TopXMLNS, + [{<<"resume">>, _val} | _attrs], Id, Location, Xmlns, + Max, _Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, + Location, Xmlns, Max, _val); +decode_sm_enabled_attrs(__TopXMLNS, [_ | _attrs], Id, + Location, Xmlns, Max, Resume) -> + decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, + Location, Xmlns, Max, Resume); +decode_sm_enabled_attrs(__TopXMLNS, [], Id, Location, + Xmlns, Max, Resume) -> + {decode_sm_enabled_attr_id(__TopXMLNS, Id), + decode_sm_enabled_attr_location(__TopXMLNS, Location), + decode_sm_enabled_attr_xmlns(__TopXMLNS, Xmlns), + decode_sm_enabled_attr_max(__TopXMLNS, Max), + decode_sm_enabled_attr_resume(__TopXMLNS, Resume)}. + +encode_sm_enabled({sm_enabled, Id, Location, Max, + Resume, Xmlns}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_enabled_attr_resume(Resume, + encode_sm_enabled_attr_max(Max, + encode_sm_enabled_attr_xmlns(Xmlns, + encode_sm_enabled_attr_location(Location, + encode_sm_enabled_attr_id(Id, + _xmlns_attrs))))), + {xmlel, <<"enabled">>, _attrs, _els}. + +decode_sm_enabled_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_sm_enabled_attr_id(__TopXMLNS, _val) -> _val. + +encode_sm_enabled_attr_id(undefined, _acc) -> _acc; +encode_sm_enabled_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_sm_enabled_attr_location(__TopXMLNS, + undefined) -> + undefined; +decode_sm_enabled_attr_location(__TopXMLNS, _val) -> + _val. + +encode_sm_enabled_attr_location(undefined, _acc) -> + _acc; +encode_sm_enabled_attr_location(_val, _acc) -> + [{<<"location">>, _val} | _acc]. + +decode_sm_enabled_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_enabled_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_enabled_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_enabled_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_enabled_attr_max(__TopXMLNS, undefined) -> + undefined; +decode_sm_enabled_attr_max(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"max">>, <<"enabled">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_sm_enabled_attr_max(undefined, _acc) -> _acc; +encode_sm_enabled_attr_max(_val, _acc) -> + [{<<"max">>, enc_int(_val)} | _acc]. + +decode_sm_enabled_attr_resume(__TopXMLNS, undefined) -> + false; +decode_sm_enabled_attr_resume(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"resume">>, <<"enabled">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_sm_enabled_attr_resume(false, _acc) -> _acc; +encode_sm_enabled_attr_resume(_val, _acc) -> + [{<<"resume">>, enc_bool(_val)} | _acc]. + +decode_sm_enable(__TopXMLNS, __IgnoreEls, + {xmlel, <<"enable">>, _attrs, _els}) -> + {Max, Xmlns, Resume} = + decode_sm_enable_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {sm_enable, Max, Resume, Xmlns}. + +decode_sm_enable_attrs(__TopXMLNS, + [{<<"max">>, _val} | _attrs], _Max, Xmlns, Resume) -> + decode_sm_enable_attrs(__TopXMLNS, _attrs, _val, Xmlns, + Resume); +decode_sm_enable_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Max, _Xmlns, Resume) -> + decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, _val, + Resume); +decode_sm_enable_attrs(__TopXMLNS, + [{<<"resume">>, _val} | _attrs], Max, Xmlns, _Resume) -> + decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, Xmlns, + _val); +decode_sm_enable_attrs(__TopXMLNS, [_ | _attrs], Max, + Xmlns, Resume) -> + decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, Xmlns, + Resume); +decode_sm_enable_attrs(__TopXMLNS, [], Max, Xmlns, + Resume) -> + {decode_sm_enable_attr_max(__TopXMLNS, Max), + decode_sm_enable_attr_xmlns(__TopXMLNS, Xmlns), + decode_sm_enable_attr_resume(__TopXMLNS, Resume)}. + +encode_sm_enable({sm_enable, Max, Resume, Xmlns}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_sm_enable_attr_resume(Resume, + encode_sm_enable_attr_xmlns(Xmlns, + encode_sm_enable_attr_max(Max, + _xmlns_attrs))), + {xmlel, <<"enable">>, _attrs, _els}. + +decode_sm_enable_attr_max(__TopXMLNS, undefined) -> + undefined; +decode_sm_enable_attr_max(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"max">>, <<"enable">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sm_enable_attr_max(undefined, _acc) -> _acc; +encode_sm_enable_attr_max(_val, _acc) -> + [{<<"max">>, enc_int(_val)} | _acc]. + +decode_sm_enable_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sm_enable_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sm_enable_attr_xmlns(undefined, _acc) -> _acc; +encode_sm_enable_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sm_enable_attr_resume(__TopXMLNS, undefined) -> + false; +decode_sm_enable_attr_resume(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"resume">>, <<"enable">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_sm_enable_attr_resume(false, _acc) -> _acc; +encode_sm_enable_attr_resume(_val, _acc) -> + [{<<"resume">>, enc_bool(_val)} | _acc]. + +decode_feature_sm(__TopXMLNS, __IgnoreEls, + {xmlel, <<"sm">>, _attrs, _els}) -> + Xmlns = decode_feature_sm_attrs(__TopXMLNS, _attrs, + undefined), + {feature_sm, Xmlns}. + +decode_feature_sm_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_feature_sm_attrs(__TopXMLNS, _attrs, _val); +decode_feature_sm_attrs(__TopXMLNS, [_ | _attrs], + Xmlns) -> + decode_feature_sm_attrs(__TopXMLNS, _attrs, Xmlns); +decode_feature_sm_attrs(__TopXMLNS, [], Xmlns) -> + decode_feature_sm_attr_xmlns(__TopXMLNS, Xmlns). + +encode_feature_sm({feature_sm, Xmlns}, _xmlns_attrs) -> + _els = [], + _attrs = encode_feature_sm_attr_xmlns(Xmlns, + _xmlns_attrs), + {xmlel, <<"sm">>, _attrs, _els}. + +decode_feature_sm_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_feature_sm_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_feature_sm_attr_xmlns(undefined, _acc) -> _acc; +encode_feature_sm_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_csi_inactive(__TopXMLNS, __IgnoreEls, + {xmlel, <<"inactive">>, _attrs, _els}) -> + {csi, inactive}. + +encode_csi_inactive({csi, inactive}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"inactive">>, _attrs, _els}. + +decode_csi_active(__TopXMLNS, __IgnoreEls, + {xmlel, <<"active">>, _attrs, _els}) -> + {csi, active}. + +encode_csi_active({csi, active}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"active">>, _attrs, _els}. + +decode_feature_csi(__TopXMLNS, __IgnoreEls, + {xmlel, <<"csi">>, _attrs, _els}) -> + Xmlns = decode_feature_csi_attrs(__TopXMLNS, _attrs, + undefined), + {feature_csi, Xmlns}. + +decode_feature_csi_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_feature_csi_attrs(__TopXMLNS, _attrs, _val); +decode_feature_csi_attrs(__TopXMLNS, [_ | _attrs], + Xmlns) -> + decode_feature_csi_attrs(__TopXMLNS, _attrs, Xmlns); +decode_feature_csi_attrs(__TopXMLNS, [], Xmlns) -> + decode_feature_csi_attr_xmlns(__TopXMLNS, Xmlns). + +encode_feature_csi({feature_csi, Xmlns}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_feature_csi_attr_xmlns(Xmlns, + _xmlns_attrs), + {xmlel, <<"csi">>, _attrs, _els}. + +decode_feature_csi_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_feature_csi_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_feature_csi_attr_xmlns(undefined, _acc) -> _acc; +encode_feature_csi_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_carbons_sent(__TopXMLNS, __IgnoreEls, + {xmlel, <<"sent">>, _attrs, _els}) -> + Forwarded = decode_carbons_sent_els(__TopXMLNS, + __IgnoreEls, _els, error), + {carbons_sent, Forwarded}. + +decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, [], + Forwarded) -> + case Forwarded of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"forwarded">>, __TopXMLNS}}); + {value, Forwarded1} -> Forwarded1 + end; +decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], + Forwarded) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:xmpp:forward:0">> -> + decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, + {value, + decode_forwarded(<<"urn:xmpp:forward:0">>, + __IgnoreEls, _el)}); + _ -> + decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, + Forwarded) + end; +decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Forwarded) -> + decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, + Forwarded). + +encode_carbons_sent({carbons_sent, Forwarded}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_carbons_sent_$forwarded'(Forwarded, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"sent">>, _attrs, _els}. + +'encode_carbons_sent_$forwarded'(Forwarded, _acc) -> + [encode_forwarded(Forwarded, + [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]) + | _acc]. + +decode_carbons_received(__TopXMLNS, __IgnoreEls, + {xmlel, <<"received">>, _attrs, _els}) -> + Forwarded = decode_carbons_received_els(__TopXMLNS, + __IgnoreEls, _els, error), + {carbons_received, Forwarded}. + +decode_carbons_received_els(__TopXMLNS, __IgnoreEls, [], + Forwarded) -> + case Forwarded of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"forwarded">>, __TopXMLNS}}); + {value, Forwarded1} -> Forwarded1 + end; +decode_carbons_received_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], + Forwarded) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:xmpp:forward:0">> -> + decode_carbons_received_els(__TopXMLNS, __IgnoreEls, + _els, + {value, + decode_forwarded(<<"urn:xmpp:forward:0">>, + __IgnoreEls, _el)}); + _ -> + decode_carbons_received_els(__TopXMLNS, __IgnoreEls, + _els, Forwarded) + end; +decode_carbons_received_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Forwarded) -> + decode_carbons_received_els(__TopXMLNS, __IgnoreEls, + _els, Forwarded). + +encode_carbons_received({carbons_received, Forwarded}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_carbons_received_$forwarded'(Forwarded, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"received">>, _attrs, _els}. + +'encode_carbons_received_$forwarded'(Forwarded, _acc) -> + [encode_forwarded(Forwarded, + [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]) + | _acc]. + +decode_carbons_private(__TopXMLNS, __IgnoreEls, + {xmlel, <<"private">>, _attrs, _els}) -> + {carbons_private}. + +encode_carbons_private({carbons_private}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"private">>, _attrs, _els}. + +decode_carbons_enable(__TopXMLNS, __IgnoreEls, + {xmlel, <<"enable">>, _attrs, _els}) -> + {carbons_enable}. + +encode_carbons_enable({carbons_enable}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"enable">>, _attrs, _els}. + +decode_carbons_disable(__TopXMLNS, __IgnoreEls, + {xmlel, <<"disable">>, _attrs, _els}) -> + {carbons_disable}. + +encode_carbons_disable({carbons_disable}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"disable">>, _attrs, _els}. + +decode_forwarded(__TopXMLNS, __IgnoreEls, + {xmlel, <<"forwarded">>, _attrs, _els}) -> + {Delay, __Els} = decode_forwarded_els(__TopXMLNS, + __IgnoreEls, _els, undefined, []), + {forwarded, Delay, __Els}. + +decode_forwarded_els(__TopXMLNS, __IgnoreEls, [], Delay, + __Els) -> + {Delay, lists:reverse(__Els)}; +decode_forwarded_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"delay">>, _attrs, _} = _el | _els], Delay, + __Els) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:xmpp:delay">> -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + decode_delay(<<"urn:xmpp:delay">>, __IgnoreEls, + _el), + __Els); + _ -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, __Els) + end; +decode_forwarded_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], Delay, __Els) -> + if __IgnoreEls -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, [decode(_el) | __Els]); + false -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, __Els) + end + end; +decode_forwarded_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Delay, __Els) -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, __Els). + +encode_forwarded({forwarded, Delay, __Els}, + _xmlns_attrs) -> + _els = [encode(_el) || _el <- __Els] ++ + lists:reverse('encode_forwarded_$delay'(Delay, [])), + _attrs = _xmlns_attrs, + {xmlel, <<"forwarded">>, _attrs, _els}. + +'encode_forwarded_$delay'(undefined, _acc) -> _acc; +'encode_forwarded_$delay'(Delay, _acc) -> + [encode_delay(Delay, + [{<<"xmlns">>, <<"urn:xmpp:delay">>}]) + | _acc]. + +decode_mam_fin(__TopXMLNS, __IgnoreEls, + {xmlel, <<"fin">>, _attrs, _els}) -> + Rsm = decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, + undefined), + {Id, Stable, Complete} = + decode_mam_fin_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {mam_fin, Id, Rsm, Stable, Complete}. + +decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [], Rsm) -> + Rsm; +decode_mam_fin_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"set">>, _attrs, _} = _el | _els], Rsm) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/rsm">> -> + decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, + decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el)); + _ -> + 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, Stable, + Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, _val, Stable, + Complete); +decode_mam_fin_attrs(__TopXMLNS, + [{<<"stable">>, _val} | _attrs], Id, _Stable, + Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, _val, + Complete); +decode_mam_fin_attrs(__TopXMLNS, + [{<<"complete">>, _val} | _attrs], Id, Stable, + _Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Stable, + _val); +decode_mam_fin_attrs(__TopXMLNS, [_ | _attrs], Id, + Stable, Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Stable, + Complete); +decode_mam_fin_attrs(__TopXMLNS, [], Id, Stable, + Complete) -> + {decode_mam_fin_attr_queryid(__TopXMLNS, Id), + decode_mam_fin_attr_stable(__TopXMLNS, Stable), + decode_mam_fin_attr_complete(__TopXMLNS, Complete)}. + +encode_mam_fin({mam_fin, Id, Rsm, Stable, Complete}, + _xmlns_attrs) -> + _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, [])), + _attrs = encode_mam_fin_attr_complete(Complete, + encode_mam_fin_attr_stable(Stable, + 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_fin_attr_stable(__TopXMLNS, undefined) -> + undefined; +decode_mam_fin_attr_stable(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"stable">>, <<"fin">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mam_fin_attr_stable(undefined, _acc) -> _acc; +encode_mam_fin_attr_stable(_val, _acc) -> + [{<<"stable">>, enc_bool(_val)} | _acc]. + +decode_mam_fin_attr_complete(__TopXMLNS, undefined) -> + undefined; +decode_mam_fin_attr_complete(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"complete">>, <<"fin">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_mam_fin_attr_complete(undefined, _acc) -> _acc; +encode_mam_fin_attr_complete(_val, _acc) -> + [{<<"complete">>, enc_bool(_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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + Never, + decode_mam_always(__TopXMLNS, __IgnoreEls, _el)); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + Never, + decode_mam_always(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el)); + _ -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + Never, Always) + end; +decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"never">>, _attrs, _} = _el | _els], Never, + Always) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + decode_mam_never(__TopXMLNS, __IgnoreEls, _el), + Always); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + decode_mam_never(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el), + Always); + _ -> + 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, []) | _acc]. + +'encode_mam_prefs_$always'([], _acc) -> _acc; +'encode_mam_prefs_$always'(Always, _acc) -> + [encode_mam_always(Always, []) | _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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(__TopXMLNS, __IgnoreEls, + _el) + of + [] -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el) + of + [] -> Jids; + _new_el -> [_new_el | Jids] + end); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(__TopXMLNS, __IgnoreEls, _el) + of + [] -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el) + of + [] -> Jids; + _new_el -> [_new_el | Jids] + end); + _ -> + 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, + <>); +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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, End, + decode_mam_start(__TopXMLNS, __IgnoreEls, _el), + With, Rsm); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, End, + decode_mam_start(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el), + With, Rsm); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + decode_mam_end(__TopXMLNS, __IgnoreEls, _el), + Start, With, Rsm); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + decode_mam_end(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el), + Start, With, Rsm); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, End, Start, + decode_mam_with(__TopXMLNS, __IgnoreEls, _el), + Rsm); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, End, Start, + decode_mam_with(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el), + Rsm); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/rsm">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, End, Start, With, + decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el)); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, __IgnoreEls, + _el), + End, Start, With, Rsm); + _ -> + 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, []) | _acc]. + +'encode_mam_query_$start'(undefined, _acc) -> _acc; +'encode_mam_query_$start'(Start, _acc) -> + [encode_mam_start(Start, []) | _acc]. + +'encode_mam_query_$with'(undefined, _acc) -> _acc; +'encode_mam_query_$with'(With, _acc) -> + [encode_mam_with(With, []) | _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, + <>); +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, + <>); +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, + <>); +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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, + decode_rsm_after(__TopXMLNS, __IgnoreEls, _el), + Last, First, Count, Before, Max, Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, + decode_rsm_after(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Last, First, Count, Before, Max, Index); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, + decode_rsm_before(__TopXMLNS, __IgnoreEls, _el), + Max, Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, + decode_rsm_before(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Max, Index); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, + decode_rsm_count(__TopXMLNS, __IgnoreEls, _el), + Before, Max, Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, + decode_rsm_count(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Before, Max, Index); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, + decode_rsm_first(__TopXMLNS, __IgnoreEls, _el), + Count, Before, Max, Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, + decode_rsm_first(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Count, Before, Max, Index); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, Before, Max, + decode_rsm_index(__TopXMLNS, __IgnoreEls, _el)); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, Before, Max, + decode_rsm_index(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el)); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + decode_rsm_last(__TopXMLNS, __IgnoreEls, _el), + First, Count, Before, Max, Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + decode_rsm_last(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + First, Count, Before, Max, Index); + _ -> + 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) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, Before, + decode_rsm_max(__TopXMLNS, __IgnoreEls, _el), + Index); + <<"http://jabber.org/protocol/rsm">> -> + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, + Last, First, Count, Before, + decode_rsm_max(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Index); + _ -> + 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, + <>); +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, + <>); +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, + <>); +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, + <>); +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, + <>); +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, + <>); +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, <<>>) -> none; +decode_rsm_before_cdata(__TopXMLNS, _val) -> _val. + +encode_rsm_before_cdata(none, _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, + <>); +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, + undefined), + Password = decode_muc_attrs(__TopXMLNS, _attrs, + undefined), + {muc, History, Password}. + +decode_muc_els(__TopXMLNS, __IgnoreEls, [], History) -> + History; +decode_muc_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"history">>, _attrs, _} = _el | _els], + History) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_history(__TopXMLNS, __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_history(<<"http://jabber.org/protocol/muc">>, + __IgnoreEls, _el)); + _ -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, History) + end; +decode_muc_els(__TopXMLNS, __IgnoreEls, [_ | _els], + History) -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, History). + +decode_muc_attrs(__TopXMLNS, + [{<<"password">>, _val} | _attrs], _Password) -> + decode_muc_attrs(__TopXMLNS, _attrs, _val); +decode_muc_attrs(__TopXMLNS, [_ | _attrs], Password) -> + decode_muc_attrs(__TopXMLNS, _attrs, Password); +decode_muc_attrs(__TopXMLNS, [], Password) -> + decode_muc_attr_password(__TopXMLNS, Password). + +encode_muc({muc, History, Password}, _xmlns_attrs) -> + _els = lists:reverse('encode_muc_$history'(History, + [])), + _attrs = encode_muc_attr_password(Password, + _xmlns_attrs), + {xmlel, <<"x">>, _attrs, _els}. + +'encode_muc_$history'(undefined, _acc) -> _acc; +'encode_muc_$history'(History, _acc) -> + [encode_muc_history(History, []) | _acc]. + +decode_muc_attr_password(__TopXMLNS, undefined) -> + undefined; +decode_muc_attr_password(__TopXMLNS, _val) -> _val. + +encode_muc_attr_password(undefined, _acc) -> _acc; +encode_muc_attr_password(_val, _acc) -> + [{<<"password">>, _val} | _acc]. + +decode_muc_admin(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + Items = decode_muc_admin_els(__TopXMLNS, __IgnoreEls, + _els, []), + {muc_admin, Items}. + +decode_muc_admin_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_muc_admin_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_admin_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_muc_admin_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +encode_muc_admin({muc_admin, Items}, _xmlns_attrs) -> + _els = lists:reverse('encode_muc_admin_$items'(Items, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_muc_admin_$items'([], _acc) -> _acc; +'encode_muc_admin_$items'([Items | _els], _acc) -> + 'encode_muc_admin_$items'(_els, + [encode_muc_admin_item(Items, []) | _acc]). + +decode_muc_admin_reason(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reason">>, _attrs, _els}) -> + Cdata = decode_muc_admin_reason_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_muc_admin_reason_cdata(__TopXMLNS, Cdata); +decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_muc_admin_reason(Cdata, _xmlns_attrs) -> + _els = encode_muc_admin_reason_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"reason">>, _attrs, _els}. + +decode_muc_admin_reason_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_muc_admin_reason_cdata(__TopXMLNS, _val) -> _val. + +encode_muc_admin_reason_cdata(undefined, _acc) -> _acc; +encode_muc_admin_reason_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc_admin_continue(__TopXMLNS, __IgnoreEls, + {xmlel, <<"continue">>, _attrs, _els}) -> + Thread = decode_muc_admin_continue_attrs(__TopXMLNS, + _attrs, undefined), + Thread. + +decode_muc_admin_continue_attrs(__TopXMLNS, + [{<<"thread">>, _val} | _attrs], _Thread) -> + decode_muc_admin_continue_attrs(__TopXMLNS, _attrs, + _val); +decode_muc_admin_continue_attrs(__TopXMLNS, + [_ | _attrs], Thread) -> + decode_muc_admin_continue_attrs(__TopXMLNS, _attrs, + Thread); +decode_muc_admin_continue_attrs(__TopXMLNS, [], + Thread) -> + decode_muc_admin_continue_attr_thread(__TopXMLNS, + Thread). + +encode_muc_admin_continue(Thread, _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_admin_continue_attr_thread(Thread, + _xmlns_attrs), + {xmlel, <<"continue">>, _attrs, _els}. + +decode_muc_admin_continue_attr_thread(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_continue_attr_thread(__TopXMLNS, + _val) -> + _val. + +encode_muc_admin_continue_attr_thread(undefined, + _acc) -> + _acc; +encode_muc_admin_continue_attr_thread(_val, _acc) -> + [{<<"thread">>, _val} | _acc]. + +decode_muc_admin_actor(__TopXMLNS, __IgnoreEls, + {xmlel, <<"actor">>, _attrs, _els}) -> + {Jid, Nick} = decode_muc_admin_actor_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {muc_actor, Jid, Nick}. + +decode_muc_admin_actor_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> + decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, _val, + Nick); +decode_muc_admin_actor_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> + decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, Jid, + _val); +decode_muc_admin_actor_attrs(__TopXMLNS, [_ | _attrs], + Jid, Nick) -> + decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, Jid, + Nick); +decode_muc_admin_actor_attrs(__TopXMLNS, [], Jid, + Nick) -> + {decode_muc_admin_actor_attr_jid(__TopXMLNS, Jid), + decode_muc_admin_actor_attr_nick(__TopXMLNS, Nick)}. + +encode_muc_admin_actor({muc_actor, Jid, Nick}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_admin_actor_attr_nick(Nick, + encode_muc_admin_actor_attr_jid(Jid, + _xmlns_attrs)), + {xmlel, <<"actor">>, _attrs, _els}. + +decode_muc_admin_actor_attr_jid(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_actor_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"actor">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_admin_actor_attr_jid(undefined, _acc) -> + _acc; +encode_muc_admin_actor_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_admin_actor_attr_nick(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_actor_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_admin_actor_attr_nick(undefined, _acc) -> + _acc; +encode_muc_admin_actor_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_muc_admin_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Actor, Continue, Reason} = + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined), + {Affiliation, Role, Jid, Nick} = + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, undefined), + {muc_item, Actor, Continue, Reason, Affiliation, Role, + Jid, Nick}. + +decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, [], + Actor, Continue, Reason) -> + {Actor, Continue, Reason}; +decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, + Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_admin_actor(__TopXMLNS, + __IgnoreEls, _el), + Continue, Reason); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el), + Continue, Reason); + _ -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"continue">>, _attrs, _} = _el | _els], + Actor, Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, + decode_muc_admin_continue(__TopXMLNS, + __IgnoreEls, _el), + Reason); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, + decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el), + Reason); + _ -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Actor, Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_admin_reason(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_admin_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + _ -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Actor, Continue, Reason) -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason). + +decode_muc_admin_item_attrs(__TopXMLNS, + [{<<"affiliation">>, _val} | _attrs], _Affiliation, + Role, Jid, Nick) -> + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, _val, + Role, Jid, Nick); +decode_muc_admin_item_attrs(__TopXMLNS, + [{<<"role">>, _val} | _attrs], Affiliation, _Role, + Jid, Nick) -> + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, + Affiliation, _val, Jid, Nick); +decode_muc_admin_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Affiliation, Role, + _Jid, Nick) -> + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, _val, Nick); +decode_muc_admin_item_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Affiliation, Role, + Jid, _Nick) -> + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, _val); +decode_muc_admin_item_attrs(__TopXMLNS, [_ | _attrs], + Affiliation, Role, Jid, Nick) -> + decode_muc_admin_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, Nick); +decode_muc_admin_item_attrs(__TopXMLNS, [], Affiliation, + Role, Jid, Nick) -> + {decode_muc_admin_item_attr_affiliation(__TopXMLNS, + Affiliation), + decode_muc_admin_item_attr_role(__TopXMLNS, Role), + decode_muc_admin_item_attr_jid(__TopXMLNS, Jid), + decode_muc_admin_item_attr_nick(__TopXMLNS, Nick)}. + +encode_muc_admin_item({muc_item, Actor, Continue, + Reason, Affiliation, Role, Jid, Nick}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_admin_item_$actor'(Actor, + 'encode_muc_admin_item_$continue'(Continue, + 'encode_muc_admin_item_$reason'(Reason, + [])))), + _attrs = encode_muc_admin_item_attr_nick(Nick, + encode_muc_admin_item_attr_jid(Jid, + encode_muc_admin_item_attr_role(Role, + encode_muc_admin_item_attr_affiliation(Affiliation, + _xmlns_attrs)))), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_muc_admin_item_$actor'(undefined, _acc) -> _acc; +'encode_muc_admin_item_$actor'(Actor, _acc) -> + [encode_muc_admin_actor(Actor, []) | _acc]. + +'encode_muc_admin_item_$continue'(undefined, _acc) -> + _acc; +'encode_muc_admin_item_$continue'(Continue, _acc) -> + [encode_muc_admin_continue(Continue, []) | _acc]. + +'encode_muc_admin_item_$reason'(undefined, _acc) -> + _acc; +'encode_muc_admin_item_$reason'(Reason, _acc) -> + [encode_muc_admin_reason(Reason, []) | _acc]. + +decode_muc_admin_item_attr_affiliation(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_item_attr_affiliation(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [admin, member, none, outcast, owner]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"affiliation">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_admin_item_attr_affiliation(undefined, + _acc) -> + _acc; +encode_muc_admin_item_attr_affiliation(_val, _acc) -> + [{<<"affiliation">>, enc_enum(_val)} | _acc]. + +decode_muc_admin_item_attr_role(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_item_attr_role(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [moderator, none, participant, visitor]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_admin_item_attr_role(undefined, _acc) -> + _acc; +encode_muc_admin_item_attr_role(_val, _acc) -> + [{<<"role">>, enc_enum(_val)} | _acc]. + +decode_muc_admin_item_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_muc_admin_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_admin_item_attr_jid(undefined, _acc) -> _acc; +encode_muc_admin_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_admin_item_attr_nick(__TopXMLNS, + undefined) -> + undefined; +decode_muc_admin_item_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_admin_item_attr_nick(undefined, _acc) -> + _acc; +encode_muc_admin_item_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_muc_owner(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Config, Destroy} = decode_muc_owner_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined), + {muc_owner, Destroy, Config}. + +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, [], + Config, Destroy) -> + {Config, Destroy}; +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], + Config, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Config, + decode_muc_owner_destroy(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Config, + decode_muc_owner_destroy(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); + _ -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Config, Destroy) + end; +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Config, + Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, __IgnoreEls, + _el), + Destroy); + _ -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Config, Destroy) + end; +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Config, Destroy) -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Config, Destroy). + +encode_muc_owner({muc_owner, Destroy, Config}, + _xmlns_attrs) -> + _els = lists:reverse('encode_muc_owner_$config'(Config, + 'encode_muc_owner_$destroy'(Destroy, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_muc_owner_$config'(undefined, _acc) -> _acc; +'encode_muc_owner_$config'(Config, _acc) -> + [encode_xdata(Config, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +'encode_muc_owner_$destroy'(undefined, _acc) -> _acc; +'encode_muc_owner_$destroy'(Destroy, _acc) -> + [encode_muc_owner_destroy(Destroy, []) | _acc]. + +decode_muc_owner_destroy(__TopXMLNS, __IgnoreEls, + {xmlel, <<"destroy">>, _attrs, _els}) -> + {Password, Reason} = + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, undefined, undefined), + Jid = decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, + undefined), + {muc_owner_destroy, Jid, Reason, Password}. + +decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + [], Password, Reason) -> + {Password, Reason}; +decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], + Password, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_owner_password(__TopXMLNS, + __IgnoreEls, + _el), + Reason); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_owner_password(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, + _el), + Reason); + _ -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Password, Reason) + end; +decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Password, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Password, + decode_muc_owner_reason(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Password, + decode_muc_owner_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, + _el)); + _ -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Password, Reason) + end; +decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Password, Reason) -> + decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Password, Reason). + +decode_muc_owner_destroy_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, + _val); +decode_muc_owner_destroy_attrs(__TopXMLNS, [_ | _attrs], + Jid) -> + decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, Jid); +decode_muc_owner_destroy_attrs(__TopXMLNS, [], Jid) -> + decode_muc_owner_destroy_attr_jid(__TopXMLNS, Jid). + +encode_muc_owner_destroy({muc_owner_destroy, Jid, + Reason, Password}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_owner_destroy_$password'(Password, + 'encode_muc_owner_destroy_$reason'(Reason, + []))), + _attrs = encode_muc_owner_destroy_attr_jid(Jid, + _xmlns_attrs), + {xmlel, <<"destroy">>, _attrs, _els}. + +'encode_muc_owner_destroy_$password'(undefined, _acc) -> + _acc; +'encode_muc_owner_destroy_$password'(Password, _acc) -> + [encode_muc_owner_password(Password, []) | _acc]. + +'encode_muc_owner_destroy_$reason'(undefined, _acc) -> + _acc; +'encode_muc_owner_destroy_$reason'(Reason, _acc) -> + [encode_muc_owner_reason(Reason, []) | _acc]. + +decode_muc_owner_destroy_attr_jid(__TopXMLNS, + undefined) -> + undefined; +decode_muc_owner_destroy_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"destroy">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_owner_destroy_attr_jid(undefined, _acc) -> + _acc; +encode_muc_owner_destroy_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_owner_reason(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reason">>, _attrs, _els}) -> + Cdata = decode_muc_owner_reason_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_muc_owner_reason_cdata(__TopXMLNS, Cdata); +decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_muc_owner_reason(Cdata, _xmlns_attrs) -> + _els = encode_muc_owner_reason_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"reason">>, _attrs, _els}. + +decode_muc_owner_reason_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_muc_owner_reason_cdata(__TopXMLNS, _val) -> _val. + +encode_muc_owner_reason_cdata(undefined, _acc) -> _acc; +encode_muc_owner_reason_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc_owner_password(__TopXMLNS, __IgnoreEls, + {xmlel, <<"password">>, _attrs, _els}) -> + Cdata = decode_muc_owner_password_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_muc_owner_password_cdata(__TopXMLNS, Cdata); +decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_muc_owner_password(Cdata, _xmlns_attrs) -> + _els = encode_muc_owner_password_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"password">>, _attrs, _els}. + +decode_muc_owner_password_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_muc_owner_password_cdata(__TopXMLNS, _val) -> + _val. + +encode_muc_owner_password_cdata(undefined, _acc) -> + _acc; +encode_muc_owner_password_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc_user(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Status_codes, Items, Invites, Decline, Destroy} = + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, [], + [], [], undefined, undefined), + Password = decode_muc_user_attrs(__TopXMLNS, _attrs, + undefined), + {muc_user, Decline, Destroy, Invites, Items, + Status_codes, Password}. + +decode_muc_user_els(__TopXMLNS, __IgnoreEls, [], + Status_codes, Items, Invites, Decline, Destroy) -> + {lists:reverse(Status_codes), lists:reverse(Items), + lists:reverse(Invites), Decline, Destroy}; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"decline">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_user_decline(__TopXMLNS, __IgnoreEls, + _el), + Destroy); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Destroy); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, + decode_muc_user_destroy(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, + decode_muc_user_destroy(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invite">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, + [decode_muc_user_invite(__TopXMLNS, __IgnoreEls, + _el) + | Invites], + Decline, Destroy); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, + [decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el) + | Invites], + Decline, Destroy); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, + [decode_muc_user_item(__TopXMLNS, __IgnoreEls, + _el) + | Items], + Invites, Decline, Destroy); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, + [decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el) + | Items], + Invites, Decline, Destroy); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"status">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + case decode_muc_user_status(__TopXMLNS, + __IgnoreEls, _el) + of + undefined -> Status_codes; + _new_el -> [_new_el | Status_codes] + end, + Items, Invites, Decline, Destroy); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + case + decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el) + of + undefined -> Status_codes; + _new_el -> [_new_el | Status_codes] + end, + Items, Invites, Decline, Destroy); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Status_codes, Items, Invites, Decline, Destroy) -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Decline, Destroy). + +decode_muc_user_attrs(__TopXMLNS, + [{<<"password">>, _val} | _attrs], _Password) -> + decode_muc_user_attrs(__TopXMLNS, _attrs, _val); +decode_muc_user_attrs(__TopXMLNS, [_ | _attrs], + Password) -> + decode_muc_user_attrs(__TopXMLNS, _attrs, Password); +decode_muc_user_attrs(__TopXMLNS, [], Password) -> + decode_muc_user_attr_password(__TopXMLNS, Password). + +encode_muc_user({muc_user, Decline, Destroy, Invites, + Items, Status_codes, Password}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_user_$status_codes'(Status_codes, + 'encode_muc_user_$items'(Items, + 'encode_muc_user_$invites'(Invites, + 'encode_muc_user_$decline'(Decline, + 'encode_muc_user_$destroy'(Destroy, + [])))))), + _attrs = encode_muc_user_attr_password(Password, + _xmlns_attrs), + {xmlel, <<"x">>, _attrs, _els}. + +'encode_muc_user_$status_codes'([], _acc) -> _acc; +'encode_muc_user_$status_codes'([Status_codes | _els], + _acc) -> + 'encode_muc_user_$status_codes'(_els, + [encode_muc_user_status(Status_codes, []) + | _acc]). + +'encode_muc_user_$items'([], _acc) -> _acc; +'encode_muc_user_$items'([Items | _els], _acc) -> + 'encode_muc_user_$items'(_els, + [encode_muc_user_item(Items, []) | _acc]). + +'encode_muc_user_$invites'([], _acc) -> _acc; +'encode_muc_user_$invites'([Invites | _els], _acc) -> + 'encode_muc_user_$invites'(_els, + [encode_muc_user_invite(Invites, []) | _acc]). + +'encode_muc_user_$decline'(undefined, _acc) -> _acc; +'encode_muc_user_$decline'(Decline, _acc) -> + [encode_muc_user_decline(Decline, []) | _acc]. + +'encode_muc_user_$destroy'(undefined, _acc) -> _acc; +'encode_muc_user_$destroy'(Destroy, _acc) -> + [encode_muc_user_destroy(Destroy, []) | _acc]. + +decode_muc_user_attr_password(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_attr_password(__TopXMLNS, _val) -> _val. + +encode_muc_user_attr_password(undefined, _acc) -> _acc; +encode_muc_user_attr_password(_val, _acc) -> + [{<<"password">>, _val} | _acc]. + +decode_muc_user_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Actor, Continue, Reason} = + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined), + {Affiliation, Role, Jid, Nick} = + decode_muc_user_item_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, undefined), + {muc_item, Actor, Continue, Reason, Affiliation, Role, + Jid, Nick}. + +decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, [], + Actor, Continue, Reason) -> + {Actor, Continue, Reason}; +decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, + Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_user_actor(__TopXMLNS, + __IgnoreEls, _el), + Continue, Reason); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Continue, Reason); + _ -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"continue">>, _attrs, _} = _el | _els], + Actor, Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, + decode_muc_user_continue(__TopXMLNS, + __IgnoreEls, _el), + Reason); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, + decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Reason); + _ -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], Actor, + Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_user_reason(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Actor, Continue, Reason) -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason). + +decode_muc_user_item_attrs(__TopXMLNS, + [{<<"affiliation">>, _val} | _attrs], _Affiliation, + Role, Jid, Nick) -> + decode_muc_user_item_attrs(__TopXMLNS, _attrs, _val, + Role, Jid, Nick); +decode_muc_user_item_attrs(__TopXMLNS, + [{<<"role">>, _val} | _attrs], Affiliation, _Role, + Jid, Nick) -> + decode_muc_user_item_attrs(__TopXMLNS, _attrs, + Affiliation, _val, Jid, Nick); +decode_muc_user_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Affiliation, Role, + _Jid, Nick) -> + decode_muc_user_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, _val, Nick); +decode_muc_user_item_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Affiliation, Role, + Jid, _Nick) -> + decode_muc_user_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, _val); +decode_muc_user_item_attrs(__TopXMLNS, [_ | _attrs], + Affiliation, Role, Jid, Nick) -> + decode_muc_user_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, Nick); +decode_muc_user_item_attrs(__TopXMLNS, [], Affiliation, + Role, Jid, Nick) -> + {decode_muc_user_item_attr_affiliation(__TopXMLNS, + Affiliation), + decode_muc_user_item_attr_role(__TopXMLNS, Role), + decode_muc_user_item_attr_jid(__TopXMLNS, Jid), + decode_muc_user_item_attr_nick(__TopXMLNS, Nick)}. + +encode_muc_user_item({muc_item, Actor, Continue, Reason, + Affiliation, Role, Jid, Nick}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_user_item_$actor'(Actor, + 'encode_muc_user_item_$continue'(Continue, + 'encode_muc_user_item_$reason'(Reason, + [])))), + _attrs = encode_muc_user_item_attr_nick(Nick, + encode_muc_user_item_attr_jid(Jid, + encode_muc_user_item_attr_role(Role, + encode_muc_user_item_attr_affiliation(Affiliation, + _xmlns_attrs)))), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_muc_user_item_$actor'(undefined, _acc) -> _acc; +'encode_muc_user_item_$actor'(Actor, _acc) -> + [encode_muc_user_actor(Actor, []) | _acc]. + +'encode_muc_user_item_$continue'(undefined, _acc) -> + _acc; +'encode_muc_user_item_$continue'(Continue, _acc) -> + [encode_muc_user_continue(Continue, []) | _acc]. + +'encode_muc_user_item_$reason'(undefined, _acc) -> _acc; +'encode_muc_user_item_$reason'(Reason, _acc) -> + [encode_muc_user_reason(Reason, []) | _acc]. + +decode_muc_user_item_attr_affiliation(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_item_attr_affiliation(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [admin, member, none, outcast, owner]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"affiliation">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_item_attr_affiliation(undefined, + _acc) -> + _acc; +encode_muc_user_item_attr_affiliation(_val, _acc) -> + [{<<"affiliation">>, enc_enum(_val)} | _acc]. + +decode_muc_user_item_attr_role(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_item_attr_role(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [moderator, none, participant, visitor]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_item_attr_role(undefined, _acc) -> _acc; +encode_muc_user_item_attr_role(_val, _acc) -> + [{<<"role">>, enc_enum(_val)} | _acc]. + +decode_muc_user_item_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_item_attr_jid(undefined, _acc) -> _acc; +encode_muc_user_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_user_item_attr_nick(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_item_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_user_item_attr_nick(undefined, _acc) -> _acc; +encode_muc_user_item_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_muc_user_status(__TopXMLNS, __IgnoreEls, + {xmlel, <<"status">>, _attrs, _els}) -> + Code = decode_muc_user_status_attrs(__TopXMLNS, _attrs, + undefined), + Code. + +decode_muc_user_status_attrs(__TopXMLNS, + [{<<"code">>, _val} | _attrs], _Code) -> + decode_muc_user_status_attrs(__TopXMLNS, _attrs, _val); +decode_muc_user_status_attrs(__TopXMLNS, [_ | _attrs], + Code) -> + decode_muc_user_status_attrs(__TopXMLNS, _attrs, Code); +decode_muc_user_status_attrs(__TopXMLNS, [], Code) -> + decode_muc_user_status_attr_code(__TopXMLNS, Code). + +encode_muc_user_status(Code, _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_user_status_attr_code(Code, + _xmlns_attrs), + {xmlel, <<"status">>, _attrs, _els}. + +decode_muc_user_status_attr_code(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_status_attr_code(__TopXMLNS, _val) -> + case catch dec_int(_val, 100, 999) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"code">>, <<"status">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_status_attr_code(undefined, _acc) -> + _acc; +encode_muc_user_status_attr_code(_val, _acc) -> + [{<<"code">>, enc_int(_val)} | _acc]. + +decode_muc_user_continue(__TopXMLNS, __IgnoreEls, + {xmlel, <<"continue">>, _attrs, _els}) -> + Thread = decode_muc_user_continue_attrs(__TopXMLNS, + _attrs, undefined), + Thread. + +decode_muc_user_continue_attrs(__TopXMLNS, + [{<<"thread">>, _val} | _attrs], _Thread) -> + decode_muc_user_continue_attrs(__TopXMLNS, _attrs, + _val); +decode_muc_user_continue_attrs(__TopXMLNS, [_ | _attrs], + Thread) -> + decode_muc_user_continue_attrs(__TopXMLNS, _attrs, + Thread); +decode_muc_user_continue_attrs(__TopXMLNS, [], + Thread) -> + decode_muc_user_continue_attr_thread(__TopXMLNS, + Thread). + +encode_muc_user_continue(Thread, _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_user_continue_attr_thread(Thread, + _xmlns_attrs), + {xmlel, <<"continue">>, _attrs, _els}. + +decode_muc_user_continue_attr_thread(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_continue_attr_thread(__TopXMLNS, + _val) -> + _val. + +encode_muc_user_continue_attr_thread(undefined, _acc) -> + _acc; +encode_muc_user_continue_attr_thread(_val, _acc) -> + [{<<"thread">>, _val} | _acc]. + +decode_muc_user_actor(__TopXMLNS, __IgnoreEls, + {xmlel, <<"actor">>, _attrs, _els}) -> + {Jid, Nick} = decode_muc_user_actor_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {muc_actor, Jid, Nick}. + +decode_muc_user_actor_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> + decode_muc_user_actor_attrs(__TopXMLNS, _attrs, _val, + Nick); +decode_muc_user_actor_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> + decode_muc_user_actor_attrs(__TopXMLNS, _attrs, Jid, + _val); +decode_muc_user_actor_attrs(__TopXMLNS, [_ | _attrs], + Jid, Nick) -> + decode_muc_user_actor_attrs(__TopXMLNS, _attrs, Jid, + Nick); +decode_muc_user_actor_attrs(__TopXMLNS, [], Jid, + Nick) -> + {decode_muc_user_actor_attr_jid(__TopXMLNS, Jid), + decode_muc_user_actor_attr_nick(__TopXMLNS, Nick)}. + +encode_muc_user_actor({muc_actor, Jid, Nick}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_user_actor_attr_nick(Nick, + encode_muc_user_actor_attr_jid(Jid, + _xmlns_attrs)), + {xmlel, <<"actor">>, _attrs, _els}. + +decode_muc_user_actor_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_actor_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"actor">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_actor_attr_jid(undefined, _acc) -> _acc; +encode_muc_user_actor_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_user_actor_attr_nick(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_actor_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_user_actor_attr_nick(undefined, _acc) -> + _acc; +encode_muc_user_actor_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_muc_user_invite(__TopXMLNS, __IgnoreEls, + {xmlel, <<"invite">>, _attrs, _els}) -> + Reason = decode_muc_user_invite_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + {To, From} = decode_muc_user_invite_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {muc_invite, Reason, From, To}. + +decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, [], + Reason) -> + Reason; +decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Reason) -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Reason). + +decode_muc_user_invite_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], _To, From) -> + decode_muc_user_invite_attrs(__TopXMLNS, _attrs, _val, + From); +decode_muc_user_invite_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], To, _From) -> + decode_muc_user_invite_attrs(__TopXMLNS, _attrs, To, + _val); +decode_muc_user_invite_attrs(__TopXMLNS, [_ | _attrs], + To, From) -> + decode_muc_user_invite_attrs(__TopXMLNS, _attrs, To, + From); +decode_muc_user_invite_attrs(__TopXMLNS, [], To, + From) -> + {decode_muc_user_invite_attr_to(__TopXMLNS, To), + decode_muc_user_invite_attr_from(__TopXMLNS, From)}. + +encode_muc_user_invite({muc_invite, Reason, From, To}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_user_invite_$reason'(Reason, + [])), + _attrs = encode_muc_user_invite_attr_from(From, + encode_muc_user_invite_attr_to(To, + _xmlns_attrs)), + {xmlel, <<"invite">>, _attrs, _els}. + +'encode_muc_user_invite_$reason'(undefined, _acc) -> + _acc; +'encode_muc_user_invite_$reason'(Reason, _acc) -> + [encode_muc_user_reason(Reason, []) | _acc]. + +decode_muc_user_invite_attr_to(__TopXMLNS, undefined) -> + undefined; +decode_muc_user_invite_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"invite">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_invite_attr_to(undefined, _acc) -> _acc; +encode_muc_user_invite_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +decode_muc_user_invite_attr_from(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_invite_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"invite">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_invite_attr_from(undefined, _acc) -> + _acc; +encode_muc_user_invite_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_muc_user_destroy(__TopXMLNS, __IgnoreEls, + {xmlel, <<"destroy">>, _attrs, _els}) -> + Reason = decode_muc_user_destroy_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + Jid = decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, + undefined), + {muc_user_destroy, Reason, Jid}. + +decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, [], + Reason) -> + Reason; +decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Reason) -> + decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, + _els, Reason). + +decode_muc_user_destroy_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, _val); +decode_muc_user_destroy_attrs(__TopXMLNS, [_ | _attrs], + Jid) -> + decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, Jid); +decode_muc_user_destroy_attrs(__TopXMLNS, [], Jid) -> + decode_muc_user_destroy_attr_jid(__TopXMLNS, Jid). + +encode_muc_user_destroy({muc_user_destroy, Reason, Jid}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_user_destroy_$reason'(Reason, + [])), + _attrs = encode_muc_user_destroy_attr_jid(Jid, + _xmlns_attrs), + {xmlel, <<"destroy">>, _attrs, _els}. + +'encode_muc_user_destroy_$reason'(undefined, _acc) -> + _acc; +'encode_muc_user_destroy_$reason'(Reason, _acc) -> + [encode_muc_user_reason(Reason, []) | _acc]. + +decode_muc_user_destroy_attr_jid(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_destroy_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"destroy">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_destroy_attr_jid(undefined, _acc) -> + _acc; +encode_muc_user_destroy_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_user_decline(__TopXMLNS, __IgnoreEls, + {xmlel, <<"decline">>, _attrs, _els}) -> + Reason = decode_muc_user_decline_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + {To, From} = decode_muc_user_decline_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {muc_decline, Reason, From, To}. + +decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, [], + Reason) -> + Reason; +decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Reason) -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, Reason). + +decode_muc_user_decline_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], _To, From) -> + decode_muc_user_decline_attrs(__TopXMLNS, _attrs, _val, + From); +decode_muc_user_decline_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], To, _From) -> + decode_muc_user_decline_attrs(__TopXMLNS, _attrs, To, + _val); +decode_muc_user_decline_attrs(__TopXMLNS, [_ | _attrs], + To, From) -> + decode_muc_user_decline_attrs(__TopXMLNS, _attrs, To, + From); +decode_muc_user_decline_attrs(__TopXMLNS, [], To, + From) -> + {decode_muc_user_decline_attr_to(__TopXMLNS, To), + decode_muc_user_decline_attr_from(__TopXMLNS, From)}. + +encode_muc_user_decline({muc_decline, Reason, From, To}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_user_decline_$reason'(Reason, + [])), + _attrs = encode_muc_user_decline_attr_from(From, + encode_muc_user_decline_attr_to(To, + _xmlns_attrs)), + {xmlel, <<"decline">>, _attrs, _els}. + +'encode_muc_user_decline_$reason'(undefined, _acc) -> + _acc; +'encode_muc_user_decline_$reason'(Reason, _acc) -> + [encode_muc_user_reason(Reason, []) | _acc]. + +decode_muc_user_decline_attr_to(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_decline_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"decline">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_decline_attr_to(undefined, _acc) -> + _acc; +encode_muc_user_decline_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +decode_muc_user_decline_attr_from(__TopXMLNS, + undefined) -> + undefined; +decode_muc_user_decline_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"decline">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_user_decline_attr_from(undefined, _acc) -> + _acc; +encode_muc_user_decline_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_muc_user_reason(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reason">>, _attrs, _els}) -> + Cdata = decode_muc_user_reason_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_muc_user_reason_cdata(__TopXMLNS, Cdata); +decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_muc_user_reason(Cdata, _xmlns_attrs) -> + _els = encode_muc_user_reason_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"reason">>, _attrs, _els}. + +decode_muc_user_reason_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_muc_user_reason_cdata(__TopXMLNS, _val) -> _val. + +encode_muc_user_reason_cdata(undefined, _acc) -> _acc; +encode_muc_user_reason_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc_history(__TopXMLNS, __IgnoreEls, + {xmlel, <<"history">>, _attrs, _els}) -> + {Maxchars, Maxstanzas, Seconds, Since} = + decode_muc_history_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {muc_history, Maxchars, Maxstanzas, Seconds, Since}. + +decode_muc_history_attrs(__TopXMLNS, + [{<<"maxchars">>, _val} | _attrs], _Maxchars, + Maxstanzas, Seconds, Since) -> + decode_muc_history_attrs(__TopXMLNS, _attrs, _val, + Maxstanzas, Seconds, Since); +decode_muc_history_attrs(__TopXMLNS, + [{<<"maxstanzas">>, _val} | _attrs], Maxchars, + _Maxstanzas, Seconds, Since) -> + decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, + _val, Seconds, Since); +decode_muc_history_attrs(__TopXMLNS, + [{<<"seconds">>, _val} | _attrs], Maxchars, Maxstanzas, + _Seconds, Since) -> + decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, + Maxstanzas, _val, Since); +decode_muc_history_attrs(__TopXMLNS, + [{<<"since">>, _val} | _attrs], Maxchars, Maxstanzas, + Seconds, _Since) -> + decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, + Maxstanzas, Seconds, _val); +decode_muc_history_attrs(__TopXMLNS, [_ | _attrs], + Maxchars, Maxstanzas, Seconds, Since) -> + decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, + Maxstanzas, Seconds, Since); +decode_muc_history_attrs(__TopXMLNS, [], Maxchars, + Maxstanzas, Seconds, Since) -> + {decode_muc_history_attr_maxchars(__TopXMLNS, Maxchars), + decode_muc_history_attr_maxstanzas(__TopXMLNS, + Maxstanzas), + decode_muc_history_attr_seconds(__TopXMLNS, Seconds), + decode_muc_history_attr_since(__TopXMLNS, Since)}. + +encode_muc_history({muc_history, Maxchars, Maxstanzas, + Seconds, Since}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_history_attr_since(Since, + encode_muc_history_attr_seconds(Seconds, + encode_muc_history_attr_maxstanzas(Maxstanzas, + encode_muc_history_attr_maxchars(Maxchars, + _xmlns_attrs)))), + {xmlel, <<"history">>, _attrs, _els}. + +decode_muc_history_attr_maxchars(__TopXMLNS, + undefined) -> + undefined; +decode_muc_history_attr_maxchars(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"maxchars">>, <<"history">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_history_attr_maxchars(undefined, _acc) -> + _acc; +encode_muc_history_attr_maxchars(_val, _acc) -> + [{<<"maxchars">>, enc_int(_val)} | _acc]. + +decode_muc_history_attr_maxstanzas(__TopXMLNS, + undefined) -> + undefined; +decode_muc_history_attr_maxstanzas(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"maxstanzas">>, <<"history">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_history_attr_maxstanzas(undefined, _acc) -> + _acc; +encode_muc_history_attr_maxstanzas(_val, _acc) -> + [{<<"maxstanzas">>, enc_int(_val)} | _acc]. + +decode_muc_history_attr_seconds(__TopXMLNS, + undefined) -> + undefined; +decode_muc_history_attr_seconds(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"seconds">>, <<"history">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_history_attr_seconds(undefined, _acc) -> + _acc; +encode_muc_history_attr_seconds(_val, _acc) -> + [{<<"seconds">>, enc_int(_val)} | _acc]. + +decode_muc_history_attr_since(__TopXMLNS, undefined) -> + undefined; +decode_muc_history_attr_since(__TopXMLNS, _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"since">>, <<"history">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_history_attr_since(undefined, _acc) -> _acc; +encode_muc_history_attr_since(_val, _acc) -> + [{<<"since">>, enc_utc(_val)} | _acc]. + +decode_bytestreams(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Hosts, Used, Activate} = + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + [], undefined, undefined), + {Dstaddr, Sid, Mode} = + decode_bytestreams_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {bytestreams, Hosts, Used, Activate, Dstaddr, Mode, + Sid}. + +decode_bytestreams_els(__TopXMLNS, __IgnoreEls, [], + Hosts, Used, Activate) -> + {lists:reverse(Hosts), Used, Activate}; +decode_bytestreams_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"streamhost">>, _attrs, _} = _el | _els], + Hosts, Used, Activate) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + [decode_bytestreams_streamhost(__TopXMLNS, + __IgnoreEls, + _el) + | Hosts], + Used, Activate); + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + [decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, + __IgnoreEls, + _el) + | Hosts], + Used, Activate); + _ -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, Activate) + end; +decode_bytestreams_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"streamhost-used">>, _attrs, _} = _el + | _els], + Hosts, Used, Activate) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, + decode_bytestreams_streamhost_used(__TopXMLNS, + __IgnoreEls, + _el), + Activate); + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, + decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, + __IgnoreEls, + _el), + Activate); + _ -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, Activate) + end; +decode_bytestreams_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"activate">>, _attrs, _} = _el | _els], + Hosts, Used, Activate) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, + decode_bytestreams_activate(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/bytestreams">> -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, + decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, + __IgnoreEls, _el)); + _ -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, Activate) + end; +decode_bytestreams_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Hosts, Used, Activate) -> + decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, + Hosts, Used, Activate). + +decode_bytestreams_attrs(__TopXMLNS, + [{<<"dstaddr">>, _val} | _attrs], _Dstaddr, Sid, + Mode) -> + decode_bytestreams_attrs(__TopXMLNS, _attrs, _val, Sid, + Mode); +decode_bytestreams_attrs(__TopXMLNS, + [{<<"sid">>, _val} | _attrs], Dstaddr, _Sid, Mode) -> + decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, + _val, Mode); +decode_bytestreams_attrs(__TopXMLNS, + [{<<"mode">>, _val} | _attrs], Dstaddr, Sid, _Mode) -> + decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, + Sid, _val); +decode_bytestreams_attrs(__TopXMLNS, [_ | _attrs], + Dstaddr, Sid, Mode) -> + decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, + Sid, Mode); +decode_bytestreams_attrs(__TopXMLNS, [], Dstaddr, Sid, + Mode) -> + {decode_bytestreams_attr_dstaddr(__TopXMLNS, Dstaddr), + decode_bytestreams_attr_sid(__TopXMLNS, Sid), + decode_bytestreams_attr_mode(__TopXMLNS, Mode)}. + +encode_bytestreams({bytestreams, Hosts, Used, Activate, + Dstaddr, Mode, Sid}, + _xmlns_attrs) -> + _els = lists:reverse('encode_bytestreams_$hosts'(Hosts, + 'encode_bytestreams_$used'(Used, + 'encode_bytestreams_$activate'(Activate, + [])))), + _attrs = encode_bytestreams_attr_mode(Mode, + encode_bytestreams_attr_sid(Sid, + encode_bytestreams_attr_dstaddr(Dstaddr, + _xmlns_attrs))), + {xmlel, <<"query">>, _attrs, _els}. + +'encode_bytestreams_$hosts'([], _acc) -> _acc; +'encode_bytestreams_$hosts'([Hosts | _els], _acc) -> + 'encode_bytestreams_$hosts'(_els, + [encode_bytestreams_streamhost(Hosts, []) + | _acc]). + +'encode_bytestreams_$used'(undefined, _acc) -> _acc; +'encode_bytestreams_$used'(Used, _acc) -> + [encode_bytestreams_streamhost_used(Used, []) | _acc]. + +'encode_bytestreams_$activate'(undefined, _acc) -> _acc; +'encode_bytestreams_$activate'(Activate, _acc) -> + [encode_bytestreams_activate(Activate, []) | _acc]. + +decode_bytestreams_attr_dstaddr(__TopXMLNS, + undefined) -> + undefined; +decode_bytestreams_attr_dstaddr(__TopXMLNS, _val) -> + _val. + +encode_bytestreams_attr_dstaddr(undefined, _acc) -> + _acc; +encode_bytestreams_attr_dstaddr(_val, _acc) -> + [{<<"dstaddr">>, _val} | _acc]. + +decode_bytestreams_attr_sid(__TopXMLNS, undefined) -> + undefined; +decode_bytestreams_attr_sid(__TopXMLNS, _val) -> _val. + +encode_bytestreams_attr_sid(undefined, _acc) -> _acc; +encode_bytestreams_attr_sid(_val, _acc) -> + [{<<"sid">>, _val} | _acc]. + +decode_bytestreams_attr_mode(__TopXMLNS, undefined) -> + tcp; +decode_bytestreams_attr_mode(__TopXMLNS, _val) -> + case catch dec_enum(_val, [tcp, udp]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"mode">>, <<"query">>, __TopXMLNS}}); + _res -> _res + end. + +encode_bytestreams_attr_mode(tcp, _acc) -> _acc; +encode_bytestreams_attr_mode(_val, _acc) -> + [{<<"mode">>, enc_enum(_val)} | _acc]. + +decode_bytestreams_activate(__TopXMLNS, __IgnoreEls, + {xmlel, <<"activate">>, _attrs, _els}) -> + Cdata = decode_bytestreams_activate_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_bytestreams_activate_cdata(__TopXMLNS, Cdata); +decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_bytestreams_activate(Cdata, _xmlns_attrs) -> + _els = encode_bytestreams_activate_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"activate">>, _attrs, _els}. + +decode_bytestreams_activate_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_bytestreams_activate_cdata(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"activate">>, __TopXMLNS}}); + _res -> _res + end. + +encode_bytestreams_activate_cdata(undefined, _acc) -> + _acc; +encode_bytestreams_activate_cdata(_val, _acc) -> + [{xmlcdata, enc_jid(_val)} | _acc]. + +decode_bytestreams_streamhost_used(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"streamhost-used">>, _attrs, + _els}) -> + Jid = + decode_bytestreams_streamhost_used_attrs(__TopXMLNS, + _attrs, undefined), + Jid. + +decode_bytestreams_streamhost_used_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_bytestreams_streamhost_used_attrs(__TopXMLNS, + _attrs, _val); +decode_bytestreams_streamhost_used_attrs(__TopXMLNS, + [_ | _attrs], Jid) -> + decode_bytestreams_streamhost_used_attrs(__TopXMLNS, + _attrs, Jid); +decode_bytestreams_streamhost_used_attrs(__TopXMLNS, [], + Jid) -> + decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, + Jid). + +encode_bytestreams_streamhost_used(Jid, _xmlns_attrs) -> + _els = [], + _attrs = + encode_bytestreams_streamhost_used_attr_jid(Jid, + _xmlns_attrs), + {xmlel, <<"streamhost-used">>, _attrs, _els}. + +decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"streamhost-used">>, + __TopXMLNS}}); +decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, + _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"streamhost-used">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_bytestreams_streamhost_used_attr_jid(_val, + _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_bytestreams_streamhost(__TopXMLNS, __IgnoreEls, + {xmlel, <<"streamhost">>, _attrs, _els}) -> + {Jid, Host, Port} = + decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined), + {streamhost, Jid, Host, Port}. + +decode_bytestreams_streamhost_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Host, + Port) -> + decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, + _val, Host, Port); +decode_bytestreams_streamhost_attrs(__TopXMLNS, + [{<<"host">>, _val} | _attrs], Jid, _Host, + Port) -> + decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, + Jid, _val, Port); +decode_bytestreams_streamhost_attrs(__TopXMLNS, + [{<<"port">>, _val} | _attrs], Jid, Host, + _Port) -> + decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, + Jid, Host, _val); +decode_bytestreams_streamhost_attrs(__TopXMLNS, + [_ | _attrs], Jid, Host, Port) -> + decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, + Jid, Host, Port); +decode_bytestreams_streamhost_attrs(__TopXMLNS, [], Jid, + Host, Port) -> + {decode_bytestreams_streamhost_attr_jid(__TopXMLNS, + Jid), + decode_bytestreams_streamhost_attr_host(__TopXMLNS, + Host), + decode_bytestreams_streamhost_attr_port(__TopXMLNS, + Port)}. + +encode_bytestreams_streamhost({streamhost, Jid, Host, + Port}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_bytestreams_streamhost_attr_port(Port, + encode_bytestreams_streamhost_attr_host(Host, + encode_bytestreams_streamhost_attr_jid(Jid, + _xmlns_attrs))), + {xmlel, <<"streamhost">>, _attrs, _els}. + +decode_bytestreams_streamhost_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"streamhost">>, + __TopXMLNS}}); +decode_bytestreams_streamhost_attr_jid(__TopXMLNS, + _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"streamhost">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_bytestreams_streamhost_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_bytestreams_streamhost_attr_host(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"host">>, <<"streamhost">>, + __TopXMLNS}}); +decode_bytestreams_streamhost_attr_host(__TopXMLNS, + _val) -> + _val. + +encode_bytestreams_streamhost_attr_host(_val, _acc) -> + [{<<"host">>, _val} | _acc]. + +decode_bytestreams_streamhost_attr_port(__TopXMLNS, + undefined) -> + 1080; +decode_bytestreams_streamhost_attr_port(__TopXMLNS, + _val) -> + case catch dec_int(_val, 0, 65535) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"port">>, <<"streamhost">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_bytestreams_streamhost_attr_port(1080, _acc) -> + _acc; +encode_bytestreams_streamhost_attr_port(_val, _acc) -> + [{<<"port">>, enc_int(_val)} | _acc]. + +decode_delay(__TopXMLNS, __IgnoreEls, + {xmlel, <<"delay">>, _attrs, _els}) -> + Desc = decode_delay_els(__TopXMLNS, __IgnoreEls, _els, + <<>>), + {Stamp, From} = decode_delay_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {delay, Stamp, From, Desc}. + +decode_delay_els(__TopXMLNS, __IgnoreEls, [], Desc) -> + decode_delay_cdata(__TopXMLNS, Desc); +decode_delay_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Desc) -> + decode_delay_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_delay_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Desc) -> + decode_delay_els(__TopXMLNS, __IgnoreEls, _els, Desc). + +decode_delay_attrs(__TopXMLNS, + [{<<"stamp">>, _val} | _attrs], _Stamp, From) -> + decode_delay_attrs(__TopXMLNS, _attrs, _val, From); +decode_delay_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], Stamp, _From) -> + decode_delay_attrs(__TopXMLNS, _attrs, Stamp, _val); +decode_delay_attrs(__TopXMLNS, [_ | _attrs], Stamp, + From) -> + decode_delay_attrs(__TopXMLNS, _attrs, Stamp, From); +decode_delay_attrs(__TopXMLNS, [], Stamp, From) -> + {decode_delay_attr_stamp(__TopXMLNS, Stamp), + decode_delay_attr_from(__TopXMLNS, From)}. + +encode_delay({delay, Stamp, From, Desc}, + _xmlns_attrs) -> + _els = encode_delay_cdata(Desc, []), + _attrs = encode_delay_attr_from(From, + encode_delay_attr_stamp(Stamp, + _xmlns_attrs)), + {xmlel, <<"delay">>, _attrs, _els}. + +decode_delay_attr_stamp(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"stamp">>, <<"delay">>, __TopXMLNS}}); +decode_delay_attr_stamp(__TopXMLNS, _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"stamp">>, <<"delay">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_delay_attr_stamp(_val, _acc) -> + [{<<"stamp">>, enc_utc(_val)} | _acc]. + +decode_delay_attr_from(__TopXMLNS, undefined) -> + undefined; +decode_delay_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"delay">>, __TopXMLNS}}); + _res -> _res + end. + +encode_delay_attr_from(undefined, _acc) -> _acc; +encode_delay_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_delay_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_delay_cdata(__TopXMLNS, _val) -> _val. + +encode_delay_cdata(<<>>, _acc) -> _acc; +encode_delay_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_chatstate_paused(__TopXMLNS, __IgnoreEls, + {xmlel, <<"paused">>, _attrs, _els}) -> + {chatstate, paused}. + +encode_chatstate_paused({chatstate, paused}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"paused">>, _attrs, _els}. + +decode_chatstate_inactive(__TopXMLNS, __IgnoreEls, + {xmlel, <<"inactive">>, _attrs, _els}) -> + {chatstate, inactive}. + +encode_chatstate_inactive({chatstate, inactive}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"inactive">>, _attrs, _els}. + +decode_chatstate_gone(__TopXMLNS, __IgnoreEls, + {xmlel, <<"gone">>, _attrs, _els}) -> + {chatstate, gone}. + +encode_chatstate_gone({chatstate, gone}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"gone">>, _attrs, _els}. + +decode_chatstate_composing(__TopXMLNS, __IgnoreEls, + {xmlel, <<"composing">>, _attrs, _els}) -> + {chatstate, composing}. + +encode_chatstate_composing({chatstate, composing}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"composing">>, _attrs, _els}. + +decode_chatstate_active(__TopXMLNS, __IgnoreEls, + {xmlel, <<"active">>, _attrs, _els}) -> + {chatstate, active}. + +encode_chatstate_active({chatstate, active}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"active">>, _attrs, _els}. + +decode_shim_headers(__TopXMLNS, __IgnoreEls, + {xmlel, <<"headers">>, _attrs, _els}) -> + Headers = decode_shim_headers_els(__TopXMLNS, + __IgnoreEls, _els, []), + {shim, Headers}. + +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, [], + Headers) -> + lists:reverse(Headers); +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"header">>, _attrs, _} = _el | _els], + Headers) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/shim">> -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + [decode_shim_header(__TopXMLNS, __IgnoreEls, + _el) + | Headers]); + <<"http://jabber.org/protocol/shim">> -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + [decode_shim_header(<<"http://jabber.org/protocol/shim">>, + __IgnoreEls, _el) + | Headers]); + _ -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + Headers) + end; +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Headers) -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + Headers). + +encode_shim_headers({shim, Headers}, _xmlns_attrs) -> + _els = + lists:reverse('encode_shim_headers_$headers'(Headers, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"headers">>, _attrs, _els}. + +'encode_shim_headers_$headers'([], _acc) -> _acc; +'encode_shim_headers_$headers'([Headers | _els], + _acc) -> + 'encode_shim_headers_$headers'(_els, + [encode_shim_header(Headers, []) | _acc]). + +decode_shim_header(__TopXMLNS, __IgnoreEls, + {xmlel, <<"header">>, _attrs, _els}) -> + Cdata = decode_shim_header_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Name = decode_shim_header_attrs(__TopXMLNS, _attrs, + undefined), + {Name, Cdata}. + +decode_shim_header_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_shim_header_cdata(__TopXMLNS, Cdata); +decode_shim_header_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_shim_header_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +decode_shim_header_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name) -> + decode_shim_header_attrs(__TopXMLNS, _attrs, _val); +decode_shim_header_attrs(__TopXMLNS, [_ | _attrs], + Name) -> + decode_shim_header_attrs(__TopXMLNS, _attrs, Name); +decode_shim_header_attrs(__TopXMLNS, [], Name) -> + decode_shim_header_attr_name(__TopXMLNS, Name). + +encode_shim_header({Name, Cdata}, _xmlns_attrs) -> + _els = encode_shim_header_cdata(Cdata, []), + _attrs = encode_shim_header_attr_name(Name, + _xmlns_attrs), + {xmlel, <<"header">>, _attrs, _els}. + +decode_shim_header_attr_name(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"header">>, __TopXMLNS}}); +decode_shim_header_attr_name(__TopXMLNS, _val) -> _val. + +encode_shim_header_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_shim_header_cdata(__TopXMLNS, <<>>) -> undefined; +decode_shim_header_cdata(__TopXMLNS, _val) -> _val. + +encode_shim_header_cdata(undefined, _acc) -> _acc; +encode_shim_header_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_pubsub(__TopXMLNS, __IgnoreEls, + {xmlel, <<"pubsub">>, _attrs, _els}) -> + {Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish} = + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, undefined, + undefined, undefined, undefined), + {pubsub, Subscriptions, Affiliations, Publish, + Subscribe, Unsubscribe, Options, Items, Retract}. + +decode_pubsub_els(__TopXMLNS, __IgnoreEls, [], Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + {Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish}; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], + Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, + decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, + _el), + Retract, Unsubscribe, Subscribe, Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Retract, Unsubscribe, Subscribe, Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], + Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, + decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, + _el), + Subscriptions, Retract, Unsubscribe, Subscribe, + Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, + decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Subscriptions, Retract, Unsubscribe, Subscribe, + Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], + Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, + decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, + _el), + Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, + decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsubscribe">>, _attrs, _} = _el | _els], + Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, + _el), + Subscribe, Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Subscribe, Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"options">>, _attrs, _} = _el | _els], Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + decode_pubsub_options(__TopXMLNS, __IgnoreEls, _el), + Affiliations, Subscriptions, Retract, Unsubscribe, + Subscribe, Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Affiliations, Subscriptions, Retract, Unsubscribe, + Subscribe, Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"items">>, _attrs, _} = _el | _els], Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_items(__TopXMLNS, __IgnoreEls, _el), + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"retract">>, _attrs, _} = _el | _els], Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, + decode_pubsub_retract(__TopXMLNS, __IgnoreEls, _el), + Unsubscribe, Subscribe, Publish); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, + decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Unsubscribe, Subscribe, Publish); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"publish">>, _attrs, _} = _el | _els], Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, + decode_pubsub_publish(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, + decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Items, Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish) -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, + Options, Affiliations, Subscriptions, Retract, + Unsubscribe, Subscribe, Publish). + +encode_pubsub({pubsub, Subscriptions, Affiliations, + Publish, Subscribe, Unsubscribe, Options, Items, + Retract}, + _xmlns_attrs) -> + _els = lists:reverse('encode_pubsub_$items'(Items, + 'encode_pubsub_$options'(Options, + 'encode_pubsub_$affiliations'(Affiliations, + 'encode_pubsub_$subscriptions'(Subscriptions, + 'encode_pubsub_$retract'(Retract, + 'encode_pubsub_$unsubscribe'(Unsubscribe, + 'encode_pubsub_$subscribe'(Subscribe, + 'encode_pubsub_$publish'(Publish, + []))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"pubsub">>, _attrs, _els}. + +'encode_pubsub_$items'(undefined, _acc) -> _acc; +'encode_pubsub_$items'(Items, _acc) -> + [encode_pubsub_items(Items, []) | _acc]. + +'encode_pubsub_$options'(undefined, _acc) -> _acc; +'encode_pubsub_$options'(Options, _acc) -> + [encode_pubsub_options(Options, []) | _acc]. + +'encode_pubsub_$affiliations'(undefined, _acc) -> _acc; +'encode_pubsub_$affiliations'(Affiliations, _acc) -> + [encode_pubsub_affiliations(Affiliations, []) | _acc]. + +'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc; +'encode_pubsub_$subscriptions'(Subscriptions, _acc) -> + [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. + +'encode_pubsub_$retract'(undefined, _acc) -> _acc; +'encode_pubsub_$retract'(Retract, _acc) -> + [encode_pubsub_retract(Retract, []) | _acc]. + +'encode_pubsub_$unsubscribe'(undefined, _acc) -> _acc; +'encode_pubsub_$unsubscribe'(Unsubscribe, _acc) -> + [encode_pubsub_unsubscribe(Unsubscribe, []) | _acc]. + +'encode_pubsub_$subscribe'(undefined, _acc) -> _acc; +'encode_pubsub_$subscribe'(Subscribe, _acc) -> + [encode_pubsub_subscribe(Subscribe, []) | _acc]. + +'encode_pubsub_$publish'(undefined, _acc) -> _acc; +'encode_pubsub_$publish'(Publish, _acc) -> + [encode_pubsub_publish(Publish, []) | _acc]. + +decode_pubsub_retract(__TopXMLNS, __IgnoreEls, + {xmlel, <<"retract">>, _attrs, _els}) -> + Items = decode_pubsub_retract_els(__TopXMLNS, + __IgnoreEls, _els, []), + {Node, Notify} = decode_pubsub_retract_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {pubsub_retract, Node, Notify, Items}. + +decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], + Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_pubsub_retract_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Notify) -> + decode_pubsub_retract_attrs(__TopXMLNS, _attrs, _val, + Notify); +decode_pubsub_retract_attrs(__TopXMLNS, + [{<<"notify">>, _val} | _attrs], Node, _Notify) -> + decode_pubsub_retract_attrs(__TopXMLNS, _attrs, Node, + _val); +decode_pubsub_retract_attrs(__TopXMLNS, [_ | _attrs], + Node, Notify) -> + decode_pubsub_retract_attrs(__TopXMLNS, _attrs, Node, + Notify); +decode_pubsub_retract_attrs(__TopXMLNS, [], Node, + Notify) -> + {decode_pubsub_retract_attr_node(__TopXMLNS, Node), + decode_pubsub_retract_attr_notify(__TopXMLNS, Notify)}. + +encode_pubsub_retract({pubsub_retract, Node, Notify, + Items}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_retract_$items'(Items, + [])), + _attrs = encode_pubsub_retract_attr_notify(Notify, + encode_pubsub_retract_attr_node(Node, + _xmlns_attrs)), + {xmlel, <<"retract">>, _attrs, _els}. + +'encode_pubsub_retract_$items'([], _acc) -> _acc; +'encode_pubsub_retract_$items'([Items | _els], _acc) -> + 'encode_pubsub_retract_$items'(_els, + [encode_pubsub_item(Items, []) | _acc]). + +decode_pubsub_retract_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"retract">>, __TopXMLNS}}); +decode_pubsub_retract_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_retract_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_retract_attr_notify(__TopXMLNS, + undefined) -> + false; +decode_pubsub_retract_attr_notify(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"notify">>, <<"retract">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_retract_attr_notify(false, _acc) -> _acc; +encode_pubsub_retract_attr_notify(_val, _acc) -> + [{<<"notify">>, enc_bool(_val)} | _acc]. + +decode_pubsub_options(__TopXMLNS, __IgnoreEls, + {xmlel, <<"options">>, _attrs, _els}) -> + Xdata = decode_pubsub_options_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + {Node, Subid, Jid} = + decode_pubsub_options_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined), + {pubsub_options, Node, Jid, Subid, Xdata}. + +decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, [], + Xdata) -> + Xdata; +decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, + Xdata) + end; +decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Xdata) -> + decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, + Xdata). + +decode_pubsub_options_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Subid, Jid) -> + decode_pubsub_options_attrs(__TopXMLNS, _attrs, _val, + Subid, Jid); +decode_pubsub_options_attrs(__TopXMLNS, + [{<<"subid">>, _val} | _attrs], Node, _Subid, + Jid) -> + decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, + _val, Jid); +decode_pubsub_options_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Node, Subid, _Jid) -> + decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, + Subid, _val); +decode_pubsub_options_attrs(__TopXMLNS, [_ | _attrs], + Node, Subid, Jid) -> + decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, + Subid, Jid); +decode_pubsub_options_attrs(__TopXMLNS, [], Node, Subid, + Jid) -> + {decode_pubsub_options_attr_node(__TopXMLNS, Node), + decode_pubsub_options_attr_subid(__TopXMLNS, Subid), + decode_pubsub_options_attr_jid(__TopXMLNS, Jid)}. + +encode_pubsub_options({pubsub_options, Node, Jid, Subid, + Xdata}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_options_$xdata'(Xdata, + [])), + _attrs = encode_pubsub_options_attr_jid(Jid, + encode_pubsub_options_attr_subid(Subid, + encode_pubsub_options_attr_node(Node, + _xmlns_attrs))), + {xmlel, <<"options">>, _attrs, _els}. + +'encode_pubsub_options_$xdata'(undefined, _acc) -> _acc; +'encode_pubsub_options_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +decode_pubsub_options_attr_node(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_options_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_options_attr_node(undefined, _acc) -> + _acc; +encode_pubsub_options_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_options_attr_subid(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_options_attr_subid(__TopXMLNS, _val) -> + _val. + +encode_pubsub_options_attr_subid(undefined, _acc) -> + _acc; +encode_pubsub_options_attr_subid(_val, _acc) -> + [{<<"subid">>, _val} | _acc]. + +decode_pubsub_options_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"options">>, __TopXMLNS}}); +decode_pubsub_options_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"options">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_options_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_pubsub_publish(__TopXMLNS, __IgnoreEls, + {xmlel, <<"publish">>, _attrs, _els}) -> + Items = decode_pubsub_publish_els(__TopXMLNS, + __IgnoreEls, _els, []), + Node = decode_pubsub_publish_attrs(__TopXMLNS, _attrs, + undefined), + {pubsub_publish, Node, Items}. + +decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], + Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_pubsub_publish_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_publish_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_publish_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_publish_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_publish_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_publish_attr_node(__TopXMLNS, Node). + +encode_pubsub_publish({pubsub_publish, Node, Items}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_publish_$items'(Items, + [])), + _attrs = encode_pubsub_publish_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"publish">>, _attrs, _els}. + +'encode_pubsub_publish_$items'([], _acc) -> _acc; +'encode_pubsub_publish_$items'([Items | _els], _acc) -> + 'encode_pubsub_publish_$items'(_els, + [encode_pubsub_item(Items, []) | _acc]). + +decode_pubsub_publish_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"publish">>, __TopXMLNS}}); +decode_pubsub_publish_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_publish_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unsubscribe">>, _attrs, _els}) -> + {Node, Subid, Jid} = + decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined), + {pubsub_unsubscribe, Node, Jid, Subid}. + +decode_pubsub_unsubscribe_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Subid, + Jid) -> + decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, + _val, Subid, Jid); +decode_pubsub_unsubscribe_attrs(__TopXMLNS, + [{<<"subid">>, _val} | _attrs], Node, _Subid, + Jid) -> + decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, + Node, _val, Jid); +decode_pubsub_unsubscribe_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Node, Subid, + _Jid) -> + decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, + Node, Subid, _val); +decode_pubsub_unsubscribe_attrs(__TopXMLNS, + [_ | _attrs], Node, Subid, Jid) -> + decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, + Node, Subid, Jid); +decode_pubsub_unsubscribe_attrs(__TopXMLNS, [], Node, + Subid, Jid) -> + {decode_pubsub_unsubscribe_attr_node(__TopXMLNS, Node), + decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, Subid), + decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, Jid)}. + +encode_pubsub_unsubscribe({pubsub_unsubscribe, Node, + Jid, Subid}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_unsubscribe_attr_jid(Jid, + encode_pubsub_unsubscribe_attr_subid(Subid, + encode_pubsub_unsubscribe_attr_node(Node, + _xmlns_attrs))), + {xmlel, <<"unsubscribe">>, _attrs, _els}. + +decode_pubsub_unsubscribe_attr_node(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_unsubscribe_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_unsubscribe_attr_node(undefined, _acc) -> + _acc; +encode_pubsub_unsubscribe_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_unsubscribe_attr_subid(undefined, _acc) -> + _acc; +encode_pubsub_unsubscribe_attr_subid(_val, _acc) -> + [{<<"subid">>, _val} | _acc]. + +decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"unsubscribe">>, + __TopXMLNS}}); +decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"unsubscribe">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_unsubscribe_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscribe">>, _attrs, _els}) -> + {Node, Jid} = decode_pubsub_subscribe_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {pubsub_subscribe, Node, Jid}. + +decode_pubsub_subscribe_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Jid) -> + decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, _val, + Jid); +decode_pubsub_subscribe_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Node, _Jid) -> + decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, Node, + _val); +decode_pubsub_subscribe_attrs(__TopXMLNS, [_ | _attrs], + Node, Jid) -> + decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, Node, + Jid); +decode_pubsub_subscribe_attrs(__TopXMLNS, [], Node, + Jid) -> + {decode_pubsub_subscribe_attr_node(__TopXMLNS, Node), + decode_pubsub_subscribe_attr_jid(__TopXMLNS, Jid)}. + +encode_pubsub_subscribe({pubsub_subscribe, Node, Jid}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_subscribe_attr_jid(Jid, + encode_pubsub_subscribe_attr_node(Node, + _xmlns_attrs)), + {xmlel, <<"subscribe">>, _attrs, _els}. + +decode_pubsub_subscribe_attr_node(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_subscribe_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_subscribe_attr_node(undefined, _acc) -> + _acc; +encode_pubsub_subscribe_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_subscribe_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"subscribe">>, + __TopXMLNS}}); +decode_pubsub_subscribe_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"subscribe">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_subscribe_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, + {xmlel, <<"affiliations">>, _attrs, _els}) -> + Affiliations = + decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + _els, []), + Affiliations. + +decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + [], Affiliations) -> + lists:reverse(Affiliations); +decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"affiliation">>, _attrs, _} = _el + | _els], + Affiliations) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_affiliation(__TopXMLNS, + __IgnoreEls, + _el) + | Affiliations]); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, + _el) + | Affiliations]); + _ -> + decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + _els, Affiliations) + end; +decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Affiliations) -> + decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, + _els, Affiliations). + +encode_pubsub_affiliations(Affiliations, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_affiliations_$affiliations'(Affiliations, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"affiliations">>, _attrs, _els}. + +'encode_pubsub_affiliations_$affiliations'([], _acc) -> + _acc; +'encode_pubsub_affiliations_$affiliations'([Affiliations + | _els], + _acc) -> + 'encode_pubsub_affiliations_$affiliations'(_els, + [encode_pubsub_affiliation(Affiliations, + []) + | _acc]). + +decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscriptions">>, _attrs, _els}) -> + Subscriptions = + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, []), + Node = decode_pubsub_subscriptions_attrs(__TopXMLNS, + _attrs, undefined), + {Node, Subscriptions}. + +decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + [], Subscriptions) -> + lists:reverse(Subscriptions); +decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscription">>, _attrs, _} = _el + | _els], + Subscriptions) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_subscription(__TopXMLNS, + __IgnoreEls, + _el) + | Subscriptions]); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, + _el) + | Subscriptions]); + _ -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, Subscriptions) + end; +decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Subscriptions) -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, Subscriptions). + +decode_pubsub_subscriptions_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_subscriptions_attrs(__TopXMLNS, _attrs, + _val); +decode_pubsub_subscriptions_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_pubsub_subscriptions_attrs(__TopXMLNS, _attrs, + Node); +decode_pubsub_subscriptions_attrs(__TopXMLNS, [], + Node) -> + decode_pubsub_subscriptions_attr_node(__TopXMLNS, Node). + +encode_pubsub_subscriptions({Node, Subscriptions}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_subscriptions_$subscriptions'(Subscriptions, + [])), + _attrs = encode_pubsub_subscriptions_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"subscriptions">>, _attrs, _els}. + +'encode_pubsub_subscriptions_$subscriptions'([], + _acc) -> + _acc; +'encode_pubsub_subscriptions_$subscriptions'([Subscriptions + | _els], + _acc) -> + 'encode_pubsub_subscriptions_$subscriptions'(_els, + [encode_pubsub_subscription(Subscriptions, + []) + | _acc]). + +decode_pubsub_subscriptions_attr_node(__TopXMLNS, + undefined) -> + none; +decode_pubsub_subscriptions_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_subscriptions_attr_node(none, _acc) -> + _acc; +encode_pubsub_subscriptions_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_event(__TopXMLNS, __IgnoreEls, + {xmlel, <<"event">>, _attrs, _els}) -> + Items = decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + _els, []), + {pubsub_event, Items}. + +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"items">>, _attrs, _} = _el | _els], + Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_event_items(__TopXMLNS, + __IgnoreEls, _el) + | Items]); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_event_items(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +encode_pubsub_event({pubsub_event, Items}, + _xmlns_attrs) -> + _els = lists:reverse('encode_pubsub_event_$items'(Items, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"event">>, _attrs, _els}. + +'encode_pubsub_event_$items'([], _acc) -> _acc; +'encode_pubsub_event_$items'([Items | _els], _acc) -> + 'encode_pubsub_event_$items'(_els, + [encode_pubsub_event_items(Items, []) | _acc]). + +decode_pubsub_event_items(__TopXMLNS, __IgnoreEls, + {xmlel, <<"items">>, _attrs, _els}) -> + {Items, Retract} = + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, [], []), + Node = decode_pubsub_event_items_attrs(__TopXMLNS, + _attrs, undefined), + {pubsub_event_items, Node, Retract, Items}. + +decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + [], Items, Retract) -> + {lists:reverse(Items), lists:reverse(Retract)}; +decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"retract">>, _attrs, _} = _el | _els], + Items, Retract) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, Items, + [decode_pubsub_event_retract(__TopXMLNS, + __IgnoreEls, + _el) + | Retract]); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, Items, + [decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, + _el) + | Retract]); + _ -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, Items, Retract) + end; +decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], + Items, Retract) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_event_item(__TopXMLNS, + __IgnoreEls, + _el) + | Items], + Retract); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_event_item(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, + _el) + | Items], + Retract); + _ -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, Items, Retract) + end; +decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items, Retract) -> + decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, + _els, Items, Retract). + +decode_pubsub_event_items_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_event_items_attrs(__TopXMLNS, _attrs, + _val); +decode_pubsub_event_items_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_pubsub_event_items_attrs(__TopXMLNS, _attrs, + Node); +decode_pubsub_event_items_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_event_items_attr_node(__TopXMLNS, Node). + +encode_pubsub_event_items({pubsub_event_items, Node, + Retract, Items}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_event_items_$items'(Items, + 'encode_pubsub_event_items_$retract'(Retract, + []))), + _attrs = encode_pubsub_event_items_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"items">>, _attrs, _els}. + +'encode_pubsub_event_items_$items'([], _acc) -> _acc; +'encode_pubsub_event_items_$items'([Items | _els], + _acc) -> + 'encode_pubsub_event_items_$items'(_els, + [encode_pubsub_event_item(Items, []) + | _acc]). + +'encode_pubsub_event_items_$retract'([], _acc) -> _acc; +'encode_pubsub_event_items_$retract'([Retract | _els], + _acc) -> + 'encode_pubsub_event_items_$retract'(_els, + [encode_pubsub_event_retract(Retract, + []) + | _acc]). + +decode_pubsub_event_items_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"items">>, __TopXMLNS}}); +decode_pubsub_event_items_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_event_items_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_event_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + __Xmls = decode_pubsub_event_item_els(__TopXMLNS, + __IgnoreEls, _els, []), + {Id, Node, Publisher} = + decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined), + {pubsub_event_item, Id, Node, Publisher, __Xmls}. + +decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, + [], __Xmls) -> + lists:reverse(__Xmls); +decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], __Xmls) -> + decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, + _els, [_el | __Xmls]); +decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], __Xmls) -> + decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, + _els, __Xmls). + +decode_pubsub_event_item_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, Node, + Publisher) -> + decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, _val, + Node, Publisher); +decode_pubsub_event_item_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Id, _Node, + Publisher) -> + decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, + _val, Publisher); +decode_pubsub_event_item_attrs(__TopXMLNS, + [{<<"publisher">>, _val} | _attrs], Id, Node, + _Publisher) -> + decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, + Node, _val); +decode_pubsub_event_item_attrs(__TopXMLNS, [_ | _attrs], + Id, Node, Publisher) -> + decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, + Node, Publisher); +decode_pubsub_event_item_attrs(__TopXMLNS, [], Id, Node, + Publisher) -> + {decode_pubsub_event_item_attr_id(__TopXMLNS, Id), + decode_pubsub_event_item_attr_node(__TopXMLNS, Node), + decode_pubsub_event_item_attr_publisher(__TopXMLNS, + Publisher)}. + +encode_pubsub_event_item({pubsub_event_item, Id, Node, + Publisher, __Xmls}, + _xmlns_attrs) -> + _els = __Xmls, + _attrs = + encode_pubsub_event_item_attr_publisher(Publisher, + encode_pubsub_event_item_attr_node(Node, + encode_pubsub_event_item_attr_id(Id, + _xmlns_attrs))), + {xmlel, <<"item">>, _attrs, _els}. + +decode_pubsub_event_item_attr_id(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_event_item_attr_id(__TopXMLNS, _val) -> + _val. + +encode_pubsub_event_item_attr_id(undefined, _acc) -> + _acc; +encode_pubsub_event_item_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_pubsub_event_item_attr_node(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_event_item_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_event_item_attr_node(undefined, _acc) -> + _acc; +encode_pubsub_event_item_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_event_item_attr_publisher(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_event_item_attr_publisher(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_event_item_attr_publisher(undefined, + _acc) -> + _acc; +encode_pubsub_event_item_attr_publisher(_val, _acc) -> + [{<<"publisher">>, _val} | _acc]. + +decode_pubsub_event_retract(__TopXMLNS, __IgnoreEls, + {xmlel, <<"retract">>, _attrs, _els}) -> + Id = decode_pubsub_event_retract_attrs(__TopXMLNS, + _attrs, undefined), + Id. + +decode_pubsub_event_retract_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id) -> + decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, + _val); +decode_pubsub_event_retract_attrs(__TopXMLNS, + [_ | _attrs], Id) -> + decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, + Id); +decode_pubsub_event_retract_attrs(__TopXMLNS, [], Id) -> + decode_pubsub_event_retract_attr_id(__TopXMLNS, Id). + +encode_pubsub_event_retract(Id, _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_event_retract_attr_id(Id, + _xmlns_attrs), + {xmlel, <<"retract">>, _attrs, _els}. + +decode_pubsub_event_retract_attr_id(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"id">>, <<"retract">>, __TopXMLNS}}); +decode_pubsub_event_retract_attr_id(__TopXMLNS, _val) -> + _val. + +encode_pubsub_event_retract_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_pubsub_items(__TopXMLNS, __IgnoreEls, + {xmlel, <<"items">>, _attrs, _els}) -> + Items = decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, + _els, []), + {Max_items, Node, Subid} = + decode_pubsub_items_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {pubsub_items, Node, Max_items, Subid, Items}. + +decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_pubsub_items_attrs(__TopXMLNS, + [{<<"max_items">>, _val} | _attrs], _Max_items, Node, + Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, _val, + Node, Subid); +decode_pubsub_items_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Max_items, _Node, + Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, + _val, Subid); +decode_pubsub_items_attrs(__TopXMLNS, + [{<<"subid">>, _val} | _attrs], Max_items, Node, + _Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, + Node, _val); +decode_pubsub_items_attrs(__TopXMLNS, [_ | _attrs], + Max_items, Node, Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, + Node, Subid); +decode_pubsub_items_attrs(__TopXMLNS, [], Max_items, + Node, Subid) -> + {decode_pubsub_items_attr_max_items(__TopXMLNS, + Max_items), + decode_pubsub_items_attr_node(__TopXMLNS, Node), + decode_pubsub_items_attr_subid(__TopXMLNS, Subid)}. + +encode_pubsub_items({pubsub_items, Node, Max_items, + Subid, Items}, + _xmlns_attrs) -> + _els = lists:reverse('encode_pubsub_items_$items'(Items, + [])), + _attrs = encode_pubsub_items_attr_subid(Subid, + encode_pubsub_items_attr_node(Node, + encode_pubsub_items_attr_max_items(Max_items, + _xmlns_attrs))), + {xmlel, <<"items">>, _attrs, _els}. + +'encode_pubsub_items_$items'([], _acc) -> _acc; +'encode_pubsub_items_$items'([Items | _els], _acc) -> + 'encode_pubsub_items_$items'(_els, + [encode_pubsub_item(Items, []) | _acc]). + +decode_pubsub_items_attr_max_items(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_items_attr_max_items(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"max_items">>, <<"items">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_items_attr_max_items(undefined, _acc) -> + _acc; +encode_pubsub_items_attr_max_items(_val, _acc) -> + [{<<"max_items">>, enc_int(_val)} | _acc]. + +decode_pubsub_items_attr_node(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"items">>, __TopXMLNS}}); +decode_pubsub_items_attr_node(__TopXMLNS, _val) -> _val. + +encode_pubsub_items_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_items_attr_subid(__TopXMLNS, undefined) -> + undefined; +decode_pubsub_items_attr_subid(__TopXMLNS, _val) -> + _val. + +encode_pubsub_items_attr_subid(undefined, _acc) -> _acc; +encode_pubsub_items_attr_subid(_val, _acc) -> + [{<<"subid">>, _val} | _acc]. + +decode_pubsub_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + __Xmls = decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, + _els, []), + Id = decode_pubsub_item_attrs(__TopXMLNS, _attrs, + undefined), + {pubsub_item, Id, __Xmls}. + +decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, [], + __Xmls) -> + lists:reverse(__Xmls); +decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], __Xmls) -> + decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, _els, + [_el | __Xmls]); +decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], __Xmls) -> + decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, _els, + __Xmls). + +decode_pubsub_item_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_item_attrs(__TopXMLNS, [_ | _attrs], + Id) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id); +decode_pubsub_item_attrs(__TopXMLNS, [], Id) -> + decode_pubsub_item_attr_id(__TopXMLNS, Id). + +encode_pubsub_item({pubsub_item, Id, __Xmls}, + _xmlns_attrs) -> + _els = __Xmls, + _attrs = encode_pubsub_item_attr_id(Id, _xmlns_attrs), + {xmlel, <<"item">>, _attrs, _els}. + +decode_pubsub_item_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_pubsub_item_attr_id(__TopXMLNS, _val) -> _val. + +encode_pubsub_item_attr_id(undefined, _acc) -> _acc; +encode_pubsub_item_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_pubsub_affiliation(__TopXMLNS, __IgnoreEls, + {xmlel, <<"affiliation">>, _attrs, _els}) -> + {Node, Type} = + decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {pubsub_affiliation, Node, Type}. + +decode_pubsub_affiliation_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Type) -> + decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, + _val, Type); +decode_pubsub_affiliation_attrs(__TopXMLNS, + [{<<"affiliation">>, _val} | _attrs], Node, + _Type) -> + decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, + Node, _val); +decode_pubsub_affiliation_attrs(__TopXMLNS, + [_ | _attrs], Node, Type) -> + decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, + Node, Type); +decode_pubsub_affiliation_attrs(__TopXMLNS, [], Node, + Type) -> + {decode_pubsub_affiliation_attr_node(__TopXMLNS, Node), + decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, + Type)}. + +encode_pubsub_affiliation({pubsub_affiliation, Node, + Type}, + _xmlns_attrs) -> + _els = [], + _attrs = + encode_pubsub_affiliation_attr_affiliation(Type, + encode_pubsub_affiliation_attr_node(Node, + _xmlns_attrs)), + {xmlel, <<"affiliation">>, _attrs, _els}. + +decode_pubsub_affiliation_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"affiliation">>, + __TopXMLNS}}); +decode_pubsub_affiliation_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_affiliation_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"affiliation">>, <<"affiliation">>, + __TopXMLNS}}); +decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [member, none, outcast, owner, publisher, + 'publish-only']) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"affiliation">>, <<"affiliation">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_affiliation_attr_affiliation(_val, + _acc) -> + [{<<"affiliation">>, enc_enum(_val)} | _acc]. + +decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscription">>, _attrs, _els}) -> + {Jid, Node, Subid, Type} = + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, + undefined), + {pubsub_subscription, Jid, Node, Subid, Type}. + +decode_pubsub_subscription_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Node, + Subid, Type) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + _val, Node, Subid, Type); +decode_pubsub_subscription_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Jid, _Node, + Subid, Type) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + Jid, _val, Subid, Type); +decode_pubsub_subscription_attrs(__TopXMLNS, + [{<<"subid">>, _val} | _attrs], Jid, Node, + _Subid, Type) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + Jid, Node, _val, Type); +decode_pubsub_subscription_attrs(__TopXMLNS, + [{<<"subscription">>, _val} | _attrs], Jid, + Node, Subid, _Type) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + Jid, Node, Subid, _val); +decode_pubsub_subscription_attrs(__TopXMLNS, + [_ | _attrs], Jid, Node, Subid, Type) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + Jid, Node, Subid, Type); +decode_pubsub_subscription_attrs(__TopXMLNS, [], Jid, + Node, Subid, Type) -> + {decode_pubsub_subscription_attr_jid(__TopXMLNS, Jid), + decode_pubsub_subscription_attr_node(__TopXMLNS, Node), + decode_pubsub_subscription_attr_subid(__TopXMLNS, + Subid), + decode_pubsub_subscription_attr_subscription(__TopXMLNS, + Type)}. + +encode_pubsub_subscription({pubsub_subscription, Jid, + Node, Subid, Type}, + _xmlns_attrs) -> + _els = [], + _attrs = + encode_pubsub_subscription_attr_subscription(Type, + encode_pubsub_subscription_attr_subid(Subid, + encode_pubsub_subscription_attr_node(Node, + encode_pubsub_subscription_attr_jid(Jid, + _xmlns_attrs)))), + {xmlel, <<"subscription">>, _attrs, _els}. + +decode_pubsub_subscription_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"subscription">>, + __TopXMLNS}}); +decode_pubsub_subscription_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"subscription">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_subscription_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_pubsub_subscription_attr_node(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_subscription_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_subscription_attr_node(undefined, _acc) -> + _acc; +encode_pubsub_subscription_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_subscription_attr_subid(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_subscription_attr_subid(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_subscription_attr_subid(undefined, + _acc) -> + _acc; +encode_pubsub_subscription_attr_subid(_val, _acc) -> + [{<<"subid">>, _val} | _acc]. + +decode_pubsub_subscription_attr_subscription(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_subscription_attr_subscription(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [none, pending, subscribed, unconfigured]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"subscription">>, <<"subscription">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_subscription_attr_subscription(undefined, + _acc) -> + _acc; +encode_pubsub_subscription_attr_subscription(_val, + _acc) -> + [{<<"subscription">>, enc_enum(_val)} | _acc]. + +decode_xdata(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Fields, Items, Instructions, Reported, Title} = + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, [], [], + [], undefined, undefined), + Type = decode_xdata_attrs(__TopXMLNS, _attrs, + undefined), + {xdata, Type, Instructions, Title, Reported, Items, + Fields}. + +decode_xdata_els(__TopXMLNS, __IgnoreEls, [], Fields, + Items, Instructions, Reported, Title) -> + {lists:reverse(Fields), lists:reverse(Items), + lists:reverse(Instructions), Reported, Title}; +decode_xdata_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], + Fields, Items, Instructions, Reported, Title) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, + case decode_xdata_instructions(__TopXMLNS, + __IgnoreEls, _el) + of + undefined -> Instructions; + _new_el -> [_new_el | Instructions] + end, + Reported, Title); + <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, + case decode_xdata_instructions(<<"jabber:x:data">>, + __IgnoreEls, _el) + of + undefined -> Instructions; + _new_el -> [_new_el | Instructions] + end, + Reported, Title); + _ -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title) + end; +decode_xdata_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"title">>, _attrs, _} = _el | _els], Fields, + Items, Instructions, Reported, Title) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, + decode_xdata_title(__TopXMLNS, __IgnoreEls, _el)); + <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, + decode_xdata_title(<<"jabber:x:data">>, __IgnoreEls, + _el)); + _ -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title) + end; +decode_xdata_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reported">>, _attrs, _} = _el | _els], + Fields, Items, Instructions, Reported, Title) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, + decode_xdata_reported(__TopXMLNS, __IgnoreEls, _el), + Title); + <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, + decode_xdata_reported(<<"jabber:x:data">>, + __IgnoreEls, _el), + Title); + _ -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title) + end; +decode_xdata_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Fields, + Items, Instructions, Reported, Title) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + [decode_xdata_item(__TopXMLNS, __IgnoreEls, _el) + | Items], + Instructions, Reported, Title); + <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + [decode_xdata_item(<<"jabber:x:data">>, __IgnoreEls, + _el) + | Items], + Instructions, Reported, Title); + _ -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title) + end; +decode_xdata_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"field">>, _attrs, _} = _el | _els], Fields, + Items, Instructions, Reported, Title) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(__TopXMLNS, __IgnoreEls, _el) + | Fields], + Items, Instructions, Reported, Title); + <<"jabber:x:data">> -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(<<"jabber:x:data">>, __IgnoreEls, + _el) + | Fields], + Items, Instructions, Reported, Title); + _ -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title) + end; +decode_xdata_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Fields, Items, Instructions, Reported, Title) -> + decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, + Items, Instructions, Reported, Title). + +decode_xdata_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], _Type) -> + decode_xdata_attrs(__TopXMLNS, _attrs, _val); +decode_xdata_attrs(__TopXMLNS, [_ | _attrs], Type) -> + decode_xdata_attrs(__TopXMLNS, _attrs, Type); +decode_xdata_attrs(__TopXMLNS, [], Type) -> + decode_xdata_attr_type(__TopXMLNS, Type). + +encode_xdata({xdata, Type, Instructions, Title, + Reported, Items, Fields}, + _xmlns_attrs) -> + _els = lists:reverse('encode_xdata_$fields'(Fields, + 'encode_xdata_$items'(Items, + 'encode_xdata_$instructions'(Instructions, + 'encode_xdata_$reported'(Reported, + 'encode_xdata_$title'(Title, + [])))))), + _attrs = encode_xdata_attr_type(Type, _xmlns_attrs), + {xmlel, <<"x">>, _attrs, _els}. + +'encode_xdata_$fields'([], _acc) -> _acc; +'encode_xdata_$fields'([Fields | _els], _acc) -> + 'encode_xdata_$fields'(_els, + [encode_xdata_field(Fields, []) | _acc]). + +'encode_xdata_$items'([], _acc) -> _acc; +'encode_xdata_$items'([Items | _els], _acc) -> + 'encode_xdata_$items'(_els, + [encode_xdata_item(Items, []) | _acc]). + +'encode_xdata_$instructions'([], _acc) -> _acc; +'encode_xdata_$instructions'([Instructions | _els], + _acc) -> + 'encode_xdata_$instructions'(_els, + [encode_xdata_instructions(Instructions, []) + | _acc]). + +'encode_xdata_$reported'(undefined, _acc) -> _acc; +'encode_xdata_$reported'(Reported, _acc) -> + [encode_xdata_reported(Reported, []) | _acc]. + +'encode_xdata_$title'(undefined, _acc) -> _acc; +'encode_xdata_$title'(Title, _acc) -> + [encode_xdata_title(Title, []) | _acc]. + +decode_xdata_attr_type(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"x">>, __TopXMLNS}}); +decode_xdata_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [cancel, form, result, submit]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"x">>, __TopXMLNS}}); + _res -> _res + end. + +encode_xdata_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_xdata_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + Fields = decode_xdata_item_els(__TopXMLNS, __IgnoreEls, + _els, []), + Fields. + +decode_xdata_item_els(__TopXMLNS, __IgnoreEls, [], + Fields) -> + lists:reverse(Fields); +decode_xdata_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"field">>, _attrs, _} = _el | _els], + Fields) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(__TopXMLNS, __IgnoreEls, + _el) + | Fields]); + <<"jabber:x:data">> -> + decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(<<"jabber:x:data">>, + __IgnoreEls, _el) + | Fields]); + _ -> + decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, + Fields) + end; +decode_xdata_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Fields) -> + decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, + Fields). + +encode_xdata_item(Fields, _xmlns_attrs) -> + _els = lists:reverse('encode_xdata_item_$fields'(Fields, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"item">>, _attrs, _els}. + +'encode_xdata_item_$fields'([], _acc) -> _acc; +'encode_xdata_item_$fields'([Fields | _els], _acc) -> + 'encode_xdata_item_$fields'(_els, + [encode_xdata_field(Fields, []) | _acc]). + +decode_xdata_reported(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reported">>, _attrs, _els}) -> + Fields = decode_xdata_reported_els(__TopXMLNS, + __IgnoreEls, _els, []), + Fields. + +decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, [], + Fields) -> + lists:reverse(Fields); +decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"field">>, _attrs, _} = _el | _els], + Fields) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(__TopXMLNS, __IgnoreEls, + _el) + | Fields]); + <<"jabber:x:data">> -> + decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata_field(<<"jabber:x:data">>, + __IgnoreEls, _el) + | Fields]); + _ -> + decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, + Fields) + end; +decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Fields) -> + decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, + Fields). + +encode_xdata_reported(Fields, _xmlns_attrs) -> + _els = + lists:reverse('encode_xdata_reported_$fields'(Fields, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"reported">>, _attrs, _els}. + +'encode_xdata_reported_$fields'([], _acc) -> _acc; +'encode_xdata_reported_$fields'([Fields | _els], + _acc) -> + 'encode_xdata_reported_$fields'(_els, + [encode_xdata_field(Fields, []) | _acc]). + +decode_xdata_title(__TopXMLNS, __IgnoreEls, + {xmlel, <<"title">>, _attrs, _els}) -> + Cdata = decode_xdata_title_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_xdata_title_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_xdata_title_cdata(__TopXMLNS, Cdata); +decode_xdata_title_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_xdata_title_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_xdata_title_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_xdata_title_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_xdata_title(Cdata, _xmlns_attrs) -> + _els = encode_xdata_title_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"title">>, _attrs, _els}. + +decode_xdata_title_cdata(__TopXMLNS, <<>>) -> undefined; +decode_xdata_title_cdata(__TopXMLNS, _val) -> _val. + +encode_xdata_title_cdata(undefined, _acc) -> _acc; +encode_xdata_title_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_xdata_instructions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"instructions">>, _attrs, _els}) -> + Cdata = decode_xdata_instructions_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_xdata_instructions_cdata(__TopXMLNS, Cdata); +decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_xdata_instructions(Cdata, _xmlns_attrs) -> + _els = encode_xdata_instructions_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"instructions">>, _attrs, _els}. + +decode_xdata_instructions_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_xdata_instructions_cdata(__TopXMLNS, _val) -> + _val. + +encode_xdata_instructions_cdata(undefined, _acc) -> + _acc; +encode_xdata_instructions_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_xdata_field(__TopXMLNS, __IgnoreEls, + {xmlel, <<"field">>, _attrs, _els}) -> + {Options, Values, Desc, Required} = + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + [], [], undefined, false), + {Label, Type, Var} = + decode_xdata_field_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {xdata_field, Label, Type, Var, Required, Desc, Values, + Options}. + +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [], + Options, Values, Desc, Required) -> + {lists:reverse(Options), lists:reverse(Values), Desc, + Required}; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"required">>, _attrs, _} = _el | _els], + Options, Values, Desc, Required) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, + decode_xdata_field_required(__TopXMLNS, + __IgnoreEls, _el)); + <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, + decode_xdata_field_required(<<"jabber:x:data">>, + __IgnoreEls, _el)); + _ -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required) + end; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"desc">>, _attrs, _} = _el | _els], Options, + Values, Desc, Required) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, + decode_xdata_field_desc(__TopXMLNS, + __IgnoreEls, _el), + Required); + <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, + decode_xdata_field_desc(<<"jabber:x:data">>, + __IgnoreEls, _el), + Required); + _ -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required) + end; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"value">>, _attrs, _} = _el | _els], Options, + Values, Desc, Required) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, + case decode_xdata_field_value(__TopXMLNS, + __IgnoreEls, _el) + of + undefined -> Values; + _new_el -> [_new_el | Values] + end, + Desc, Required); + <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, + case + decode_xdata_field_value(<<"jabber:x:data">>, + __IgnoreEls, _el) + of + undefined -> Values; + _new_el -> [_new_el | Values] + end, + Desc, Required); + _ -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required) + end; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"option">>, _attrs, _} = _el | _els], + Options, Values, Desc, Required) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + case decode_xdata_field_option(__TopXMLNS, + __IgnoreEls, + _el) + of + undefined -> Options; + _new_el -> [_new_el | Options] + end, + Values, Desc, Required); + <<"jabber:x:data">> -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + case + decode_xdata_field_option(<<"jabber:x:data">>, + __IgnoreEls, _el) + of + undefined -> Options; + _new_el -> [_new_el | Options] + end, + Values, Desc, Required); + _ -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required) + end; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Options, Values, Desc, Required) -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required). + +decode_xdata_field_attrs(__TopXMLNS, + [{<<"label">>, _val} | _attrs], _Label, Type, Var) -> + decode_xdata_field_attrs(__TopXMLNS, _attrs, _val, Type, + Var); +decode_xdata_field_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Label, _Type, Var) -> + decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, + _val, Var); +decode_xdata_field_attrs(__TopXMLNS, + [{<<"var">>, _val} | _attrs], Label, Type, _Var) -> + decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, + Type, _val); +decode_xdata_field_attrs(__TopXMLNS, [_ | _attrs], + Label, Type, Var) -> + decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, + Type, Var); +decode_xdata_field_attrs(__TopXMLNS, [], Label, Type, + Var) -> + {decode_xdata_field_attr_label(__TopXMLNS, Label), + decode_xdata_field_attr_type(__TopXMLNS, Type), + decode_xdata_field_attr_var(__TopXMLNS, Var)}. + +encode_xdata_field({xdata_field, Label, Type, Var, + Required, Desc, Values, Options}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_xdata_field_$options'(Options, + 'encode_xdata_field_$values'(Values, + 'encode_xdata_field_$desc'(Desc, + 'encode_xdata_field_$required'(Required, + []))))), + _attrs = encode_xdata_field_attr_var(Var, + encode_xdata_field_attr_type(Type, + encode_xdata_field_attr_label(Label, + _xmlns_attrs))), + {xmlel, <<"field">>, _attrs, _els}. + +'encode_xdata_field_$options'([], _acc) -> _acc; +'encode_xdata_field_$options'([Options | _els], _acc) -> + 'encode_xdata_field_$options'(_els, + [encode_xdata_field_option(Options, []) + | _acc]). + +'encode_xdata_field_$values'([], _acc) -> _acc; +'encode_xdata_field_$values'([Values | _els], _acc) -> + 'encode_xdata_field_$values'(_els, + [encode_xdata_field_value(Values, []) | _acc]). + +'encode_xdata_field_$desc'(undefined, _acc) -> _acc; +'encode_xdata_field_$desc'(Desc, _acc) -> + [encode_xdata_field_desc(Desc, []) | _acc]. + +'encode_xdata_field_$required'(false, _acc) -> _acc; +'encode_xdata_field_$required'(Required, _acc) -> + [encode_xdata_field_required(Required, []) | _acc]. + +decode_xdata_field_attr_label(__TopXMLNS, undefined) -> + undefined; +decode_xdata_field_attr_label(__TopXMLNS, _val) -> _val. + +encode_xdata_field_attr_label(undefined, _acc) -> _acc; +encode_xdata_field_attr_label(_val, _acc) -> + [{<<"label">>, _val} | _acc]. + +decode_xdata_field_attr_type(__TopXMLNS, undefined) -> + undefined; +decode_xdata_field_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [boolean, fixed, hidden, 'jid-multi', 'jid-single', + 'list-multi', 'list-single', 'text-multi', + 'text-private', 'text-single']) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"field">>, __TopXMLNS}}); + _res -> _res + end. + +encode_xdata_field_attr_type(undefined, _acc) -> _acc; +encode_xdata_field_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_xdata_field_attr_var(__TopXMLNS, undefined) -> + undefined; +decode_xdata_field_attr_var(__TopXMLNS, _val) -> _val. + +encode_xdata_field_attr_var(undefined, _acc) -> _acc; +encode_xdata_field_attr_var(_val, _acc) -> + [{<<"var">>, _val} | _acc]. + +decode_xdata_field_option(__TopXMLNS, __IgnoreEls, + {xmlel, <<"option">>, _attrs, _els}) -> + Value = decode_xdata_field_option_els(__TopXMLNS, + __IgnoreEls, _els, error), + Value. + +decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + [], Value) -> + case Value of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"value">>, __TopXMLNS}}); + {value, Value1} -> Value1 + end; +decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"value">>, _attrs, _} = _el | _els], + Value) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:data">> -> + decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + _els, + {value, + decode_xdata_field_value(__TopXMLNS, + __IgnoreEls, + _el)}); + <<"jabber:x:data">> -> + decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + _els, + {value, + decode_xdata_field_value(<<"jabber:x:data">>, + __IgnoreEls, + _el)}); + _ -> + decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + _els, Value) + end; +decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Value) -> + decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, + _els, Value). + +encode_xdata_field_option(Value, _xmlns_attrs) -> + _els = + lists:reverse('encode_xdata_field_option_$value'(Value, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"option">>, _attrs, _els}. + +'encode_xdata_field_option_$value'(Value, _acc) -> + [encode_xdata_field_value(Value, []) | _acc]. + +decode_xdata_field_value(__TopXMLNS, __IgnoreEls, + {xmlel, <<"value">>, _attrs, _els}) -> + Cdata = decode_xdata_field_value_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_xdata_field_value_cdata(__TopXMLNS, Cdata); +decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_xdata_field_value(Cdata, _xmlns_attrs) -> + _els = encode_xdata_field_value_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"value">>, _attrs, _els}. + +decode_xdata_field_value_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_xdata_field_value_cdata(__TopXMLNS, _val) -> + _val. + +encode_xdata_field_value_cdata(undefined, _acc) -> _acc; +encode_xdata_field_value_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_xdata_field_desc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"desc">>, _attrs, _els}) -> + Cdata = decode_xdata_field_desc_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_xdata_field_desc_cdata(__TopXMLNS, Cdata); +decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_xdata_field_desc(Cdata, _xmlns_attrs) -> + _els = encode_xdata_field_desc_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"desc">>, _attrs, _els}. + +decode_xdata_field_desc_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_xdata_field_desc_cdata(__TopXMLNS, _val) -> _val. + +encode_xdata_field_desc_cdata(undefined, _acc) -> _acc; +encode_xdata_field_desc_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_xdata_field_required(__TopXMLNS, __IgnoreEls, + {xmlel, <<"required">>, _attrs, _els}) -> + true. + +encode_xdata_field_required(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"required">>, _attrs, _els}. + +decode_vcard_xupdate(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + Hash = decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, + _els, undefined), + {vcard_xupdate, undefined, Hash}. + +decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, [], + Hash) -> + Hash; +decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"photo">>, _attrs, _} = _el | _els], + Hash) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp:x:update">> -> + decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_xupdate_photo(__TopXMLNS, + __IgnoreEls, + _el)); + <<"vcard-temp:x:update">> -> + decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, + __IgnoreEls, + _el)); + _ -> + decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, + Hash) + end; +decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Hash) -> + decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, + Hash). + +encode_vcard_xupdate({vcard_xupdate, undefined, Hash}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_xupdate_$hash'(Hash, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"x">>, _attrs, _els}. + +'encode_vcard_xupdate_$hash'(undefined, _acc) -> _acc; +'encode_vcard_xupdate_$hash'(Hash, _acc) -> + [encode_vcard_xupdate_photo(Hash, []) | _acc]. + +decode_vcard_xupdate_photo(__TopXMLNS, __IgnoreEls, + {xmlel, <<"photo">>, _attrs, _els}) -> + Cdata = decode_vcard_xupdate_photo_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_vcard_xupdate_photo_cdata(__TopXMLNS, Cdata); +decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_vcard_xupdate_photo(Cdata, _xmlns_attrs) -> + _els = encode_vcard_xupdate_photo_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"photo">>, _attrs, _els}. + +decode_vcard_xupdate_photo_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_xupdate_photo_cdata(__TopXMLNS, _val) -> + _val. + +encode_vcard_xupdate_photo_cdata(undefined, _acc) -> + _acc; +encode_vcard_xupdate_photo_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_temp(__TopXMLNS, __IgnoreEls, + {xmlel, <<"vCard">>, _attrs, _els}) -> + {Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo} = + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + undefined, [], undefined, [], undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, [], [], [], + undefined, undefined, undefined, undefined, + undefined, undefined), + {vcard_temp, Version, Fn, N, Nickname, Photo, Bday, Adr, + Label, Tel, Email, Jabberid, Mailer, Tz, Geo, Title, + Role, Logo, Org, Categories, Note, Prodid, Rev, + Sort_string, Sound, Uid, Url, Class, Key, Desc}. + +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, [], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + {Mailer, lists:reverse(Adr), Class, Categories, Desc, + Uid, Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url, + lists:reverse(Email), lists:reverse(Tel), + lists:reverse(Label), Fn, Version, N, Photo, Logo, Geo}; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"N">>, _attrs, _} = _el | _els], Mailer, Adr, + Class, Categories, Desc, Uid, Prodid, Jabberid, Sound, + Note, Role, Title, Nickname, Rev, Sort_string, Org, + Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, + decode_vcard_N(__TopXMLNS, __IgnoreEls, _el), + Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, + decode_vcard_N(<<"vcard-temp">>, __IgnoreEls, + _el), + Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ADR">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, + [decode_vcard_ADR(__TopXMLNS, __IgnoreEls, _el) + | Adr], + Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, + [decode_vcard_ADR(<<"vcard-temp">>, __IgnoreEls, + _el) + | Adr], + Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LABEL">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, + [decode_vcard_LABEL(__TopXMLNS, __IgnoreEls, + _el) + | Label], + Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, + [decode_vcard_LABEL(<<"vcard-temp">>, + __IgnoreEls, _el) + | Label], + Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TEL">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, + [decode_vcard_TEL(__TopXMLNS, __IgnoreEls, _el) + | Tel], + Label, Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, + [decode_vcard_TEL(<<"vcard-temp">>, __IgnoreEls, + _el) + | Tel], + Label, Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"EMAIL">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, + [decode_vcard_EMAIL(__TopXMLNS, __IgnoreEls, + _el) + | Email], + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, + [decode_vcard_EMAIL(<<"vcard-temp">>, + __IgnoreEls, _el) + | Email], + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"GEO">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, + decode_vcard_GEO(__TopXMLNS, __IgnoreEls, _el)); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, + decode_vcard_GEO(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LOGO">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + decode_vcard_LOGO(__TopXMLNS, __IgnoreEls, _el), + Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + decode_vcard_LOGO(<<"vcard-temp">>, __IgnoreEls, + _el), + Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PHOTO">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, + decode_vcard_PHOTO(__TopXMLNS, __IgnoreEls, + _el), + Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, + decode_vcard_PHOTO(<<"vcard-temp">>, + __IgnoreEls, _el), + Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ORG">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, + decode_vcard_ORG(__TopXMLNS, __IgnoreEls, _el), + Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, + decode_vcard_ORG(<<"vcard-temp">>, __IgnoreEls, + _el), + Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"SOUND">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, + decode_vcard_SOUND(__TopXMLNS, __IgnoreEls, + _el), + Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, + decode_vcard_SOUND(<<"vcard-temp">>, + __IgnoreEls, _el), + Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"KEY">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, + decode_vcard_KEY(__TopXMLNS, __IgnoreEls, _el), + Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, + decode_vcard_KEY(<<"vcard-temp">>, __IgnoreEls, + _el), + Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"VERSION">>, _attrs, _} = _el | _els], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, + decode_vcard_VERSION(__TopXMLNS, __IgnoreEls, + _el), + N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, + decode_vcard_VERSION(<<"vcard-temp">>, + __IgnoreEls, _el), + N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"FN">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, + decode_vcard_FN(__TopXMLNS, __IgnoreEls, _el), + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, + decode_vcard_FN(<<"vcard-temp">>, __IgnoreEls, + _el), + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"NICKNAME">>, _attrs, _} = _el | _els], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + decode_vcard_NICKNAME(__TopXMLNS, __IgnoreEls, + _el), + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + decode_vcard_NICKNAME(<<"vcard-temp">>, + __IgnoreEls, _el), + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"BDAY">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, + decode_vcard_BDAY(__TopXMLNS, __IgnoreEls, _el), + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, + decode_vcard_BDAY(<<"vcard-temp">>, __IgnoreEls, + _el), + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"JABBERID">>, _attrs, _} = _el | _els], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, + decode_vcard_JABBERID(__TopXMLNS, __IgnoreEls, + _el), + Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, + decode_vcard_JABBERID(<<"vcard-temp">>, + __IgnoreEls, _el), + Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"MAILER">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_MAILER(__TopXMLNS, __IgnoreEls, + _el), + Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_MAILER(<<"vcard-temp">>, + __IgnoreEls, _el), + Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TZ">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, + decode_vcard_TZ(__TopXMLNS, __IgnoreEls, _el), + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, + decode_vcard_TZ(<<"vcard-temp">>, __IgnoreEls, + _el), + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TITLE">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, + decode_vcard_TITLE(__TopXMLNS, __IgnoreEls, + _el), + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, + decode_vcard_TITLE(<<"vcard-temp">>, + __IgnoreEls, _el), + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ROLE">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, + decode_vcard_ROLE(__TopXMLNS, __IgnoreEls, _el), + Title, Nickname, Rev, Sort_string, Org, Bday, + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, + decode_vcard_ROLE(<<"vcard-temp">>, __IgnoreEls, + _el), + Title, Nickname, Rev, Sort_string, Org, Bday, + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"NOTE">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, + decode_vcard_NOTE(__TopXMLNS, __IgnoreEls, _el), + Role, Title, Nickname, Rev, Sort_string, Org, + Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, + decode_vcard_NOTE(<<"vcard-temp">>, __IgnoreEls, + _el), + Role, Title, Nickname, Rev, Sort_string, Org, + Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PRODID">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + decode_vcard_PRODID(__TopXMLNS, __IgnoreEls, + _el), + Jabberid, Sound, Note, Role, Title, Nickname, + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + decode_vcard_PRODID(<<"vcard-temp">>, + __IgnoreEls, _el), + Jabberid, Sound, Note, Role, Title, Nickname, + Rev, Sort_string, Org, Bday, Key, Tz, Url, + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"REV">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, + decode_vcard_REV(__TopXMLNS, __IgnoreEls, _el), + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, + decode_vcard_REV(<<"vcard-temp">>, __IgnoreEls, + _el), + Sort_string, Org, Bday, Key, Tz, Url, Email, + Tel, Label, Fn, Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"SORT-STRING">>, _attrs, _} = _el | _els], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, + decode_vcard_SORT_STRING(__TopXMLNS, + __IgnoreEls, _el), + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, + decode_vcard_SORT_STRING(<<"vcard-temp">>, + __IgnoreEls, _el), + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"UID">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, + decode_vcard_UID(__TopXMLNS, __IgnoreEls, _el), + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, + decode_vcard_UID(<<"vcard-temp">>, __IgnoreEls, + _el), + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"URL">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + decode_vcard_URL(__TopXMLNS, __IgnoreEls, _el), + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + decode_vcard_URL(<<"vcard-temp">>, __IgnoreEls, + _el), + Email, Tel, Label, Fn, Version, N, Photo, Logo, + Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"DESC">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, + decode_vcard_DESC(__TopXMLNS, __IgnoreEls, _el), + Uid, Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, + decode_vcard_DESC(<<"vcard-temp">>, __IgnoreEls, + _el), + Uid, Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CATEGORIES">>, _attrs, _} = _el | _els], + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, + Fn, Version, N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, + decode_vcard_CATEGORIES(__TopXMLNS, __IgnoreEls, + _el), + Desc, Uid, Prodid, Jabberid, Sound, Note, Role, + Title, Nickname, Rev, Sort_string, Org, Bday, + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, + decode_vcard_CATEGORIES(<<"vcard-temp">>, + __IgnoreEls, _el), + Desc, Uid, Prodid, Jabberid, Sound, Note, Role, + Title, Nickname, Rev, Sort_string, Org, Bday, + Key, Tz, Url, Email, Tel, Label, Fn, Version, N, + Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CLASS">>, _attrs, _} = _el | _els], Mailer, + Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, + Sound, Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, + N, Photo, Logo, Geo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, + decode_vcard_CLASS(__TopXMLNS, __IgnoreEls, + _el), + Categories, Desc, Uid, Prodid, Jabberid, Sound, + Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + <<"vcard-temp">> -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, + decode_vcard_CLASS(<<"vcard-temp">>, + __IgnoreEls, _el), + Categories, Desc, Uid, Prodid, Jabberid, Sound, + Note, Role, Title, Nickname, Rev, Sort_string, + Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, + Version, N, Photo, Logo, Geo); + _ -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, + Nickname, Rev, Sort_string, Org, Bday, Key, Tz, + Url, Email, Tel, Label, Fn, Version, N, Photo, + Logo, Geo) + end; +decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Mailer, Adr, Class, Categories, Desc, Uid, + Prodid, Jabberid, Sound, Note, Role, Title, Nickname, + Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, + Label, Fn, Version, N, Photo, Logo, Geo) -> + decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, + Mailer, Adr, Class, Categories, Desc, Uid, Prodid, + Jabberid, Sound, Note, Role, Title, Nickname, Rev, + Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, + Label, Fn, Version, N, Photo, Logo, Geo). + +encode_vcard_temp({vcard_temp, Version, Fn, N, Nickname, + Photo, Bday, Adr, Label, Tel, Email, Jabberid, Mailer, + Tz, Geo, Title, Role, Logo, Org, Categories, Note, + Prodid, Rev, Sort_string, Sound, Uid, Url, Class, Key, + Desc}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_temp_$mailer'(Mailer, + 'encode_vcard_temp_$adr'(Adr, + 'encode_vcard_temp_$class'(Class, + 'encode_vcard_temp_$categories'(Categories, + 'encode_vcard_temp_$desc'(Desc, + 'encode_vcard_temp_$uid'(Uid, + 'encode_vcard_temp_$prodid'(Prodid, + 'encode_vcard_temp_$jabberid'(Jabberid, + 'encode_vcard_temp_$sound'(Sound, + 'encode_vcard_temp_$note'(Note, + 'encode_vcard_temp_$role'(Role, + 'encode_vcard_temp_$title'(Title, + 'encode_vcard_temp_$nickname'(Nickname, + 'encode_vcard_temp_$rev'(Rev, + 'encode_vcard_temp_$sort_string'(Sort_string, + 'encode_vcard_temp_$org'(Org, + 'encode_vcard_temp_$bday'(Bday, + 'encode_vcard_temp_$key'(Key, + 'encode_vcard_temp_$tz'(Tz, + 'encode_vcard_temp_$url'(Url, + 'encode_vcard_temp_$email'(Email, + 'encode_vcard_temp_$tel'(Tel, + 'encode_vcard_temp_$label'(Label, + 'encode_vcard_temp_$fn'(Fn, + 'encode_vcard_temp_$version'(Version, + 'encode_vcard_temp_$n'(N, + 'encode_vcard_temp_$photo'(Photo, + 'encode_vcard_temp_$logo'(Logo, + 'encode_vcard_temp_$geo'(Geo, + [])))))))))))))))))))))))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"vCard">>, _attrs, _els}. + +'encode_vcard_temp_$mailer'(undefined, _acc) -> _acc; +'encode_vcard_temp_$mailer'(Mailer, _acc) -> + [encode_vcard_MAILER(Mailer, []) | _acc]. + +'encode_vcard_temp_$adr'([], _acc) -> _acc; +'encode_vcard_temp_$adr'([Adr | _els], _acc) -> + 'encode_vcard_temp_$adr'(_els, + [encode_vcard_ADR(Adr, []) | _acc]). + +'encode_vcard_temp_$class'(undefined, _acc) -> _acc; +'encode_vcard_temp_$class'(Class, _acc) -> + [encode_vcard_CLASS(Class, []) | _acc]. + +'encode_vcard_temp_$categories'([], _acc) -> _acc; +'encode_vcard_temp_$categories'(Categories, _acc) -> + [encode_vcard_CATEGORIES(Categories, []) | _acc]. + +'encode_vcard_temp_$desc'(undefined, _acc) -> _acc; +'encode_vcard_temp_$desc'(Desc, _acc) -> + [encode_vcard_DESC(Desc, []) | _acc]. + +'encode_vcard_temp_$uid'(undefined, _acc) -> _acc; +'encode_vcard_temp_$uid'(Uid, _acc) -> + [encode_vcard_UID(Uid, []) | _acc]. + +'encode_vcard_temp_$prodid'(undefined, _acc) -> _acc; +'encode_vcard_temp_$prodid'(Prodid, _acc) -> + [encode_vcard_PRODID(Prodid, []) | _acc]. + +'encode_vcard_temp_$jabberid'(undefined, _acc) -> _acc; +'encode_vcard_temp_$jabberid'(Jabberid, _acc) -> + [encode_vcard_JABBERID(Jabberid, []) | _acc]. + +'encode_vcard_temp_$sound'(undefined, _acc) -> _acc; +'encode_vcard_temp_$sound'(Sound, _acc) -> + [encode_vcard_SOUND(Sound, []) | _acc]. + +'encode_vcard_temp_$note'(undefined, _acc) -> _acc; +'encode_vcard_temp_$note'(Note, _acc) -> + [encode_vcard_NOTE(Note, []) | _acc]. + +'encode_vcard_temp_$role'(undefined, _acc) -> _acc; +'encode_vcard_temp_$role'(Role, _acc) -> + [encode_vcard_ROLE(Role, []) | _acc]. + +'encode_vcard_temp_$title'(undefined, _acc) -> _acc; +'encode_vcard_temp_$title'(Title, _acc) -> + [encode_vcard_TITLE(Title, []) | _acc]. + +'encode_vcard_temp_$nickname'(undefined, _acc) -> _acc; +'encode_vcard_temp_$nickname'(Nickname, _acc) -> + [encode_vcard_NICKNAME(Nickname, []) | _acc]. + +'encode_vcard_temp_$rev'(undefined, _acc) -> _acc; +'encode_vcard_temp_$rev'(Rev, _acc) -> + [encode_vcard_REV(Rev, []) | _acc]. + +'encode_vcard_temp_$sort_string'(undefined, _acc) -> + _acc; +'encode_vcard_temp_$sort_string'(Sort_string, _acc) -> + [encode_vcard_SORT_STRING(Sort_string, []) | _acc]. + +'encode_vcard_temp_$org'(undefined, _acc) -> _acc; +'encode_vcard_temp_$org'(Org, _acc) -> + [encode_vcard_ORG(Org, []) | _acc]. + +'encode_vcard_temp_$bday'(undefined, _acc) -> _acc; +'encode_vcard_temp_$bday'(Bday, _acc) -> + [encode_vcard_BDAY(Bday, []) | _acc]. + +'encode_vcard_temp_$key'(undefined, _acc) -> _acc; +'encode_vcard_temp_$key'(Key, _acc) -> + [encode_vcard_KEY(Key, []) | _acc]. + +'encode_vcard_temp_$tz'(undefined, _acc) -> _acc; +'encode_vcard_temp_$tz'(Tz, _acc) -> + [encode_vcard_TZ(Tz, []) | _acc]. + +'encode_vcard_temp_$url'(undefined, _acc) -> _acc; +'encode_vcard_temp_$url'(Url, _acc) -> + [encode_vcard_URL(Url, []) | _acc]. + +'encode_vcard_temp_$email'([], _acc) -> _acc; +'encode_vcard_temp_$email'([Email | _els], _acc) -> + 'encode_vcard_temp_$email'(_els, + [encode_vcard_EMAIL(Email, []) | _acc]). + +'encode_vcard_temp_$tel'([], _acc) -> _acc; +'encode_vcard_temp_$tel'([Tel | _els], _acc) -> + 'encode_vcard_temp_$tel'(_els, + [encode_vcard_TEL(Tel, []) | _acc]). + +'encode_vcard_temp_$label'([], _acc) -> _acc; +'encode_vcard_temp_$label'([Label | _els], _acc) -> + 'encode_vcard_temp_$label'(_els, + [encode_vcard_LABEL(Label, []) | _acc]). + +'encode_vcard_temp_$fn'(undefined, _acc) -> _acc; +'encode_vcard_temp_$fn'(Fn, _acc) -> + [encode_vcard_FN(Fn, []) | _acc]. + +'encode_vcard_temp_$version'(undefined, _acc) -> _acc; +'encode_vcard_temp_$version'(Version, _acc) -> + [encode_vcard_VERSION(Version, []) | _acc]. + +'encode_vcard_temp_$n'(undefined, _acc) -> _acc; +'encode_vcard_temp_$n'(N, _acc) -> + [encode_vcard_N(N, []) | _acc]. + +'encode_vcard_temp_$photo'(undefined, _acc) -> _acc; +'encode_vcard_temp_$photo'(Photo, _acc) -> + [encode_vcard_PHOTO(Photo, []) | _acc]. + +'encode_vcard_temp_$logo'(undefined, _acc) -> _acc; +'encode_vcard_temp_$logo'(Logo, _acc) -> + [encode_vcard_LOGO(Logo, []) | _acc]. + +'encode_vcard_temp_$geo'(undefined, _acc) -> _acc; +'encode_vcard_temp_$geo'(Geo, _acc) -> + [encode_vcard_GEO(Geo, []) | _acc]. + +decode_vcard_CLASS(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CLASS">>, _attrs, _els}) -> + Class = decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, + _els, undefined), + Class. + +decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, [], + Class) -> + Class; +decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PUBLIC">>, _attrs, _} = _el | _els], + Class) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PUBLIC(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PUBLIC(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + Class) + end; +decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PRIVATE">>, _attrs, _} = _el | _els], + Class) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PRIVATE(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PRIVATE(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + Class) + end; +decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CONFIDENTIAL">>, _attrs, _} = _el | _els], + Class) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_CONFIDENTIAL(__TopXMLNS, + __IgnoreEls, _el)); + <<"vcard-temp">> -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + Class) + end; +decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Class) -> + decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, + Class). + +encode_vcard_CLASS(Class, _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_CLASS_$class'(Class, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"CLASS">>, _attrs, _els}. + +'encode_vcard_CLASS_$class'(undefined, _acc) -> _acc; +'encode_vcard_CLASS_$class'(public = Class, _acc) -> + [encode_vcard_PUBLIC(Class, []) | _acc]; +'encode_vcard_CLASS_$class'(private = Class, _acc) -> + [encode_vcard_PRIVATE(Class, []) | _acc]; +'encode_vcard_CLASS_$class'(confidential = Class, + _acc) -> + [encode_vcard_CONFIDENTIAL(Class, []) | _acc]. + +decode_vcard_CATEGORIES(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CATEGORIES">>, _attrs, _els}) -> + Keywords = decode_vcard_CATEGORIES_els(__TopXMLNS, + __IgnoreEls, _els, []), + Keywords. + +decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, [], + Keywords) -> + lists:reverse(Keywords); +decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"KEYWORD">>, _attrs, _} = _el | _els], + Keywords) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + _els, + case decode_vcard_KEYWORD(__TopXMLNS, + __IgnoreEls, + _el) + of + undefined -> Keywords; + _new_el -> [_new_el | Keywords] + end); + <<"vcard-temp">> -> + decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + _els, + case + decode_vcard_KEYWORD(<<"vcard-temp">>, + __IgnoreEls, _el) + of + undefined -> Keywords; + _new_el -> [_new_el | Keywords] + end); + _ -> + decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + _els, Keywords) + end; +decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Keywords) -> + decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, + _els, Keywords). + +encode_vcard_CATEGORIES(Keywords, _xmlns_attrs) -> + _els = + lists:reverse('encode_vcard_CATEGORIES_$keywords'(Keywords, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"CATEGORIES">>, _attrs, _els}. + +'encode_vcard_CATEGORIES_$keywords'([], _acc) -> _acc; +'encode_vcard_CATEGORIES_$keywords'([Keywords | _els], + _acc) -> + 'encode_vcard_CATEGORIES_$keywords'(_els, + [encode_vcard_KEYWORD(Keywords, []) + | _acc]). + +decode_vcard_KEY(__TopXMLNS, __IgnoreEls, + {xmlel, <<"KEY">>, _attrs, _els}) -> + {Cred, Type} = decode_vcard_KEY_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined), + {vcard_key, Type, Cred}. + +decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, [], Cred, + Type) -> + {Cred, Type}; +decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Cred, + Type) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + Cred, + decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, _el)); + <<"vcard-temp">> -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + Cred, + decode_vcard_TYPE(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + Cred, Type) + end; +decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CRED">>, _attrs, _} = _el | _els], Cred, + Type) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_CRED(__TopXMLNS, __IgnoreEls, _el), + Type); + <<"vcard-temp">> -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_CRED(<<"vcard-temp">>, __IgnoreEls, + _el), + Type); + _ -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + Cred, Type) + end; +decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cred, Type) -> + decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, + Cred, Type). + +encode_vcard_KEY({vcard_key, Type, Cred}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_KEY_$cred'(Cred, + 'encode_vcard_KEY_$type'(Type, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"KEY">>, _attrs, _els}. + +'encode_vcard_KEY_$cred'(undefined, _acc) -> _acc; +'encode_vcard_KEY_$cred'(Cred, _acc) -> + [encode_vcard_CRED(Cred, []) | _acc]. + +'encode_vcard_KEY_$type'(undefined, _acc) -> _acc; +'encode_vcard_KEY_$type'(Type, _acc) -> + [encode_vcard_TYPE(Type, []) | _acc]. + +decode_vcard_SOUND(__TopXMLNS, __IgnoreEls, + {xmlel, <<"SOUND">>, _attrs, _els}) -> + {Phonetic, Extval, Binval} = + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined), + {vcard_sound, Phonetic, Binval, Extval}. + +decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, [], + Phonetic, Extval, Binval) -> + {Phonetic, Extval, Binval}; +decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], + Phonetic, Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, + decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, + decode_vcard_BINVAL(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, Binval) + end; +decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], + Phonetic, Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, + decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, + _el), + Binval); + <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, + decode_vcard_EXTVAL(<<"vcard-temp">>, + __IgnoreEls, _el), + Binval); + _ -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, Binval) + end; +decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PHONETIC">>, _attrs, _} = _el | _els], + Phonetic, Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PHONETIC(__TopXMLNS, __IgnoreEls, + _el), + Extval, Binval); + <<"vcard-temp">> -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_PHONETIC(<<"vcard-temp">>, + __IgnoreEls, _el), + Extval, Binval); + _ -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, Binval) + end; +decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Phonetic, Extval, Binval) -> + decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, + Phonetic, Extval, Binval). + +encode_vcard_SOUND({vcard_sound, Phonetic, Binval, + Extval}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_vcard_SOUND_$phonetic'(Phonetic, + 'encode_vcard_SOUND_$extval'(Extval, + 'encode_vcard_SOUND_$binval'(Binval, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"SOUND">>, _attrs, _els}. + +'encode_vcard_SOUND_$phonetic'(undefined, _acc) -> _acc; +'encode_vcard_SOUND_$phonetic'(Phonetic, _acc) -> + [encode_vcard_PHONETIC(Phonetic, []) | _acc]. + +'encode_vcard_SOUND_$extval'(undefined, _acc) -> _acc; +'encode_vcard_SOUND_$extval'(Extval, _acc) -> + [encode_vcard_EXTVAL(Extval, []) | _acc]. + +'encode_vcard_SOUND_$binval'(undefined, _acc) -> _acc; +'encode_vcard_SOUND_$binval'(Binval, _acc) -> + [encode_vcard_BINVAL(Binval, []) | _acc]. + +decode_vcard_ORG(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ORG">>, _attrs, _els}) -> + {Units, Name} = decode_vcard_ORG_els(__TopXMLNS, + __IgnoreEls, _els, [], undefined), + {vcard_org, Name, Units}. + +decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, [], Units, + Name) -> + {lists:reverse(Units), Name}; +decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ORGNAME">>, _attrs, _} = _el | _els], Units, + Name) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + Units, + decode_vcard_ORGNAME(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + Units, + decode_vcard_ORGNAME(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + Units, Name) + end; +decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ORGUNIT">>, _attrs, _} = _el | _els], Units, + Name) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + case decode_vcard_ORGUNIT(__TopXMLNS, + __IgnoreEls, _el) + of + undefined -> Units; + _new_el -> [_new_el | Units] + end, + Name); + <<"vcard-temp">> -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + case decode_vcard_ORGUNIT(<<"vcard-temp">>, + __IgnoreEls, _el) + of + undefined -> Units; + _new_el -> [_new_el | Units] + end, + Name); + _ -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + Units, Name) + end; +decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Units, Name) -> + decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, + Units, Name). + +encode_vcard_ORG({vcard_org, Name, Units}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_ORG_$units'(Units, + 'encode_vcard_ORG_$name'(Name, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"ORG">>, _attrs, _els}. + +'encode_vcard_ORG_$units'([], _acc) -> _acc; +'encode_vcard_ORG_$units'([Units | _els], _acc) -> + 'encode_vcard_ORG_$units'(_els, + [encode_vcard_ORGUNIT(Units, []) | _acc]). + +'encode_vcard_ORG_$name'(undefined, _acc) -> _acc; +'encode_vcard_ORG_$name'(Name, _acc) -> + [encode_vcard_ORGNAME(Name, []) | _acc]. + +decode_vcard_PHOTO(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PHOTO">>, _attrs, _els}) -> + {Type, Extval, Binval} = + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined), + {vcard_photo, Type, Binval, Extval}. + +decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, [], + Type, Extval, Binval) -> + {Type, Extval, Binval}; +decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, + _el), + Extval, Binval); + <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_TYPE(<<"vcard-temp">>, + __IgnoreEls, _el), + Extval, Binval); + _ -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, + decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, + decode_vcard_BINVAL(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, + decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, + _el), + Binval); + <<"vcard-temp">> -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, + decode_vcard_EXTVAL(<<"vcard-temp">>, + __IgnoreEls, _el), + Binval); + _ -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Type, Extval, Binval) -> + decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval). + +encode_vcard_PHOTO({vcard_photo, Type, Binval, Extval}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_PHOTO_$type'(Type, + 'encode_vcard_PHOTO_$extval'(Extval, + 'encode_vcard_PHOTO_$binval'(Binval, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"PHOTO">>, _attrs, _els}. + +'encode_vcard_PHOTO_$type'(undefined, _acc) -> _acc; +'encode_vcard_PHOTO_$type'(Type, _acc) -> + [encode_vcard_TYPE(Type, []) | _acc]. + +'encode_vcard_PHOTO_$extval'(undefined, _acc) -> _acc; +'encode_vcard_PHOTO_$extval'(Extval, _acc) -> + [encode_vcard_EXTVAL(Extval, []) | _acc]. + +'encode_vcard_PHOTO_$binval'(undefined, _acc) -> _acc; +'encode_vcard_PHOTO_$binval'(Binval, _acc) -> + [encode_vcard_BINVAL(Binval, []) | _acc]. + +decode_vcard_LOGO(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LOGO">>, _attrs, _els}) -> + {Type, Extval, Binval} = + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined), + {vcard_logo, Type, Binval, Extval}. + +decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, [], Type, + Extval, Binval) -> + {Type, Extval, Binval}; +decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, _el), + Extval, Binval); + <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_TYPE(<<"vcard-temp">>, __IgnoreEls, + _el), + Extval, Binval); + _ -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, + decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, + decode_vcard_BINVAL(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], Type, + Extval, Binval) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, + decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, + _el), + Binval); + <<"vcard-temp">> -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, + decode_vcard_EXTVAL(<<"vcard-temp">>, + __IgnoreEls, _el), + Binval); + _ -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval) + end; +decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Type, Extval, Binval) -> + decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, + Type, Extval, Binval). + +encode_vcard_LOGO({vcard_logo, Type, Binval, Extval}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_LOGO_$type'(Type, + 'encode_vcard_LOGO_$extval'(Extval, + 'encode_vcard_LOGO_$binval'(Binval, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"LOGO">>, _attrs, _els}. + +'encode_vcard_LOGO_$type'(undefined, _acc) -> _acc; +'encode_vcard_LOGO_$type'(Type, _acc) -> + [encode_vcard_TYPE(Type, []) | _acc]. + +'encode_vcard_LOGO_$extval'(undefined, _acc) -> _acc; +'encode_vcard_LOGO_$extval'(Extval, _acc) -> + [encode_vcard_EXTVAL(Extval, []) | _acc]. + +'encode_vcard_LOGO_$binval'(undefined, _acc) -> _acc; +'encode_vcard_LOGO_$binval'(Binval, _acc) -> + [encode_vcard_BINVAL(Binval, []) | _acc]. + +decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"BINVAL">>, _attrs, _els}) -> + Cdata = decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_BINVAL_cdata(__TopXMLNS, Cdata); +decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_BINVAL(Cdata, _xmlns_attrs) -> + _els = encode_vcard_BINVAL_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"BINVAL">>, _attrs, _els}. + +decode_vcard_BINVAL_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_BINVAL_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"BINVAL">>, __TopXMLNS}}); + _res -> _res + end. + +encode_vcard_BINVAL_cdata(undefined, _acc) -> _acc; +encode_vcard_BINVAL_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + +decode_vcard_GEO(__TopXMLNS, __IgnoreEls, + {xmlel, <<"GEO">>, _attrs, _els}) -> + {Lat, Lon} = decode_vcard_GEO_els(__TopXMLNS, + __IgnoreEls, _els, undefined, undefined), + {vcard_geo, Lat, Lon}. + +decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, [], Lat, + Lon) -> + {Lat, Lon}; +decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LAT">>, _attrs, _} = _el | _els], Lat, + Lon) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_LAT(__TopXMLNS, __IgnoreEls, _el), + Lon); + <<"vcard-temp">> -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_LAT(<<"vcard-temp">>, __IgnoreEls, + _el), + Lon); + _ -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, + Lon) + end; +decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LON">>, _attrs, _} = _el | _els], Lat, + Lon) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, + decode_vcard_LON(__TopXMLNS, __IgnoreEls, _el)); + <<"vcard-temp">> -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, + decode_vcard_LON(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, + Lon) + end; +decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Lat, Lon) -> + decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, + Lon). + +encode_vcard_GEO({vcard_geo, Lat, Lon}, _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_GEO_$lat'(Lat, + 'encode_vcard_GEO_$lon'(Lon, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"GEO">>, _attrs, _els}. + +'encode_vcard_GEO_$lat'(undefined, _acc) -> _acc; +'encode_vcard_GEO_$lat'(Lat, _acc) -> + [encode_vcard_LAT(Lat, []) | _acc]. + +'encode_vcard_GEO_$lon'(undefined, _acc) -> _acc; +'encode_vcard_GEO_$lon'(Lon, _acc) -> + [encode_vcard_LON(Lon, []) | _acc]. + +decode_vcard_EMAIL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"EMAIL">>, _attrs, _els}) -> + {X400, Userid, Internet, Home, Pref, Work} = + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + false, undefined, false, false, false, false), + {vcard_email, Home, Work, Internet, Pref, X400, Userid}. + +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, [], + X400, Userid, Internet, Home, Pref, Work) -> + {X400, Userid, Internet, Home, Pref, Work}; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, + decode_vcard_HOME(__TopXMLNS, __IgnoreEls, + _el), + Pref, Work); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, + decode_vcard_HOME(<<"vcard-temp">>, + __IgnoreEls, _el), + Pref, Work); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, + decode_vcard_WORK(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, + decode_vcard_WORK(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"INTERNET">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, + decode_vcard_INTERNET(__TopXMLNS, __IgnoreEls, + _el), + Home, Pref, Work); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, + decode_vcard_INTERNET(<<"vcard-temp">>, + __IgnoreEls, _el), + Home, Pref, Work); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, + decode_vcard_PREF(__TopXMLNS, __IgnoreEls, + _el), + Work); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, + decode_vcard_PREF(<<"vcard-temp">>, + __IgnoreEls, _el), + Work); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"X400">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_X400(__TopXMLNS, __IgnoreEls, + _el), + Userid, Internet, Home, Pref, Work); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_X400(<<"vcard-temp">>, + __IgnoreEls, _el), + Userid, Internet, Home, Pref, Work); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"USERID">>, _attrs, _} = _el | _els], X400, + Userid, Internet, Home, Pref, Work) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, + decode_vcard_USERID(__TopXMLNS, __IgnoreEls, + _el), + Internet, Home, Pref, Work); + <<"vcard-temp">> -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, + decode_vcard_USERID(<<"vcard-temp">>, + __IgnoreEls, _el), + Internet, Home, Pref, Work); + _ -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work) + end; +decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], X400, Userid, Internet, Home, Pref, Work) -> + decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, + X400, Userid, Internet, Home, Pref, Work). + +encode_vcard_EMAIL({vcard_email, Home, Work, Internet, + Pref, X400, Userid}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_EMAIL_$x400'(X400, + 'encode_vcard_EMAIL_$userid'(Userid, + 'encode_vcard_EMAIL_$internet'(Internet, + 'encode_vcard_EMAIL_$home'(Home, + 'encode_vcard_EMAIL_$pref'(Pref, + 'encode_vcard_EMAIL_$work'(Work, + []))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"EMAIL">>, _attrs, _els}. + +'encode_vcard_EMAIL_$x400'(false, _acc) -> _acc; +'encode_vcard_EMAIL_$x400'(X400, _acc) -> + [encode_vcard_X400(X400, []) | _acc]. + +'encode_vcard_EMAIL_$userid'(undefined, _acc) -> _acc; +'encode_vcard_EMAIL_$userid'(Userid, _acc) -> + [encode_vcard_USERID(Userid, []) | _acc]. + +'encode_vcard_EMAIL_$internet'(false, _acc) -> _acc; +'encode_vcard_EMAIL_$internet'(Internet, _acc) -> + [encode_vcard_INTERNET(Internet, []) | _acc]. + +'encode_vcard_EMAIL_$home'(false, _acc) -> _acc; +'encode_vcard_EMAIL_$home'(Home, _acc) -> + [encode_vcard_HOME(Home, []) | _acc]. + +'encode_vcard_EMAIL_$pref'(false, _acc) -> _acc; +'encode_vcard_EMAIL_$pref'(Pref, _acc) -> + [encode_vcard_PREF(Pref, []) | _acc]. + +'encode_vcard_EMAIL_$work'(false, _acc) -> _acc; +'encode_vcard_EMAIL_$work'(Work, _acc) -> + [encode_vcard_WORK(Work, []) | _acc]. + +decode_vcard_TEL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"TEL">>, _attrs, _els}) -> + {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video} = + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + undefined, false, false, false, false, false, + false, false, false, false, false, false, false, + false), + {vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell, + Video, Bbs, Modem, Isdn, Pcs, Pref, Number}. + +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, [], + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video) -> + {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video}; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, + decode_vcard_HOME(__TopXMLNS, __IgnoreEls, _el), + Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, + decode_vcard_HOME(<<"vcard-temp">>, __IgnoreEls, + _el), + Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, + decode_vcard_WORK(__TopXMLNS, __IgnoreEls, _el), + Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, + decode_vcard_WORK(<<"vcard-temp">>, __IgnoreEls, + _el), + Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"VOICE">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, + decode_vcard_VOICE(__TopXMLNS, __IgnoreEls, _el), + Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn, + Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, + decode_vcard_VOICE(<<"vcard-temp">>, __IgnoreEls, + _el), + Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn, + Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"FAX">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + decode_vcard_FAX(__TopXMLNS, __IgnoreEls, _el), + Work, Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + decode_vcard_FAX(<<"vcard-temp">>, __IgnoreEls, + _el), + Work, Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PAGER">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, + decode_vcard_PAGER(__TopXMLNS, __IgnoreEls, _el), + Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, + decode_vcard_PAGER(<<"vcard-temp">>, __IgnoreEls, + _el), + Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"MSG">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, + decode_vcard_MSG(__TopXMLNS, __IgnoreEls, _el), + Fax, Work, Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, + decode_vcard_MSG(<<"vcard-temp">>, __IgnoreEls, + _el), + Fax, Work, Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CELL">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, + decode_vcard_CELL(__TopXMLNS, __IgnoreEls, _el), + Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, + decode_vcard_CELL(<<"vcard-temp">>, __IgnoreEls, + _el), + Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"VIDEO">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, + decode_vcard_VIDEO(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, + decode_vcard_VIDEO(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"BBS">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, + decode_vcard_BBS(__TopXMLNS, __IgnoreEls, _el), + Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, + Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, + decode_vcard_BBS(<<"vcard-temp">>, __IgnoreEls, + _el), + Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, + Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"MODEM">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, + decode_vcard_MODEM(__TopXMLNS, __IgnoreEls, _el), + Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, + decode_vcard_MODEM(<<"vcard-temp">>, __IgnoreEls, + _el), + Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ISDN">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, + decode_vcard_ISDN(__TopXMLNS, __IgnoreEls, _el), + Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, + decode_vcard_ISDN(<<"vcard-temp">>, __IgnoreEls, + _el), + Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PCS">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, + decode_vcard_PCS(__TopXMLNS, __IgnoreEls, _el), + Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, + Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, + decode_vcard_PCS(<<"vcard-temp">>, __IgnoreEls, + _el), + Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, + Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, + decode_vcard_PREF(__TopXMLNS, __IgnoreEls, _el), + Msg, Fax, Work, Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, + decode_vcard_PREF(<<"vcard-temp">>, __IgnoreEls, + _el), + Msg, Fax, Work, Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"NUMBER">>, _attrs, _} = _el | _els], Number, + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, + Cell, Modem, Isdn, Video) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_NUMBER(__TopXMLNS, __IgnoreEls, + _el), + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video); + <<"vcard-temp">> -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_NUMBER(<<"vcard-temp">>, + __IgnoreEls, _el), + Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video); + _ -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, + Fax, Work, Cell, Modem, Isdn, Video) + end; +decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Number, Pager, Pcs, Bbs, Voice, Home, Pref, + Msg, Fax, Work, Cell, Modem, Isdn, Video) -> + decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, + Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, + Work, Cell, Modem, Isdn, Video). + +encode_vcard_TEL({vcard_tel, Home, Work, Voice, Fax, + Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs, Pref, + Number}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_TEL_$number'(Number, + 'encode_vcard_TEL_$pager'(Pager, + 'encode_vcard_TEL_$pcs'(Pcs, + 'encode_vcard_TEL_$bbs'(Bbs, + 'encode_vcard_TEL_$voice'(Voice, + 'encode_vcard_TEL_$home'(Home, + 'encode_vcard_TEL_$pref'(Pref, + 'encode_vcard_TEL_$msg'(Msg, + 'encode_vcard_TEL_$fax'(Fax, + 'encode_vcard_TEL_$work'(Work, + 'encode_vcard_TEL_$cell'(Cell, + 'encode_vcard_TEL_$modem'(Modem, + 'encode_vcard_TEL_$isdn'(Isdn, + 'encode_vcard_TEL_$video'(Video, + []))))))))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"TEL">>, _attrs, _els}. + +'encode_vcard_TEL_$number'(undefined, _acc) -> _acc; +'encode_vcard_TEL_$number'(Number, _acc) -> + [encode_vcard_NUMBER(Number, []) | _acc]. + +'encode_vcard_TEL_$pager'(false, _acc) -> _acc; +'encode_vcard_TEL_$pager'(Pager, _acc) -> + [encode_vcard_PAGER(Pager, []) | _acc]. + +'encode_vcard_TEL_$pcs'(false, _acc) -> _acc; +'encode_vcard_TEL_$pcs'(Pcs, _acc) -> + [encode_vcard_PCS(Pcs, []) | _acc]. + +'encode_vcard_TEL_$bbs'(false, _acc) -> _acc; +'encode_vcard_TEL_$bbs'(Bbs, _acc) -> + [encode_vcard_BBS(Bbs, []) | _acc]. + +'encode_vcard_TEL_$voice'(false, _acc) -> _acc; +'encode_vcard_TEL_$voice'(Voice, _acc) -> + [encode_vcard_VOICE(Voice, []) | _acc]. + +'encode_vcard_TEL_$home'(false, _acc) -> _acc; +'encode_vcard_TEL_$home'(Home, _acc) -> + [encode_vcard_HOME(Home, []) | _acc]. + +'encode_vcard_TEL_$pref'(false, _acc) -> _acc; +'encode_vcard_TEL_$pref'(Pref, _acc) -> + [encode_vcard_PREF(Pref, []) | _acc]. + +'encode_vcard_TEL_$msg'(false, _acc) -> _acc; +'encode_vcard_TEL_$msg'(Msg, _acc) -> + [encode_vcard_MSG(Msg, []) | _acc]. + +'encode_vcard_TEL_$fax'(false, _acc) -> _acc; +'encode_vcard_TEL_$fax'(Fax, _acc) -> + [encode_vcard_FAX(Fax, []) | _acc]. + +'encode_vcard_TEL_$work'(false, _acc) -> _acc; +'encode_vcard_TEL_$work'(Work, _acc) -> + [encode_vcard_WORK(Work, []) | _acc]. + +'encode_vcard_TEL_$cell'(false, _acc) -> _acc; +'encode_vcard_TEL_$cell'(Cell, _acc) -> + [encode_vcard_CELL(Cell, []) | _acc]. + +'encode_vcard_TEL_$modem'(false, _acc) -> _acc; +'encode_vcard_TEL_$modem'(Modem, _acc) -> + [encode_vcard_MODEM(Modem, []) | _acc]. + +'encode_vcard_TEL_$isdn'(false, _acc) -> _acc; +'encode_vcard_TEL_$isdn'(Isdn, _acc) -> + [encode_vcard_ISDN(Isdn, []) | _acc]. + +'encode_vcard_TEL_$video'(false, _acc) -> _acc; +'encode_vcard_TEL_$video'(Video, _acc) -> + [encode_vcard_VIDEO(Video, []) | _acc]. + +decode_vcard_LABEL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LABEL">>, _attrs, _els}) -> + {Line, Home, Pref, Work, Intl, Parcel, Postal, Dom} = + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + [], false, false, false, false, false, false, + false), + {vcard_label, Home, Work, Postal, Parcel, Dom, Intl, + Pref, Line}. + +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, [], + Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + {lists:reverse(Line), Home, Pref, Work, Intl, Parcel, + Postal, Dom}; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, + decode_vcard_HOME(__TopXMLNS, __IgnoreEls, + _el), + Pref, Work, Intl, Parcel, Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, + decode_vcard_HOME(<<"vcard-temp">>, + __IgnoreEls, _el), + Pref, Work, Intl, Parcel, Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, + decode_vcard_WORK(__TopXMLNS, __IgnoreEls, + _el), + Intl, Parcel, Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, + decode_vcard_WORK(<<"vcard-temp">>, + __IgnoreEls, _el), + Intl, Parcel, Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"POSTAL">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, + decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, + _el), + Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, + decode_vcard_POSTAL(<<"vcard-temp">>, + __IgnoreEls, _el), + Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PARCEL">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, + decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, + _el), + Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, + decode_vcard_PARCEL(<<"vcard-temp">>, + __IgnoreEls, _el), + Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"DOM">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + decode_vcard_DOM(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + decode_vcard_DOM(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"INTL">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, + decode_vcard_INTL(__TopXMLNS, __IgnoreEls, + _el), + Parcel, Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, + decode_vcard_INTL(<<"vcard-temp">>, + __IgnoreEls, _el), + Parcel, Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, + decode_vcard_PREF(__TopXMLNS, __IgnoreEls, + _el), + Work, Intl, Parcel, Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, + decode_vcard_PREF(<<"vcard-temp">>, + __IgnoreEls, _el), + Work, Intl, Parcel, Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LINE">>, _attrs, _} = _el | _els], Line, + Home, Pref, Work, Intl, Parcel, Postal, Dom) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + case decode_vcard_LINE(__TopXMLNS, __IgnoreEls, + _el) + of + undefined -> Line; + _new_el -> [_new_el | Line] + end, + Home, Pref, Work, Intl, Parcel, Postal, Dom); + <<"vcard-temp">> -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + case decode_vcard_LINE(<<"vcard-temp">>, + __IgnoreEls, _el) + of + undefined -> Line; + _new_el -> [_new_el | Line] + end, + Home, Pref, Work, Intl, Parcel, Postal, Dom); + _ -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, + Dom) + end; +decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Line, Home, Pref, Work, Intl, Parcel, + Postal, Dom) -> + decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, + Line, Home, Pref, Work, Intl, Parcel, Postal, Dom). + +encode_vcard_LABEL({vcard_label, Home, Work, Postal, + Parcel, Dom, Intl, Pref, Line}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_LABEL_$line'(Line, + 'encode_vcard_LABEL_$home'(Home, + 'encode_vcard_LABEL_$pref'(Pref, + 'encode_vcard_LABEL_$work'(Work, + 'encode_vcard_LABEL_$intl'(Intl, + 'encode_vcard_LABEL_$parcel'(Parcel, + 'encode_vcard_LABEL_$postal'(Postal, + 'encode_vcard_LABEL_$dom'(Dom, + []))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"LABEL">>, _attrs, _els}. + +'encode_vcard_LABEL_$line'([], _acc) -> _acc; +'encode_vcard_LABEL_$line'([Line | _els], _acc) -> + 'encode_vcard_LABEL_$line'(_els, + [encode_vcard_LINE(Line, []) | _acc]). + +'encode_vcard_LABEL_$home'(false, _acc) -> _acc; +'encode_vcard_LABEL_$home'(Home, _acc) -> + [encode_vcard_HOME(Home, []) | _acc]. + +'encode_vcard_LABEL_$pref'(false, _acc) -> _acc; +'encode_vcard_LABEL_$pref'(Pref, _acc) -> + [encode_vcard_PREF(Pref, []) | _acc]. + +'encode_vcard_LABEL_$work'(false, _acc) -> _acc; +'encode_vcard_LABEL_$work'(Work, _acc) -> + [encode_vcard_WORK(Work, []) | _acc]. + +'encode_vcard_LABEL_$intl'(false, _acc) -> _acc; +'encode_vcard_LABEL_$intl'(Intl, _acc) -> + [encode_vcard_INTL(Intl, []) | _acc]. + +'encode_vcard_LABEL_$parcel'(false, _acc) -> _acc; +'encode_vcard_LABEL_$parcel'(Parcel, _acc) -> + [encode_vcard_PARCEL(Parcel, []) | _acc]. + +'encode_vcard_LABEL_$postal'(false, _acc) -> _acc; +'encode_vcard_LABEL_$postal'(Postal, _acc) -> + [encode_vcard_POSTAL(Postal, []) | _acc]. + +'encode_vcard_LABEL_$dom'(false, _acc) -> _acc; +'encode_vcard_LABEL_$dom'(Dom, _acc) -> + [encode_vcard_DOM(Dom, []) | _acc]. + +decode_vcard_ADR(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ADR">>, _attrs, _els}) -> + {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, Region} = + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, false, false, + undefined, undefined, undefined, false, false, + false, false, false, undefined), + {vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref, + Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}. + +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, [], + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, Region) -> + {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, Region}; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, + decode_vcard_HOME(__TopXMLNS, __IgnoreEls, _el), + Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, + Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, + decode_vcard_HOME(<<"vcard-temp">>, __IgnoreEls, + _el), + Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, + Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, + decode_vcard_WORK(__TopXMLNS, __IgnoreEls, _el), + Intl, Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, + decode_vcard_WORK(<<"vcard-temp">>, __IgnoreEls, + _el), + Intl, Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"POSTAL">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, + decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, + _el), + Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, + decode_vcard_POSTAL(<<"vcard-temp">>, + __IgnoreEls, _el), + Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PARCEL">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, + decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, + _el), + Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, + decode_vcard_PARCEL(<<"vcard-temp">>, + __IgnoreEls, _el), + Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"DOM">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, + decode_vcard_DOM(__TopXMLNS, __IgnoreEls, _el), + Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, + decode_vcard_DOM(<<"vcard-temp">>, __IgnoreEls, + _el), + Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"INTL">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, + decode_vcard_INTL(__TopXMLNS, __IgnoreEls, _el), + Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, + decode_vcard_INTL(<<"vcard-temp">>, __IgnoreEls, + _el), + Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, + decode_vcard_PREF(__TopXMLNS, __IgnoreEls, _el), + Pobox, Ctry, Locality, Work, Intl, Parcel, + Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, + decode_vcard_PREF(<<"vcard-temp">>, __IgnoreEls, + _el), + Pobox, Ctry, Locality, Work, Intl, Parcel, + Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"POBOX">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, + decode_vcard_POBOX(__TopXMLNS, __IgnoreEls, _el), + Ctry, Locality, Work, Intl, Parcel, Postal, Dom, + Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, + decode_vcard_POBOX(<<"vcard-temp">>, __IgnoreEls, + _el), + Ctry, Locality, Work, Intl, Parcel, Postal, Dom, + Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"EXTADD">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, + decode_vcard_EXTADD(__TopXMLNS, __IgnoreEls, + _el), + Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, + decode_vcard_EXTADD(<<"vcard-temp">>, + __IgnoreEls, _el), + Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"STREET">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_STREET(__TopXMLNS, __IgnoreEls, + _el), + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, + Work, Intl, Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_STREET(<<"vcard-temp">>, + __IgnoreEls, _el), + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, + Work, Intl, Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"LOCALITY">>, _attrs, _} = _el | _els], + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + decode_vcard_LOCALITY(__TopXMLNS, __IgnoreEls, + _el), + Work, Intl, Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + decode_vcard_LOCALITY(<<"vcard-temp">>, + __IgnoreEls, _el), + Work, Intl, Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"REGION">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + decode_vcard_REGION(__TopXMLNS, __IgnoreEls, + _el)); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + decode_vcard_REGION(<<"vcard-temp">>, + __IgnoreEls, _el)); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PCODE">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, + decode_vcard_PCODE(__TopXMLNS, __IgnoreEls, _el), + Home, Pref, Pobox, Ctry, Locality, Work, Intl, + Parcel, Postal, Dom, Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, + decode_vcard_PCODE(<<"vcard-temp">>, __IgnoreEls, + _el), + Home, Pref, Pobox, Ctry, Locality, Work, Intl, + Parcel, Postal, Dom, Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"CTRY">>, _attrs, _} = _el | _els], Street, + Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, + Intl, Parcel, Postal, Dom, Region) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, + decode_vcard_CTRY(__TopXMLNS, __IgnoreEls, _el), + Locality, Work, Intl, Parcel, Postal, Dom, + Region); + <<"vcard-temp">> -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, + decode_vcard_CTRY(<<"vcard-temp">>, __IgnoreEls, + _el), + Locality, Work, Intl, Parcel, Postal, Dom, + Region); + _ -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, + Region) + end; +decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Street, Extadd, Pcode, Home, Pref, Pobox, + Ctry, Locality, Work, Intl, Parcel, Postal, Dom, + Region) -> + decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, + Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, + Locality, Work, Intl, Parcel, Postal, Dom, Region). + +encode_vcard_ADR({vcard_adr, Home, Work, Postal, Parcel, + Dom, Intl, Pref, Pobox, Extadd, Street, Locality, + Region, Pcode, Ctry}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_ADR_$street'(Street, + 'encode_vcard_ADR_$extadd'(Extadd, + 'encode_vcard_ADR_$pcode'(Pcode, + 'encode_vcard_ADR_$home'(Home, + 'encode_vcard_ADR_$pref'(Pref, + 'encode_vcard_ADR_$pobox'(Pobox, + 'encode_vcard_ADR_$ctry'(Ctry, + 'encode_vcard_ADR_$locality'(Locality, + 'encode_vcard_ADR_$work'(Work, + 'encode_vcard_ADR_$intl'(Intl, + 'encode_vcard_ADR_$parcel'(Parcel, + 'encode_vcard_ADR_$postal'(Postal, + 'encode_vcard_ADR_$dom'(Dom, + 'encode_vcard_ADR_$region'(Region, + []))))))))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"ADR">>, _attrs, _els}. + +'encode_vcard_ADR_$street'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$street'(Street, _acc) -> + [encode_vcard_STREET(Street, []) | _acc]. + +'encode_vcard_ADR_$extadd'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$extadd'(Extadd, _acc) -> + [encode_vcard_EXTADD(Extadd, []) | _acc]. + +'encode_vcard_ADR_$pcode'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$pcode'(Pcode, _acc) -> + [encode_vcard_PCODE(Pcode, []) | _acc]. + +'encode_vcard_ADR_$home'(false, _acc) -> _acc; +'encode_vcard_ADR_$home'(Home, _acc) -> + [encode_vcard_HOME(Home, []) | _acc]. + +'encode_vcard_ADR_$pref'(false, _acc) -> _acc; +'encode_vcard_ADR_$pref'(Pref, _acc) -> + [encode_vcard_PREF(Pref, []) | _acc]. + +'encode_vcard_ADR_$pobox'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$pobox'(Pobox, _acc) -> + [encode_vcard_POBOX(Pobox, []) | _acc]. + +'encode_vcard_ADR_$ctry'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$ctry'(Ctry, _acc) -> + [encode_vcard_CTRY(Ctry, []) | _acc]. + +'encode_vcard_ADR_$locality'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$locality'(Locality, _acc) -> + [encode_vcard_LOCALITY(Locality, []) | _acc]. + +'encode_vcard_ADR_$work'(false, _acc) -> _acc; +'encode_vcard_ADR_$work'(Work, _acc) -> + [encode_vcard_WORK(Work, []) | _acc]. + +'encode_vcard_ADR_$intl'(false, _acc) -> _acc; +'encode_vcard_ADR_$intl'(Intl, _acc) -> + [encode_vcard_INTL(Intl, []) | _acc]. + +'encode_vcard_ADR_$parcel'(false, _acc) -> _acc; +'encode_vcard_ADR_$parcel'(Parcel, _acc) -> + [encode_vcard_PARCEL(Parcel, []) | _acc]. + +'encode_vcard_ADR_$postal'(false, _acc) -> _acc; +'encode_vcard_ADR_$postal'(Postal, _acc) -> + [encode_vcard_POSTAL(Postal, []) | _acc]. + +'encode_vcard_ADR_$dom'(false, _acc) -> _acc; +'encode_vcard_ADR_$dom'(Dom, _acc) -> + [encode_vcard_DOM(Dom, []) | _acc]. + +'encode_vcard_ADR_$region'(undefined, _acc) -> _acc; +'encode_vcard_ADR_$region'(Region, _acc) -> + [encode_vcard_REGION(Region, []) | _acc]. + +decode_vcard_N(__TopXMLNS, __IgnoreEls, + {xmlel, <<"N">>, _attrs, _els}) -> + {Middle, Suffix, Prefix, Family, Given} = + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined), + {vcard_name, Family, Given, Middle, Prefix, Suffix}. + +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, [], Middle, + Suffix, Prefix, Family, Given) -> + {Middle, Suffix, Prefix, Family, Given}; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"FAMILY">>, _attrs, _} = _el | _els], Middle, + Suffix, Prefix, Family, Given) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, + decode_vcard_FAMILY(__TopXMLNS, __IgnoreEls, _el), + Given); + <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, + decode_vcard_FAMILY(<<"vcard-temp">>, __IgnoreEls, + _el), + Given); + _ -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given) + end; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"GIVEN">>, _attrs, _} = _el | _els], Middle, + Suffix, Prefix, Family, Given) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, + decode_vcard_GIVEN(__TopXMLNS, __IgnoreEls, _el)); + <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, + decode_vcard_GIVEN(<<"vcard-temp">>, __IgnoreEls, + _el)); + _ -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given) + end; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"MIDDLE">>, _attrs, _} = _el | _els], Middle, + Suffix, Prefix, Family, Given) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_MIDDLE(__TopXMLNS, __IgnoreEls, _el), + Suffix, Prefix, Family, Given); + <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + decode_vcard_MIDDLE(<<"vcard-temp">>, __IgnoreEls, + _el), + Suffix, Prefix, Family, Given); + _ -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given) + end; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"PREFIX">>, _attrs, _} = _el | _els], Middle, + Suffix, Prefix, Family, Given) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, + decode_vcard_PREFIX(__TopXMLNS, __IgnoreEls, _el), + Family, Given); + <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, + decode_vcard_PREFIX(<<"vcard-temp">>, __IgnoreEls, + _el), + Family, Given); + _ -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given) + end; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"SUFFIX">>, _attrs, _} = _el | _els], Middle, + Suffix, Prefix, Family, Given) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, + decode_vcard_SUFFIX(__TopXMLNS, __IgnoreEls, _el), + Prefix, Family, Given); + <<"vcard-temp">> -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, + decode_vcard_SUFFIX(<<"vcard-temp">>, __IgnoreEls, + _el), + Prefix, Family, Given); + _ -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given) + end; +decode_vcard_N_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Middle, Suffix, Prefix, Family, Given) -> + decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, + Middle, Suffix, Prefix, Family, Given). + +encode_vcard_N({vcard_name, Family, Given, Middle, + Prefix, Suffix}, + _xmlns_attrs) -> + _els = lists:reverse('encode_vcard_N_$middle'(Middle, + 'encode_vcard_N_$suffix'(Suffix, + 'encode_vcard_N_$prefix'(Prefix, + 'encode_vcard_N_$family'(Family, + 'encode_vcard_N_$given'(Given, + [])))))), + _attrs = _xmlns_attrs, + {xmlel, <<"N">>, _attrs, _els}. + +'encode_vcard_N_$middle'(undefined, _acc) -> _acc; +'encode_vcard_N_$middle'(Middle, _acc) -> + [encode_vcard_MIDDLE(Middle, []) | _acc]. + +'encode_vcard_N_$suffix'(undefined, _acc) -> _acc; +'encode_vcard_N_$suffix'(Suffix, _acc) -> + [encode_vcard_SUFFIX(Suffix, []) | _acc]. + +'encode_vcard_N_$prefix'(undefined, _acc) -> _acc; +'encode_vcard_N_$prefix'(Prefix, _acc) -> + [encode_vcard_PREFIX(Prefix, []) | _acc]. + +'encode_vcard_N_$family'(undefined, _acc) -> _acc; +'encode_vcard_N_$family'(Family, _acc) -> + [encode_vcard_FAMILY(Family, []) | _acc]. + +'encode_vcard_N_$given'(undefined, _acc) -> _acc; +'encode_vcard_N_$given'(Given, _acc) -> + [encode_vcard_GIVEN(Given, []) | _acc]. + +decode_vcard_CONFIDENTIAL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}) -> + confidential. + +encode_vcard_CONFIDENTIAL(confidential, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}. + +decode_vcard_PRIVATE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PRIVATE">>, _attrs, _els}) -> + private. + +encode_vcard_PRIVATE(private, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PRIVATE">>, _attrs, _els}. + +decode_vcard_PUBLIC(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PUBLIC">>, _attrs, _els}) -> + public. + +encode_vcard_PUBLIC(public, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PUBLIC">>, _attrs, _els}. + +decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"EXTVAL">>, _attrs, _els}) -> + Cdata = decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_EXTVAL_cdata(__TopXMLNS, Cdata); +decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_EXTVAL(Cdata, _xmlns_attrs) -> + _els = encode_vcard_EXTVAL_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"EXTVAL">>, _attrs, _els}. + +decode_vcard_EXTVAL_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_EXTVAL_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_EXTVAL_cdata(undefined, _acc) -> _acc; +encode_vcard_EXTVAL_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"TYPE">>, _attrs, _els}) -> + Cdata = decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_TYPE_cdata(__TopXMLNS, Cdata); +decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_TYPE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_TYPE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"TYPE">>, _attrs, _els}. + +decode_vcard_TYPE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_TYPE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_TYPE_cdata(undefined, _acc) -> _acc; +encode_vcard_TYPE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_DESC(__TopXMLNS, __IgnoreEls, + {xmlel, <<"DESC">>, _attrs, _els}) -> + Cdata = decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_DESC_cdata(__TopXMLNS, Cdata); +decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_DESC(Cdata, _xmlns_attrs) -> + _els = encode_vcard_DESC_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"DESC">>, _attrs, _els}. + +decode_vcard_DESC_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_DESC_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_DESC_cdata(undefined, _acc) -> _acc; +encode_vcard_DESC_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_URL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"URL">>, _attrs, _els}) -> + Cdata = decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_URL_cdata(__TopXMLNS, Cdata); +decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_URL(Cdata, _xmlns_attrs) -> + _els = encode_vcard_URL_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"URL">>, _attrs, _els}. + +decode_vcard_URL_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_URL_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_URL_cdata(undefined, _acc) -> _acc; +encode_vcard_URL_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_UID(__TopXMLNS, __IgnoreEls, + {xmlel, <<"UID">>, _attrs, _els}) -> + Cdata = decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_UID_cdata(__TopXMLNS, Cdata); +decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_UID(Cdata, _xmlns_attrs) -> + _els = encode_vcard_UID_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"UID">>, _attrs, _els}. + +decode_vcard_UID_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_UID_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_UID_cdata(undefined, _acc) -> _acc; +encode_vcard_UID_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_SORT_STRING(__TopXMLNS, __IgnoreEls, + {xmlel, <<"SORT-STRING">>, _attrs, _els}) -> + Cdata = decode_vcard_SORT_STRING_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_vcard_SORT_STRING_cdata(__TopXMLNS, Cdata); +decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_vcard_SORT_STRING(Cdata, _xmlns_attrs) -> + _els = encode_vcard_SORT_STRING_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"SORT-STRING">>, _attrs, _els}. + +decode_vcard_SORT_STRING_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_SORT_STRING_cdata(__TopXMLNS, _val) -> + _val. + +encode_vcard_SORT_STRING_cdata(undefined, _acc) -> _acc; +encode_vcard_SORT_STRING_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_REV(__TopXMLNS, __IgnoreEls, + {xmlel, <<"REV">>, _attrs, _els}) -> + Cdata = decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_REV_cdata(__TopXMLNS, Cdata); +decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_REV(Cdata, _xmlns_attrs) -> + _els = encode_vcard_REV_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"REV">>, _attrs, _els}. + +decode_vcard_REV_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_REV_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_REV_cdata(undefined, _acc) -> _acc; +encode_vcard_REV_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_PRODID(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PRODID">>, _attrs, _els}) -> + Cdata = decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_PRODID_cdata(__TopXMLNS, Cdata); +decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_PRODID(Cdata, _xmlns_attrs) -> + _els = encode_vcard_PRODID_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"PRODID">>, _attrs, _els}. + +decode_vcard_PRODID_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_PRODID_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_PRODID_cdata(undefined, _acc) -> _acc; +encode_vcard_PRODID_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_NOTE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"NOTE">>, _attrs, _els}) -> + Cdata = decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_NOTE_cdata(__TopXMLNS, Cdata); +decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_NOTE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_NOTE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"NOTE">>, _attrs, _els}. + +decode_vcard_NOTE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_NOTE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_NOTE_cdata(undefined, _acc) -> _acc; +encode_vcard_NOTE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_KEYWORD(__TopXMLNS, __IgnoreEls, + {xmlel, <<"KEYWORD">>, _attrs, _els}) -> + Cdata = decode_vcard_KEYWORD_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_KEYWORD_cdata(__TopXMLNS, Cdata); +decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_KEYWORD(Cdata, _xmlns_attrs) -> + _els = encode_vcard_KEYWORD_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"KEYWORD">>, _attrs, _els}. + +decode_vcard_KEYWORD_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_KEYWORD_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_KEYWORD_cdata(undefined, _acc) -> _acc; +encode_vcard_KEYWORD_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_ROLE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ROLE">>, _attrs, _els}) -> + Cdata = decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_ROLE_cdata(__TopXMLNS, Cdata); +decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_ROLE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_ROLE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"ROLE">>, _attrs, _els}. + +decode_vcard_ROLE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_ROLE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_ROLE_cdata(undefined, _acc) -> _acc; +encode_vcard_ROLE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_TITLE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"TITLE">>, _attrs, _els}) -> + Cdata = decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_TITLE_cdata(__TopXMLNS, Cdata); +decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_TITLE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_TITLE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"TITLE">>, _attrs, _els}. + +decode_vcard_TITLE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_TITLE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_TITLE_cdata(undefined, _acc) -> _acc; +encode_vcard_TITLE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_TZ(__TopXMLNS, __IgnoreEls, + {xmlel, <<"TZ">>, _attrs, _els}) -> + Cdata = decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_TZ_cdata(__TopXMLNS, Cdata); +decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_TZ(Cdata, _xmlns_attrs) -> + _els = encode_vcard_TZ_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"TZ">>, _attrs, _els}. + +decode_vcard_TZ_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_TZ_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_TZ_cdata(undefined, _acc) -> _acc; +encode_vcard_TZ_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_MAILER(__TopXMLNS, __IgnoreEls, + {xmlel, <<"MAILER">>, _attrs, _els}) -> + Cdata = decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_MAILER_cdata(__TopXMLNS, Cdata); +decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_MAILER(Cdata, _xmlns_attrs) -> + _els = encode_vcard_MAILER_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"MAILER">>, _attrs, _els}. + +decode_vcard_MAILER_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_MAILER_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_MAILER_cdata(undefined, _acc) -> _acc; +encode_vcard_MAILER_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_JABBERID(__TopXMLNS, __IgnoreEls, + {xmlel, <<"JABBERID">>, _attrs, _els}) -> + Cdata = decode_vcard_JABBERID_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_JABBERID_cdata(__TopXMLNS, Cdata); +decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_JABBERID(Cdata, _xmlns_attrs) -> + _els = encode_vcard_JABBERID_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"JABBERID">>, _attrs, _els}. + +decode_vcard_JABBERID_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_JABBERID_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_JABBERID_cdata(undefined, _acc) -> _acc; +encode_vcard_JABBERID_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_BDAY(__TopXMLNS, __IgnoreEls, + {xmlel, <<"BDAY">>, _attrs, _els}) -> + Cdata = decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_BDAY_cdata(__TopXMLNS, Cdata); +decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_BDAY(Cdata, _xmlns_attrs) -> + _els = encode_vcard_BDAY_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"BDAY">>, _attrs, _els}. + +decode_vcard_BDAY_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_BDAY_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_BDAY_cdata(undefined, _acc) -> _acc; +encode_vcard_BDAY_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_NICKNAME(__TopXMLNS, __IgnoreEls, + {xmlel, <<"NICKNAME">>, _attrs, _els}) -> + Cdata = decode_vcard_NICKNAME_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_NICKNAME_cdata(__TopXMLNS, Cdata); +decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_NICKNAME(Cdata, _xmlns_attrs) -> + _els = encode_vcard_NICKNAME_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"NICKNAME">>, _attrs, _els}. + +decode_vcard_NICKNAME_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_NICKNAME_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_NICKNAME_cdata(undefined, _acc) -> _acc; +encode_vcard_NICKNAME_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_FN(__TopXMLNS, __IgnoreEls, + {xmlel, <<"FN">>, _attrs, _els}) -> + Cdata = decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_FN_cdata(__TopXMLNS, Cdata); +decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_FN(Cdata, _xmlns_attrs) -> + _els = encode_vcard_FN_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"FN">>, _attrs, _els}. + +decode_vcard_FN_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_FN_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_FN_cdata(undefined, _acc) -> _acc; +encode_vcard_FN_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_VERSION(__TopXMLNS, __IgnoreEls, + {xmlel, <<"VERSION">>, _attrs, _els}) -> + Cdata = decode_vcard_VERSION_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_VERSION_cdata(__TopXMLNS, Cdata); +decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_VERSION(Cdata, _xmlns_attrs) -> + _els = encode_vcard_VERSION_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"VERSION">>, _attrs, _els}. + +decode_vcard_VERSION_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_VERSION_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_VERSION_cdata(undefined, _acc) -> _acc; +encode_vcard_VERSION_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_CRED(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CRED">>, _attrs, _els}) -> + Cdata = decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_CRED_cdata(__TopXMLNS, Cdata); +decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_CRED(Cdata, _xmlns_attrs) -> + _els = encode_vcard_CRED_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"CRED">>, _attrs, _els}. + +decode_vcard_CRED_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_CRED_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_CRED_cdata(undefined, _acc) -> _acc; +encode_vcard_CRED_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_PHONETIC(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PHONETIC">>, _attrs, _els}) -> + Cdata = decode_vcard_PHONETIC_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_PHONETIC_cdata(__TopXMLNS, Cdata); +decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_PHONETIC(Cdata, _xmlns_attrs) -> + _els = encode_vcard_PHONETIC_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"PHONETIC">>, _attrs, _els}. + +decode_vcard_PHONETIC_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_PHONETIC_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_PHONETIC_cdata(undefined, _acc) -> _acc; +encode_vcard_PHONETIC_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_ORGUNIT(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ORGUNIT">>, _attrs, _els}) -> + Cdata = decode_vcard_ORGUNIT_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_ORGUNIT_cdata(__TopXMLNS, Cdata); +decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_ORGUNIT(Cdata, _xmlns_attrs) -> + _els = encode_vcard_ORGUNIT_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"ORGUNIT">>, _attrs, _els}. + +decode_vcard_ORGUNIT_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_ORGUNIT_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_ORGUNIT_cdata(undefined, _acc) -> _acc; +encode_vcard_ORGUNIT_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_ORGNAME(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ORGNAME">>, _attrs, _els}) -> + Cdata = decode_vcard_ORGNAME_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_ORGNAME_cdata(__TopXMLNS, Cdata); +decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_ORGNAME(Cdata, _xmlns_attrs) -> + _els = encode_vcard_ORGNAME_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"ORGNAME">>, _attrs, _els}. + +decode_vcard_ORGNAME_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_ORGNAME_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_ORGNAME_cdata(undefined, _acc) -> _acc; +encode_vcard_ORGNAME_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_LON(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LON">>, _attrs, _els}) -> + Cdata = decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_LON_cdata(__TopXMLNS, Cdata); +decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_LON(Cdata, _xmlns_attrs) -> + _els = encode_vcard_LON_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"LON">>, _attrs, _els}. + +decode_vcard_LON_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_LON_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_LON_cdata(undefined, _acc) -> _acc; +encode_vcard_LON_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_LAT(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LAT">>, _attrs, _els}) -> + Cdata = decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_LAT_cdata(__TopXMLNS, Cdata); +decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_LAT(Cdata, _xmlns_attrs) -> + _els = encode_vcard_LAT_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"LAT">>, _attrs, _els}. + +decode_vcard_LAT_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_LAT_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_LAT_cdata(undefined, _acc) -> _acc; +encode_vcard_LAT_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_USERID(__TopXMLNS, __IgnoreEls, + {xmlel, <<"USERID">>, _attrs, _els}) -> + Cdata = decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_USERID_cdata(__TopXMLNS, Cdata); +decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_USERID(Cdata, _xmlns_attrs) -> + _els = encode_vcard_USERID_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"USERID">>, _attrs, _els}. + +decode_vcard_USERID_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_USERID_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_USERID_cdata(undefined, _acc) -> _acc; +encode_vcard_USERID_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_NUMBER(__TopXMLNS, __IgnoreEls, + {xmlel, <<"NUMBER">>, _attrs, _els}) -> + Cdata = decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_NUMBER_cdata(__TopXMLNS, Cdata); +decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_NUMBER(Cdata, _xmlns_attrs) -> + _els = encode_vcard_NUMBER_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"NUMBER">>, _attrs, _els}. + +decode_vcard_NUMBER_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_NUMBER_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_NUMBER_cdata(undefined, _acc) -> _acc; +encode_vcard_NUMBER_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_LINE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LINE">>, _attrs, _els}) -> + Cdata = decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_LINE_cdata(__TopXMLNS, Cdata); +decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_LINE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_LINE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"LINE">>, _attrs, _els}. + +decode_vcard_LINE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_LINE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_LINE_cdata(undefined, _acc) -> _acc; +encode_vcard_LINE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_CTRY(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CTRY">>, _attrs, _els}) -> + Cdata = decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_CTRY_cdata(__TopXMLNS, Cdata); +decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_CTRY(Cdata, _xmlns_attrs) -> + _els = encode_vcard_CTRY_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"CTRY">>, _attrs, _els}. + +decode_vcard_CTRY_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_CTRY_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_CTRY_cdata(undefined, _acc) -> _acc; +encode_vcard_CTRY_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_PCODE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PCODE">>, _attrs, _els}) -> + Cdata = decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_PCODE_cdata(__TopXMLNS, Cdata); +decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_PCODE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_PCODE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"PCODE">>, _attrs, _els}. + +decode_vcard_PCODE_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_PCODE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_PCODE_cdata(undefined, _acc) -> _acc; +encode_vcard_PCODE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_REGION(__TopXMLNS, __IgnoreEls, + {xmlel, <<"REGION">>, _attrs, _els}) -> + Cdata = decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_REGION_cdata(__TopXMLNS, Cdata); +decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_REGION(Cdata, _xmlns_attrs) -> + _els = encode_vcard_REGION_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"REGION">>, _attrs, _els}. + +decode_vcard_REGION_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_REGION_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_REGION_cdata(undefined, _acc) -> _acc; +encode_vcard_REGION_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_LOCALITY(__TopXMLNS, __IgnoreEls, + {xmlel, <<"LOCALITY">>, _attrs, _els}) -> + Cdata = decode_vcard_LOCALITY_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_LOCALITY_cdata(__TopXMLNS, Cdata); +decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_LOCALITY(Cdata, _xmlns_attrs) -> + _els = encode_vcard_LOCALITY_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"LOCALITY">>, _attrs, _els}. + +decode_vcard_LOCALITY_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_LOCALITY_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_LOCALITY_cdata(undefined, _acc) -> _acc; +encode_vcard_LOCALITY_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_STREET(__TopXMLNS, __IgnoreEls, + {xmlel, <<"STREET">>, _attrs, _els}) -> + Cdata = decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_STREET_cdata(__TopXMLNS, Cdata); +decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_STREET(Cdata, _xmlns_attrs) -> + _els = encode_vcard_STREET_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"STREET">>, _attrs, _els}. + +decode_vcard_STREET_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_STREET_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_STREET_cdata(undefined, _acc) -> _acc; +encode_vcard_STREET_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_EXTADD(__TopXMLNS, __IgnoreEls, + {xmlel, <<"EXTADD">>, _attrs, _els}) -> + Cdata = decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_EXTADD_cdata(__TopXMLNS, Cdata); +decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_EXTADD(Cdata, _xmlns_attrs) -> + _els = encode_vcard_EXTADD_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"EXTADD">>, _attrs, _els}. + +decode_vcard_EXTADD_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_EXTADD_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_EXTADD_cdata(undefined, _acc) -> _acc; +encode_vcard_EXTADD_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_POBOX(__TopXMLNS, __IgnoreEls, + {xmlel, <<"POBOX">>, _attrs, _els}) -> + Cdata = decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_POBOX_cdata(__TopXMLNS, Cdata); +decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_POBOX(Cdata, _xmlns_attrs) -> + _els = encode_vcard_POBOX_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"POBOX">>, _attrs, _els}. + +decode_vcard_POBOX_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_POBOX_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_POBOX_cdata(undefined, _acc) -> _acc; +encode_vcard_POBOX_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_SUFFIX(__TopXMLNS, __IgnoreEls, + {xmlel, <<"SUFFIX">>, _attrs, _els}) -> + Cdata = decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_SUFFIX_cdata(__TopXMLNS, Cdata); +decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_SUFFIX(Cdata, _xmlns_attrs) -> + _els = encode_vcard_SUFFIX_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"SUFFIX">>, _attrs, _els}. + +decode_vcard_SUFFIX_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_SUFFIX_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_SUFFIX_cdata(undefined, _acc) -> _acc; +encode_vcard_SUFFIX_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_PREFIX(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PREFIX">>, _attrs, _els}) -> + Cdata = decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_PREFIX_cdata(__TopXMLNS, Cdata); +decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_PREFIX(Cdata, _xmlns_attrs) -> + _els = encode_vcard_PREFIX_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"PREFIX">>, _attrs, _els}. + +decode_vcard_PREFIX_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_PREFIX_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_PREFIX_cdata(undefined, _acc) -> _acc; +encode_vcard_PREFIX_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_MIDDLE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"MIDDLE">>, _attrs, _els}) -> + Cdata = decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_MIDDLE_cdata(__TopXMLNS, Cdata); +decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_MIDDLE(Cdata, _xmlns_attrs) -> + _els = encode_vcard_MIDDLE_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"MIDDLE">>, _attrs, _els}. + +decode_vcard_MIDDLE_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_MIDDLE_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_MIDDLE_cdata(undefined, _acc) -> _acc; +encode_vcard_MIDDLE_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_GIVEN(__TopXMLNS, __IgnoreEls, + {xmlel, <<"GIVEN">>, _attrs, _els}) -> + Cdata = decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_GIVEN_cdata(__TopXMLNS, Cdata); +decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_GIVEN(Cdata, _xmlns_attrs) -> + _els = encode_vcard_GIVEN_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"GIVEN">>, _attrs, _els}. + +decode_vcard_GIVEN_cdata(__TopXMLNS, <<>>) -> undefined; +decode_vcard_GIVEN_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_GIVEN_cdata(undefined, _acc) -> _acc; +encode_vcard_GIVEN_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_FAMILY(__TopXMLNS, __IgnoreEls, + {xmlel, <<"FAMILY">>, _attrs, _els}) -> + Cdata = decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_vcard_FAMILY_cdata(__TopXMLNS, Cdata); +decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_vcard_FAMILY(Cdata, _xmlns_attrs) -> + _els = encode_vcard_FAMILY_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"FAMILY">>, _attrs, _els}. + +decode_vcard_FAMILY_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_vcard_FAMILY_cdata(__TopXMLNS, _val) -> _val. + +encode_vcard_FAMILY_cdata(undefined, _acc) -> _acc; +encode_vcard_FAMILY_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_vcard_X400(__TopXMLNS, __IgnoreEls, + {xmlel, <<"X400">>, _attrs, _els}) -> + true. + +encode_vcard_X400(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"X400">>, _attrs, _els}. + +decode_vcard_INTERNET(__TopXMLNS, __IgnoreEls, + {xmlel, <<"INTERNET">>, _attrs, _els}) -> + true. + +encode_vcard_INTERNET(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"INTERNET">>, _attrs, _els}. + +decode_vcard_PREF(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PREF">>, _attrs, _els}) -> + true. + +encode_vcard_PREF(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PREF">>, _attrs, _els}. + +decode_vcard_INTL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"INTL">>, _attrs, _els}) -> + true. + +encode_vcard_INTL(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"INTL">>, _attrs, _els}. + +decode_vcard_DOM(__TopXMLNS, __IgnoreEls, + {xmlel, <<"DOM">>, _attrs, _els}) -> + true. + +encode_vcard_DOM(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"DOM">>, _attrs, _els}. + +decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PARCEL">>, _attrs, _els}) -> + true. + +encode_vcard_PARCEL(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PARCEL">>, _attrs, _els}. + +decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"POSTAL">>, _attrs, _els}) -> + true. + +encode_vcard_POSTAL(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"POSTAL">>, _attrs, _els}. + +decode_vcard_PCS(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PCS">>, _attrs, _els}) -> + true. + +encode_vcard_PCS(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PCS">>, _attrs, _els}. + +decode_vcard_ISDN(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ISDN">>, _attrs, _els}) -> + true. + +encode_vcard_ISDN(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"ISDN">>, _attrs, _els}. + +decode_vcard_MODEM(__TopXMLNS, __IgnoreEls, + {xmlel, <<"MODEM">>, _attrs, _els}) -> + true. + +encode_vcard_MODEM(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"MODEM">>, _attrs, _els}. + +decode_vcard_BBS(__TopXMLNS, __IgnoreEls, + {xmlel, <<"BBS">>, _attrs, _els}) -> + true. + +encode_vcard_BBS(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"BBS">>, _attrs, _els}. + +decode_vcard_VIDEO(__TopXMLNS, __IgnoreEls, + {xmlel, <<"VIDEO">>, _attrs, _els}) -> + true. + +encode_vcard_VIDEO(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"VIDEO">>, _attrs, _els}. + +decode_vcard_CELL(__TopXMLNS, __IgnoreEls, + {xmlel, <<"CELL">>, _attrs, _els}) -> + true. + +encode_vcard_CELL(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"CELL">>, _attrs, _els}. + +decode_vcard_MSG(__TopXMLNS, __IgnoreEls, + {xmlel, <<"MSG">>, _attrs, _els}) -> + true. + +encode_vcard_MSG(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"MSG">>, _attrs, _els}. + +decode_vcard_PAGER(__TopXMLNS, __IgnoreEls, + {xmlel, <<"PAGER">>, _attrs, _els}) -> + true. + +encode_vcard_PAGER(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"PAGER">>, _attrs, _els}. + +decode_vcard_FAX(__TopXMLNS, __IgnoreEls, + {xmlel, <<"FAX">>, _attrs, _els}) -> + true. + +encode_vcard_FAX(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"FAX">>, _attrs, _els}. + +decode_vcard_VOICE(__TopXMLNS, __IgnoreEls, + {xmlel, <<"VOICE">>, _attrs, _els}) -> + true. + +encode_vcard_VOICE(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"VOICE">>, _attrs, _els}. + +decode_vcard_WORK(__TopXMLNS, __IgnoreEls, + {xmlel, <<"WORK">>, _attrs, _els}) -> + true. + +encode_vcard_WORK(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"WORK">>, _attrs, _els}. + +decode_vcard_HOME(__TopXMLNS, __IgnoreEls, + {xmlel, <<"HOME">>, _attrs, _els}) -> + true. + +encode_vcard_HOME(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"HOME">>, _attrs, _els}. + +decode_stream_error(__TopXMLNS, __IgnoreEls, + {xmlel, <<"stream:error">>, _attrs, _els}) -> + {Text, Reason} = decode_stream_error_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined), + {stream_error, Reason, Text}. + +decode_stream_error_els(__TopXMLNS, __IgnoreEls, [], + Text, Reason) -> + {Text, Reason}; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, _el), + Reason); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"bad-format">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"bad-namespace-prefix">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], Text, + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"connection-timeout">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"host-gone">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"host-unknown">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"improper-addressing">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"internal-server-error">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-from">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-id">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-namespace">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-xml">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-well-formed">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"policy-violation">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remote-connection-failed">>, _attrs, _} = + _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reset">>, _attrs, _} = _el | _els], Text, + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"resource-constraint">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"restricted-xml">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"see-other-host">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"system-shutdown">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"undefined-condition">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsupported-encoding">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsupported-stanza-type">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsupported-version">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"urn:ietf:params:xml:ns:xmpp-streams">> -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + __IgnoreEls, + _el)); + _ -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_stream_error_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text, Reason) -> + decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason). + +encode_stream_error({stream_error, Reason, Text}, + _xmlns_attrs) -> + _els = lists:reverse('encode_stream_error_$text'(Text, + 'encode_stream_error_$reason'(Reason, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"stream:error">>, _attrs, _els}. + +'encode_stream_error_$text'(undefined, _acc) -> _acc; +'encode_stream_error_$text'(Text, _acc) -> + [encode_stream_error_text(Text, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]. + +'encode_stream_error_$reason'(undefined, _acc) -> _acc; +'encode_stream_error_$reason'('bad-format' = Reason, + _acc) -> + [encode_stream_error_bad_format(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('bad-namespace-prefix' = + Reason, + _acc) -> + [encode_stream_error_bad_namespace_prefix(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'(conflict = Reason, + _acc) -> + [encode_stream_error_conflict(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('connection-timeout' = + Reason, + _acc) -> + [encode_stream_error_connection_timeout(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('host-gone' = Reason, + _acc) -> + [encode_stream_error_host_gone(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('host-unknown' = Reason, + _acc) -> + [encode_stream_error_host_unknown(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('improper-addressing' = + Reason, + _acc) -> + [encode_stream_error_improper_addressing(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('internal-server-error' = + Reason, + _acc) -> + [encode_stream_error_internal_server_error(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('invalid-from' = Reason, + _acc) -> + [encode_stream_error_invalid_from(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('invalid-id' = Reason, + _acc) -> + [encode_stream_error_invalid_id(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('invalid-namespace' = + Reason, + _acc) -> + [encode_stream_error_invalid_namespace(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('invalid-xml' = Reason, + _acc) -> + [encode_stream_error_invalid_xml(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('not-authorized' = Reason, + _acc) -> + [encode_stream_error_not_authorized(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('not-well-formed' = + Reason, + _acc) -> + [encode_stream_error_not_well_formed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('policy-violation' = + Reason, + _acc) -> + [encode_stream_error_policy_violation(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('remote-connection-failed' = + Reason, + _acc) -> + [encode_stream_error_remote_connection_failed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'(reset = Reason, _acc) -> + [encode_stream_error_reset(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('resource-constraint' = + Reason, + _acc) -> + [encode_stream_error_resource_constraint(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('restricted-xml' = Reason, + _acc) -> + [encode_stream_error_restricted_xml(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'({'see-other-host', _} = + Reason, + _acc) -> + [encode_stream_error_see_other_host(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('system-shutdown' = + Reason, + _acc) -> + [encode_stream_error_system_shutdown(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('undefined-condition' = + Reason, + _acc) -> + [encode_stream_error_undefined_condition(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('unsupported-encoding' = + Reason, + _acc) -> + [encode_stream_error_unsupported_encoding(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('unsupported-stanza-type' = + Reason, + _acc) -> + [encode_stream_error_unsupported_stanza_type(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]; +'encode_stream_error_$reason'('unsupported-version' = + Reason, + _acc) -> + [encode_stream_error_unsupported_version(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + | _acc]. + +decode_stream_error_unsupported_version(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"unsupported-version">>, + _attrs, _els}) -> + 'unsupported-version'. + +encode_stream_error_unsupported_version('unsupported-version', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsupported-version">>, _attrs, _els}. + +decode_stream_error_unsupported_stanza_type(__TopXMLNS, + __IgnoreEls, + {xmlel, + <<"unsupported-stanza-type">>, + _attrs, _els}) -> + 'unsupported-stanza-type'. + +encode_stream_error_unsupported_stanza_type('unsupported-stanza-type', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsupported-stanza-type">>, _attrs, _els}. + +decode_stream_error_unsupported_encoding(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"unsupported-encoding">>, + _attrs, _els}) -> + 'unsupported-encoding'. + +encode_stream_error_unsupported_encoding('unsupported-encoding', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsupported-encoding">>, _attrs, _els}. + +decode_stream_error_undefined_condition(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"undefined-condition">>, + _attrs, _els}) -> + 'undefined-condition'. + +encode_stream_error_undefined_condition('undefined-condition', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"undefined-condition">>, _attrs, _els}. + +decode_stream_error_system_shutdown(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"system-shutdown">>, _attrs, + _els}) -> + 'system-shutdown'. + +encode_stream_error_system_shutdown('system-shutdown', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"system-shutdown">>, _attrs, _els}. + +decode_stream_error_see_other_host(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"see-other-host">>, _attrs, + _els}) -> + Host = + decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + {'see-other-host', Host}. + +decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, [], Host) -> + decode_stream_error_see_other_host_cdata(__TopXMLNS, + Host); +decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, [{xmlcdata, _data} | _els], + Host) -> + decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, _els, + <>); +decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Host) -> + decode_stream_error_see_other_host_els(__TopXMLNS, + __IgnoreEls, _els, Host). + +encode_stream_error_see_other_host({'see-other-host', + Host}, + _xmlns_attrs) -> + _els = encode_stream_error_see_other_host_cdata(Host, + []), + _attrs = _xmlns_attrs, + {xmlel, <<"see-other-host">>, _attrs, _els}. + +decode_stream_error_see_other_host_cdata(__TopXMLNS, + <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"see-other-host">>, + __TopXMLNS}}); +decode_stream_error_see_other_host_cdata(__TopXMLNS, + _val) -> + _val. + +encode_stream_error_see_other_host_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_stream_error_restricted_xml(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"restricted-xml">>, _attrs, + _els}) -> + 'restricted-xml'. + +encode_stream_error_restricted_xml('restricted-xml', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"restricted-xml">>, _attrs, _els}. + +decode_stream_error_resource_constraint(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"resource-constraint">>, + _attrs, _els}) -> + 'resource-constraint'. + +encode_stream_error_resource_constraint('resource-constraint', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"resource-constraint">>, _attrs, _els}. + +decode_stream_error_reset(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reset">>, _attrs, _els}) -> + reset. + +encode_stream_error_reset(reset, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"reset">>, _attrs, _els}. + +decode_stream_error_remote_connection_failed(__TopXMLNS, + __IgnoreEls, + {xmlel, + <<"remote-connection-failed">>, + _attrs, _els}) -> + 'remote-connection-failed'. + +encode_stream_error_remote_connection_failed('remote-connection-failed', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"remote-connection-failed">>, _attrs, _els}. + +decode_stream_error_policy_violation(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"policy-violation">>, _attrs, + _els}) -> + 'policy-violation'. + +encode_stream_error_policy_violation('policy-violation', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"policy-violation">>, _attrs, _els}. + +decode_stream_error_not_well_formed(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"not-well-formed">>, _attrs, + _els}) -> + 'not-well-formed'. + +encode_stream_error_not_well_formed('not-well-formed', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-well-formed">>, _attrs, _els}. + +decode_stream_error_not_authorized(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"not-authorized">>, _attrs, + _els}) -> + 'not-authorized'. + +encode_stream_error_not_authorized('not-authorized', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-authorized">>, _attrs, _els}. + +decode_stream_error_invalid_xml(__TopXMLNS, __IgnoreEls, + {xmlel, <<"invalid-xml">>, _attrs, _els}) -> + 'invalid-xml'. + +encode_stream_error_invalid_xml('invalid-xml', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-xml">>, _attrs, _els}. + +decode_stream_error_invalid_namespace(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-namespace">>, _attrs, + _els}) -> + 'invalid-namespace'. + +encode_stream_error_invalid_namespace('invalid-namespace', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-namespace">>, _attrs, _els}. + +decode_stream_error_invalid_id(__TopXMLNS, __IgnoreEls, + {xmlel, <<"invalid-id">>, _attrs, _els}) -> + 'invalid-id'. + +encode_stream_error_invalid_id('invalid-id', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-id">>, _attrs, _els}. + +decode_stream_error_invalid_from(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-from">>, _attrs, _els}) -> + 'invalid-from'. + +encode_stream_error_invalid_from('invalid-from', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-from">>, _attrs, _els}. + +decode_stream_error_internal_server_error(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"internal-server-error">>, + _attrs, _els}) -> + 'internal-server-error'. + +encode_stream_error_internal_server_error('internal-server-error', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"internal-server-error">>, _attrs, _els}. + +decode_stream_error_improper_addressing(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"improper-addressing">>, + _attrs, _els}) -> + 'improper-addressing'. + +encode_stream_error_improper_addressing('improper-addressing', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"improper-addressing">>, _attrs, _els}. + +decode_stream_error_host_unknown(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"host-unknown">>, _attrs, _els}) -> + 'host-unknown'. + +encode_stream_error_host_unknown('host-unknown', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"host-unknown">>, _attrs, _els}. + +decode_stream_error_host_gone(__TopXMLNS, __IgnoreEls, + {xmlel, <<"host-gone">>, _attrs, _els}) -> + 'host-gone'. + +encode_stream_error_host_gone('host-gone', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"host-gone">>, _attrs, _els}. + +decode_stream_error_connection_timeout(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"connection-timeout">>, _attrs, + _els}) -> + 'connection-timeout'. + +encode_stream_error_connection_timeout('connection-timeout', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"connection-timeout">>, _attrs, _els}. + +decode_stream_error_conflict(__TopXMLNS, __IgnoreEls, + {xmlel, <<"conflict">>, _attrs, _els}) -> + conflict. + +encode_stream_error_conflict(conflict, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"conflict">>, _attrs, _els}. + +decode_stream_error_bad_namespace_prefix(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"bad-namespace-prefix">>, + _attrs, _els}) -> + 'bad-namespace-prefix'. + +encode_stream_error_bad_namespace_prefix('bad-namespace-prefix', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"bad-namespace-prefix">>, _attrs, _els}. + +decode_stream_error_bad_format(__TopXMLNS, __IgnoreEls, + {xmlel, <<"bad-format">>, _attrs, _els}) -> + 'bad-format'. + +encode_stream_error_bad_format('bad-format', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"bad-format">>, _attrs, _els}. + +decode_stream_error_text(__TopXMLNS, __IgnoreEls, + {xmlel, <<"text">>, _attrs, _els}) -> + Data = decode_stream_error_text_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Lang = decode_stream_error_text_attrs(__TopXMLNS, + _attrs, undefined), + {text, Lang, Data}. + +decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, + [], Data) -> + decode_stream_error_text_cdata(__TopXMLNS, Data); +decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, + _els, Data). + +decode_stream_error_text_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_stream_error_text_attrs(__TopXMLNS, _attrs, + _val); +decode_stream_error_text_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_stream_error_text_attrs(__TopXMLNS, _attrs, + Lang); +decode_stream_error_text_attrs(__TopXMLNS, [], Lang) -> + 'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, + Lang). + +encode_stream_error_text({text, Lang, Data}, + _xmlns_attrs) -> + _els = encode_stream_error_text_cdata(Data, []), + _attrs = 'encode_stream_error_text_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"text">>, _attrs, _els}. + +'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_stream_error_text_attr_xml:lang'(undefined, + _acc) -> + _acc; +'encode_stream_error_text_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_stream_error_text_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_stream_error_text_cdata(__TopXMLNS, _val) -> + _val. + +encode_stream_error_text_cdata(undefined, _acc) -> _acc; +encode_stream_error_text_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_time(__TopXMLNS, __IgnoreEls, + {xmlel, <<"time">>, _attrs, _els}) -> + {Utc, Tzo} = decode_time_els(__TopXMLNS, __IgnoreEls, + _els, undefined, undefined), + {time, Tzo, Utc}. + +decode_time_els(__TopXMLNS, __IgnoreEls, [], Utc, + Tzo) -> + {Utc, Tzo}; +decode_time_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"tzo">>, _attrs, _} = _el | _els], Utc, + Tzo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:time">> -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, + decode_time_tzo(__TopXMLNS, __IgnoreEls, _el)); + <<"urn:xmpp:time">> -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, + decode_time_tzo(<<"urn:xmpp:time">>, __IgnoreEls, + _el)); + _ -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, Tzo) + end; +decode_time_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"utc">>, _attrs, _} = _el | _els], Utc, + Tzo) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:time">> -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, + decode_time_utc(__TopXMLNS, __IgnoreEls, _el), Tzo); + <<"urn:xmpp:time">> -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, + decode_time_utc(<<"urn:xmpp:time">>, __IgnoreEls, + _el), + Tzo); + _ -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, Tzo) + end; +decode_time_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Utc, Tzo) -> + decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, + Tzo). + +encode_time({time, Tzo, Utc}, _xmlns_attrs) -> + _els = lists:reverse('encode_time_$utc'(Utc, + 'encode_time_$tzo'(Tzo, []))), + _attrs = _xmlns_attrs, + {xmlel, <<"time">>, _attrs, _els}. + +'encode_time_$utc'(undefined, _acc) -> _acc; +'encode_time_$utc'(Utc, _acc) -> + [encode_time_utc(Utc, []) | _acc]. + +'encode_time_$tzo'(undefined, _acc) -> _acc; +'encode_time_$tzo'(Tzo, _acc) -> + [encode_time_tzo(Tzo, []) | _acc]. + +decode_time_tzo(__TopXMLNS, __IgnoreEls, + {xmlel, <<"tzo">>, _attrs, _els}) -> + Cdata = decode_time_tzo_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_time_tzo_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_time_tzo_cdata(__TopXMLNS, Cdata); +decode_time_tzo_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_time_tzo_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_time_tzo_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_time_tzo_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_time_tzo(Cdata, _xmlns_attrs) -> + _els = encode_time_tzo_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"tzo">>, _attrs, _els}. + +decode_time_tzo_cdata(__TopXMLNS, <<>>) -> undefined; +decode_time_tzo_cdata(__TopXMLNS, _val) -> + case catch dec_tzo(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"tzo">>, __TopXMLNS}}); + _res -> _res + end. + +encode_time_tzo_cdata(undefined, _acc) -> _acc; +encode_time_tzo_cdata(_val, _acc) -> + [{xmlcdata, enc_tzo(_val)} | _acc]. + +decode_time_utc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"utc">>, _attrs, _els}) -> + Cdata = decode_time_utc_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_time_utc_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_time_utc_cdata(__TopXMLNS, Cdata); +decode_time_utc_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_time_utc_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_time_utc_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_time_utc_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_time_utc(Cdata, _xmlns_attrs) -> + _els = encode_time_utc_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"utc">>, _attrs, _els}. + +decode_time_utc_cdata(__TopXMLNS, <<>>) -> undefined; +decode_time_utc_cdata(__TopXMLNS, _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"utc">>, __TopXMLNS}}); + _res -> _res + end. + +encode_time_utc_cdata(undefined, _acc) -> _acc; +encode_time_utc_cdata(_val, _acc) -> + [{xmlcdata, enc_utc(_val)} | _acc]. + +decode_ping(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ping">>, _attrs, _els}) -> + {ping}. + +encode_ping({ping}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"ping">>, _attrs, _els}. + +decode_session(__TopXMLNS, __IgnoreEls, + {xmlel, <<"session">>, _attrs, _els}) -> + Optional = decode_session_els(__TopXMLNS, __IgnoreEls, + _els, false), + {xmpp_session, Optional}. + +decode_session_els(__TopXMLNS, __IgnoreEls, [], + Optional) -> + Optional; +decode_session_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"optional">>, _attrs, _} = _el | _els], + Optional) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-session">> -> + decode_session_els(__TopXMLNS, __IgnoreEls, _els, + decode_session_optional(__TopXMLNS, __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-session">> -> + decode_session_els(__TopXMLNS, __IgnoreEls, _els, + decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, + __IgnoreEls, _el)); + _ -> + decode_session_els(__TopXMLNS, __IgnoreEls, _els, + Optional) + end; +decode_session_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Optional) -> + decode_session_els(__TopXMLNS, __IgnoreEls, _els, + Optional). + +encode_session({xmpp_session, Optional}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_session_$optional'(Optional, [])), + _attrs = _xmlns_attrs, + {xmlel, <<"session">>, _attrs, _els}. + +'encode_session_$optional'(false, _acc) -> _acc; +'encode_session_$optional'(Optional, _acc) -> + [encode_session_optional(Optional, []) | _acc]. + +decode_session_optional(__TopXMLNS, __IgnoreEls, + {xmlel, <<"optional">>, _attrs, _els}) -> + true. + +encode_session_optional(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"optional">>, _attrs, _els}. + +decode_register(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Zip, Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email} = + decode_register_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, false, undefined, undefined, undefined, + undefined, undefined, false, undefined, undefined, + undefined, undefined, undefined), + {register, Registered, Remove, Instructions, Username, + Nick, Password, Name, First, Last, Email, Address, City, + State, Zip, Phone, Url, Date, Misc, Text, Key, Xdata}. + +decode_register_els(__TopXMLNS, __IgnoreEls, [], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + {Zip, Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email}; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Zip, Xdata, + Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + decode_xdata(<<"jabber:x:data">>, __IgnoreEls, + _el), + Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"registered">>, _attrs, _} = _el | _els], + Zip, Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, + decode_register_registered(__TopXMLNS, + __IgnoreEls, _el), + Date, Phone, State, Name, Username, Remove, Key, + City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, + decode_register_registered(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Date, Phone, State, Name, Username, Remove, Key, + City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remove">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, + decode_register_remove(__TopXMLNS, __IgnoreEls, + _el), + Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, + decode_register_remove(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], + Zip, Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, + decode_register_instructions(__TopXMLNS, + __IgnoreEls, _el), + Text, Last, First, Password, Registered, Date, + Phone, State, Name, Username, Remove, Key, City, + Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, + decode_register_instructions(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Text, Last, First, Password, Registered, Date, + Phone, State, Name, Username, Remove, Key, City, + Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"username">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, + decode_register_username(__TopXMLNS, __IgnoreEls, + _el), + Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, + decode_register_username(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, + decode_register_nick(__TopXMLNS, __IgnoreEls, + _el), + Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, + decode_register_nick(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, + decode_register_password(__TopXMLNS, __IgnoreEls, + _el), + Registered, Date, Phone, State, Name, Username, + Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, + decode_register_password(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Registered, Date, Phone, State, Name, Username, + Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"name">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + decode_register_name(__TopXMLNS, __IgnoreEls, + _el), + Username, Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + decode_register_name(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Username, Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"first">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + decode_register_first(__TopXMLNS, __IgnoreEls, + _el), + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + decode_register_first(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"last">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, + decode_register_last(__TopXMLNS, __IgnoreEls, + _el), + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, + decode_register_last(<<"jabber:iq:register">>, + __IgnoreEls, _el), + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"email">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + decode_register_email(__TopXMLNS, __IgnoreEls, + _el)); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + decode_register_email(<<"jabber:iq:register">>, + __IgnoreEls, _el)); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"address">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, + decode_register_address(__TopXMLNS, __IgnoreEls, + _el), + Instructions, Text, Last, First, Password, + Registered, Date, Phone, State, Name, Username, + Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, + decode_register_address(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Instructions, Text, Last, First, Password, + Registered, Date, Phone, State, Name, Username, + Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"city">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, + decode_register_city(__TopXMLNS, __IgnoreEls, + _el), + Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, + decode_register_city(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"state">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, + decode_register_state(__TopXMLNS, __IgnoreEls, + _el), + Name, Username, Remove, Key, City, Nick, Url, + Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, + decode_register_state(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Name, Username, Remove, Key, City, Nick, Url, + Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"zip">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, + decode_register_zip(__TopXMLNS, __IgnoreEls, _el), + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, + decode_register_zip(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"phone">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, + decode_register_phone(__TopXMLNS, __IgnoreEls, + _el), + State, Name, Username, Remove, Key, City, Nick, + Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, + decode_register_phone(<<"jabber:iq:register">>, + __IgnoreEls, _el), + State, Name, Username, Remove, Key, City, Nick, + Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"url">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, + decode_register_url(__TopXMLNS, __IgnoreEls, _el), + Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, + decode_register_url(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"date">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, + decode_register_date(__TopXMLNS, __IgnoreEls, + _el), + Phone, State, Name, Username, Remove, Key, City, + Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, + decode_register_date(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Phone, State, Name, Username, Remove, Key, City, + Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"misc">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, + decode_register_misc(__TopXMLNS, __IgnoreEls, + _el), + Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, + decode_register_misc(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"text">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, + decode_register_text(__TopXMLNS, __IgnoreEls, + _el), + Last, First, Password, Registered, Date, Phone, + State, Name, Username, Remove, Key, City, Nick, + Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, + decode_register_text(<<"jabber:iq:register">>, + __IgnoreEls, _el), + Last, First, Password, Registered, Date, Phone, + State, Name, Username, Remove, Key, City, Nick, + Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"key">>, _attrs, _} = _el | _els], Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, + decode_register_key(__TopXMLNS, __IgnoreEls, _el), + City, Nick, Url, Email); + <<"jabber:iq:register">> -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, + decode_register_key(<<"jabber:iq:register">>, + __IgnoreEls, _el), + City, Nick, Url, Email); + _ -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Zip, Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email) -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, First, + Password, Registered, Date, Phone, State, Name, + Username, Remove, Key, City, Nick, Url, Email). + +encode_register({register, Registered, Remove, + Instructions, Username, Nick, Password, Name, First, + Last, Email, Address, City, State, Zip, Phone, Url, + Date, Misc, Text, Key, Xdata}, + _xmlns_attrs) -> + _els = lists:reverse('encode_register_$zip'(Zip, + 'encode_register_$xdata'(Xdata, + 'encode_register_$misc'(Misc, + 'encode_register_$address'(Address, + 'encode_register_$instructions'(Instructions, + 'encode_register_$text'(Text, + 'encode_register_$last'(Last, + 'encode_register_$first'(First, + 'encode_register_$password'(Password, + 'encode_register_$registered'(Registered, + 'encode_register_$date'(Date, + 'encode_register_$phone'(Phone, + 'encode_register_$state'(State, + 'encode_register_$name'(Name, + 'encode_register_$username'(Username, + 'encode_register_$remove'(Remove, + 'encode_register_$key'(Key, + 'encode_register_$city'(City, + 'encode_register_$nick'(Nick, + 'encode_register_$url'(Url, + 'encode_register_$email'(Email, + [])))))))))))))))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_register_$zip'(undefined, _acc) -> _acc; +'encode_register_$zip'(Zip, _acc) -> + [encode_register_zip(Zip, []) | _acc]. + +'encode_register_$xdata'(undefined, _acc) -> _acc; +'encode_register_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +'encode_register_$misc'(undefined, _acc) -> _acc; +'encode_register_$misc'(Misc, _acc) -> + [encode_register_misc(Misc, []) | _acc]. + +'encode_register_$address'(undefined, _acc) -> _acc; +'encode_register_$address'(Address, _acc) -> + [encode_register_address(Address, []) | _acc]. + +'encode_register_$instructions'(undefined, _acc) -> + _acc; +'encode_register_$instructions'(Instructions, _acc) -> + [encode_register_instructions(Instructions, []) | _acc]. + +'encode_register_$text'(undefined, _acc) -> _acc; +'encode_register_$text'(Text, _acc) -> + [encode_register_text(Text, []) | _acc]. + +'encode_register_$last'(undefined, _acc) -> _acc; +'encode_register_$last'(Last, _acc) -> + [encode_register_last(Last, []) | _acc]. + +'encode_register_$first'(undefined, _acc) -> _acc; +'encode_register_$first'(First, _acc) -> + [encode_register_first(First, []) | _acc]. + +'encode_register_$password'(undefined, _acc) -> _acc; +'encode_register_$password'(Password, _acc) -> + [encode_register_password(Password, []) | _acc]. + +'encode_register_$registered'(false, _acc) -> _acc; +'encode_register_$registered'(Registered, _acc) -> + [encode_register_registered(Registered, []) | _acc]. + +'encode_register_$date'(undefined, _acc) -> _acc; +'encode_register_$date'(Date, _acc) -> + [encode_register_date(Date, []) | _acc]. + +'encode_register_$phone'(undefined, _acc) -> _acc; +'encode_register_$phone'(Phone, _acc) -> + [encode_register_phone(Phone, []) | _acc]. + +'encode_register_$state'(undefined, _acc) -> _acc; +'encode_register_$state'(State, _acc) -> + [encode_register_state(State, []) | _acc]. + +'encode_register_$name'(undefined, _acc) -> _acc; +'encode_register_$name'(Name, _acc) -> + [encode_register_name(Name, []) | _acc]. + +'encode_register_$username'(undefined, _acc) -> _acc; +'encode_register_$username'(Username, _acc) -> + [encode_register_username(Username, []) | _acc]. + +'encode_register_$remove'(false, _acc) -> _acc; +'encode_register_$remove'(Remove, _acc) -> + [encode_register_remove(Remove, []) | _acc]. + +'encode_register_$key'(undefined, _acc) -> _acc; +'encode_register_$key'(Key, _acc) -> + [encode_register_key(Key, []) | _acc]. + +'encode_register_$city'(undefined, _acc) -> _acc; +'encode_register_$city'(City, _acc) -> + [encode_register_city(City, []) | _acc]. + +'encode_register_$nick'(undefined, _acc) -> _acc; +'encode_register_$nick'(Nick, _acc) -> + [encode_register_nick(Nick, []) | _acc]. + +'encode_register_$url'(undefined, _acc) -> _acc; +'encode_register_$url'(Url, _acc) -> + [encode_register_url(Url, []) | _acc]. + +'encode_register_$email'(undefined, _acc) -> _acc; +'encode_register_$email'(Email, _acc) -> + [encode_register_email(Email, []) | _acc]. + +decode_register_key(__TopXMLNS, __IgnoreEls, + {xmlel, <<"key">>, _attrs, _els}) -> + Cdata = decode_register_key_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_register_key_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_key_cdata(__TopXMLNS, Cdata); +decode_register_key_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_key_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_key_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_key_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_key(Cdata, _xmlns_attrs) -> + _els = encode_register_key_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"key">>, _attrs, _els}. + +decode_register_key_cdata(__TopXMLNS, <<>>) -> none; +decode_register_key_cdata(__TopXMLNS, _val) -> _val. + +encode_register_key_cdata(none, _acc) -> _acc; +encode_register_key_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_text(__TopXMLNS, __IgnoreEls, + {xmlel, <<"text">>, _attrs, _els}) -> + Cdata = decode_register_text_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_text_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_text_cdata(__TopXMLNS, Cdata); +decode_register_text_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_text_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_text_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_text_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_text(Cdata, _xmlns_attrs) -> + _els = encode_register_text_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"text">>, _attrs, _els}. + +decode_register_text_cdata(__TopXMLNS, <<>>) -> none; +decode_register_text_cdata(__TopXMLNS, _val) -> _val. + +encode_register_text_cdata(none, _acc) -> _acc; +encode_register_text_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_misc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"misc">>, _attrs, _els}) -> + Cdata = decode_register_misc_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_misc_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_misc_cdata(__TopXMLNS, Cdata); +decode_register_misc_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_misc_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_misc_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_misc_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_misc(Cdata, _xmlns_attrs) -> + _els = encode_register_misc_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"misc">>, _attrs, _els}. + +decode_register_misc_cdata(__TopXMLNS, <<>>) -> none; +decode_register_misc_cdata(__TopXMLNS, _val) -> _val. + +encode_register_misc_cdata(none, _acc) -> _acc; +encode_register_misc_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_date(__TopXMLNS, __IgnoreEls, + {xmlel, <<"date">>, _attrs, _els}) -> + Cdata = decode_register_date_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_date_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_date_cdata(__TopXMLNS, Cdata); +decode_register_date_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_date_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_date_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_date_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_date(Cdata, _xmlns_attrs) -> + _els = encode_register_date_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"date">>, _attrs, _els}. + +decode_register_date_cdata(__TopXMLNS, <<>>) -> none; +decode_register_date_cdata(__TopXMLNS, _val) -> _val. + +encode_register_date_cdata(none, _acc) -> _acc; +encode_register_date_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_url(__TopXMLNS, __IgnoreEls, + {xmlel, <<"url">>, _attrs, _els}) -> + Cdata = decode_register_url_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_register_url_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_url_cdata(__TopXMLNS, Cdata); +decode_register_url_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_url_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_url_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_url_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_url(Cdata, _xmlns_attrs) -> + _els = encode_register_url_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"url">>, _attrs, _els}. + +decode_register_url_cdata(__TopXMLNS, <<>>) -> none; +decode_register_url_cdata(__TopXMLNS, _val) -> _val. + +encode_register_url_cdata(none, _acc) -> _acc; +encode_register_url_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_phone(__TopXMLNS, __IgnoreEls, + {xmlel, <<"phone">>, _attrs, _els}) -> + Cdata = decode_register_phone_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_phone_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_phone_cdata(__TopXMLNS, Cdata); +decode_register_phone_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_phone_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_phone_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_phone_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_phone(Cdata, _xmlns_attrs) -> + _els = encode_register_phone_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"phone">>, _attrs, _els}. + +decode_register_phone_cdata(__TopXMLNS, <<>>) -> none; +decode_register_phone_cdata(__TopXMLNS, _val) -> _val. + +encode_register_phone_cdata(none, _acc) -> _acc; +encode_register_phone_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_zip(__TopXMLNS, __IgnoreEls, + {xmlel, <<"zip">>, _attrs, _els}) -> + Cdata = decode_register_zip_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_register_zip_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_zip_cdata(__TopXMLNS, Cdata); +decode_register_zip_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_zip_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_zip_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_zip_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_zip(Cdata, _xmlns_attrs) -> + _els = encode_register_zip_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"zip">>, _attrs, _els}. + +decode_register_zip_cdata(__TopXMLNS, <<>>) -> none; +decode_register_zip_cdata(__TopXMLNS, _val) -> _val. + +encode_register_zip_cdata(none, _acc) -> _acc; +encode_register_zip_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_state(__TopXMLNS, __IgnoreEls, + {xmlel, <<"state">>, _attrs, _els}) -> + Cdata = decode_register_state_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_state_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_state_cdata(__TopXMLNS, Cdata); +decode_register_state_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_state_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_state_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_state_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_state(Cdata, _xmlns_attrs) -> + _els = encode_register_state_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"state">>, _attrs, _els}. + +decode_register_state_cdata(__TopXMLNS, <<>>) -> none; +decode_register_state_cdata(__TopXMLNS, _val) -> _val. + +encode_register_state_cdata(none, _acc) -> _acc; +encode_register_state_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_city(__TopXMLNS, __IgnoreEls, + {xmlel, <<"city">>, _attrs, _els}) -> + Cdata = decode_register_city_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_city_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_city_cdata(__TopXMLNS, Cdata); +decode_register_city_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_city_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_city_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_city_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_city(Cdata, _xmlns_attrs) -> + _els = encode_register_city_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"city">>, _attrs, _els}. + +decode_register_city_cdata(__TopXMLNS, <<>>) -> none; +decode_register_city_cdata(__TopXMLNS, _val) -> _val. + +encode_register_city_cdata(none, _acc) -> _acc; +encode_register_city_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_address(__TopXMLNS, __IgnoreEls, + {xmlel, <<"address">>, _attrs, _els}) -> + Cdata = decode_register_address_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_address_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_address_cdata(__TopXMLNS, Cdata); +decode_register_address_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_address_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_register_address_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_address_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_register_address(Cdata, _xmlns_attrs) -> + _els = encode_register_address_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"address">>, _attrs, _els}. + +decode_register_address_cdata(__TopXMLNS, <<>>) -> none; +decode_register_address_cdata(__TopXMLNS, _val) -> _val. + +encode_register_address_cdata(none, _acc) -> _acc; +encode_register_address_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_email(__TopXMLNS, __IgnoreEls, + {xmlel, <<"email">>, _attrs, _els}) -> + Cdata = decode_register_email_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_email_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_email_cdata(__TopXMLNS, Cdata); +decode_register_email_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_email_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_email_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_email_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_email(Cdata, _xmlns_attrs) -> + _els = encode_register_email_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"email">>, _attrs, _els}. + +decode_register_email_cdata(__TopXMLNS, <<>>) -> none; +decode_register_email_cdata(__TopXMLNS, _val) -> _val. + +encode_register_email_cdata(none, _acc) -> _acc; +encode_register_email_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_last(__TopXMLNS, __IgnoreEls, + {xmlel, <<"last">>, _attrs, _els}) -> + Cdata = decode_register_last_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_last_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_last_cdata(__TopXMLNS, Cdata); +decode_register_last_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_last_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_last_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_last_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_last(Cdata, _xmlns_attrs) -> + _els = encode_register_last_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"last">>, _attrs, _els}. + +decode_register_last_cdata(__TopXMLNS, <<>>) -> none; +decode_register_last_cdata(__TopXMLNS, _val) -> _val. + +encode_register_last_cdata(none, _acc) -> _acc; +encode_register_last_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_first(__TopXMLNS, __IgnoreEls, + {xmlel, <<"first">>, _attrs, _els}) -> + Cdata = decode_register_first_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_first_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_first_cdata(__TopXMLNS, Cdata); +decode_register_first_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_first_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_first_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_first_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_first(Cdata, _xmlns_attrs) -> + _els = encode_register_first_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"first">>, _attrs, _els}. + +decode_register_first_cdata(__TopXMLNS, <<>>) -> none; +decode_register_first_cdata(__TopXMLNS, _val) -> _val. + +encode_register_first_cdata(none, _acc) -> _acc; +encode_register_first_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_name(__TopXMLNS, __IgnoreEls, + {xmlel, <<"name">>, _attrs, _els}) -> + Cdata = decode_register_name_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_name_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_name_cdata(__TopXMLNS, Cdata); +decode_register_name_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_name_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_name_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_name_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_name(Cdata, _xmlns_attrs) -> + _els = encode_register_name_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"name">>, _attrs, _els}. + +decode_register_name_cdata(__TopXMLNS, <<>>) -> none; +decode_register_name_cdata(__TopXMLNS, _val) -> _val. + +encode_register_name_cdata(none, _acc) -> _acc; +encode_register_name_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_password(__TopXMLNS, __IgnoreEls, + {xmlel, <<"password">>, _attrs, _els}) -> + Cdata = decode_register_password_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_password_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_register_password_cdata(__TopXMLNS, Cdata); +decode_register_password_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_password_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_register_password_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_password_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_register_password(Cdata, _xmlns_attrs) -> + _els = encode_register_password_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"password">>, _attrs, _els}. + +decode_register_password_cdata(__TopXMLNS, <<>>) -> + none; +decode_register_password_cdata(__TopXMLNS, _val) -> + _val. + +encode_register_password_cdata(none, _acc) -> _acc; +encode_register_password_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_nick(__TopXMLNS, __IgnoreEls, + {xmlel, <<"nick">>, _attrs, _els}) -> + Cdata = decode_register_nick_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_nick_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_register_nick_cdata(__TopXMLNS, Cdata); +decode_register_nick_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_nick_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_register_nick_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_nick_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_register_nick(Cdata, _xmlns_attrs) -> + _els = encode_register_nick_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"nick">>, _attrs, _els}. + +decode_register_nick_cdata(__TopXMLNS, <<>>) -> none; +decode_register_nick_cdata(__TopXMLNS, _val) -> _val. + +encode_register_nick_cdata(none, _acc) -> _acc; +encode_register_nick_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_username(__TopXMLNS, __IgnoreEls, + {xmlel, <<"username">>, _attrs, _els}) -> + Cdata = decode_register_username_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_username_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_register_username_cdata(__TopXMLNS, Cdata); +decode_register_username_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_register_username_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_register_username_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_register_username_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_register_username(Cdata, _xmlns_attrs) -> + _els = encode_register_username_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"username">>, _attrs, _els}. + +decode_register_username_cdata(__TopXMLNS, <<>>) -> + none; +decode_register_username_cdata(__TopXMLNS, _val) -> + _val. + +encode_register_username_cdata(none, _acc) -> _acc; +encode_register_username_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_instructions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"instructions">>, _attrs, _els}) -> + Cdata = decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, [], Cdata) -> + decode_register_instructions_cdata(__TopXMLNS, Cdata); +decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, [{xmlcdata, _data} | _els], + Cdata) -> + decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, _els, + <>); +decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Cdata) -> + decode_register_instructions_els(__TopXMLNS, + __IgnoreEls, _els, Cdata). + +encode_register_instructions(Cdata, _xmlns_attrs) -> + _els = encode_register_instructions_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"instructions">>, _attrs, _els}. + +decode_register_instructions_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_register_instructions_cdata(__TopXMLNS, _val) -> + _val. + +encode_register_instructions_cdata(undefined, _acc) -> + _acc; +encode_register_instructions_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_register_remove(__TopXMLNS, __IgnoreEls, + {xmlel, <<"remove">>, _attrs, _els}) -> + true. + +encode_register_remove(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"remove">>, _attrs, _els}. + +decode_register_registered(__TopXMLNS, __IgnoreEls, + {xmlel, <<"registered">>, _attrs, _els}) -> + true. + +encode_register_registered(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"registered">>, _attrs, _els}. + +decode_feature_register(__TopXMLNS, __IgnoreEls, + {xmlel, <<"register">>, _attrs, _els}) -> + {feature_register}. + +encode_feature_register({feature_register}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"register">>, _attrs, _els}. + +decode_caps(__TopXMLNS, __IgnoreEls, + {xmlel, <<"c">>, _attrs, _els}) -> + {Hash, Node, Exts, Version} = + decode_caps_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {caps, Node, Version, Hash, Exts}. + +decode_caps_attrs(__TopXMLNS, + [{<<"hash">>, _val} | _attrs], _Hash, Node, Exts, + Version) -> + decode_caps_attrs(__TopXMLNS, _attrs, _val, Node, Exts, + Version); +decode_caps_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Hash, _Node, Exts, + Version) -> + decode_caps_attrs(__TopXMLNS, _attrs, Hash, _val, Exts, + Version); +decode_caps_attrs(__TopXMLNS, + [{<<"ext">>, _val} | _attrs], Hash, Node, _Exts, + Version) -> + decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, _val, + Version); +decode_caps_attrs(__TopXMLNS, + [{<<"ver">>, _val} | _attrs], Hash, Node, Exts, + _Version) -> + decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, Exts, + _val); +decode_caps_attrs(__TopXMLNS, [_ | _attrs], Hash, Node, + Exts, Version) -> + decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, Exts, + Version); +decode_caps_attrs(__TopXMLNS, [], Hash, Node, Exts, + Version) -> + {decode_caps_attr_hash(__TopXMLNS, Hash), + decode_caps_attr_node(__TopXMLNS, Node), + decode_caps_attr_ext(__TopXMLNS, Exts), + decode_caps_attr_ver(__TopXMLNS, Version)}. + +encode_caps({caps, Node, Version, Hash, Exts}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_caps_attr_ver(Version, + encode_caps_attr_ext(Exts, + encode_caps_attr_node(Node, + encode_caps_attr_hash(Hash, + _xmlns_attrs)))), + {xmlel, <<"c">>, _attrs, _els}. + +decode_caps_attr_hash(__TopXMLNS, undefined) -> + undefined; +decode_caps_attr_hash(__TopXMLNS, _val) -> _val. + +encode_caps_attr_hash(undefined, _acc) -> _acc; +encode_caps_attr_hash(_val, _acc) -> + [{<<"hash">>, _val} | _acc]. + +decode_caps_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_caps_attr_node(__TopXMLNS, _val) -> _val. + +encode_caps_attr_node(undefined, _acc) -> _acc; +encode_caps_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_caps_attr_ext(__TopXMLNS, undefined) -> []; +decode_caps_attr_ext(__TopXMLNS, _val) -> + case catch re:split(_val, "\\h+") of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"ext">>, <<"c">>, __TopXMLNS}}); + _res -> _res + end. + +encode_caps_attr_ext([], _acc) -> _acc; +encode_caps_attr_ext(_val, _acc) -> + [{<<"ext">>, join(_val, 32)} | _acc]. + +decode_caps_attr_ver(__TopXMLNS, undefined) -> + undefined; +decode_caps_attr_ver(__TopXMLNS, _val) -> _val. + +encode_caps_attr_ver(undefined, _acc) -> _acc; +encode_caps_attr_ver(_val, _acc) -> + [{<<"ver">>, _val} | _acc]. + +decode_p1_ack(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ack">>, _attrs, _els}) -> + {p1_ack}. + +encode_p1_ack({p1_ack}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"ack">>, _attrs, _els}. + +decode_p1_rebind(__TopXMLNS, __IgnoreEls, + {xmlel, <<"rebind">>, _attrs, _els}) -> + {p1_rebind}. + +encode_p1_rebind({p1_rebind}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"rebind">>, _attrs, _els}. + +decode_p1_push(__TopXMLNS, __IgnoreEls, + {xmlel, <<"push">>, _attrs, _els}) -> + {p1_push}. + +encode_p1_push({p1_push}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"push">>, _attrs, _els}. + +decode_stream_features(__TopXMLNS, __IgnoreEls, + {xmlel, <<"stream:features">>, _attrs, _els}) -> + __Els = decode_stream_features_els(__TopXMLNS, + __IgnoreEls, _els, []), + {stream_features, __Els}. + +decode_stream_features_els(__TopXMLNS, __IgnoreEls, [], + __Els) -> + lists:reverse(__Els); +decode_stream_features_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], __Els) -> + if __IgnoreEls -> + decode_stream_features_els(__TopXMLNS, __IgnoreEls, + _els, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_stream_features_els(__TopXMLNS, __IgnoreEls, + _els, [decode(_el) | __Els]); + false -> + decode_stream_features_els(__TopXMLNS, __IgnoreEls, + _els, __Els) + end + end; +decode_stream_features_els(__TopXMLNS, __IgnoreEls, + [_ | _els], __Els) -> + decode_stream_features_els(__TopXMLNS, __IgnoreEls, + _els, __Els). + +encode_stream_features({stream_features, __Els}, + _xmlns_attrs) -> + _els = [encode(_el) || _el <- __Els], + _attrs = _xmlns_attrs, + {xmlel, <<"stream:features">>, _attrs, _els}. + +decode_compression(__TopXMLNS, __IgnoreEls, + {xmlel, <<"compression">>, _attrs, _els}) -> + Methods = decode_compression_els(__TopXMLNS, + __IgnoreEls, _els, []), + {compression, Methods}. + +decode_compression_els(__TopXMLNS, __IgnoreEls, [], + Methods) -> + lists:reverse(Methods); +decode_compression_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"method">>, _attrs, _} = _el | _els], + Methods) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/features/compress">> -> + decode_compression_els(__TopXMLNS, __IgnoreEls, _els, + case decode_compression_method(__TopXMLNS, + __IgnoreEls, + _el) + of + undefined -> Methods; + _new_el -> [_new_el | Methods] + end); + <<"http://jabber.org/features/compress">> -> + decode_compression_els(__TopXMLNS, __IgnoreEls, _els, + case + decode_compression_method(<<"http://jabber.org/features/compress">>, + __IgnoreEls, _el) + of + undefined -> Methods; + _new_el -> [_new_el | Methods] + end); + _ -> + decode_compression_els(__TopXMLNS, __IgnoreEls, _els, + Methods) + end; +decode_compression_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Methods) -> + decode_compression_els(__TopXMLNS, __IgnoreEls, _els, + Methods). + +encode_compression({compression, Methods}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_compression_$methods'(Methods, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"compression">>, _attrs, _els}. + +'encode_compression_$methods'([], _acc) -> _acc; +'encode_compression_$methods'([Methods | _els], _acc) -> + 'encode_compression_$methods'(_els, + [encode_compression_method(Methods, []) + | _acc]). + +decode_compression_method(__TopXMLNS, __IgnoreEls, + {xmlel, <<"method">>, _attrs, _els}) -> + Cdata = decode_compression_method_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_compression_method_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_compression_method_cdata(__TopXMLNS, Cdata); +decode_compression_method_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_compression_method_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_compression_method_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_compression_method_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_compression_method(Cdata, _xmlns_attrs) -> + _els = encode_compression_method_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"method">>, _attrs, _els}. + +decode_compression_method_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_compression_method_cdata(__TopXMLNS, _val) -> + _val. + +encode_compression_method_cdata(undefined, _acc) -> + _acc; +encode_compression_method_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_compressed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"compressed">>, _attrs, _els}) -> + {compressed}. + +encode_compressed({compressed}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"compressed">>, _attrs, _els}. + +decode_compress(__TopXMLNS, __IgnoreEls, + {xmlel, <<"compress">>, _attrs, _els}) -> + Methods = decode_compress_els(__TopXMLNS, __IgnoreEls, + _els, []), + {compress, Methods}. + +decode_compress_els(__TopXMLNS, __IgnoreEls, [], + Methods) -> + lists:reverse(Methods); +decode_compress_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"method">>, _attrs, _} = _el | _els], + Methods) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/compress">> -> + decode_compress_els(__TopXMLNS, __IgnoreEls, _els, + case decode_compress_method(__TopXMLNS, + __IgnoreEls, _el) + of + undefined -> Methods; + _new_el -> [_new_el | Methods] + end); + <<"http://jabber.org/protocol/compress">> -> + decode_compress_els(__TopXMLNS, __IgnoreEls, _els, + case + decode_compress_method(<<"http://jabber.org/protocol/compress">>, + __IgnoreEls, _el) + of + undefined -> Methods; + _new_el -> [_new_el | Methods] + end); + _ -> + decode_compress_els(__TopXMLNS, __IgnoreEls, _els, + Methods) + end; +decode_compress_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Methods) -> + decode_compress_els(__TopXMLNS, __IgnoreEls, _els, + Methods). + +encode_compress({compress, Methods}, _xmlns_attrs) -> + _els = lists:reverse('encode_compress_$methods'(Methods, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"compress">>, _attrs, _els}. + +'encode_compress_$methods'([], _acc) -> _acc; +'encode_compress_$methods'([Methods | _els], _acc) -> + 'encode_compress_$methods'(_els, + [encode_compress_method(Methods, []) | _acc]). + +decode_compress_method(__TopXMLNS, __IgnoreEls, + {xmlel, <<"method">>, _attrs, _els}) -> + Cdata = decode_compress_method_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_compress_method_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_compress_method_cdata(__TopXMLNS, Cdata); +decode_compress_method_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_compress_method_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_compress_method_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_compress_method_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_compress_method(Cdata, _xmlns_attrs) -> + _els = encode_compress_method_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"method">>, _attrs, _els}. + +decode_compress_method_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_compress_method_cdata(__TopXMLNS, _val) -> _val. + +encode_compress_method_cdata(undefined, _acc) -> _acc; +encode_compress_method_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_compress_failure(__TopXMLNS, __IgnoreEls, + {xmlel, <<"failure">>, _attrs, _els}) -> + Reason = decode_compress_failure_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + {compress_failure, Reason}. + +decode_compress_failure_els(__TopXMLNS, __IgnoreEls, [], + Reason) -> + Reason; +decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"setup-failed">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_setup_failed(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, + __IgnoreEls, + _el)); + _ -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"processing-failed">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_processing_failed(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, + __IgnoreEls, + _el)); + _ -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsupported-method">>, _attrs, _} = _el + | _els], + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_unsupported_method(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/compress">> -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, + __IgnoreEls, + _el)); + _ -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, Reason) + end; +decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Reason) -> + decode_compress_failure_els(__TopXMLNS, __IgnoreEls, + _els, Reason). + +encode_compress_failure({compress_failure, Reason}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_compress_failure_$reason'(Reason, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"failure">>, _attrs, _els}. + +'encode_compress_failure_$reason'(undefined, _acc) -> + _acc; +'encode_compress_failure_$reason'('setup-failed' = + Reason, + _acc) -> + [encode_compress_failure_setup_failed(Reason, []) + | _acc]; +'encode_compress_failure_$reason'('processing-failed' = + Reason, + _acc) -> + [encode_compress_failure_processing_failed(Reason, []) + | _acc]; +'encode_compress_failure_$reason'('unsupported-method' = + Reason, + _acc) -> + [encode_compress_failure_unsupported_method(Reason, []) + | _acc]. + +decode_compress_failure_unsupported_method(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"unsupported-method">>, + _attrs, _els}) -> + 'unsupported-method'. + +encode_compress_failure_unsupported_method('unsupported-method', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsupported-method">>, _attrs, _els}. + +decode_compress_failure_processing_failed(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"processing-failed">>, + _attrs, _els}) -> + 'processing-failed'. + +encode_compress_failure_processing_failed('processing-failed', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"processing-failed">>, _attrs, _els}. + +decode_compress_failure_setup_failed(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"setup-failed">>, _attrs, + _els}) -> + 'setup-failed'. + +encode_compress_failure_setup_failed('setup-failed', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"setup-failed">>, _attrs, _els}. + +decode_starttls_failure(__TopXMLNS, __IgnoreEls, + {xmlel, <<"failure">>, _attrs, _els}) -> + {starttls_failure}. + +encode_starttls_failure({starttls_failure}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"failure">>, _attrs, _els}. + +decode_starttls_proceed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"proceed">>, _attrs, _els}) -> + {starttls_proceed}. + +encode_starttls_proceed({starttls_proceed}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"proceed">>, _attrs, _els}. + +decode_starttls(__TopXMLNS, __IgnoreEls, + {xmlel, <<"starttls">>, _attrs, _els}) -> + Required = decode_starttls_els(__TopXMLNS, __IgnoreEls, + _els, false), + {starttls, Required}. + +decode_starttls_els(__TopXMLNS, __IgnoreEls, [], + Required) -> + Required; +decode_starttls_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"required">>, _attrs, _} = _el | _els], + Required) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-tls">> -> + decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, + decode_starttls_required(__TopXMLNS, __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-tls">> -> + decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, + decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + __IgnoreEls, _el)); + _ -> + decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, + Required) + end; +decode_starttls_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Required) -> + decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, + Required). + +encode_starttls({starttls, Required}, _xmlns_attrs) -> + _els = + lists:reverse('encode_starttls_$required'(Required, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"starttls">>, _attrs, _els}. + +'encode_starttls_$required'(false, _acc) -> _acc; +'encode_starttls_$required'(Required, _acc) -> + [encode_starttls_required(Required, []) | _acc]. + +decode_starttls_required(__TopXMLNS, __IgnoreEls, + {xmlel, <<"required">>, _attrs, _els}) -> + true. + +encode_starttls_required(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"required">>, _attrs, _els}. + +decode_sasl_mechanisms(__TopXMLNS, __IgnoreEls, + {xmlel, <<"mechanisms">>, _attrs, _els}) -> + List = decode_sasl_mechanisms_els(__TopXMLNS, + __IgnoreEls, _els, []), + {sasl_mechanisms, List}. + +decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, [], + List) -> + lists:reverse(List); +decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"mechanism">>, _attrs, _} = _el | _els], + List) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + _els, + case decode_sasl_mechanism(__TopXMLNS, + __IgnoreEls, + _el) + of + undefined -> List; + _new_el -> [_new_el | List] + end); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + _els, + case + decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, _el) + of + undefined -> List; + _new_el -> [_new_el | List] + end); + _ -> + decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + _els, List) + end; +decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + [_ | _els], List) -> + decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, + _els, List). + +encode_sasl_mechanisms({sasl_mechanisms, List}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_sasl_mechanisms_$list'(List, [])), + _attrs = _xmlns_attrs, + {xmlel, <<"mechanisms">>, _attrs, _els}. + +'encode_sasl_mechanisms_$list'([], _acc) -> _acc; +'encode_sasl_mechanisms_$list'([List | _els], _acc) -> + 'encode_sasl_mechanisms_$list'(_els, + [encode_sasl_mechanism(List, []) | _acc]). + +decode_sasl_mechanism(__TopXMLNS, __IgnoreEls, + {xmlel, <<"mechanism">>, _attrs, _els}) -> + Cdata = decode_sasl_mechanism_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_sasl_mechanism_cdata(__TopXMLNS, Cdata); +decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_sasl_mechanism(Cdata, _xmlns_attrs) -> + _els = encode_sasl_mechanism_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"mechanism">>, _attrs, _els}. + +decode_sasl_mechanism_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_sasl_mechanism_cdata(__TopXMLNS, _val) -> _val. + +encode_sasl_mechanism_cdata(undefined, _acc) -> _acc; +encode_sasl_mechanism_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_sasl_failure(__TopXMLNS, __IgnoreEls, + {xmlel, <<"failure">>, _attrs, _els}) -> + {Text, Reason} = decode_sasl_failure_els(__TopXMLNS, + __IgnoreEls, _els, [], undefined), + {sasl_failure, Reason, Text}. + +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, [], + Text, Reason) -> + {lists:reverse(Text), Reason}; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + [decode_sasl_failure_text(__TopXMLNS, + __IgnoreEls, _el) + | Text], + Reason); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + [decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, _el) + | Text], + Reason); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"aborted">>, _attrs, _} = _el | _els], Text, + Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_aborted(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"account-disabled">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_account_disabled(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"credentials-expired">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_credentials_expired(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"encryption-required">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_encryption_required(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"incorrect-encoding">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_incorrect_encoding(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-authzid">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_invalid_authzid(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"invalid-mechanism">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_invalid_mechanism(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"malformed-request">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_malformed_request(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"mechanism-too-weak">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_mechanism_too_weak(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_not_authorized(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"bad-protocol">>, _attrs, _} = _el | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_bad_protocol(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"temporary-auth-failure">>, _attrs, _} = _el + | _els], + Text, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_temporary_auth_failure(__TopXMLNS, + __IgnoreEls, + _el)); + <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, + decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + __IgnoreEls, + _el)); + _ -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason) + end; +decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text, Reason) -> + decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, + Text, Reason). + +encode_sasl_failure({sasl_failure, Reason, Text}, + _xmlns_attrs) -> + _els = lists:reverse('encode_sasl_failure_$text'(Text, + 'encode_sasl_failure_$reason'(Reason, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"failure">>, _attrs, _els}. + +'encode_sasl_failure_$text'([], _acc) -> _acc; +'encode_sasl_failure_$text'([Text | _els], _acc) -> + 'encode_sasl_failure_$text'(_els, + [encode_sasl_failure_text(Text, []) | _acc]). + +'encode_sasl_failure_$reason'(undefined, _acc) -> _acc; +'encode_sasl_failure_$reason'(aborted = Reason, _acc) -> + [encode_sasl_failure_aborted(Reason, []) | _acc]; +'encode_sasl_failure_$reason'('account-disabled' = + Reason, + _acc) -> + [encode_sasl_failure_account_disabled(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('credentials-expired' = + Reason, + _acc) -> + [encode_sasl_failure_credentials_expired(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('encryption-required' = + Reason, + _acc) -> + [encode_sasl_failure_encryption_required(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('incorrect-encoding' = + Reason, + _acc) -> + [encode_sasl_failure_incorrect_encoding(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('invalid-authzid' = + Reason, + _acc) -> + [encode_sasl_failure_invalid_authzid(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('invalid-mechanism' = + Reason, + _acc) -> + [encode_sasl_failure_invalid_mechanism(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('malformed-request' = + Reason, + _acc) -> + [encode_sasl_failure_malformed_request(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('mechanism-too-weak' = + Reason, + _acc) -> + [encode_sasl_failure_mechanism_too_weak(Reason, []) + | _acc]; +'encode_sasl_failure_$reason'('not-authorized' = Reason, + _acc) -> + [encode_sasl_failure_not_authorized(Reason, []) | _acc]; +'encode_sasl_failure_$reason'('bad-protocol' = Reason, + _acc) -> + [encode_sasl_failure_bad_protocol(Reason, []) | _acc]; +'encode_sasl_failure_$reason'('temporary-auth-failure' = + Reason, + _acc) -> + [encode_sasl_failure_temporary_auth_failure(Reason, []) + | _acc]. + +decode_sasl_failure_temporary_auth_failure(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"temporary-auth-failure">>, + _attrs, _els}) -> + 'temporary-auth-failure'. + +encode_sasl_failure_temporary_auth_failure('temporary-auth-failure', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"temporary-auth-failure">>, _attrs, _els}. + +decode_sasl_failure_bad_protocol(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"bad-protocol">>, _attrs, _els}) -> + 'bad-protocol'. + +encode_sasl_failure_bad_protocol('bad-protocol', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"bad-protocol">>, _attrs, _els}. + +decode_sasl_failure_not_authorized(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"not-authorized">>, _attrs, + _els}) -> + 'not-authorized'. + +encode_sasl_failure_not_authorized('not-authorized', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-authorized">>, _attrs, _els}. + +decode_sasl_failure_mechanism_too_weak(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"mechanism-too-weak">>, _attrs, + _els}) -> + 'mechanism-too-weak'. + +encode_sasl_failure_mechanism_too_weak('mechanism-too-weak', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"mechanism-too-weak">>, _attrs, _els}. + +decode_sasl_failure_malformed_request(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"malformed-request">>, _attrs, + _els}) -> + 'malformed-request'. + +encode_sasl_failure_malformed_request('malformed-request', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"malformed-request">>, _attrs, _els}. + +decode_sasl_failure_invalid_mechanism(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-mechanism">>, _attrs, + _els}) -> + 'invalid-mechanism'. + +encode_sasl_failure_invalid_mechanism('invalid-mechanism', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-mechanism">>, _attrs, _els}. + +decode_sasl_failure_invalid_authzid(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-authzid">>, _attrs, + _els}) -> + 'invalid-authzid'. + +encode_sasl_failure_invalid_authzid('invalid-authzid', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-authzid">>, _attrs, _els}. + +decode_sasl_failure_incorrect_encoding(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"incorrect-encoding">>, _attrs, + _els}) -> + 'incorrect-encoding'. + +encode_sasl_failure_incorrect_encoding('incorrect-encoding', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"incorrect-encoding">>, _attrs, _els}. + +decode_sasl_failure_encryption_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"encryption-required">>, + _attrs, _els}) -> + 'encryption-required'. + +encode_sasl_failure_encryption_required('encryption-required', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"encryption-required">>, _attrs, _els}. + +decode_sasl_failure_credentials_expired(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"credentials-expired">>, + _attrs, _els}) -> + 'credentials-expired'. + +encode_sasl_failure_credentials_expired('credentials-expired', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"credentials-expired">>, _attrs, _els}. + +decode_sasl_failure_account_disabled(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"account-disabled">>, _attrs, + _els}) -> + 'account-disabled'. + +encode_sasl_failure_account_disabled('account-disabled', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"account-disabled">>, _attrs, _els}. + +decode_sasl_failure_aborted(__TopXMLNS, __IgnoreEls, + {xmlel, <<"aborted">>, _attrs, _els}) -> + aborted. + +encode_sasl_failure_aborted(aborted, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"aborted">>, _attrs, _els}. + +decode_sasl_failure_text(__TopXMLNS, __IgnoreEls, + {xmlel, <<"text">>, _attrs, _els}) -> + Data = decode_sasl_failure_text_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Lang = decode_sasl_failure_text_attrs(__TopXMLNS, + _attrs, undefined), + {text, Lang, Data}. + +decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, + [], Data) -> + decode_sasl_failure_text_cdata(__TopXMLNS, Data); +decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, + _els, Data). + +decode_sasl_failure_text_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_sasl_failure_text_attrs(__TopXMLNS, _attrs, + _val); +decode_sasl_failure_text_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_sasl_failure_text_attrs(__TopXMLNS, _attrs, + Lang); +decode_sasl_failure_text_attrs(__TopXMLNS, [], Lang) -> + 'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, + Lang). + +encode_sasl_failure_text({text, Lang, Data}, + _xmlns_attrs) -> + _els = encode_sasl_failure_text_cdata(Data, []), + _attrs = 'encode_sasl_failure_text_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"text">>, _attrs, _els}. + +'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_sasl_failure_text_attr_xml:lang'(undefined, + _acc) -> + _acc; +'encode_sasl_failure_text_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_sasl_failure_text_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_sasl_failure_text_cdata(__TopXMLNS, _val) -> + _val. + +encode_sasl_failure_text_cdata(undefined, _acc) -> _acc; +encode_sasl_failure_text_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_sasl_success(__TopXMLNS, __IgnoreEls, + {xmlel, <<"success">>, _attrs, _els}) -> + Text = decode_sasl_success_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {sasl_success, Text}. + +decode_sasl_success_els(__TopXMLNS, __IgnoreEls, [], + Text) -> + decode_sasl_success_cdata(__TopXMLNS, Text); +decode_sasl_success_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Text) -> + decode_sasl_success_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sasl_success_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text) -> + decode_sasl_success_els(__TopXMLNS, __IgnoreEls, _els, + Text). + +encode_sasl_success({sasl_success, Text}, + _xmlns_attrs) -> + _els = encode_sasl_success_cdata(Text, []), + _attrs = _xmlns_attrs, + {xmlel, <<"success">>, _attrs, _els}. + +decode_sasl_success_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_sasl_success_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"success">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sasl_success_cdata(undefined, _acc) -> _acc; +encode_sasl_success_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + +decode_sasl_response(__TopXMLNS, __IgnoreEls, + {xmlel, <<"response">>, _attrs, _els}) -> + Text = decode_sasl_response_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {sasl_response, Text}. + +decode_sasl_response_els(__TopXMLNS, __IgnoreEls, [], + Text) -> + decode_sasl_response_cdata(__TopXMLNS, Text); +decode_sasl_response_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Text) -> + decode_sasl_response_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sasl_response_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text) -> + decode_sasl_response_els(__TopXMLNS, __IgnoreEls, _els, + Text). + +encode_sasl_response({sasl_response, Text}, + _xmlns_attrs) -> + _els = encode_sasl_response_cdata(Text, []), + _attrs = _xmlns_attrs, + {xmlel, <<"response">>, _attrs, _els}. + +decode_sasl_response_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_sasl_response_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"response">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sasl_response_cdata(undefined, _acc) -> _acc; +encode_sasl_response_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + +decode_sasl_challenge(__TopXMLNS, __IgnoreEls, + {xmlel, <<"challenge">>, _attrs, _els}) -> + Text = decode_sasl_challenge_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + {sasl_challenge, Text}. + +decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, [], + Text) -> + decode_sasl_challenge_cdata(__TopXMLNS, Text); +decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Text) -> + decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text) -> + decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, _els, + Text). + +encode_sasl_challenge({sasl_challenge, Text}, + _xmlns_attrs) -> + _els = encode_sasl_challenge_cdata(Text, []), + _attrs = _xmlns_attrs, + {xmlel, <<"challenge">>, _attrs, _els}. + +decode_sasl_challenge_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_sasl_challenge_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"challenge">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sasl_challenge_cdata(undefined, _acc) -> _acc; +encode_sasl_challenge_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + +decode_sasl_abort(__TopXMLNS, __IgnoreEls, + {xmlel, <<"abort">>, _attrs, _els}) -> + {sasl_abort}. + +encode_sasl_abort({sasl_abort}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"abort">>, _attrs, _els}. + +decode_sasl_auth(__TopXMLNS, __IgnoreEls, + {xmlel, <<"auth">>, _attrs, _els}) -> + Text = decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Mechanism = decode_sasl_auth_attrs(__TopXMLNS, _attrs, + undefined), + {sasl_auth, Mechanism, Text}. + +decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, [], + Text) -> + decode_sasl_auth_cdata(__TopXMLNS, Text); +decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Text) -> + decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Text) -> + decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, _els, + Text). + +decode_sasl_auth_attrs(__TopXMLNS, + [{<<"mechanism">>, _val} | _attrs], _Mechanism) -> + decode_sasl_auth_attrs(__TopXMLNS, _attrs, _val); +decode_sasl_auth_attrs(__TopXMLNS, [_ | _attrs], + Mechanism) -> + decode_sasl_auth_attrs(__TopXMLNS, _attrs, Mechanism); +decode_sasl_auth_attrs(__TopXMLNS, [], Mechanism) -> + decode_sasl_auth_attr_mechanism(__TopXMLNS, Mechanism). + +encode_sasl_auth({sasl_auth, Mechanism, Text}, + _xmlns_attrs) -> + _els = encode_sasl_auth_cdata(Text, []), + _attrs = encode_sasl_auth_attr_mechanism(Mechanism, + _xmlns_attrs), + {xmlel, <<"auth">>, _attrs, _els}. + +decode_sasl_auth_attr_mechanism(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"mechanism">>, <<"auth">>, + __TopXMLNS}}); +decode_sasl_auth_attr_mechanism(__TopXMLNS, _val) -> + _val. + +encode_sasl_auth_attr_mechanism(_val, _acc) -> + [{<<"mechanism">>, _val} | _acc]. + +decode_sasl_auth_cdata(__TopXMLNS, <<>>) -> undefined; +decode_sasl_auth_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"auth">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sasl_auth_cdata(undefined, _acc) -> _acc; +encode_sasl_auth_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + +decode_legacy_auth(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Digest, Password, Resource, Username} = + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined), + {legacy_auth, Username, Password, Digest, Resource}. + +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, [], + Digest, Password, Resource, Username) -> + {Digest, Password, Resource, Username}; +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"username">>, _attrs, _} = _el | _els], + Digest, Password, Resource, Username) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, + decode_legacy_auth_username(__TopXMLNS, + __IgnoreEls, _el)); + <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, + decode_legacy_auth_username(<<"jabber:iq:auth">>, + __IgnoreEls, _el)); + _ -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, Username) + end; +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], + Digest, Password, Resource, Username) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, + decode_legacy_auth_password(__TopXMLNS, + __IgnoreEls, _el), + Resource, Username); + <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, + decode_legacy_auth_password(<<"jabber:iq:auth">>, + __IgnoreEls, _el), + Resource, Username); + _ -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, Username) + end; +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"digest">>, _attrs, _} = _el | _els], Digest, + Password, Resource, Username) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + decode_legacy_auth_digest(__TopXMLNS, + __IgnoreEls, _el), + Password, Resource, Username); + <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + decode_legacy_auth_digest(<<"jabber:iq:auth">>, + __IgnoreEls, _el), + Password, Resource, Username); + _ -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, Username) + end; +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"resource">>, _attrs, _} = _el | _els], + Digest, Password, Resource, Username) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, + decode_legacy_auth_resource(__TopXMLNS, + __IgnoreEls, _el), + Username); + <<"jabber:iq:auth">> -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, + decode_legacy_auth_resource(<<"jabber:iq:auth">>, + __IgnoreEls, _el), + Username); + _ -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, Username) + end; +decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Digest, Password, Resource, Username) -> + decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, + Digest, Password, Resource, Username). + +encode_legacy_auth({legacy_auth, Username, Password, + Digest, Resource}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_legacy_auth_$digest'(Digest, + 'encode_legacy_auth_$password'(Password, + 'encode_legacy_auth_$resource'(Resource, + 'encode_legacy_auth_$username'(Username, + []))))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_legacy_auth_$digest'(undefined, _acc) -> _acc; +'encode_legacy_auth_$digest'(Digest, _acc) -> + [encode_legacy_auth_digest(Digest, []) | _acc]. + +'encode_legacy_auth_$password'(undefined, _acc) -> _acc; +'encode_legacy_auth_$password'(Password, _acc) -> + [encode_legacy_auth_password(Password, []) | _acc]. + +'encode_legacy_auth_$resource'(undefined, _acc) -> _acc; +'encode_legacy_auth_$resource'(Resource, _acc) -> + [encode_legacy_auth_resource(Resource, []) | _acc]. + +'encode_legacy_auth_$username'(undefined, _acc) -> _acc; +'encode_legacy_auth_$username'(Username, _acc) -> + [encode_legacy_auth_username(Username, []) | _acc]. + +decode_legacy_auth_resource(__TopXMLNS, __IgnoreEls, + {xmlel, <<"resource">>, _attrs, _els}) -> + Cdata = decode_legacy_auth_resource_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_legacy_auth_resource_cdata(__TopXMLNS, Cdata); +decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_legacy_auth_resource(Cdata, _xmlns_attrs) -> + _els = encode_legacy_auth_resource_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"resource">>, _attrs, _els}. + +decode_legacy_auth_resource_cdata(__TopXMLNS, <<>>) -> + none; +decode_legacy_auth_resource_cdata(__TopXMLNS, _val) -> + _val. + +encode_legacy_auth_resource_cdata(none, _acc) -> _acc; +encode_legacy_auth_resource_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_legacy_auth_digest(__TopXMLNS, __IgnoreEls, + {xmlel, <<"digest">>, _attrs, _els}) -> + Cdata = decode_legacy_auth_digest_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_legacy_auth_digest_cdata(__TopXMLNS, Cdata); +decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_legacy_auth_digest(Cdata, _xmlns_attrs) -> + _els = encode_legacy_auth_digest_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"digest">>, _attrs, _els}. + +decode_legacy_auth_digest_cdata(__TopXMLNS, <<>>) -> + none; +decode_legacy_auth_digest_cdata(__TopXMLNS, _val) -> + _val. + +encode_legacy_auth_digest_cdata(none, _acc) -> _acc; +encode_legacy_auth_digest_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_legacy_auth_password(__TopXMLNS, __IgnoreEls, + {xmlel, <<"password">>, _attrs, _els}) -> + Cdata = decode_legacy_auth_password_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_legacy_auth_password_cdata(__TopXMLNS, Cdata); +decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_legacy_auth_password(Cdata, _xmlns_attrs) -> + _els = encode_legacy_auth_password_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"password">>, _attrs, _els}. + +decode_legacy_auth_password_cdata(__TopXMLNS, <<>>) -> + none; +decode_legacy_auth_password_cdata(__TopXMLNS, _val) -> + _val. + +encode_legacy_auth_password_cdata(none, _acc) -> _acc; +encode_legacy_auth_password_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_legacy_auth_username(__TopXMLNS, __IgnoreEls, + {xmlel, <<"username">>, _attrs, _els}) -> + Cdata = decode_legacy_auth_username_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_legacy_auth_username_cdata(__TopXMLNS, Cdata); +decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_legacy_auth_username(Cdata, _xmlns_attrs) -> + _els = encode_legacy_auth_username_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"username">>, _attrs, _els}. + +decode_legacy_auth_username_cdata(__TopXMLNS, <<>>) -> + none; +decode_legacy_auth_username_cdata(__TopXMLNS, _val) -> + _val. + +encode_legacy_auth_username_cdata(none, _acc) -> _acc; +encode_legacy_auth_username_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_bind(__TopXMLNS, __IgnoreEls, + {xmlel, <<"bind">>, _attrs, _els}) -> + {Jid, Resource} = decode_bind_els(__TopXMLNS, + __IgnoreEls, _els, undefined, undefined), + {bind, Jid, Resource}. + +decode_bind_els(__TopXMLNS, __IgnoreEls, [], Jid, + Resource) -> + {Jid, Resource}; +decode_bind_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jid, + Resource) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-bind">> -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, + decode_bind_jid(__TopXMLNS, __IgnoreEls, _el), + Resource); + <<"urn:ietf:params:xml:ns:xmpp-bind">> -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, + decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + __IgnoreEls, _el), + Resource); + _ -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, + Resource) + end; +decode_bind_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"resource">>, _attrs, _} = _el | _els], Jid, + Resource) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"urn:ietf:params:xml:ns:xmpp-bind">> -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, + decode_bind_resource(__TopXMLNS, __IgnoreEls, _el)); + <<"urn:ietf:params:xml:ns:xmpp-bind">> -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, + decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + __IgnoreEls, _el)); + _ -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, + Resource) + end; +decode_bind_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Jid, Resource) -> + decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, + Resource). + +encode_bind({bind, Jid, Resource}, _xmlns_attrs) -> + _els = lists:reverse('encode_bind_$jid'(Jid, + 'encode_bind_$resource'(Resource, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"bind">>, _attrs, _els}. + +'encode_bind_$jid'(undefined, _acc) -> _acc; +'encode_bind_$jid'(Jid, _acc) -> + [encode_bind_jid(Jid, []) | _acc]. + +'encode_bind_$resource'(undefined, _acc) -> _acc; +'encode_bind_$resource'(Resource, _acc) -> + [encode_bind_resource(Resource, []) | _acc]. + +decode_bind_resource(__TopXMLNS, __IgnoreEls, + {xmlel, <<"resource">>, _attrs, _els}) -> + Cdata = decode_bind_resource_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_bind_resource_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_bind_resource_cdata(__TopXMLNS, Cdata); +decode_bind_resource_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_bind_resource_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_bind_resource_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_bind_resource_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_bind_resource(Cdata, _xmlns_attrs) -> + _els = encode_bind_resource_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"resource">>, _attrs, _els}. + +decode_bind_resource_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_bind_resource_cdata(__TopXMLNS, _val) -> + case catch resourceprep(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"resource">>, __TopXMLNS}}); + _res -> _res + end. + +encode_bind_resource_cdata(undefined, _acc) -> _acc; +encode_bind_resource_cdata(_val, _acc) -> + [{xmlcdata, resourceprep(_val)} | _acc]. + +decode_bind_jid(__TopXMLNS, __IgnoreEls, + {xmlel, <<"jid">>, _attrs, _els}) -> + Cdata = decode_bind_jid_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_bind_jid_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_bind_jid_cdata(__TopXMLNS, Cdata); +decode_bind_jid_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_bind_jid_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_bind_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_bind_jid_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_bind_jid(Cdata, _xmlns_attrs) -> + _els = encode_bind_jid_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"jid">>, _attrs, _els}. + +decode_bind_jid_cdata(__TopXMLNS, <<>>) -> undefined; +decode_bind_jid_cdata(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"jid">>, __TopXMLNS}}); + _res -> _res + end. + +encode_bind_jid_cdata(undefined, _acc) -> _acc; +encode_bind_jid_cdata(_val, _acc) -> + [{xmlcdata, enc_jid(_val)} | _acc]. + +decode_error(__TopXMLNS, __IgnoreEls, + {xmlel, <<"error">>, _attrs, _els}) -> + {Text, Reason} = 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}. + +decode_error_els(__TopXMLNS, __IgnoreEls, [], Text, + Reason) -> + {Text, Reason}; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, + Reason) -> + 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); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"bad-request">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], Text, + Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"feature-not-implemented">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"forbidden">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"gone">>, _attrs, _} = _el | _els], Text, + Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"internal-server-error">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item-not-found">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"jid-malformed">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-acceptable">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-allowed">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"policy-violation">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"recipient-unavailable">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], Text, + Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"registration-required">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remote-server-not-found">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"remote-server-timeout">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"resource-constraint">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"service-unavailable">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscription-required">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"undefined-condition">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unexpected-request">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Text, Reason) -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason). + +decode_error_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], _Type, Code, By) -> + decode_error_attrs(__TopXMLNS, _attrs, _val, Code, By); +decode_error_attrs(__TopXMLNS, + [{<<"code">>, _val} | _attrs], Type, _Code, By) -> + decode_error_attrs(__TopXMLNS, _attrs, Type, _val, By); +decode_error_attrs(__TopXMLNS, + [{<<"by">>, _val} | _attrs], Type, Code, _By) -> + decode_error_attrs(__TopXMLNS, _attrs, Type, Code, + _val); +decode_error_attrs(__TopXMLNS, [_ | _attrs], Type, Code, + By) -> + decode_error_attrs(__TopXMLNS, _attrs, Type, Code, By); +decode_error_attrs(__TopXMLNS, [], Type, Code, By) -> + {decode_error_attr_type(__TopXMLNS, Type), + decode_error_attr_code(__TopXMLNS, Code), + decode_error_attr_by(__TopXMLNS, By)}. + +encode_error({error, Type, Code, By, Reason, Text}, + _xmlns_attrs) -> + _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, + _xmlns_attrs))), + {xmlel, <<"error">>, _attrs, _els}. + +'encode_error_$text'(undefined, _acc) -> _acc; +'encode_error_$text'(Text, _acc) -> + [encode_error_text(Text, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]. + +'encode_error_$reason'(undefined, _acc) -> _acc; +'encode_error_$reason'('bad-request' = Reason, _acc) -> + [encode_error_bad_request(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'(conflict = Reason, _acc) -> + [encode_error_conflict(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('feature-not-implemented' = + Reason, + _acc) -> + [encode_error_feature_not_implemented(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'(forbidden = Reason, _acc) -> + [encode_error_forbidden(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'({gone, _} = Reason, _acc) -> + [encode_error_gone(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('internal-server-error' = Reason, + _acc) -> + [encode_error_internal_server_error(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('item-not-found' = Reason, + _acc) -> + [encode_error_item_not_found(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('jid-malformed' = Reason, + _acc) -> + [encode_error_jid_malformed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('not-acceptable' = Reason, + _acc) -> + [encode_error_not_acceptable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('not-allowed' = Reason, _acc) -> + [encode_error_not_allowed(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('not-authorized' = Reason, + _acc) -> + [encode_error_not_authorized(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('policy-violation' = Reason, + _acc) -> + [encode_error_policy_violation(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('recipient-unavailable' = Reason, + _acc) -> + [encode_error_recipient_unavailable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'({redirect, _} = Reason, _acc) -> + [encode_error_redirect(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('registration-required' = Reason, + _acc) -> + [encode_error_registration_required(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('remote-server-not-found' = + Reason, + _acc) -> + [encode_error_remote_server_not_found(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('remote-server-timeout' = Reason, + _acc) -> + [encode_error_remote_server_timeout(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('resource-constraint' = Reason, + _acc) -> + [encode_error_resource_constraint(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('service-unavailable' = Reason, + _acc) -> + [encode_error_service_unavailable(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('subscription-required' = Reason, + _acc) -> + [encode_error_subscription_required(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('undefined-condition' = Reason, + _acc) -> + [encode_error_undefined_condition(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; +'encode_error_$reason'('unexpected-request' = Reason, + _acc) -> + [encode_error_unexpected_request(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]. + +decode_error_attr_type(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"error">>, __TopXMLNS}}); +decode_error_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [auth, cancel, continue, modify, wait]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"error">>, __TopXMLNS}}); + _res -> _res + end. + +encode_error_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_error_attr_code(__TopXMLNS, undefined) -> + undefined; +decode_error_attr_code(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"code">>, <<"error">>, __TopXMLNS}}); + _res -> _res + end. + +encode_error_attr_code(undefined, _acc) -> _acc; +encode_error_attr_code(_val, _acc) -> + [{<<"code">>, enc_int(_val)} | _acc]. + +decode_error_attr_by(__TopXMLNS, undefined) -> + undefined; +decode_error_attr_by(__TopXMLNS, _val) -> _val. + +encode_error_attr_by(undefined, _acc) -> _acc; +encode_error_attr_by(_val, _acc) -> + [{<<"by">>, _val} | _acc]. + +decode_error_text(__TopXMLNS, __IgnoreEls, + {xmlel, <<"text">>, _attrs, _els}) -> + Data = decode_error_text_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Lang = decode_error_text_attrs(__TopXMLNS, _attrs, + undefined), + {text, Lang, Data}. + +decode_error_text_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_error_text_cdata(__TopXMLNS, Data); +decode_error_text_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_error_text_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_error_text_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_error_text_els(__TopXMLNS, __IgnoreEls, _els, + Data). + +decode_error_text_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_error_text_attrs(__TopXMLNS, _attrs, _val); +decode_error_text_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_error_text_attrs(__TopXMLNS, _attrs, Lang); +decode_error_text_attrs(__TopXMLNS, [], Lang) -> + 'decode_error_text_attr_xml:lang'(__TopXMLNS, Lang). + +encode_error_text({text, Lang, Data}, _xmlns_attrs) -> + _els = encode_error_text_cdata(Data, []), + _attrs = 'encode_error_text_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"text">>, _attrs, _els}. + +'decode_error_text_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_error_text_attr_xml:lang'(__TopXMLNS, _val) -> + _val. + +'encode_error_text_attr_xml:lang'(undefined, _acc) -> + _acc; +'encode_error_text_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_error_text_cdata(__TopXMLNS, <<>>) -> undefined; +decode_error_text_cdata(__TopXMLNS, _val) -> _val. + +encode_error_text_cdata(undefined, _acc) -> _acc; +encode_error_text_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_error_unexpected_request(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unexpected-request">>, _attrs, + _els}) -> + 'unexpected-request'. + +encode_error_unexpected_request('unexpected-request', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unexpected-request">>, _attrs, _els}. + +decode_error_undefined_condition(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"undefined-condition">>, _attrs, + _els}) -> + 'undefined-condition'. + +encode_error_undefined_condition('undefined-condition', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"undefined-condition">>, _attrs, _els}. + +decode_error_subscription_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"subscription-required">>, _attrs, + _els}) -> + 'subscription-required'. + +encode_error_subscription_required('subscription-required', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"subscription-required">>, _attrs, _els}. + +decode_error_service_unavailable(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"service-unavailable">>, _attrs, + _els}) -> + 'service-unavailable'. + +encode_error_service_unavailable('service-unavailable', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"service-unavailable">>, _attrs, _els}. + +decode_error_resource_constraint(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"resource-constraint">>, _attrs, + _els}) -> + 'resource-constraint'. + +encode_error_resource_constraint('resource-constraint', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"resource-constraint">>, _attrs, _els}. + +decode_error_remote_server_timeout(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"remote-server-timeout">>, _attrs, + _els}) -> + 'remote-server-timeout'. + +encode_error_remote_server_timeout('remote-server-timeout', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"remote-server-timeout">>, _attrs, _els}. + +decode_error_remote_server_not_found(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"remote-server-not-found">>, + _attrs, _els}) -> + 'remote-server-not-found'. + +encode_error_remote_server_not_found('remote-server-not-found', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"remote-server-not-found">>, _attrs, _els}. + +decode_error_registration_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"registration-required">>, _attrs, + _els}) -> + 'registration-required'. + +encode_error_registration_required('registration-required', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"registration-required">>, _attrs, _els}. + +decode_error_redirect(__TopXMLNS, __IgnoreEls, + {xmlel, <<"redirect">>, _attrs, _els}) -> + Uri = decode_error_redirect_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {redirect, Uri}. + +decode_error_redirect_els(__TopXMLNS, __IgnoreEls, [], + Uri) -> + decode_error_redirect_cdata(__TopXMLNS, Uri); +decode_error_redirect_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Uri) -> + decode_error_redirect_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_error_redirect_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Uri) -> + decode_error_redirect_els(__TopXMLNS, __IgnoreEls, _els, + Uri). + +encode_error_redirect({redirect, Uri}, _xmlns_attrs) -> + _els = encode_error_redirect_cdata(Uri, []), + _attrs = _xmlns_attrs, + {xmlel, <<"redirect">>, _attrs, _els}. + +decode_error_redirect_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_error_redirect_cdata(__TopXMLNS, _val) -> _val. + +encode_error_redirect_cdata(undefined, _acc) -> _acc; +encode_error_redirect_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_error_recipient_unavailable(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"recipient-unavailable">>, _attrs, + _els}) -> + 'recipient-unavailable'. + +encode_error_recipient_unavailable('recipient-unavailable', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"recipient-unavailable">>, _attrs, _els}. + +decode_error_policy_violation(__TopXMLNS, __IgnoreEls, + {xmlel, <<"policy-violation">>, _attrs, _els}) -> + 'policy-violation'. + +encode_error_policy_violation('policy-violation', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"policy-violation">>, _attrs, _els}. + +decode_error_not_authorized(__TopXMLNS, __IgnoreEls, + {xmlel, <<"not-authorized">>, _attrs, _els}) -> + 'not-authorized'. + +encode_error_not_authorized('not-authorized', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-authorized">>, _attrs, _els}. + +decode_error_not_allowed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"not-allowed">>, _attrs, _els}) -> + 'not-allowed'. + +encode_error_not_allowed('not-allowed', _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-allowed">>, _attrs, _els}. + +decode_error_not_acceptable(__TopXMLNS, __IgnoreEls, + {xmlel, <<"not-acceptable">>, _attrs, _els}) -> + 'not-acceptable'. + +encode_error_not_acceptable('not-acceptable', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-acceptable">>, _attrs, _els}. + +decode_error_jid_malformed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"jid-malformed">>, _attrs, _els}) -> + 'jid-malformed'. + +encode_error_jid_malformed('jid-malformed', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"jid-malformed">>, _attrs, _els}. + +decode_error_item_not_found(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item-not-found">>, _attrs, _els}) -> + 'item-not-found'. + +encode_error_item_not_found('item-not-found', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"item-not-found">>, _attrs, _els}. + +decode_error_internal_server_error(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"internal-server-error">>, _attrs, + _els}) -> + 'internal-server-error'. + +encode_error_internal_server_error('internal-server-error', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"internal-server-error">>, _attrs, _els}. + +decode_error_gone(__TopXMLNS, __IgnoreEls, + {xmlel, <<"gone">>, _attrs, _els}) -> + Uri = decode_error_gone_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {gone, Uri}. + +decode_error_gone_els(__TopXMLNS, __IgnoreEls, [], + Uri) -> + decode_error_gone_cdata(__TopXMLNS, Uri); +decode_error_gone_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Uri) -> + decode_error_gone_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_error_gone_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Uri) -> + decode_error_gone_els(__TopXMLNS, __IgnoreEls, _els, + Uri). + +encode_error_gone({gone, Uri}, _xmlns_attrs) -> + _els = encode_error_gone_cdata(Uri, []), + _attrs = _xmlns_attrs, + {xmlel, <<"gone">>, _attrs, _els}. + +decode_error_gone_cdata(__TopXMLNS, <<>>) -> undefined; +decode_error_gone_cdata(__TopXMLNS, _val) -> _val. + +encode_error_gone_cdata(undefined, _acc) -> _acc; +encode_error_gone_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_error_forbidden(__TopXMLNS, __IgnoreEls, + {xmlel, <<"forbidden">>, _attrs, _els}) -> + forbidden. + +encode_error_forbidden(forbidden, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"forbidden">>, _attrs, _els}. + +decode_error_feature_not_implemented(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"feature-not-implemented">>, + _attrs, _els}) -> + 'feature-not-implemented'. + +encode_error_feature_not_implemented('feature-not-implemented', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"feature-not-implemented">>, _attrs, _els}. + +decode_error_conflict(__TopXMLNS, __IgnoreEls, + {xmlel, <<"conflict">>, _attrs, _els}) -> + conflict. + +encode_error_conflict(conflict, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"conflict">>, _attrs, _els}. + +decode_error_bad_request(__TopXMLNS, __IgnoreEls, + {xmlel, <<"bad-request">>, _attrs, _els}) -> + 'bad-request'. + +encode_error_bad_request('bad-request', _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"bad-request">>, _attrs, _els}. + +decode_presence(__TopXMLNS, __IgnoreEls, + {xmlel, <<"presence">>, _attrs, _els}) -> + {Error, Status, Show, Priority, __Els} = + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + undefined, [], 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}. + +decode_presence_els(__TopXMLNS, __IgnoreEls, [], Error, + Status, Show, Priority, __Els) -> + {Error, lists:reverse(Status), Show, Priority, + lists:reverse(__Els)}; +decode_presence_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"error">>, _attrs, _} = _el | _els], Error, + 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, + decode_presence_show(__TopXMLNS, __IgnoreEls, + _el), + Priority, __Els); + <<"jabber:client">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, + decode_presence_show(<<"jabber:client">>, + __IgnoreEls, _el), + Priority, __Els); + _ -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, __Els) + end; +decode_presence_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"status">>, _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, + [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) + end; +decode_presence_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"priority">>, _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, Show, + decode_presence_priority(__TopXMLNS, __IgnoreEls, + _el), + __Els); + <<"jabber:client">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, + decode_presence_priority(<<"jabber:client">>, + __IgnoreEls, _el), + __Els); + _ -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, __Els) + end; +decode_presence_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], Error, Status, Show, + Priority, __Els) -> + if __IgnoreEls -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, + [decode(_el) | __Els]); + false -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, __Els) + end + end; +decode_presence_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Error, Status, Show, Priority, __Els) -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Error, Status, Show, Priority, __Els). + +decode_presence_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, Type, From, To, + Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, _val, Type, + From, To, Lang); +decode_presence_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Id, _Type, From, To, + Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, Id, _val, + From, To, Lang); +decode_presence_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], Id, Type, _From, To, + Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, + _val, To, Lang); +decode_presence_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], Id, Type, From, _To, + Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, + From, _val, Lang); +decode_presence_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, + _Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, + From, To, _val); +decode_presence_attrs(__TopXMLNS, [_ | _attrs], Id, + Type, From, To, Lang) -> + decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, + From, To, Lang); +decode_presence_attrs(__TopXMLNS, [], Id, Type, From, + To, Lang) -> + {decode_presence_attr_id(__TopXMLNS, Id), + decode_presence_attr_type(__TopXMLNS, Type), + decode_presence_attr_from(__TopXMLNS, From), + decode_presence_attr_to(__TopXMLNS, To), + 'decode_presence_attr_xml:lang'(__TopXMLNS, Lang)}. + +encode_presence({presence, Id, Type, Lang, From, To, + Show, Status, Priority, Error, __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, + []))))), + _attrs = 'encode_presence_attr_xml:lang'(Lang, + encode_presence_attr_to(To, + encode_presence_attr_from(From, + encode_presence_attr_type(Type, + encode_presence_attr_id(Id, + _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, + [encode_presence_status(Status, []) | _acc]). + +'encode_presence_$show'(undefined, _acc) -> _acc; +'encode_presence_$show'(Show, _acc) -> + [encode_presence_show(Show, []) | _acc]. + +'encode_presence_$priority'(undefined, _acc) -> _acc; +'encode_presence_$priority'(Priority, _acc) -> + [encode_presence_priority(Priority, []) | _acc]. + +decode_presence_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_presence_attr_id(__TopXMLNS, _val) -> _val. + +encode_presence_attr_id(undefined, _acc) -> _acc; +encode_presence_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_presence_attr_type(__TopXMLNS, undefined) -> + available; +decode_presence_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [unavailable, subscribe, subscribed, unsubscribe, + unsubscribed, available, probe, error]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"presence">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_presence_attr_type(available, _acc) -> _acc; +encode_presence_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_presence_attr_from(__TopXMLNS, undefined) -> + undefined; +decode_presence_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"presence">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_presence_attr_from(undefined, _acc) -> _acc; +encode_presence_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_presence_attr_to(__TopXMLNS, undefined) -> + undefined; +decode_presence_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"presence">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_presence_attr_to(undefined, _acc) -> _acc; +encode_presence_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +'decode_presence_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_presence_attr_xml:lang'(__TopXMLNS, _val) -> + _val. + +'encode_presence_attr_xml:lang'(undefined, _acc) -> + _acc; +'encode_presence_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_presence_priority(__TopXMLNS, __IgnoreEls, + {xmlel, <<"priority">>, _attrs, _els}) -> + Cdata = decode_presence_priority_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_presence_priority_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_presence_priority_cdata(__TopXMLNS, Cdata); +decode_presence_priority_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_presence_priority_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_presence_priority_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_presence_priority_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_presence_priority(Cdata, _xmlns_attrs) -> + _els = encode_presence_priority_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"priority">>, _attrs, _els}. + +decode_presence_priority_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_presence_priority_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"priority">>, __TopXMLNS}}); + _res -> _res + end. + +encode_presence_priority_cdata(undefined, _acc) -> _acc; +encode_presence_priority_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_presence_status(__TopXMLNS, __IgnoreEls, + {xmlel, <<"status">>, _attrs, _els}) -> + Data = decode_presence_status_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Lang = decode_presence_status_attrs(__TopXMLNS, _attrs, + undefined), + {text, Lang, Data}. + +decode_presence_status_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_presence_status_cdata(__TopXMLNS, Data); +decode_presence_status_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_presence_status_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_presence_status_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_presence_status_els(__TopXMLNS, __IgnoreEls, + _els, Data). + +decode_presence_status_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_presence_status_attrs(__TopXMLNS, _attrs, _val); +decode_presence_status_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_presence_status_attrs(__TopXMLNS, _attrs, Lang); +decode_presence_status_attrs(__TopXMLNS, [], Lang) -> + 'decode_presence_status_attr_xml:lang'(__TopXMLNS, + Lang). + +encode_presence_status({text, Lang, Data}, + _xmlns_attrs) -> + _els = encode_presence_status_cdata(Data, []), + _attrs = 'encode_presence_status_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"status">>, _attrs, _els}. + +'decode_presence_status_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_presence_status_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_presence_status_attr_xml:lang'(undefined, + _acc) -> + _acc; +'encode_presence_status_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_presence_status_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_presence_status_cdata(__TopXMLNS, _val) -> _val. + +encode_presence_status_cdata(undefined, _acc) -> _acc; +encode_presence_status_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_presence_show(__TopXMLNS, __IgnoreEls, + {xmlel, <<"show">>, _attrs, _els}) -> + Cdata = decode_presence_show_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_presence_show_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_presence_show_cdata(__TopXMLNS, Cdata); +decode_presence_show_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_presence_show_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_presence_show_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_presence_show_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_presence_show(Cdata, _xmlns_attrs) -> + _els = encode_presence_show_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"show">>, _attrs, _els}. + +decode_presence_show_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_presence_show_cdata(__TopXMLNS, _val) -> + case catch dec_enum(_val, [away, chat, dnd, xa]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"show">>, __TopXMLNS}}); + _res -> _res + end. + +encode_presence_show_cdata(undefined, _acc) -> _acc; +encode_presence_show_cdata(_val, _acc) -> + [{xmlcdata, enc_enum(_val)} | _acc]. + +decode_message(__TopXMLNS, __IgnoreEls, + {xmlel, <<"message">>, _attrs, _els}) -> + {Error, Thread, Subject, Body, __Els} = + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + 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}. + +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, + [{xmlel, <<"error">>, _attrs, _} = _el | _els], Error, + 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, + Thread, + [decode_message_subject(<<"jabber:client">>, + __IgnoreEls, _el) + | Subject], + Body, __Els); + _ -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, __Els) + end; +decode_message_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"thread">>, _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, + decode_message_thread(__TopXMLNS, __IgnoreEls, + _el), + Subject, Body, __Els); + <<"jabber:client">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_thread(<<"jabber:client">>, + __IgnoreEls, _el), + Subject, Body, __Els); + _ -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, __Els) + end; +decode_message_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"body">>, _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, Subject, + [decode_message_body(__TopXMLNS, __IgnoreEls, _el) + | Body], + __Els); + <<"jabber:client">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, + [decode_message_body(<<"jabber:client">>, + __IgnoreEls, _el) + | Body], + __Els); + _ -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, __Els) + end; +decode_message_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], Error, Thread, Subject, + Body, __Els) -> + if __IgnoreEls -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, + [decode(_el) | __Els]); + false -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + 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_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, Type, From, To, + Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, _val, Type, + From, To, Lang); +decode_message_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Id, _Type, From, To, + Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, Id, _val, From, + To, Lang); +decode_message_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], Id, Type, _From, To, + Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, Id, Type, _val, + To, Lang); +decode_message_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], Id, Type, From, _To, + Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, + _val, Lang); +decode_message_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, + _Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, + To, _val); +decode_message_attrs(__TopXMLNS, [_ | _attrs], Id, Type, + From, To, Lang) -> + decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, + To, Lang); +decode_message_attrs(__TopXMLNS, [], Id, Type, From, To, + Lang) -> + {decode_message_attr_id(__TopXMLNS, Id), + decode_message_attr_type(__TopXMLNS, Type), + decode_message_attr_from(__TopXMLNS, From), + decode_message_attr_to(__TopXMLNS, To), + 'decode_message_attr_xml:lang'(__TopXMLNS, Lang)}. + +encode_message({message, Id, Type, Lang, From, To, + Subject, Body, Thread, Error, __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, + []))))), + _attrs = 'encode_message_attr_xml:lang'(Lang, + encode_message_attr_to(To, + encode_message_attr_from(From, + encode_message_attr_type(Type, + encode_message_attr_id(Id, + _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]. + +'encode_message_$subject'([], _acc) -> _acc; +'encode_message_$subject'([Subject | _els], _acc) -> + 'encode_message_$subject'(_els, + [encode_message_subject(Subject, []) | _acc]). + +'encode_message_$body'([], _acc) -> _acc; +'encode_message_$body'([Body | _els], _acc) -> + 'encode_message_$body'(_els, + [encode_message_body(Body, []) | _acc]). + +decode_message_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_message_attr_id(__TopXMLNS, _val) -> _val. + +encode_message_attr_id(undefined, _acc) -> _acc; +encode_message_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_message_attr_type(__TopXMLNS, undefined) -> + normal; +decode_message_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [chat, normal, groupchat, headline, error]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"message">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_message_attr_type(normal, _acc) -> _acc; +encode_message_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_message_attr_from(__TopXMLNS, undefined) -> + undefined; +decode_message_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"message">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_message_attr_from(undefined, _acc) -> _acc; +encode_message_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_message_attr_to(__TopXMLNS, undefined) -> + undefined; +decode_message_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"message">>, __TopXMLNS}}); + _res -> _res + end. + +encode_message_attr_to(undefined, _acc) -> _acc; +encode_message_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +'decode_message_attr_xml:lang'(__TopXMLNS, undefined) -> + undefined; +'decode_message_attr_xml:lang'(__TopXMLNS, _val) -> + _val. + +'encode_message_attr_xml:lang'(undefined, _acc) -> _acc; +'encode_message_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_message_thread(__TopXMLNS, __IgnoreEls, + {xmlel, <<"thread">>, _attrs, _els}) -> + Cdata = decode_message_thread_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_message_thread_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_message_thread_cdata(__TopXMLNS, Cdata); +decode_message_thread_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_message_thread_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_message_thread_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_message_thread_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_message_thread(Cdata, _xmlns_attrs) -> + _els = encode_message_thread_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"thread">>, _attrs, _els}. + +decode_message_thread_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_message_thread_cdata(__TopXMLNS, _val) -> _val. + +encode_message_thread_cdata(undefined, _acc) -> _acc; +encode_message_thread_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_message_body(__TopXMLNS, __IgnoreEls, + {xmlel, <<"body">>, _attrs, _els}) -> + Data = decode_message_body_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Lang = decode_message_body_attrs(__TopXMLNS, _attrs, + undefined), + {text, Lang, Data}. + +decode_message_body_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_message_body_cdata(__TopXMLNS, Data); +decode_message_body_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_message_body_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_message_body_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_message_body_els(__TopXMLNS, __IgnoreEls, _els, + Data). + +decode_message_body_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_message_body_attrs(__TopXMLNS, _attrs, _val); +decode_message_body_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_message_body_attrs(__TopXMLNS, _attrs, Lang); +decode_message_body_attrs(__TopXMLNS, [], Lang) -> + 'decode_message_body_attr_xml:lang'(__TopXMLNS, Lang). + +encode_message_body({text, Lang, Data}, _xmlns_attrs) -> + _els = encode_message_body_cdata(Data, []), + _attrs = 'encode_message_body_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"body">>, _attrs, _els}. + +'decode_message_body_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_message_body_attr_xml:lang'(__TopXMLNS, _val) -> + _val. + +'encode_message_body_attr_xml:lang'(undefined, _acc) -> + _acc; +'encode_message_body_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_message_body_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_message_body_cdata(__TopXMLNS, _val) -> _val. + +encode_message_body_cdata(undefined, _acc) -> _acc; +encode_message_body_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_message_subject(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subject">>, _attrs, _els}) -> + Data = decode_message_subject_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Lang = decode_message_subject_attrs(__TopXMLNS, _attrs, + undefined), + {text, Lang, Data}. + +decode_message_subject_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_message_subject_cdata(__TopXMLNS, Data); +decode_message_subject_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_message_subject_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_message_subject_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_message_subject_els(__TopXMLNS, __IgnoreEls, + _els, Data). + +decode_message_subject_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], _Lang) -> + decode_message_subject_attrs(__TopXMLNS, _attrs, _val); +decode_message_subject_attrs(__TopXMLNS, [_ | _attrs], + Lang) -> + decode_message_subject_attrs(__TopXMLNS, _attrs, Lang); +decode_message_subject_attrs(__TopXMLNS, [], Lang) -> + 'decode_message_subject_attr_xml:lang'(__TopXMLNS, + Lang). + +encode_message_subject({text, Lang, Data}, + _xmlns_attrs) -> + _els = encode_message_subject_cdata(Data, []), + _attrs = 'encode_message_subject_attr_xml:lang'(Lang, + _xmlns_attrs), + {xmlel, <<"subject">>, _attrs, _els}. + +'decode_message_subject_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_message_subject_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_message_subject_attr_xml:lang'(undefined, + _acc) -> + _acc; +'encode_message_subject_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_message_subject_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_message_subject_cdata(__TopXMLNS, _val) -> _val. + +encode_message_subject_cdata(undefined, _acc) -> _acc; +encode_message_subject_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_iq(__TopXMLNS, __IgnoreEls, + {xmlel, <<"iq">>, _attrs, _els}) -> + {Error, __Els} = decode_iq_els(__TopXMLNS, __IgnoreEls, + _els, undefined, []), + {Id, Type, From, To, Lang} = decode_iq_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined, undefined, + undefined), + {iq, Id, Type, Lang, From, To, Error, __Els}. + +decode_iq_els(__TopXMLNS, __IgnoreEls, [], Error, + __Els) -> + {Error, 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) -> + if __IgnoreEls -> + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + [decode(_el) | __Els]); + false -> + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + __Els) + end + end; +decode_iq_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Error, __Els) -> + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + __Els). + +decode_iq_attrs(__TopXMLNS, [{<<"id">>, _val} | _attrs], + _Id, Type, From, To, Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, _val, Type, From, + To, Lang); +decode_iq_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Id, _Type, From, To, + Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, Id, _val, From, To, + Lang); +decode_iq_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], Id, Type, _From, To, + Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, _val, To, + Lang); +decode_iq_attrs(__TopXMLNS, [{<<"to">>, _val} | _attrs], + Id, Type, From, _To, Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, + _val, Lang); +decode_iq_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, + _Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, To, + _val); +decode_iq_attrs(__TopXMLNS, [_ | _attrs], Id, Type, + From, To, Lang) -> + decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, To, + Lang); +decode_iq_attrs(__TopXMLNS, [], Id, Type, From, To, + Lang) -> + {decode_iq_attr_id(__TopXMLNS, Id), + decode_iq_attr_type(__TopXMLNS, Type), + decode_iq_attr_from(__TopXMLNS, From), + decode_iq_attr_to(__TopXMLNS, To), + 'decode_iq_attr_xml:lang'(__TopXMLNS, Lang)}. + +encode_iq({iq, Id, Type, Lang, From, To, Error, __Els}, + _xmlns_attrs) -> + _els = [encode(_el) || _el <- __Els] ++ + lists:reverse('encode_iq_$error'(Error, [])), + _attrs = 'encode_iq_attr_xml:lang'(Lang, + encode_iq_attr_to(To, + encode_iq_attr_from(From, + encode_iq_attr_type(Type, + encode_iq_attr_id(Id, + _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}}); +decode_iq_attr_id(__TopXMLNS, _val) -> _val. + +encode_iq_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_iq_attr_type(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"iq">>, __TopXMLNS}}); +decode_iq_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, [get, set, result, error]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"iq">>, __TopXMLNS}}); + _res -> _res + end. + +encode_iq_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_iq_attr_from(__TopXMLNS, undefined) -> undefined; +decode_iq_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"iq">>, __TopXMLNS}}); + _res -> _res + end. + +encode_iq_attr_from(undefined, _acc) -> _acc; +encode_iq_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_iq_attr_to(__TopXMLNS, undefined) -> undefined; +decode_iq_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"iq">>, __TopXMLNS}}); + _res -> _res + end. + +encode_iq_attr_to(undefined, _acc) -> _acc; +encode_iq_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +'decode_iq_attr_xml:lang'(__TopXMLNS, undefined) -> + undefined; +'decode_iq_attr_xml:lang'(__TopXMLNS, _val) -> _val. + +'encode_iq_attr_xml:lang'(undefined, _acc) -> _acc; +'encode_iq_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_stats(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + Stat = decode_stats_els(__TopXMLNS, __IgnoreEls, _els, + []), + {stats, Stat}. + +decode_stats_els(__TopXMLNS, __IgnoreEls, [], Stat) -> + lists:reverse(Stat); +decode_stats_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"stat">>, _attrs, _} = _el | _els], Stat) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/stats">> -> + decode_stats_els(__TopXMLNS, __IgnoreEls, _els, + [decode_stat(__TopXMLNS, __IgnoreEls, _el) | Stat]); + <<"http://jabber.org/protocol/stats">> -> + decode_stats_els(__TopXMLNS, __IgnoreEls, _els, + [decode_stat(<<"http://jabber.org/protocol/stats">>, + __IgnoreEls, _el) + | Stat]); + _ -> + decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat) + end; +decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Stat) -> + decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat). + +encode_stats({stats, Stat}, _xmlns_attrs) -> + _els = lists:reverse('encode_stats_$stat'(Stat, [])), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_stats_$stat'([], _acc) -> _acc; +'encode_stats_$stat'([Stat | _els], _acc) -> + 'encode_stats_$stat'(_els, + [encode_stat(Stat, []) | _acc]). + +decode_stat(__TopXMLNS, __IgnoreEls, + {xmlel, <<"stat">>, _attrs, _els}) -> + Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els, + []), + {Name, Units, Value} = decode_stat_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {stat, Name, Units, Value, Error}. + +decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) -> + lists:reverse(Error); +decode_stat_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"error">>, _attrs, _} = _el | _els], + Error) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/stats">> -> + decode_stat_els(__TopXMLNS, __IgnoreEls, _els, + [decode_stat_error(__TopXMLNS, __IgnoreEls, _el) + | Error]); + <<"http://jabber.org/protocol/stats">> -> + decode_stat_els(__TopXMLNS, __IgnoreEls, _els, + [decode_stat_error(<<"http://jabber.org/protocol/stats">>, + __IgnoreEls, _el) + | Error]); + _ -> + decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error) + end; +decode_stat_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Error) -> + decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error). + +decode_stat_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name, Units, Value) -> + decode_stat_attrs(__TopXMLNS, _attrs, _val, Units, + Value); +decode_stat_attrs(__TopXMLNS, + [{<<"units">>, _val} | _attrs], Name, _Units, Value) -> + decode_stat_attrs(__TopXMLNS, _attrs, Name, _val, + Value); +decode_stat_attrs(__TopXMLNS, + [{<<"value">>, _val} | _attrs], Name, Units, _Value) -> + decode_stat_attrs(__TopXMLNS, _attrs, Name, Units, + _val); +decode_stat_attrs(__TopXMLNS, [_ | _attrs], Name, Units, + Value) -> + decode_stat_attrs(__TopXMLNS, _attrs, Name, Units, + Value); +decode_stat_attrs(__TopXMLNS, [], Name, Units, Value) -> + {decode_stat_attr_name(__TopXMLNS, Name), + decode_stat_attr_units(__TopXMLNS, Units), + decode_stat_attr_value(__TopXMLNS, Value)}. + +encode_stat({stat, Name, Units, Value, Error}, + _xmlns_attrs) -> + _els = lists:reverse('encode_stat_$error'(Error, [])), + _attrs = encode_stat_attr_value(Value, + encode_stat_attr_units(Units, + encode_stat_attr_name(Name, + _xmlns_attrs))), + {xmlel, <<"stat">>, _attrs, _els}. + +'encode_stat_$error'([], _acc) -> _acc; +'encode_stat_$error'([Error | _els], _acc) -> + 'encode_stat_$error'(_els, + [encode_stat_error(Error, []) | _acc]). + +decode_stat_attr_name(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"stat">>, __TopXMLNS}}); +decode_stat_attr_name(__TopXMLNS, _val) -> _val. + +encode_stat_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_stat_attr_units(__TopXMLNS, undefined) -> + undefined; +decode_stat_attr_units(__TopXMLNS, _val) -> _val. + +encode_stat_attr_units(undefined, _acc) -> _acc; +encode_stat_attr_units(_val, _acc) -> + [{<<"units">>, _val} | _acc]. + +decode_stat_attr_value(__TopXMLNS, undefined) -> + undefined; +decode_stat_attr_value(__TopXMLNS, _val) -> _val. + +encode_stat_attr_value(undefined, _acc) -> _acc; +encode_stat_attr_value(_val, _acc) -> + [{<<"value">>, _val} | _acc]. + +decode_stat_error(__TopXMLNS, __IgnoreEls, + {xmlel, <<"error">>, _attrs, _els}) -> + Cdata = decode_stat_error_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Code = decode_stat_error_attrs(__TopXMLNS, _attrs, + undefined), + {Code, Cdata}. + +decode_stat_error_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_stat_error_cdata(__TopXMLNS, Cdata); +decode_stat_error_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_stat_error_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +decode_stat_error_attrs(__TopXMLNS, + [{<<"code">>, _val} | _attrs], _Code) -> + decode_stat_error_attrs(__TopXMLNS, _attrs, _val); +decode_stat_error_attrs(__TopXMLNS, [_ | _attrs], + Code) -> + decode_stat_error_attrs(__TopXMLNS, _attrs, Code); +decode_stat_error_attrs(__TopXMLNS, [], Code) -> + decode_stat_error_attr_code(__TopXMLNS, Code). + +encode_stat_error({Code, Cdata}, _xmlns_attrs) -> + _els = encode_stat_error_cdata(Cdata, []), + _attrs = encode_stat_error_attr_code(Code, + _xmlns_attrs), + {xmlel, <<"error">>, _attrs, _els}. + +decode_stat_error_attr_code(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"code">>, <<"error">>, __TopXMLNS}}); +decode_stat_error_attr_code(__TopXMLNS, _val) -> + case catch dec_int(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"code">>, <<"error">>, __TopXMLNS}}); + _res -> _res + end. + +encode_stat_error_attr_code(_val, _acc) -> + [{<<"code">>, enc_int(_val)} | _acc]. + +decode_stat_error_cdata(__TopXMLNS, <<>>) -> undefined; +decode_stat_error_cdata(__TopXMLNS, _val) -> _val. + +encode_stat_error_cdata(undefined, _acc) -> _acc; +encode_stat_error_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_bookmarks_storage(__TopXMLNS, __IgnoreEls, + {xmlel, <<"storage">>, _attrs, _els}) -> + {Conference, Url} = + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, [], []), + {bookmark_storage, Conference, Url}. + +decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + [], Conference, Url) -> + {lists:reverse(Conference), lists:reverse(Url)}; +decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"conference">>, _attrs, _} = _el + | _els], + Conference, Url) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_bookmark_conference(__TopXMLNS, + __IgnoreEls, + _el) + | Conference], + Url); + <<"storage:bookmarks">> -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_bookmark_conference(<<"storage:bookmarks">>, + __IgnoreEls, + _el) + | Conference], + Url); + _ -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, Conference, Url) + end; +decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"url">>, _attrs, _} = _el | _els], + Conference, Url) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, Conference, + [decode_bookmark_url(__TopXMLNS, + __IgnoreEls, _el) + | Url]); + <<"storage:bookmarks">> -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, Conference, + [decode_bookmark_url(<<"storage:bookmarks">>, + __IgnoreEls, _el) + | Url]); + _ -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, Conference, Url) + end; +decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Conference, Url) -> + decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, + _els, Conference, Url). + +encode_bookmarks_storage({bookmark_storage, Conference, + Url}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_bookmarks_storage_$conference'(Conference, + 'encode_bookmarks_storage_$url'(Url, + []))), + _attrs = _xmlns_attrs, + {xmlel, <<"storage">>, _attrs, _els}. + +'encode_bookmarks_storage_$conference'([], _acc) -> + _acc; +'encode_bookmarks_storage_$conference'([Conference + | _els], + _acc) -> + 'encode_bookmarks_storage_$conference'(_els, + [encode_bookmark_conference(Conference, + []) + | _acc]). + +'encode_bookmarks_storage_$url'([], _acc) -> _acc; +'encode_bookmarks_storage_$url'([Url | _els], _acc) -> + 'encode_bookmarks_storage_$url'(_els, + [encode_bookmark_url(Url, []) | _acc]). + +decode_bookmark_url(__TopXMLNS, __IgnoreEls, + {xmlel, <<"url">>, _attrs, _els}) -> + {Name, Url} = decode_bookmark_url_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {bookmark_url, Name, Url}. + +decode_bookmark_url_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name, Url) -> + decode_bookmark_url_attrs(__TopXMLNS, _attrs, _val, + Url); +decode_bookmark_url_attrs(__TopXMLNS, + [{<<"url">>, _val} | _attrs], Name, _Url) -> + decode_bookmark_url_attrs(__TopXMLNS, _attrs, Name, + _val); +decode_bookmark_url_attrs(__TopXMLNS, [_ | _attrs], + Name, Url) -> + decode_bookmark_url_attrs(__TopXMLNS, _attrs, Name, + Url); +decode_bookmark_url_attrs(__TopXMLNS, [], Name, Url) -> + {decode_bookmark_url_attr_name(__TopXMLNS, Name), + decode_bookmark_url_attr_url(__TopXMLNS, Url)}. + +encode_bookmark_url({bookmark_url, Name, Url}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_bookmark_url_attr_url(Url, + encode_bookmark_url_attr_name(Name, + _xmlns_attrs)), + {xmlel, <<"url">>, _attrs, _els}. + +decode_bookmark_url_attr_name(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"url">>, __TopXMLNS}}); +decode_bookmark_url_attr_name(__TopXMLNS, _val) -> _val. + +encode_bookmark_url_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_bookmark_url_attr_url(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"url">>, <<"url">>, __TopXMLNS}}); +decode_bookmark_url_attr_url(__TopXMLNS, _val) -> _val. + +encode_bookmark_url_attr_url(_val, _acc) -> + [{<<"url">>, _val} | _acc]. + +decode_bookmark_conference(__TopXMLNS, __IgnoreEls, + {xmlel, <<"conference">>, _attrs, _els}) -> + {Password, Nick} = + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, undefined, undefined), + {Name, Jid, Autojoin} = + decode_bookmark_conference_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined), + {bookmark_conference, Name, Jid, Autojoin, Nick, + Password}. + +decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + [], Password, Nick) -> + {Password, Nick}; +decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"nick">>, _attrs, _} = _el | _els], + Password, Nick) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, Password, + decode_conference_nick(__TopXMLNS, + __IgnoreEls, + _el)); + <<"storage:bookmarks">> -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, Password, + decode_conference_nick(<<"storage:bookmarks">>, + __IgnoreEls, + _el)); + _ -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, Password, Nick) + end; +decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el + | _els], + Password, Nick) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, + decode_conference_password(__TopXMLNS, + __IgnoreEls, + _el), + Nick); + <<"storage:bookmarks">> -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, + decode_conference_password(<<"storage:bookmarks">>, + __IgnoreEls, + _el), + Nick); + _ -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, Password, Nick) + end; +decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Password, Nick) -> + decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, + _els, Password, Nick). + +decode_bookmark_conference_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name, Jid, + Autojoin) -> + decode_bookmark_conference_attrs(__TopXMLNS, _attrs, + _val, Jid, Autojoin); +decode_bookmark_conference_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Name, _Jid, + Autojoin) -> + decode_bookmark_conference_attrs(__TopXMLNS, _attrs, + Name, _val, Autojoin); +decode_bookmark_conference_attrs(__TopXMLNS, + [{<<"autojoin">>, _val} | _attrs], Name, Jid, + _Autojoin) -> + decode_bookmark_conference_attrs(__TopXMLNS, _attrs, + Name, Jid, _val); +decode_bookmark_conference_attrs(__TopXMLNS, + [_ | _attrs], Name, Jid, Autojoin) -> + decode_bookmark_conference_attrs(__TopXMLNS, _attrs, + Name, Jid, Autojoin); +decode_bookmark_conference_attrs(__TopXMLNS, [], Name, + Jid, Autojoin) -> + {decode_bookmark_conference_attr_name(__TopXMLNS, Name), + decode_bookmark_conference_attr_jid(__TopXMLNS, Jid), + decode_bookmark_conference_attr_autojoin(__TopXMLNS, + Autojoin)}. + +encode_bookmark_conference({bookmark_conference, Name, + Jid, Autojoin, Nick, Password}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_bookmark_conference_$password'(Password, + 'encode_bookmark_conference_$nick'(Nick, + []))), + _attrs = + encode_bookmark_conference_attr_autojoin(Autojoin, + encode_bookmark_conference_attr_jid(Jid, + encode_bookmark_conference_attr_name(Name, + _xmlns_attrs))), + {xmlel, <<"conference">>, _attrs, _els}. + +'encode_bookmark_conference_$password'(undefined, + _acc) -> + _acc; +'encode_bookmark_conference_$password'(Password, + _acc) -> + [encode_conference_password(Password, []) | _acc]. + +'encode_bookmark_conference_$nick'(undefined, _acc) -> + _acc; +'encode_bookmark_conference_$nick'(Nick, _acc) -> + [encode_conference_nick(Nick, []) | _acc]. + +decode_bookmark_conference_attr_name(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"conference">>, + __TopXMLNS}}); +decode_bookmark_conference_attr_name(__TopXMLNS, + _val) -> + _val. + +encode_bookmark_conference_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_bookmark_conference_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"conference">>, + __TopXMLNS}}); +decode_bookmark_conference_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"conference">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_bookmark_conference_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_bookmark_conference_attr_autojoin(__TopXMLNS, + undefined) -> + false; +decode_bookmark_conference_attr_autojoin(__TopXMLNS, + _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"autojoin">>, <<"conference">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_bookmark_conference_attr_autojoin(false, _acc) -> + _acc; +encode_bookmark_conference_attr_autojoin(_val, _acc) -> + [{<<"autojoin">>, enc_bool(_val)} | _acc]. + +decode_conference_password(__TopXMLNS, __IgnoreEls, + {xmlel, <<"password">>, _attrs, _els}) -> + Cdata = decode_conference_password_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_conference_password_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_conference_password_cdata(__TopXMLNS, Cdata); +decode_conference_password_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_conference_password_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_conference_password_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_conference_password_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_conference_password(Cdata, _xmlns_attrs) -> + _els = encode_conference_password_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"password">>, _attrs, _els}. + +decode_conference_password_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_conference_password_cdata(__TopXMLNS, _val) -> + _val. + +encode_conference_password_cdata(undefined, _acc) -> + _acc; +encode_conference_password_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_conference_nick(__TopXMLNS, __IgnoreEls, + {xmlel, <<"nick">>, _attrs, _els}) -> + Cdata = decode_conference_nick_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_conference_nick_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_conference_nick_cdata(__TopXMLNS, Cdata); +decode_conference_nick_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_conference_nick_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_conference_nick_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_conference_nick_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_conference_nick(Cdata, _xmlns_attrs) -> + _els = encode_conference_nick_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"nick">>, _attrs, _els}. + +decode_conference_nick_cdata(__TopXMLNS, <<>>) -> + undefined; +decode_conference_nick_cdata(__TopXMLNS, _val) -> _val. + +encode_conference_nick_cdata(undefined, _acc) -> _acc; +encode_conference_nick_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_private(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + __Xmls = decode_private_els(__TopXMLNS, __IgnoreEls, + _els, []), + {private, __Xmls}. + +decode_private_els(__TopXMLNS, __IgnoreEls, [], + __Xmls) -> + lists:reverse(__Xmls); +decode_private_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], __Xmls) -> + decode_private_els(__TopXMLNS, __IgnoreEls, _els, + [_el | __Xmls]); +decode_private_els(__TopXMLNS, __IgnoreEls, [_ | _els], + __Xmls) -> + decode_private_els(__TopXMLNS, __IgnoreEls, _els, + __Xmls). + +encode_private({private, __Xmls}, _xmlns_attrs) -> + _els = __Xmls, + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +decode_disco_items(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + Items = decode_disco_items_els(__TopXMLNS, __IgnoreEls, + _els, []), + Node = decode_disco_items_attrs(__TopXMLNS, _attrs, + undefined), + {disco_items, Node, Items}. + +decode_disco_items_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_disco_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/disco#items">> -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + [decode_disco_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"http://jabber.org/protocol/disco#items">> -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + [decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_disco_items_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_disco_items_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_disco_items_attrs(__TopXMLNS, _attrs, _val); +decode_disco_items_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_disco_items_attrs(__TopXMLNS, _attrs, Node); +decode_disco_items_attrs(__TopXMLNS, [], Node) -> + decode_disco_items_attr_node(__TopXMLNS, Node). + +encode_disco_items({disco_items, Node, Items}, + _xmlns_attrs) -> + _els = lists:reverse('encode_disco_items_$items'(Items, + [])), + _attrs = encode_disco_items_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"query">>, _attrs, _els}. + +'encode_disco_items_$items'([], _acc) -> _acc; +'encode_disco_items_$items'([Items | _els], _acc) -> + 'encode_disco_items_$items'(_els, + [encode_disco_item(Items, []) | _acc]). + +decode_disco_items_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_disco_items_attr_node(__TopXMLNS, _val) -> _val. + +encode_disco_items_attr_node(undefined, _acc) -> _acc; +encode_disco_items_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_disco_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Jid, Name, Node} = decode_disco_item_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {disco_item, Jid, Name, Node}. + +decode_disco_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Name, Node) -> + decode_disco_item_attrs(__TopXMLNS, _attrs, _val, Name, + Node); +decode_disco_item_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], Jid, _Name, Node) -> + decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, _val, + Node); +decode_disco_item_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Jid, Name, _Node) -> + decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, Name, + _val); +decode_disco_item_attrs(__TopXMLNS, [_ | _attrs], Jid, + Name, Node) -> + decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, Name, + Node); +decode_disco_item_attrs(__TopXMLNS, [], Jid, Name, + Node) -> + {decode_disco_item_attr_jid(__TopXMLNS, Jid), + decode_disco_item_attr_name(__TopXMLNS, Name), + decode_disco_item_attr_node(__TopXMLNS, Node)}. + +encode_disco_item({disco_item, Jid, Name, Node}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_disco_item_attr_node(Node, + encode_disco_item_attr_name(Name, + encode_disco_item_attr_jid(Jid, + _xmlns_attrs))), + {xmlel, <<"item">>, _attrs, _els}. + +decode_disco_item_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); +decode_disco_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_disco_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_disco_item_attr_name(__TopXMLNS, undefined) -> + undefined; +decode_disco_item_attr_name(__TopXMLNS, _val) -> _val. + +encode_disco_item_attr_name(undefined, _acc) -> _acc; +encode_disco_item_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_disco_item_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_disco_item_attr_node(__TopXMLNS, _val) -> _val. + +encode_disco_item_attr_node(undefined, _acc) -> _acc; +encode_disco_item_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_disco_info(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Xdata, Features, Identities} = + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, [], + [], []), + Node = decode_disco_info_attrs(__TopXMLNS, _attrs, + undefined), + {disco_info, Node, Identities, Features, Xdata}. + +decode_disco_info_els(__TopXMLNS, __IgnoreEls, [], + Xdata, Features, Identities) -> + {lists:reverse(Xdata), lists:reverse(Features), + lists:reverse(Identities)}; +decode_disco_info_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"identity">>, _attrs, _} = _el | _els], + Xdata, Features, Identities) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/disco#info">> -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, + [decode_disco_identity(__TopXMLNS, __IgnoreEls, + _el) + | Identities]); + <<"http://jabber.org/protocol/disco#info">> -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, + [decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, + __IgnoreEls, _el) + | Identities]); + _ -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, Identities) + end; +decode_disco_info_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"feature">>, _attrs, _} = _el | _els], Xdata, + Features, Identities) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/disco#info">> -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + [decode_disco_feature(__TopXMLNS, __IgnoreEls, + _el) + | Features], + Identities); + <<"http://jabber.org/protocol/disco#info">> -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + [decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, + __IgnoreEls, _el) + | Features], + Identities); + _ -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, Identities) + end; +decode_disco_info_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, + Features, Identities) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + [decode_xdata(<<"jabber:x:data">>, __IgnoreEls, + _el) + | Xdata], + Features, Identities); + _ -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, Identities) + end; +decode_disco_info_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Xdata, Features, Identities) -> + decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Features, Identities). + +decode_disco_info_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_disco_info_attrs(__TopXMLNS, _attrs, _val); +decode_disco_info_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_disco_info_attrs(__TopXMLNS, _attrs, Node); +decode_disco_info_attrs(__TopXMLNS, [], Node) -> + decode_disco_info_attr_node(__TopXMLNS, Node). + +encode_disco_info({disco_info, Node, Identities, + Features, Xdata}, + _xmlns_attrs) -> + _els = lists:reverse('encode_disco_info_$xdata'(Xdata, + 'encode_disco_info_$features'(Features, + 'encode_disco_info_$identities'(Identities, + [])))), + _attrs = encode_disco_info_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"query">>, _attrs, _els}. + +'encode_disco_info_$xdata'([], _acc) -> _acc; +'encode_disco_info_$xdata'([Xdata | _els], _acc) -> + 'encode_disco_info_$xdata'(_els, + [encode_xdata(Xdata, + [{<<"xmlns">>, + <<"jabber:x:data">>}]) + | _acc]). + +'encode_disco_info_$features'([], _acc) -> _acc; +'encode_disco_info_$features'([Features | _els], + _acc) -> + 'encode_disco_info_$features'(_els, + [encode_disco_feature(Features, []) | _acc]). + +'encode_disco_info_$identities'([], _acc) -> _acc; +'encode_disco_info_$identities'([Identities | _els], + _acc) -> + 'encode_disco_info_$identities'(_els, + [encode_disco_identity(Identities, []) + | _acc]). + +decode_disco_info_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_disco_info_attr_node(__TopXMLNS, _val) -> _val. + +encode_disco_info_attr_node(undefined, _acc) -> _acc; +encode_disco_info_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_disco_feature(__TopXMLNS, __IgnoreEls, + {xmlel, <<"feature">>, _attrs, _els}) -> + Var = decode_disco_feature_attrs(__TopXMLNS, _attrs, + undefined), + Var. + +decode_disco_feature_attrs(__TopXMLNS, + [{<<"var">>, _val} | _attrs], _Var) -> + decode_disco_feature_attrs(__TopXMLNS, _attrs, _val); +decode_disco_feature_attrs(__TopXMLNS, [_ | _attrs], + Var) -> + decode_disco_feature_attrs(__TopXMLNS, _attrs, Var); +decode_disco_feature_attrs(__TopXMLNS, [], Var) -> + decode_disco_feature_attr_var(__TopXMLNS, Var). + +encode_disco_feature(Var, _xmlns_attrs) -> + _els = [], + _attrs = encode_disco_feature_attr_var(Var, + _xmlns_attrs), + {xmlel, <<"feature">>, _attrs, _els}. + +decode_disco_feature_attr_var(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"var">>, <<"feature">>, __TopXMLNS}}); +decode_disco_feature_attr_var(__TopXMLNS, _val) -> _val. + +encode_disco_feature_attr_var(_val, _acc) -> + [{<<"var">>, _val} | _acc]. + +decode_disco_identity(__TopXMLNS, __IgnoreEls, + {xmlel, <<"identity">>, _attrs, _els}) -> + {Category, Type, Lang, Name} = + decode_disco_identity_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, undefined), + {identity, Category, Type, Lang, Name}. + +decode_disco_identity_attrs(__TopXMLNS, + [{<<"category">>, _val} | _attrs], _Category, Type, + Lang, Name) -> + decode_disco_identity_attrs(__TopXMLNS, _attrs, _val, + Type, Lang, Name); +decode_disco_identity_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Category, _Type, + Lang, Name) -> + decode_disco_identity_attrs(__TopXMLNS, _attrs, + Category, _val, Lang, Name); +decode_disco_identity_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], Category, Type, + _Lang, Name) -> + decode_disco_identity_attrs(__TopXMLNS, _attrs, + Category, Type, _val, Name); +decode_disco_identity_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], Category, Type, Lang, + _Name) -> + decode_disco_identity_attrs(__TopXMLNS, _attrs, + Category, Type, Lang, _val); +decode_disco_identity_attrs(__TopXMLNS, [_ | _attrs], + Category, Type, Lang, Name) -> + decode_disco_identity_attrs(__TopXMLNS, _attrs, + Category, Type, Lang, Name); +decode_disco_identity_attrs(__TopXMLNS, [], Category, + Type, Lang, Name) -> + {decode_disco_identity_attr_category(__TopXMLNS, + Category), + decode_disco_identity_attr_type(__TopXMLNS, Type), + 'decode_disco_identity_attr_xml:lang'(__TopXMLNS, Lang), + decode_disco_identity_attr_name(__TopXMLNS, Name)}. + +encode_disco_identity({identity, Category, Type, Lang, + Name}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_disco_identity_attr_name(Name, + 'encode_disco_identity_attr_xml:lang'(Lang, + encode_disco_identity_attr_type(Type, + encode_disco_identity_attr_category(Category, + _xmlns_attrs)))), + {xmlel, <<"identity">>, _attrs, _els}. + +decode_disco_identity_attr_category(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"category">>, <<"identity">>, + __TopXMLNS}}); +decode_disco_identity_attr_category(__TopXMLNS, _val) -> + _val. + +encode_disco_identity_attr_category(_val, _acc) -> + [{<<"category">>, _val} | _acc]. + +decode_disco_identity_attr_type(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"identity">>, + __TopXMLNS}}); +decode_disco_identity_attr_type(__TopXMLNS, _val) -> + _val. + +encode_disco_identity_attr_type(_val, _acc) -> + [{<<"type">>, _val} | _acc]. + +'decode_disco_identity_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_disco_identity_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_disco_identity_attr_xml:lang'(undefined, + _acc) -> + _acc; +'encode_disco_identity_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_disco_identity_attr_name(__TopXMLNS, + undefined) -> + undefined; +decode_disco_identity_attr_name(__TopXMLNS, _val) -> + _val. + +encode_disco_identity_attr_name(undefined, _acc) -> + _acc; +encode_disco_identity_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_block_list(__TopXMLNS, __IgnoreEls, + {xmlel, <<"blocklist">>, _attrs, _els}) -> + {block_list}. + +encode_block_list({block_list}, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"blocklist">>, _attrs, _els}. + +decode_unblock(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unblock">>, _attrs, _els}) -> + Items = decode_unblock_els(__TopXMLNS, __IgnoreEls, + _els, []), + {unblock, Items}. + +decode_unblock_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_unblock_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> + decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(__TopXMLNS, __IgnoreEls, + _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + <<"urn:xmpp:blocking">> -> + decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(<<"urn:xmpp:blocking">>, + __IgnoreEls, _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + _ -> + decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, Items) + end; +decode_unblock_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Items) -> + decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +encode_unblock({unblock, Items}, _xmlns_attrs) -> + _els = lists:reverse('encode_unblock_$items'(Items, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"unblock">>, _attrs, _els}. + +'encode_unblock_$items'([], _acc) -> _acc; +'encode_unblock_$items'([Items | _els], _acc) -> + 'encode_unblock_$items'(_els, + [encode_block_item(Items, []) | _acc]). + +decode_block(__TopXMLNS, __IgnoreEls, + {xmlel, <<"block">>, _attrs, _els}) -> + Items = decode_block_els(__TopXMLNS, __IgnoreEls, _els, + []), + {block, Items}. + +decode_block_els(__TopXMLNS, __IgnoreEls, [], Items) -> + lists:reverse(Items); +decode_block_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> + decode_block_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(__TopXMLNS, __IgnoreEls, _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + <<"urn:xmpp:blocking">> -> + decode_block_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(<<"urn:xmpp:blocking">>, + __IgnoreEls, _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + _ -> + decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items) + end; +decode_block_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Items) -> + decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items). + +encode_block({block, Items}, _xmlns_attrs) -> + _els = lists:reverse('encode_block_$items'(Items, [])), + _attrs = _xmlns_attrs, + {xmlel, <<"block">>, _attrs, _els}. + +'encode_block_$items'([], _acc) -> _acc; +'encode_block_$items'([Items | _els], _acc) -> + 'encode_block_$items'(_els, + [encode_block_item(Items, []) | _acc]). + +decode_block_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + Jid = decode_block_item_attrs(__TopXMLNS, _attrs, + undefined), + Jid. + +decode_block_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_block_item_attrs(__TopXMLNS, _attrs, _val); +decode_block_item_attrs(__TopXMLNS, [_ | _attrs], + Jid) -> + decode_block_item_attrs(__TopXMLNS, _attrs, Jid); +decode_block_item_attrs(__TopXMLNS, [], Jid) -> + decode_block_item_attr_jid(__TopXMLNS, Jid). + +encode_block_item(Jid, _xmlns_attrs) -> + _els = [], + _attrs = encode_block_item_attr_jid(Jid, _xmlns_attrs), + {xmlel, <<"item">>, _attrs, _els}. + +decode_block_item_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); +decode_block_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_block_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_privacy(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Lists, Default, Active} = + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, [], + undefined, undefined), + {privacy_query, Lists, Default, Active}. + +decode_privacy_els(__TopXMLNS, __IgnoreEls, [], Lists, + Default, Active) -> + {lists:reverse(Lists), Default, Active}; +decode_privacy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"list">>, _attrs, _} = _el | _els], Lists, + Default, Active) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, + [decode_privacy_list(__TopXMLNS, __IgnoreEls, _el) + | Lists], + Default, Active); + <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, + [decode_privacy_list(<<"jabber:iq:privacy">>, + __IgnoreEls, _el) + | Lists], + Default, Active); + _ -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, Active) + end; +decode_privacy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"default">>, _attrs, _} = _el | _els], Lists, + Default, Active) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + decode_privacy_default_list(__TopXMLNS, + __IgnoreEls, _el), + Active); + <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + decode_privacy_default_list(<<"jabber:iq:privacy">>, + __IgnoreEls, _el), + Active); + _ -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, Active) + end; +decode_privacy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"active">>, _attrs, _} = _el | _els], Lists, + Default, Active) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, + decode_privacy_active_list(__TopXMLNS, __IgnoreEls, + _el)); + <<"jabber:iq:privacy">> -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, + decode_privacy_active_list(<<"jabber:iq:privacy">>, + __IgnoreEls, _el)); + _ -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, Active) + end; +decode_privacy_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Lists, Default, Active) -> + decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, + Default, Active). + +encode_privacy({privacy_query, Lists, Default, Active}, + _xmlns_attrs) -> + _els = lists:reverse('encode_privacy_$lists'(Lists, + 'encode_privacy_$default'(Default, + 'encode_privacy_$active'(Active, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_privacy_$lists'([], _acc) -> _acc; +'encode_privacy_$lists'([Lists | _els], _acc) -> + 'encode_privacy_$lists'(_els, + [encode_privacy_list(Lists, []) | _acc]). + +'encode_privacy_$default'(undefined, _acc) -> _acc; +'encode_privacy_$default'(Default, _acc) -> + [encode_privacy_default_list(Default, []) | _acc]. + +'encode_privacy_$active'(undefined, _acc) -> _acc; +'encode_privacy_$active'(Active, _acc) -> + [encode_privacy_active_list(Active, []) | _acc]. + +decode_privacy_active_list(__TopXMLNS, __IgnoreEls, + {xmlel, <<"active">>, _attrs, _els}) -> + Name = decode_privacy_active_list_attrs(__TopXMLNS, + _attrs, undefined), + Name. + +decode_privacy_active_list_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name) -> + decode_privacy_active_list_attrs(__TopXMLNS, _attrs, + _val); +decode_privacy_active_list_attrs(__TopXMLNS, + [_ | _attrs], Name) -> + decode_privacy_active_list_attrs(__TopXMLNS, _attrs, + Name); +decode_privacy_active_list_attrs(__TopXMLNS, [], + Name) -> + decode_privacy_active_list_attr_name(__TopXMLNS, Name). + +encode_privacy_active_list(Name, _xmlns_attrs) -> + _els = [], + _attrs = encode_privacy_active_list_attr_name(Name, + _xmlns_attrs), + {xmlel, <<"active">>, _attrs, _els}. + +decode_privacy_active_list_attr_name(__TopXMLNS, + undefined) -> + none; +decode_privacy_active_list_attr_name(__TopXMLNS, + _val) -> + _val. + +encode_privacy_active_list_attr_name(none, _acc) -> + _acc; +encode_privacy_active_list_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_privacy_default_list(__TopXMLNS, __IgnoreEls, + {xmlel, <<"default">>, _attrs, _els}) -> + Name = decode_privacy_default_list_attrs(__TopXMLNS, + _attrs, undefined), + Name. + +decode_privacy_default_list_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name) -> + decode_privacy_default_list_attrs(__TopXMLNS, _attrs, + _val); +decode_privacy_default_list_attrs(__TopXMLNS, + [_ | _attrs], Name) -> + decode_privacy_default_list_attrs(__TopXMLNS, _attrs, + Name); +decode_privacy_default_list_attrs(__TopXMLNS, [], + Name) -> + decode_privacy_default_list_attr_name(__TopXMLNS, Name). + +encode_privacy_default_list(Name, _xmlns_attrs) -> + _els = [], + _attrs = encode_privacy_default_list_attr_name(Name, + _xmlns_attrs), + {xmlel, <<"default">>, _attrs, _els}. + +decode_privacy_default_list_attr_name(__TopXMLNS, + undefined) -> + none; +decode_privacy_default_list_attr_name(__TopXMLNS, + _val) -> + _val. + +encode_privacy_default_list_attr_name(none, _acc) -> + _acc; +encode_privacy_default_list_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_privacy_list(__TopXMLNS, __IgnoreEls, + {xmlel, <<"list">>, _attrs, _els}) -> + Items = decode_privacy_list_els(__TopXMLNS, __IgnoreEls, + _els, []), + Name = decode_privacy_list_attrs(__TopXMLNS, _attrs, + undefined), + {privacy_list, Name, Items}. + +decode_privacy_list_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_privacy_list_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, + [decode_privacy_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"jabber:iq:privacy">> -> + decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, + [decode_privacy_item(<<"jabber:iq:privacy">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_privacy_list_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_privacy_list_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name) -> + decode_privacy_list_attrs(__TopXMLNS, _attrs, _val); +decode_privacy_list_attrs(__TopXMLNS, [_ | _attrs], + Name) -> + decode_privacy_list_attrs(__TopXMLNS, _attrs, Name); +decode_privacy_list_attrs(__TopXMLNS, [], Name) -> + decode_privacy_list_attr_name(__TopXMLNS, Name). + +encode_privacy_list({privacy_list, Name, Items}, + _xmlns_attrs) -> + _els = lists:reverse('encode_privacy_list_$items'(Items, + [])), + _attrs = encode_privacy_list_attr_name(Name, + _xmlns_attrs), + {xmlel, <<"list">>, _attrs, _els}. + +'encode_privacy_list_$items'([], _acc) -> _acc; +'encode_privacy_list_$items'([Items | _els], _acc) -> + 'encode_privacy_list_$items'(_els, + [encode_privacy_item(Items, []) | _acc]). + +decode_privacy_list_attr_name(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"list">>, __TopXMLNS}}); +decode_privacy_list_attr_name(__TopXMLNS, _val) -> _val. + +encode_privacy_list_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_privacy_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Iq, Presence_out, Message, Presence_in} = + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + false, false, false, false), + {Action, Order, Type, Value} = + decode_privacy_item_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {privacy_item, Order, Action, Type, Value, Message, Iq, + Presence_in, Presence_out}. + +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, [], Iq, + Presence_out, Message, Presence_in) -> + {Iq, Presence_out, Message, Presence_in}; +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"message">>, _attrs, _} = _el | _els], Iq, + Presence_out, Message, Presence_in) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, + decode_privacy_message(__TopXMLNS, + __IgnoreEls, _el), + Presence_in); + <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, + decode_privacy_message(<<"jabber:iq:privacy">>, + __IgnoreEls, _el), + Presence_in); + _ -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, Presence_in) + end; +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"iq">>, _attrs, _} = _el | _els], Iq, + Presence_out, Message, Presence_in) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_privacy_iq(__TopXMLNS, __IgnoreEls, + _el), + Presence_out, Message, Presence_in); + <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_privacy_iq(<<"jabber:iq:privacy">>, + __IgnoreEls, _el), + Presence_out, Message, Presence_in); + _ -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, Presence_in) + end; +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"presence-in">>, _attrs, _} = _el | _els], + Iq, Presence_out, Message, Presence_in) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, + decode_privacy_presence_in(__TopXMLNS, + __IgnoreEls, _el)); + <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, + decode_privacy_presence_in(<<"jabber:iq:privacy">>, + __IgnoreEls, _el)); + _ -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, Presence_in) + end; +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"presence-out">>, _attrs, _} = _el | _els], + Iq, Presence_out, Message, Presence_in) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, + decode_privacy_presence_out(__TopXMLNS, + __IgnoreEls, _el), + Message, Presence_in); + <<"jabber:iq:privacy">> -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, + decode_privacy_presence_out(<<"jabber:iq:privacy">>, + __IgnoreEls, _el), + Message, Presence_in); + _ -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, Presence_in) + end; +decode_privacy_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Iq, Presence_out, Message, Presence_in) -> + decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, + Iq, Presence_out, Message, Presence_in). + +decode_privacy_item_attrs(__TopXMLNS, + [{<<"action">>, _val} | _attrs], _Action, Order, Type, + Value) -> + decode_privacy_item_attrs(__TopXMLNS, _attrs, _val, + Order, Type, Value); +decode_privacy_item_attrs(__TopXMLNS, + [{<<"order">>, _val} | _attrs], Action, _Order, Type, + Value) -> + decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, + _val, Type, Value); +decode_privacy_item_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Action, Order, _Type, + Value) -> + decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, + Order, _val, Value); +decode_privacy_item_attrs(__TopXMLNS, + [{<<"value">>, _val} | _attrs], Action, Order, Type, + _Value) -> + decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, + Order, Type, _val); +decode_privacy_item_attrs(__TopXMLNS, [_ | _attrs], + Action, Order, Type, Value) -> + decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, + Order, Type, Value); +decode_privacy_item_attrs(__TopXMLNS, [], Action, Order, + Type, Value) -> + {decode_privacy_item_attr_action(__TopXMLNS, Action), + decode_privacy_item_attr_order(__TopXMLNS, Order), + decode_privacy_item_attr_type(__TopXMLNS, Type), + decode_privacy_item_attr_value(__TopXMLNS, Value)}. + +encode_privacy_item({privacy_item, Order, Action, Type, + Value, Message, Iq, Presence_in, Presence_out}, + _xmlns_attrs) -> + _els = lists:reverse('encode_privacy_item_$iq'(Iq, + 'encode_privacy_item_$presence_out'(Presence_out, + 'encode_privacy_item_$message'(Message, + 'encode_privacy_item_$presence_in'(Presence_in, + []))))), + _attrs = encode_privacy_item_attr_value(Value, + encode_privacy_item_attr_type(Type, + encode_privacy_item_attr_order(Order, + encode_privacy_item_attr_action(Action, + _xmlns_attrs)))), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_privacy_item_$iq'(false, _acc) -> _acc; +'encode_privacy_item_$iq'(Iq, _acc) -> + [encode_privacy_iq(Iq, []) | _acc]. + +'encode_privacy_item_$presence_out'(false, _acc) -> + _acc; +'encode_privacy_item_$presence_out'(Presence_out, + _acc) -> + [encode_privacy_presence_out(Presence_out, []) | _acc]. + +'encode_privacy_item_$message'(false, _acc) -> _acc; +'encode_privacy_item_$message'(Message, _acc) -> + [encode_privacy_message(Message, []) | _acc]. + +'encode_privacy_item_$presence_in'(false, _acc) -> _acc; +'encode_privacy_item_$presence_in'(Presence_in, _acc) -> + [encode_privacy_presence_in(Presence_in, []) | _acc]. + +decode_privacy_item_attr_action(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"action">>, <<"item">>, __TopXMLNS}}); +decode_privacy_item_attr_action(__TopXMLNS, _val) -> + case catch dec_enum(_val, [allow, deny]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"action">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_privacy_item_attr_action(_val, _acc) -> + [{<<"action">>, enc_enum(_val)} | _acc]. + +decode_privacy_item_attr_order(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"order">>, <<"item">>, __TopXMLNS}}); +decode_privacy_item_attr_order(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"order">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_privacy_item_attr_order(_val, _acc) -> + [{<<"order">>, enc_int(_val)} | _acc]. + +decode_privacy_item_attr_type(__TopXMLNS, undefined) -> + undefined; +decode_privacy_item_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, [group, jid, subscription]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_privacy_item_attr_type(undefined, _acc) -> _acc; +encode_privacy_item_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_privacy_item_attr_value(__TopXMLNS, undefined) -> + undefined; +decode_privacy_item_attr_value(__TopXMLNS, _val) -> + _val. + +encode_privacy_item_attr_value(undefined, _acc) -> _acc; +encode_privacy_item_attr_value(_val, _acc) -> + [{<<"value">>, _val} | _acc]. + +decode_privacy_presence_out(__TopXMLNS, __IgnoreEls, + {xmlel, <<"presence-out">>, _attrs, _els}) -> + true. + +encode_privacy_presence_out(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"presence-out">>, _attrs, _els}. + +decode_privacy_presence_in(__TopXMLNS, __IgnoreEls, + {xmlel, <<"presence-in">>, _attrs, _els}) -> + true. + +encode_privacy_presence_in(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"presence-in">>, _attrs, _els}. + +decode_privacy_iq(__TopXMLNS, __IgnoreEls, + {xmlel, <<"iq">>, _attrs, _els}) -> + true. + +encode_privacy_iq(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"iq">>, _attrs, _els}. + +decode_privacy_message(__TopXMLNS, __IgnoreEls, + {xmlel, <<"message">>, _attrs, _els}) -> + true. + +encode_privacy_message(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"message">>, _attrs, _els}. + +decode_rosterver_feature(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ver">>, _attrs, _els}) -> + {rosterver_feature}. + +encode_rosterver_feature({rosterver_feature}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"ver">>, _attrs, _els}. + +decode_roster_query(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + Items = decode_roster_query_els(__TopXMLNS, __IgnoreEls, + _els, []), + Ver = decode_roster_query_attrs(__TopXMLNS, _attrs, + undefined), + {roster_query, Items, Ver}. + +decode_roster_query_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_roster_query_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:roster">> -> + decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, + [decode_roster_item(__TopXMLNS, __IgnoreEls, + _el) + | Items]); + <<"jabber:iq:roster">> -> + decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, + [decode_roster_item(<<"jabber:iq:roster">>, + __IgnoreEls, _el) + | Items]); + _ -> + decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_roster_query_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +decode_roster_query_attrs(__TopXMLNS, + [{<<"ver">>, _val} | _attrs], _Ver) -> + decode_roster_query_attrs(__TopXMLNS, _attrs, _val); +decode_roster_query_attrs(__TopXMLNS, [_ | _attrs], + Ver) -> + decode_roster_query_attrs(__TopXMLNS, _attrs, Ver); +decode_roster_query_attrs(__TopXMLNS, [], Ver) -> + decode_roster_query_attr_ver(__TopXMLNS, Ver). + +encode_roster_query({roster_query, Items, Ver}, + _xmlns_attrs) -> + _els = lists:reverse('encode_roster_query_$items'(Items, + [])), + _attrs = encode_roster_query_attr_ver(Ver, + _xmlns_attrs), + {xmlel, <<"query">>, _attrs, _els}. + +'encode_roster_query_$items'([], _acc) -> _acc; +'encode_roster_query_$items'([Items | _els], _acc) -> + 'encode_roster_query_$items'(_els, + [encode_roster_item(Items, []) | _acc]). + +decode_roster_query_attr_ver(__TopXMLNS, undefined) -> + undefined; +decode_roster_query_attr_ver(__TopXMLNS, _val) -> _val. + +encode_roster_query_attr_ver(undefined, _acc) -> _acc; +encode_roster_query_attr_ver(_val, _acc) -> + [{<<"ver">>, _val} | _acc]. + +decode_roster_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + Groups = decode_roster_item_els(__TopXMLNS, __IgnoreEls, + _els, []), + {Jid, Name, Subscription, Ask} = + decode_roster_item_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {roster_item, Jid, Name, Groups, Subscription, Ask}. + +decode_roster_item_els(__TopXMLNS, __IgnoreEls, [], + Groups) -> + lists:reverse(Groups); +decode_roster_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"group">>, _attrs, _} = _el | _els], + Groups) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:roster">> -> + decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, + [decode_roster_group(__TopXMLNS, __IgnoreEls, + _el) + | Groups]); + <<"jabber:iq:roster">> -> + decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, + [decode_roster_group(<<"jabber:iq:roster">>, + __IgnoreEls, _el) + | Groups]); + _ -> + decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, + Groups) + end; +decode_roster_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Groups) -> + decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, + Groups). + +decode_roster_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Name, Subscription, + Ask) -> + decode_roster_item_attrs(__TopXMLNS, _attrs, _val, Name, + Subscription, Ask); +decode_roster_item_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], Jid, _Name, + Subscription, Ask) -> + decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, _val, + Subscription, Ask); +decode_roster_item_attrs(__TopXMLNS, + [{<<"subscription">>, _val} | _attrs], Jid, Name, + _Subscription, Ask) -> + decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, + _val, Ask); +decode_roster_item_attrs(__TopXMLNS, + [{<<"ask">>, _val} | _attrs], Jid, Name, Subscription, + _Ask) -> + decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, + Subscription, _val); +decode_roster_item_attrs(__TopXMLNS, [_ | _attrs], Jid, + Name, Subscription, Ask) -> + decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, + Subscription, Ask); +decode_roster_item_attrs(__TopXMLNS, [], Jid, Name, + Subscription, Ask) -> + {decode_roster_item_attr_jid(__TopXMLNS, Jid), + decode_roster_item_attr_name(__TopXMLNS, Name), + decode_roster_item_attr_subscription(__TopXMLNS, + Subscription), + decode_roster_item_attr_ask(__TopXMLNS, Ask)}. + +encode_roster_item({roster_item, Jid, Name, Groups, + Subscription, Ask}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_roster_item_$groups'(Groups, [])), + _attrs = encode_roster_item_attr_ask(Ask, + encode_roster_item_attr_subscription(Subscription, + encode_roster_item_attr_name(Name, + encode_roster_item_attr_jid(Jid, + _xmlns_attrs)))), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_roster_item_$groups'([], _acc) -> _acc; +'encode_roster_item_$groups'([Groups | _els], _acc) -> + 'encode_roster_item_$groups'(_els, + [encode_roster_group(Groups, []) | _acc]). + +decode_roster_item_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); +decode_roster_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_roster_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_roster_item_attr_name(__TopXMLNS, undefined) -> + <<>>; +decode_roster_item_attr_name(__TopXMLNS, _val) -> _val. + +encode_roster_item_attr_name(<<>>, _acc) -> _acc; +encode_roster_item_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_roster_item_attr_subscription(__TopXMLNS, + undefined) -> + none; +decode_roster_item_attr_subscription(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [none, to, from, both, remove]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"subscription">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_roster_item_attr_subscription(none, _acc) -> + _acc; +encode_roster_item_attr_subscription(_val, _acc) -> + [{<<"subscription">>, enc_enum(_val)} | _acc]. + +decode_roster_item_attr_ask(__TopXMLNS, undefined) -> + undefined; +decode_roster_item_attr_ask(__TopXMLNS, _val) -> + case catch dec_enum(_val, [subscribe]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"ask">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_roster_item_attr_ask(undefined, _acc) -> _acc; +encode_roster_item_attr_ask(_val, _acc) -> + [{<<"ask">>, enc_enum(_val)} | _acc]. + +decode_roster_group(__TopXMLNS, __IgnoreEls, + {xmlel, <<"group">>, _attrs, _els}) -> + Cdata = decode_roster_group_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_roster_group_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_roster_group_cdata(__TopXMLNS, Cdata); +decode_roster_group_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_roster_group_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_roster_group_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_roster_group_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_roster_group(Cdata, _xmlns_attrs) -> + _els = encode_roster_group_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"group">>, _attrs, _els}. + +decode_roster_group_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"group">>, __TopXMLNS}}); +decode_roster_group_cdata(__TopXMLNS, _val) -> _val. + +encode_roster_group_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_version(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Ver, Os, Name} = decode_version_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined, undefined), + {version, Name, Ver, Os}. + +decode_version_els(__TopXMLNS, __IgnoreEls, [], Ver, Os, + Name) -> + {Ver, Os, Name}; +decode_version_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"name">>, _attrs, _} = _el | _els], Ver, Os, + Name) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, + decode_version_name(__TopXMLNS, __IgnoreEls, _el)); + <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, + decode_version_name(<<"jabber:iq:version">>, + __IgnoreEls, _el)); + _ -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, Name) + end; +decode_version_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"version">>, _attrs, _} = _el | _els], Ver, + Os, Name) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, + decode_version_ver(__TopXMLNS, __IgnoreEls, _el), + Os, Name); + <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, + decode_version_ver(<<"jabber:iq:version">>, + __IgnoreEls, _el), + Os, Name); + _ -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, Name) + end; +decode_version_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"os">>, _attrs, _} = _el | _els], Ver, Os, + Name) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + decode_version_os(__TopXMLNS, __IgnoreEls, _el), + Name); + <<"jabber:iq:version">> -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + decode_version_os(<<"jabber:iq:version">>, + __IgnoreEls, _el), + Name); + _ -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, Name) + end; +decode_version_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Ver, Os, Name) -> + decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, + Os, Name). + +encode_version({version, Name, Ver, Os}, + _xmlns_attrs) -> + _els = lists:reverse('encode_version_$ver'(Ver, + 'encode_version_$os'(Os, + 'encode_version_$name'(Name, + [])))), + _attrs = _xmlns_attrs, + {xmlel, <<"query">>, _attrs, _els}. + +'encode_version_$ver'(undefined, _acc) -> _acc; +'encode_version_$ver'(Ver, _acc) -> + [encode_version_ver(Ver, []) | _acc]. + +'encode_version_$os'(undefined, _acc) -> _acc; +'encode_version_$os'(Os, _acc) -> + [encode_version_os(Os, []) | _acc]. + +'encode_version_$name'(undefined, _acc) -> _acc; +'encode_version_$name'(Name, _acc) -> + [encode_version_name(Name, []) | _acc]. + +decode_version_os(__TopXMLNS, __IgnoreEls, + {xmlel, <<"os">>, _attrs, _els}) -> + Cdata = decode_version_os_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_version_os_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_version_os_cdata(__TopXMLNS, Cdata); +decode_version_os_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_version_os_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_version_os_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_version_os_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_version_os(Cdata, _xmlns_attrs) -> + _els = encode_version_os_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"os">>, _attrs, _els}. + +decode_version_os_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"os">>, __TopXMLNS}}); +decode_version_os_cdata(__TopXMLNS, _val) -> _val. + +encode_version_os_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_version_ver(__TopXMLNS, __IgnoreEls, + {xmlel, <<"version">>, _attrs, _els}) -> + Cdata = decode_version_ver_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_version_ver_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_version_ver_cdata(__TopXMLNS, Cdata); +decode_version_ver_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_version_ver_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_version_ver_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_version_ver_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_version_ver(Cdata, _xmlns_attrs) -> + _els = encode_version_ver_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"version">>, _attrs, _els}. + +decode_version_ver_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"version">>, __TopXMLNS}}); +decode_version_ver_cdata(__TopXMLNS, _val) -> _val. + +encode_version_ver_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_version_name(__TopXMLNS, __IgnoreEls, + {xmlel, <<"name">>, _attrs, _els}) -> + Cdata = decode_version_name_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_version_name_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_version_name_cdata(__TopXMLNS, Cdata); +decode_version_name_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_version_name_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_version_name_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_version_name_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_version_name(Cdata, _xmlns_attrs) -> + _els = encode_version_name_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"name">>, _attrs, _els}. + +decode_version_name_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"name">>, __TopXMLNS}}); +decode_version_name_cdata(__TopXMLNS, _val) -> _val. + +encode_version_name_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_last(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + Status = decode_last_els(__TopXMLNS, __IgnoreEls, _els, + <<>>), + Seconds = decode_last_attrs(__TopXMLNS, _attrs, + undefined), + {last, Seconds, Status}. + +decode_last_els(__TopXMLNS, __IgnoreEls, [], Status) -> + decode_last_cdata(__TopXMLNS, Status); +decode_last_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Status) -> + decode_last_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_last_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Status) -> + decode_last_els(__TopXMLNS, __IgnoreEls, _els, Status). + +decode_last_attrs(__TopXMLNS, + [{<<"seconds">>, _val} | _attrs], _Seconds) -> + decode_last_attrs(__TopXMLNS, _attrs, _val); +decode_last_attrs(__TopXMLNS, [_ | _attrs], Seconds) -> + decode_last_attrs(__TopXMLNS, _attrs, Seconds); +decode_last_attrs(__TopXMLNS, [], Seconds) -> + decode_last_attr_seconds(__TopXMLNS, Seconds). + +encode_last({last, Seconds, Status}, _xmlns_attrs) -> + _els = encode_last_cdata(Status, []), + _attrs = encode_last_attr_seconds(Seconds, + _xmlns_attrs), + {xmlel, <<"query">>, _attrs, _els}. + +decode_last_attr_seconds(__TopXMLNS, undefined) -> + undefined; +decode_last_attr_seconds(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"seconds">>, <<"query">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_last_attr_seconds(undefined, _acc) -> _acc; +encode_last_attr_seconds(_val, _acc) -> + [{<<"seconds">>, enc_int(_val)} | _acc]. + +decode_last_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_last_cdata(__TopXMLNS, _val) -> _val. + +encode_last_cdata(<<>>, _acc) -> _acc; +encode_last_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl new file mode 100644 index 000000000..42b251fc1 --- /dev/null +++ b/src/xmpp_util.erl @@ -0,0 +1,81 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 12 Jul 2016 by Evgeny Khramtsov +%%%------------------------------------------------------------------- +-module(xmpp_util). + +%% API +-export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, + is_standalone_chat_state/1]). + +-include("xmpp.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +-spec add_delay_info(stanza(), jid(), erlang:timestamp()) -> stanza(). +add_delay_info(Stz, From, Time) -> + add_delay_info(Stz, From, Time, <<"">>). + +-spec add_delay_info(stanza(), jid(), + erlang:timestamp(), binary()) -> stanza(). + +add_delay_info(Stz, From, Time, Desc) -> + case xmpp:get_subtag(Stz, #delay{}) of + #delay{from = OldFrom, desc = OldDesc} = Delay -> + case jid:tolower(From) == jid:tolower(OldFrom) of + true when Desc == <<"">> -> + Stz; + true when OldDesc == <<"">> -> + xmpp:set_subtag(Stz, Delay#delay{desc = Desc}); + true -> + case binary:match(OldDesc, Desc) of + nomatch -> + NewDesc = <>, + xmpp:set_subtag(Stz, Delay#delay{desc = NewDesc}); + _ -> + Stz + end; + false -> + NewDelay = #delay{stamp = Time, from = From, desc = Desc}, + xmpp:set_subtag(Stz, NewDelay) + end; + false -> + Delay = #delay{stamp = Time, from = From, desc = Desc}, + xmpp:set_subtag(Stz, Delay) + end. + +-spec unwrap_carbon(stanza()) -> xmpp_element(). +unwrap_carbon(#message{} = Msg) -> + case xmpp:get_subtag(Msg, #carbons_sent{}) of + #carbons_sent{forwarded = #forwarded{sub_els = [El]}} -> + El; + _ -> + case xmpp:get_subtag(Msg, #carbons_received{}) of + #carbons_received{forwarded = #forwarded{sub_els = [El]}} -> + El; + _ -> + Msg + end + end; +unwrap_carbon(Stanza) -> Stanza. + +-spec is_standalone_chat_state(stanza()) -> boolean(). +is_standalone_chat_state(Stanza) -> + case unwrap_carbon(Stanza) of + #message{sub_els = Els} -> + IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY], + Stripped = [El || El <- Els, + not lists:member(xmpp:get_ns(El), IgnoreNS)], + Stripped == []; + _ -> + false + end. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== -- cgit v1.2.3 From a4a9dd7f0334bf061c84a9825f8d743ec29a68bf Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 19 Jul 2016 07:56:14 +0300 Subject: Rewrite mod_offline to use XML generator --- src/mod_offline.erl | 346 +++++++++++++++++++++------------------------------- src/xmpp.erl | 6 +- src/xmpp_codec.erl | 323 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 464 insertions(+), 211 deletions(-) (limited to 'src') diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 799605c69..66edb6a7c 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -49,7 +49,7 @@ get_sm_identity/5, get_sm_items/5, get_info/5, - handle_offline_query/3, + handle_offline_query/1, remove_expired_messages/1, remove_old_messages/2, remove_user/2, @@ -73,7 +73,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). @@ -250,7 +250,7 @@ receive_all(US, Msgs, DBType) -> end end. -get_sm_features(Acc, _From, _To, <<"">>, _Lang) -> +get_sm_features(Acc, _From, _To, undefined, _Lang) -> Feats = case Acc of {result, I} -> I; _ -> [] @@ -268,12 +268,10 @@ get_sm_features(_Acc, #jid{luser = U, lserver = S}, #jid{luser = U, lserver = S} get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. -get_sm_identity(_Acc, #jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}, +get_sm_identity(Acc, #jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) -> - Identity = #xmlel{name = <<"identity">>, - attrs = [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"message-list">>}]}, - [Identity]; + [#identity{category = <<"automation">>, + type = <<"message-list">>}|Acc]; get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc. @@ -282,15 +280,16 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID, ?NS_FLEX_OFFLINE, _Lang) -> case ejabberd_sm:get_session_pid(U, S, R) of Pid when is_pid(Pid) -> - Hdrs = read_message_headers(U, S), - BareJID = jid:to_string(jid:remove_resource(JID)), + Mod = gen_mod:db_mod(S, ?MODULE), + Hdrs = Mod:read_message_headers(U, S), + BareJID = jid:remove_resource(JID), Pid ! dont_ask_offline, {result, lists:map( - fun({Node, From, _To, _El}) -> - #xmlel{name = <<"item">>, - attrs = [{<<"jid">>, BareJID}, - {<<"node">>, Node}, - {<<"name">>, jid:to_string(From)}]} + fun({Seq, From, _To, _El}) -> + Node = integer_to_binary(Seq), + #disco_item{jid = BareJID, + node = Node, + name = jid:to_string(From)} end, Hdrs)}; none -> {result, []} @@ -298,6 +297,8 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID, get_sm_items(Acc, _From, _To, _Node, _Lang) -> Acc. +-spec get_info([xdata()], jid(), jid(), + undefined | binary(), undefined | binary()) -> [xdata()]. get_info(_Acc, #jid{luser = U, lserver = S, lresource = R}, #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) -> N = jlib:integer_to_binary(count_offline_messages(U, S)), @@ -307,50 +308,42 @@ get_info(_Acc, #jid{luser = U, lserver = S, lresource = R}, none -> ok end, - [#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_FLEX_OFFLINE}]}]}, - #xmlel{name = <<"field">>, - attrs = [{<<"var">>, <<"number_of_messages">>}], - children = [#xmlel{name = <<"value">>, - children = [{xmlcdata, N}]}]}]}]; + [#xdata{type = result, + fields = [#xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = [?NS_FLEX_OFFLINE]}, + #xdata_field{var = <<"number_of_messages">>, + values = [N]}]}]; get_info(Acc, _From, _To, _Node, _Lang) -> Acc. -handle_offline_query(#jid{luser = U, lserver = S} = From, - #jid{luser = U, lserver = S} = _To, - #iq{type = Type, sub_el = SubEl} = IQ) -> +-spec handle_offline_query(iq()) -> iq(). +handle_offline_query(#iq{from = #jid{luser = U, lserver = S} = From, + to = #jid{luser = U, lserver = S} = _To, + type = Type, + sub_els = [#offline{purge = Purge, + items = Items, + fetch = Fetch}]} = IQ) -> case Type of get -> - case fxml:get_subtag(SubEl, <<"fetch">>) of - #xmlel{} -> - handle_offline_fetch(From); - false -> - handle_offline_items_view(From, SubEl) + if Fetch -> handle_offline_fetch(From); + true -> handle_offline_items_view(From, Items) end; set -> - case fxml:get_subtag(SubEl, <<"purge">>) of - #xmlel{} -> - delete_all_msgs(U, S); - false -> - handle_offline_items_remove(From, SubEl) + if Purge -> delete_all_msgs(U, S); + true -> handle_offline_items_remove(From, Items) end end, - IQ#iq{type = result, sub_el = []}; -handle_offline_query(_From, _To, #iq{sub_el = SubEl, lang = Lang} = IQ) -> + xmpp:make_iq_result(IQ); +handle_offline_query(#iq{lang = Lang} = IQ) -> Txt = <<"Query to another users is forbidden">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}. + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)). -handle_offline_items_view(JID, #xmlel{children = Items}) -> +-spec handle_offline_items_view(jid(), [offline_item()]) -> ok. +handle_offline_items_view(JID, Items) -> {U, S, R} = jid:tolower(JID), lists:foreach( - fun(Node) -> + fun(#offline_item{node = Node, action = view}) -> case fetch_msg_by_node(JID, Node) of {ok, OfflineMsg} -> case offline_msg_to_route(S, OfflineMsg) of @@ -367,40 +360,25 @@ handle_offline_items_view(JID, #xmlel{children = Items}) -> end; error -> ok - end - end, get_nodes_from_items(Items, <<"view">>)). + end; + (_) -> + ok + end, Items). -handle_offline_items_remove(JID, #xmlel{children = Items}) -> +-spec handle_offline_items_remove(jid(), [offline_item()]) -> ok. +handle_offline_items_remove(JID, Items) -> lists:foreach( - fun(Node) -> - remove_msg_by_node(JID, Node) - end, get_nodes_from_items(Items, <<"remove">>)). - -get_nodes_from_items(Items, Action) -> - lists:flatmap( - fun(#xmlel{name = <<"item">>, attrs = Attrs}) -> - case fxml:get_attr_s(<<"action">>, Attrs) of - Action -> - case fxml:get_attr_s(<<"node">>, Attrs) of - <<"">> -> - []; - TS -> - [TS] - end; - _ -> - [] - end; + fun(#offline_item{node = Node, action = remove}) -> + remove_msg_by_node(JID, Node); (_) -> - [] + ok end, Items). -set_offline_tag(#xmlel{children = Els} = El, Node) -> - OfflineEl = #xmlel{name = <<"offline">>, - attrs = [{<<"xmlns">>, ?NS_FLEX_OFFLINE}], - children = [#xmlel{name = <<"item">>, - attrs = [{<<"node">>, Node}]}]}, - El#xmlel{children = [OfflineEl|Els]}. +-spec set_offline_tag(message(), binary()) -> message(). +set_offline_tag(Msg, Node) -> + xmpp:set_subtag(Msg, #offline{items = [#offline_item{node = Node}]}). +-spec handle_offline_fetch(jid()) -> ok. handle_offline_fetch(#jid{luser = U, lserver = S, lresource = R}) -> case ejabberd_sm:get_session_pid(U, S, R) of none -> @@ -414,6 +392,7 @@ handle_offline_fetch(#jid{luser = U, lserver = S, lresource = R}) -> end, read_message_headers(U, S)) end. +-spec fetch_msg_by_node(jid(), binary()) -> error | {ok, #offline_msg{}}. fetch_msg_by_node(To, Seq) -> case catch binary_to_integer(Seq) of I when is_integer(I), I >= 0 -> @@ -425,6 +404,7 @@ fetch_msg_by_node(To, Seq) -> error end. +-spec remove_msg_by_node(jid(), binary()) -> ok. remove_msg_by_node(To, Seq) -> case catch binary_to_integer(Seq) of I when is_integer(I), I>= 0 -> @@ -436,39 +416,38 @@ remove_msg_by_node(To, Seq) -> ok end. +-spec need_to_store(binary(), message()) -> boolean(). +need_to_store(_LServer, #message{type = error}) -> false; +need_to_store(_LServer, #message{type = groupchat}) -> false; +need_to_store(_LServer, #message{type = headline}) -> false; need_to_store(LServer, Packet) -> - Type = fxml:get_tag_attr_s(<<"type">>, Packet), - if (Type /= <<"error">>) and (Type /= <<"groupchat">>) - and (Type /= <<"headline">>) -> - case has_offline_tag(Packet) of - false -> - case check_store_hint(Packet) of - store -> - true; - no_store -> - false; - none -> - case gen_mod:get_module_opt( - LServer, ?MODULE, store_empty_body, - fun(V) when is_boolean(V) -> V; - (unless_chat_state) -> unless_chat_state - end, - unless_chat_state) of - false -> - fxml:get_subtag(Packet, <<"body">>) /= false; - unless_chat_state -> - not jlib:is_standalone_chat_state(Packet); - true -> - true - end - end; - true -> - false + case xmpp:has_subtag(Packet, #offline{}) of + false -> + case check_store_hint(Packet) of + store -> + true; + no_store -> + false; + none -> + case gen_mod:get_module_opt( + LServer, ?MODULE, store_empty_body, + fun(V) when is_boolean(V) -> V; + (unless_chat_state) -> unless_chat_state + end, + unless_chat_state) of + false -> + Packet#message.body /= []; + unless_chat_state -> + not xmpp_util:is_standalone_chat_state(Packet); + true -> + true + end end; - true -> + true -> false end. +-spec store_packet(jid(), jid(), message()) -> ok | stop. store_packet(From, To, Packet) -> case need_to_store(To#jid.lserver, Packet) of true -> @@ -476,18 +455,19 @@ store_packet(From, To, Packet) -> true -> #jid{luser = LUser, lserver = LServer} = To, TimeStamp = p1_time_compat:timestamp(), - #xmlel{children = Els} = Packet, - Expire = find_x_expire(TimeStamp, Els), + Expire = find_x_expire(TimeStamp, Packet), + El = xmpp:encode(Packet), gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, expire = Expire, - from = From, to = To, packet = Packet}, + from = From, to = To, packet = El}, stop; _ -> ok end; false -> ok end. +-spec check_store_hint(message()) -> store | no_store | none. check_store_hint(Packet) -> case has_store_hint(Packet) of true -> @@ -501,89 +481,43 @@ check_store_hint(Packet) -> end end. +-spec has_store_hint(message()) -> boolean(). has_store_hint(Packet) -> - fxml:get_subtag_with_xmlns(Packet, <<"store">>, ?NS_HINTS) =/= false. + xmpp:has_subtag(Packet, #hint{type = 'store'}). +-spec has_no_store_hint(message()) -> boolean(). has_no_store_hint(Packet) -> - fxml:get_subtag_with_xmlns(Packet, <<"no-store">>, ?NS_HINTS) =/= false - orelse - fxml:get_subtag_with_xmlns(Packet, <<"no-storage">>, ?NS_HINTS) =/= false. - -has_offline_tag(Packet) -> - fxml:get_subtag_with_xmlns(Packet, <<"offline">>, ?NS_FLEX_OFFLINE) =/= false. + xmpp:has_subtag(Packet, #hint{type = 'no-store'}) + orelse + xmpp:has_subtag(Packet, #hint{type = 'no-storage'}). %% Check if the packet has any content about XEP-0022 -check_event(From, To, Packet) -> - #xmlel{name = Name, attrs = Attrs, children = Els} = - Packet, - case find_x_event(Els) of - false -> true; - El -> - case fxml:get_subtag(El, <<"id">>) of - false -> - case fxml:get_subtag(El, <<"offline">>) of - false -> true; - _ -> - ID = case fxml:get_tag_attr_s(<<"id">>, Packet) of - <<"">> -> - #xmlel{name = <<"id">>, attrs = [], - children = []}; - S -> - #xmlel{name = <<"id">>, attrs = [], - children = [{xmlcdata, S}]} - end, - ejabberd_router:route(To, From, - #xmlel{name = Name, attrs = Attrs, - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_EVENT}], - children = - [ID, - #xmlel{name - = - <<"offline">>, - attrs - = - [], - children - = - []}]}]}), - true - end; - _ -> false - end - end. - -%% Check if the packet has subelements about XEP-0022 -find_x_event([]) -> false; -find_x_event([{xmlcdata, _} | Els]) -> - find_x_event(Els); -find_x_event([El | Els]) -> - case fxml:get_tag_attr_s(<<"xmlns">>, El) of - ?NS_EVENT -> El; - _ -> find_x_event(Els) +-spec check_event(jid(), jid(), message()) -> boolean(). +check_event(From, To, #message{id = ID} = Msg) -> + case xmpp:get_subtag(Msg, #xevent{}) of + false -> + true; + #xevent{id = undefined, offline = false} -> + true; + #xevent{id = undefined, offline = true} -> + NewMsg = Msg#message{sub_els = [#xevent{id = ID, offline = true}]}, + ejabberd_router:route(To, From, xmpp:set_from_to(NewMsg, To, From)), + true; + _ -> + false end. -find_x_expire(_, []) -> never; -find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) -> - find_x_expire(TimeStamp, Els); -find_x_expire(TimeStamp, [El | Els]) -> - case fxml:get_tag_attr_s(<<"xmlns">>, El) of - ?NS_EXPIRE -> - Val = fxml:get_tag_attr_s(<<"seconds">>, El), - case catch jlib:binary_to_integer(Val) of - {'EXIT', _} -> never; - Int when Int > 0 -> - {MegaSecs, Secs, MicroSecs} = TimeStamp, - S = MegaSecs * 1000000 + Secs + Int, - MegaSecs1 = S div 1000000, - Secs1 = S rem 1000000, - {MegaSecs1, Secs1, MicroSecs}; - _ -> never - end; - _ -> find_x_expire(TimeStamp, Els) +-spec find_x_expire(erlang:timestamp(), message()) -> erlang:timestamp() | never. +find_x_expire(TimeStamp, Msg) -> + case xmpp:get_subtag(Msg, #expire{}) of + #expire{seconds = Int} -> + {MegaSecs, Secs, MicroSecs} = TimeStamp, + S = MegaSecs * 1000000 + Secs + Int, + MegaSecs1 = S div 1000000, + Secs1 = S rem 1000000, + {MegaSecs1, Secs1, MicroSecs}; + false -> + never end. resend_offline_messages(User, Server) -> @@ -612,10 +546,9 @@ pop_offline_messages(Ls, User, Server) -> end, lists:filter( fun(#offline_msg{packet = Pkt} = R) -> - #xmlel{children = Els} = Pkt, Expire = case R#offline_msg.expire of undefined -> - find_x_expire(TS, Els); + find_x_expire(TS, Pkt); Exp -> Exp end, @@ -648,17 +581,15 @@ remove_user(User, Server) -> %% Warn senders that their messages have been discarded: discard_warn_sender(Msgs) -> - lists:foreach(fun (#offline_msg{from = From, to = To, - packet = Packet}) -> - ErrText = <<"Your contact offline message queue is " - "full. The message has been discarded.">>, - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), - Err = jlib:make_error_reply(Packet, - ?ERRT_RESOURCE_CONSTRAINT(Lang, - ErrText)), - ejabberd_router:route(To, From, Err) - end, - Msgs). + lists:foreach( + fun(#offline_msg{from = From, to = To, packet = Packet}) -> + ErrText = <<"Your contact offline message queue is " + "full. The message has been discarded.">>, + Lang = xmpp:get_lang(Packet), + Err = xmpp:make_error( + Packet, xmpp:err_resource_constraint(ErrText, Lang)), + ejabberd_router:route(To, From, Err) + end, Msgs). webadmin_page(_, Host, #request{us = _US, path = [<<"user">>, U, <<"queue">>], @@ -668,29 +599,30 @@ webadmin_page(_, Host, webadmin_page(Acc, _, _) -> Acc. get_offline_els(LUser, LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Hdrs = Mod:read_message_headers(LUser, LServer), + Hdrs = read_message_headers(LUser, LServer), lists:map( fun({_Seq, From, To, Packet}) -> - jlib:replace_from_to(From, To, Packet) + xmpp:set_from_to(Packet, From, To) end, Hdrs). offline_msg_to_route(LServer, #offline_msg{} = R) -> - El = case R#offline_msg.timestamp of - undefined -> - R#offline_msg.packet; - TS -> - jlib:add_delay_info(R#offline_msg.packet, LServer, TS, - <<"Offline Storage">>) - end, - {route, R#offline_msg.from, R#offline_msg.to, El}. + Pkt = xmpp:decode(R#offline_msg.packet, [ignore_els]), + Pkt1 = case R#offline_msg.timestamp of + undefined -> + Pkt; + TS -> + xmpp_util:add_delay_info(Pkt, LServer, TS, + <<"Offline Storage">>) + end, + {route, R#offline_msg.from, R#offline_msg.to, Pkt1}. read_message_headers(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), lists:map( fun({Seq, From, To, El}) -> Node = integer_to_binary(Seq), - {Node, From, To, El} + Packet = xmpp:decode(El, [ignore_els]), + {Node, From, To, Packet} end, Mod:read_message_headers(LUser, LServer)). format_user_queue(Hdrs) -> @@ -826,6 +758,7 @@ webadmin_user(Acc, User, Server, Lang) -> ?INPUTT(<<"submit">>, <<"removealloffline">>, <<"Remove All Offline Messages">>)]. +-spec delete_all_msgs(binary(), binary()) -> {atomic, any()}. delete_all_msgs(User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -849,6 +782,7 @@ webadmin_user_parse_query(Acc, _Action, _User, _Server, Acc. %% Returns as integer the number of offline messages for a given user +-spec count_offline_messages(binary(), binary()) -> non_neg_integer(). count_offline_messages(User, Server) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), diff --git a/src/xmpp.erl b/src/xmpp.erl index ca6ed5e4c..f17eefa21 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -156,10 +156,12 @@ get_error(#iq{error = E}) -> E; get_error(#message{error = E}) -> E; get_error(#presence{error = E}) -> E. --spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()]. +-spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()]; + (xmlel()) -> [xmlel()]. get_els(#iq{sub_els = Els}) -> Els; get_els(#message{sub_els = Els}) -> Els; -get_els(#presence{sub_els = Els}) -> Els. +get_els(#presence{sub_els = Els}) -> Els; +get_els(#xmlel{children = Els}) -> [El || El = #xmlel{} <- Els]. -spec set_id(iq(), binary()) -> iq(); (message(), binary()) -> message(); diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 568c5fbc7..976a7bfeb 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,24 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"x">>, <<"jabber:x:expire">>} -> + decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); + {<<"x">>, <<"jabber:x:event">>} -> + decode_xevent(<<"jabber:x:event">>, IgnoreEls, _el); + {<<"id">>, <<"jabber:x:event">>} -> + decode_xevent_id(<<"jabber:x:event">>, IgnoreEls, _el); + {<<"composing">>, <<"jabber:x:event">>} -> + decode_xevent_composing(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"displayed">>, <<"jabber:x:event">>} -> + decode_xevent_displayed(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"delivered">>, <<"jabber:x:event">>} -> + decode_xevent_delivered(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"offline">>, <<"jabber:x:event">>} -> + decode_xevent_offline(<<"jabber:x:event">>, IgnoreEls, + _el); {<<"query">>, <<"jabber:iq:search">>} -> decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); {<<"item">>, <<"jabber:iq:search">>} -> @@ -40,6 +58,9 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls, _el); {<<"store">>, <<"urn:xmpp:hints">>} -> decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); + {<<"no-storage">>, <<"urn:xmpp:hints">>} -> + decode_hint_no_storage(<<"urn:xmpp:hints">>, IgnoreEls, + _el); {<<"no-store">>, <<"urn:xmpp:hints">>} -> decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); @@ -1162,6 +1183,13 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"x">>, <<"jabber:x:expire">>} -> true; + {<<"x">>, <<"jabber:x:event">>} -> true; + {<<"id">>, <<"jabber:x:event">>} -> true; + {<<"composing">>, <<"jabber:x:event">>} -> true; + {<<"displayed">>, <<"jabber:x:event">>} -> true; + {<<"delivered">>, <<"jabber:x:event">>} -> true; + {<<"offline">>, <<"jabber:x:event">>} -> true; {<<"query">>, <<"jabber:iq:search">>} -> true; {<<"item">>, <<"jabber:iq:search">>} -> true; {<<"email">>, <<"jabber:iq:search">>} -> true; @@ -1172,6 +1200,7 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> true; {<<"store">>, <<"urn:xmpp:hints">>} -> true; + {<<"no-storage">>, <<"urn:xmpp:hints">>} -> true; {<<"no-store">>, <<"urn:xmpp:hints">>} -> true; {<<"no-copy">>, <<"urn:xmpp:hints">>} -> true; {<<"participant">>, <<"urn:xmpp:mix:0">>} -> true; @@ -2289,6 +2318,9 @@ encode({hint, 'no-copy'} = No_copy) -> encode({hint, 'no-store'} = No_store) -> encode_hint_no_store(No_store, [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({hint, 'no-storage'} = No_storage) -> + encode_hint_no_storage(No_storage, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); encode({hint, store} = Store) -> encode_hint_store(Store, [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); @@ -2301,7 +2333,12 @@ encode({search_item, _, _, _, _, _} = Item) -> [{<<"xmlns">>, <<"jabber:iq:search">>}]); encode({search, _, _, _, _, _, _, _} = Query) -> encode_search(Query, - [{<<"xmlns">>, <<"jabber:iq:search">>}]). + [{<<"xmlns">>, <<"jabber:iq:search">>}]); +encode({xevent, _, _, _, _, _} = X) -> + encode_xevent(X, [{<<"xmlns">>, <<"jabber:x:event">>}]); +encode({expire, _, _} = X) -> + encode_expire(X, + [{<<"xmlns">>, <<"jabber:x:expire">>}]). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2460,11 +2497,14 @@ get_name({mix_leave}) -> <<"leave">>; get_name({mix_participant, _, _}) -> <<"participant">>; get_name({hint, 'no-copy'}) -> <<"no-copy">>; get_name({hint, 'no-store'}) -> <<"no-store">>; +get_name({hint, 'no-storage'}) -> <<"no-storage">>; get_name({hint, store}) -> <<"store">>; get_name({hint, 'no-permanent-store'}) -> <<"no-permanent-store">>; get_name({search_item, _, _, _, _, _}) -> <<"item">>; -get_name({search, _, _, _, _, _, _, _}) -> <<"query">>. +get_name({search, _, _, _, _, _, _, _}) -> <<"query">>; +get_name({xevent, _, _, _, _, _}) -> <<"x">>; +get_name({expire, _, _}) -> <<"x">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -2685,13 +2725,16 @@ get_ns({mix_leave}) -> <<"urn:xmpp:mix:0">>; get_ns({mix_participant, _, _}) -> <<"urn:xmpp:mix:0">>; get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; get_ns({hint, 'no-store'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-storage'}) -> <<"urn:xmpp:hints">>; get_ns({hint, store}) -> <<"urn:xmpp:hints">>; get_ns({hint, 'no-permanent-store'}) -> <<"urn:xmpp:hints">>; get_ns({search_item, _, _, _, _, _}) -> <<"jabber:iq:search">>; get_ns({search, _, _, _, _, _, _, _}) -> - <<"jabber:iq:search">>. + <<"jabber:iq:search">>; +get_ns({xevent, _, _, _, _, _}) -> <<"jabber:x:event">>; +get_ns({expire, _, _}) -> <<"jabber:x:expire">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -2908,6 +2951,9 @@ pp(hint, 1) -> [type]; pp(search_item, 5) -> [jid, first, last, nick, email]; pp(search, 7) -> [instructions, first, last, nick, email, items, xdata]; +pp(xevent, 5) -> + [offline, delivered, displayed, composing, id]; +pp(expire, 2) -> [seconds, stored]; pp(_, _) -> no. join([], _Sep) -> <<>>; @@ -2954,6 +3000,267 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_expire(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Seconds, Stored} = decode_expire_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {expire, Seconds, Stored}. + +decode_expire_attrs(__TopXMLNS, + [{<<"seconds">>, _val} | _attrs], _Seconds, Stored) -> + decode_expire_attrs(__TopXMLNS, _attrs, _val, Stored); +decode_expire_attrs(__TopXMLNS, + [{<<"stored">>, _val} | _attrs], Seconds, _Stored) -> + decode_expire_attrs(__TopXMLNS, _attrs, Seconds, _val); +decode_expire_attrs(__TopXMLNS, [_ | _attrs], Seconds, + Stored) -> + decode_expire_attrs(__TopXMLNS, _attrs, Seconds, + Stored); +decode_expire_attrs(__TopXMLNS, [], Seconds, Stored) -> + {decode_expire_attr_seconds(__TopXMLNS, Seconds), + decode_expire_attr_stored(__TopXMLNS, Stored)}. + +encode_expire({expire, Seconds, Stored}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_expire_attr_stored(Stored, + encode_expire_attr_seconds(Seconds, + _xmlns_attrs)), + {xmlel, <<"x">>, _attrs, _els}. + +decode_expire_attr_seconds(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"seconds">>, <<"x">>, __TopXMLNS}}); +decode_expire_attr_seconds(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"seconds">>, <<"x">>, __TopXMLNS}}); + _res -> _res + end. + +encode_expire_attr_seconds(_val, _acc) -> + [{<<"seconds">>, enc_int(_val)} | _acc]. + +decode_expire_attr_stored(__TopXMLNS, undefined) -> + undefined; +decode_expire_attr_stored(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"stored">>, <<"x">>, __TopXMLNS}}); + _res -> _res + end. + +encode_expire_attr_stored(undefined, _acc) -> _acc; +encode_expire_attr_stored(_val, _acc) -> + [{<<"stored">>, enc_int(_val)} | _acc]. + +decode_xevent(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Id, Displayed, Delivered, Offline, Composing} = + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, + undefined, false, false, false, false), + {xevent, Offline, Delivered, Displayed, Composing, Id}. + +decode_xevent_els(__TopXMLNS, __IgnoreEls, [], Id, + Displayed, Delivered, Offline, Composing) -> + {Id, Displayed, Delivered, Offline, Composing}; +decode_xevent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"offline">>, _attrs, _} = _el | _els], Id, + Displayed, Delivered, Offline, Composing) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, + decode_xevent_offline(__TopXMLNS, __IgnoreEls, _el), + Composing); + <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, + decode_xevent_offline(<<"jabber:x:event">>, + __IgnoreEls, _el), + Composing); + _ -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing) + end; +decode_xevent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"delivered">>, _attrs, _} = _el | _els], Id, + Displayed, Delivered, Offline, Composing) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, + decode_xevent_delivered(__TopXMLNS, __IgnoreEls, + _el), + Offline, Composing); + <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, + decode_xevent_delivered(<<"jabber:x:event">>, + __IgnoreEls, _el), + Offline, Composing); + _ -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing) + end; +decode_xevent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"displayed">>, _attrs, _} = _el | _els], Id, + Displayed, Delivered, Offline, Composing) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + decode_xevent_displayed(__TopXMLNS, __IgnoreEls, + _el), + Delivered, Offline, Composing); + <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + decode_xevent_displayed(<<"jabber:x:event">>, + __IgnoreEls, _el), + Delivered, Offline, Composing); + _ -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing) + end; +decode_xevent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"composing">>, _attrs, _} = _el | _els], Id, + Displayed, Delivered, Offline, Composing) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, + decode_xevent_composing(__TopXMLNS, __IgnoreEls, + _el)); + <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, + decode_xevent_composing(<<"jabber:x:event">>, + __IgnoreEls, _el)); + _ -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing) + end; +decode_xevent_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"id">>, _attrs, _} = _el | _els], Id, + Displayed, Delivered, Offline, Composing) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, + decode_xevent_id(__TopXMLNS, __IgnoreEls, _el), + Displayed, Delivered, Offline, Composing); + <<"jabber:x:event">> -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, + decode_xevent_id(<<"jabber:x:event">>, __IgnoreEls, + _el), + Displayed, Delivered, Offline, Composing); + _ -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing) + end; +decode_xevent_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Id, Displayed, Delivered, Offline, Composing) -> + decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, + Displayed, Delivered, Offline, Composing). + +encode_xevent({xevent, Offline, Delivered, Displayed, + Composing, Id}, + _xmlns_attrs) -> + _els = lists:reverse('encode_xevent_$id'(Id, + 'encode_xevent_$displayed'(Displayed, + 'encode_xevent_$delivered'(Delivered, + 'encode_xevent_$offline'(Offline, + 'encode_xevent_$composing'(Composing, + [])))))), + _attrs = _xmlns_attrs, + {xmlel, <<"x">>, _attrs, _els}. + +'encode_xevent_$id'(undefined, _acc) -> _acc; +'encode_xevent_$id'(Id, _acc) -> + [encode_xevent_id(Id, []) | _acc]. + +'encode_xevent_$displayed'(false, _acc) -> _acc; +'encode_xevent_$displayed'(Displayed, _acc) -> + [encode_xevent_displayed(Displayed, []) | _acc]. + +'encode_xevent_$delivered'(false, _acc) -> _acc; +'encode_xevent_$delivered'(Delivered, _acc) -> + [encode_xevent_delivered(Delivered, []) | _acc]. + +'encode_xevent_$offline'(false, _acc) -> _acc; +'encode_xevent_$offline'(Offline, _acc) -> + [encode_xevent_offline(Offline, []) | _acc]. + +'encode_xevent_$composing'(false, _acc) -> _acc; +'encode_xevent_$composing'(Composing, _acc) -> + [encode_xevent_composing(Composing, []) | _acc]. + +decode_xevent_id(__TopXMLNS, __IgnoreEls, + {xmlel, <<"id">>, _attrs, _els}) -> + Cdata = decode_xevent_id_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_xevent_id_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_xevent_id_cdata(__TopXMLNS, Cdata); +decode_xevent_id_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_xevent_id_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_xevent_id_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_xevent_id_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_xevent_id(Cdata, _xmlns_attrs) -> + _els = encode_xevent_id_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"id">>, _attrs, _els}. + +decode_xevent_id_cdata(__TopXMLNS, <<>>) -> undefined; +decode_xevent_id_cdata(__TopXMLNS, _val) -> _val. + +encode_xevent_id_cdata(undefined, _acc) -> _acc; +encode_xevent_id_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_xevent_composing(__TopXMLNS, __IgnoreEls, + {xmlel, <<"composing">>, _attrs, _els}) -> + true. + +encode_xevent_composing(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"composing">>, _attrs, _els}. + +decode_xevent_displayed(__TopXMLNS, __IgnoreEls, + {xmlel, <<"displayed">>, _attrs, _els}) -> + true. + +encode_xevent_displayed(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"displayed">>, _attrs, _els}. + +decode_xevent_delivered(__TopXMLNS, __IgnoreEls, + {xmlel, <<"delivered">>, _attrs, _els}) -> + true. + +encode_xevent_delivered(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"delivered">>, _attrs, _els}. + +decode_xevent_offline(__TopXMLNS, __IgnoreEls, + {xmlel, <<"offline">>, _attrs, _els}) -> + true. + +encode_xevent_offline(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"offline">>, _attrs, _els}. + decode_search(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> {Xdata, Items, Instructions, Last, First, Nick, Email} = @@ -3459,6 +3766,16 @@ encode_hint_store({hint, store}, _xmlns_attrs) -> _attrs = _xmlns_attrs, {xmlel, <<"store">>, _attrs, _els}. +decode_hint_no_storage(__TopXMLNS, __IgnoreEls, + {xmlel, <<"no-storage">>, _attrs, _els}) -> + {hint, 'no-storage'}. + +encode_hint_no_storage({hint, 'no-storage'}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"no-storage">>, _attrs, _els}. + decode_hint_no_store(__TopXMLNS, __IgnoreEls, {xmlel, <<"no-store">>, _attrs, _els}) -> {hint, 'no-store'}. -- cgit v1.2.3 From bc802a4049c6a75f77323bf3c07a859dc1c4be47 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 19 Jul 2016 10:07:04 +0300 Subject: Rewrite mod_blocking to use XML generator --- src/mod_blocking.erl | 166 +++++++++++++++++++++++++++------------------------ src/mod_privacy.erl | 5 +- src/xmpp_codec.erl | 53 +++++++++++++--- 3 files changed, 136 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 818d53259..743b78efd 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -29,13 +29,13 @@ -protocol({xep, 191, '1.2'}). --export([start/2, stop/1, process_iq/3, - process_iq_set/4, process_iq_get/5, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, process_iq/1, + process_iq_set/2, process_iq_get/3, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). @@ -43,6 +43,8 @@ -callback unblock_by_filter(binary(), binary(), function()) -> {atomic, any()}. -callback process_blocklist_get(binary(), binary()) -> [listitem()] | error. +-type block_event() :: {block, [jid()]} | {unblock, [jid()]} | unblock_all. + start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, one_queue), @@ -66,55 +68,65 @@ stop(Host) -> depends(_Host, _Opts) -> [{mod_privacy, hard}]. -process_iq(_From, _To, IQ) -> - SubEl = IQ#iq.sub_el, - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. +-spec process_iq(iq()) -> iq(). +process_iq(IQ) -> + xmpp:make_error(IQ, xmpp:err_not_allowed()). -process_iq_get(_, From, _To, - #iq{xmlns = ?NS_BLOCKING, lang = Lang, - sub_el = #xmlel{name = <<"blocklist">>}}, - _) -> +-spec process_iq_get({error, error()} | {result, xmpp_element() | undefined}, + iq(), userlist()) -> + {error, error()} | {result, block_list()}. +process_iq_get(_, #iq{lang = Lang, from = From, + sub_els = [#block_list{}]}, _) -> #jid{luser = LUser, lserver = LServer} = From, {stop, process_blocklist_get(LUser, LServer, Lang)}; -process_iq_get(Acc, _, _, _, _) -> Acc. +process_iq_get(Acc, _, _) -> Acc. -process_iq_set(_, From, _To, - #iq{xmlns = ?NS_BLOCKING, lang = Lang, - sub_el = - #xmlel{name = SubElName, children = SubEls}}) -> +-spec process_iq_set({error, error()} | + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}, + iq()) -> {error, error()} | + {result, undefined} | + {result, undefined, userlist()}. +process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> #jid{luser = LUser, lserver = LServer} = From, - Res = case {SubElName, fxml:remove_cdata(SubEls)} of - {<<"block">>, []} -> - Txt = <<"No items found in this query">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - {<<"block">>, Els} -> - JIDs = parse_blocklist_items(Els, []), - process_blocklist_block(LUser, LServer, JIDs, Lang); - {<<"unblock">>, []} -> - process_blocklist_unblock_all(LUser, LServer, Lang); - {<<"unblock">>, Els} -> - JIDs = parse_blocklist_items(Els, []), - process_blocklist_unblock(LUser, LServer, JIDs, Lang); - _ -> - Txt = <<"Unknown blocking command">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + Res = case SubEl of + #block{items = []} -> + Txt = <<"No items found in this query">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + #block{items = Items} -> + JIDs = [jid:tolower(Item) || Item <- Items], + process_blocklist_block(LUser, LServer, JIDs, Lang); + #unblock{items = []} -> + process_blocklist_unblock_all(LUser, LServer, Lang); + #unblock{items = Items} -> + JIDs = [jid:tolower(Item) || Item <- Items], + process_blocklist_unblock(LUser, LServer, JIDs, Lang); + _ -> + Txt = <<"Only and are allowed " + "in this request">>, + {error, xmpp:err_bad_request(Txt, Lang)} end, {stop, Res}; -process_iq_set(Acc, _, _, _) -> Acc. +process_iq_set(Acc, _) -> Acc. +-spec list_to_blocklist_jids([listitem()], [ljid()]) -> [ljid()]. list_to_blocklist_jids([], JIDs) -> JIDs; list_to_blocklist_jids([#listitem{type = jid, action = deny, value = JID} = Item | Items], JIDs) -> - case Item of - #listitem{match_all = true} -> Match = true; - #listitem{match_iq = true, match_message = true, - match_presence_in = true, match_presence_out = true} -> - Match = true; - _ -> Match = false - end, + Match = case Item of + #listitem{match_all = true} -> + true; + #listitem{match_iq = true, + match_message = true, + match_presence_in = true, + match_presence_out = true} -> + true; + _ -> + false + end, if Match -> list_to_blocklist_jids(Items, [JID | JIDs]); true -> list_to_blocklist_jids(Items, JIDs) end; @@ -122,20 +134,10 @@ list_to_blocklist_jids([#listitem{type = jid, list_to_blocklist_jids([_ | Items], JIDs) -> list_to_blocklist_jids(Items, JIDs). -parse_blocklist_items([], JIDs) -> JIDs; -parse_blocklist_items([#xmlel{name = <<"item">>, - attrs = Attrs} - | Els], - JIDs) -> - case fxml:get_attr(<<"jid">>, Attrs) of - {value, JID1} -> - JID = jid:tolower(jid:from_string(JID1)), - parse_blocklist_items(Els, [JID | JIDs]); - false -> parse_blocklist_items(Els, JIDs) - end; -parse_blocklist_items([_ | Els], JIDs) -> - parse_blocklist_items(Els, JIDs). - +-spec process_blocklist_block(binary(), binary(), [ljid()], + undefined | binary()) -> + {error, error()} | + {result, undefined, userlist()}. process_blocklist_block(LUser, LServer, JIDs, Lang) -> Filter = fun (List) -> AlreadyBlocked = list_to_blocklist_jids(List, []), @@ -161,13 +163,17 @@ process_blocklist_block(LUser, LServer, JIDs, Lang) -> broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, - {block, JIDs}), - {result, [], UserList}; + {block, [jid:make(J) || J <- JIDs]}), + {result, undefined, UserList}; _Err -> ?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer, JIDs}, _Err]), - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)} + {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)} end. +-spec process_blocklist_unblock_all(binary(), binary(), undefined | binary()) -> + {error, error()} | + {result, undefined} | + {result, undefined, userlist()}. process_blocklist_unblock_all(LUser, LServer, Lang) -> Filter = fun (List) -> lists:filter(fun (#listitem{action = A}) -> A =/= deny @@ -176,18 +182,23 @@ process_blocklist_unblock_all(LUser, LServer, Lang) -> end, Mod = db_mod(LServer), case Mod:unblock_by_filter(LUser, LServer, Filter) of - {atomic, ok} -> {result, []}; + {atomic, ok} -> {result, undefined}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, unblock_all), - {result, [], UserList}; + {result, undefined, UserList}; _Err -> ?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer}, _Err]), - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)} + {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)} end. +-spec process_blocklist_unblock(binary(), binary(), [ljid()], + undefined | binary()) -> + {error, error()} | + {result, undefined} | + {result, undefined, userlist()}. process_blocklist_unblock(LUser, LServer, JIDs, Lang) -> Filter = fun (List) -> lists:filter(fun (#listitem{action = deny, type = jid, @@ -199,56 +210,53 @@ process_blocklist_unblock(LUser, LServer, JIDs, Lang) -> end, Mod = db_mod(LServer), case Mod:unblock_by_filter(LUser, LServer, Filter) of - {atomic, ok} -> {result, []}; + {atomic, ok} -> {result, undefined}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, - {unblock, JIDs}), - {result, [], UserList}; + {unblock, [jid:make(J) || J <- JIDs]}), + {result, undefined, UserList}; _Err -> ?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer, JIDs}, _Err]), - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)} + {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)} end. +-spec make_userlist(binary(), [listitem()]) -> userlist(). make_userlist(Name, List) -> NeedDb = mod_privacy:is_list_needdb(List), #userlist{name = Name, list = List, needdb = NeedDb}. +-spec broadcast_list_update(binary(), binary(), binary(), userlist()) -> + {broadcast, + {privacy_list, userlist(), binary() | none}}. broadcast_list_update(LUser, LServer, Name, UserList) -> - ejabberd_sm:route(jid:make(LUser, LServer, - <<"">>), + ejabberd_sm:route(jid:make(LUser, LServer, <<"">>), jid:make(LUser, LServer, <<"">>), {broadcast, {privacy_list, UserList, Name}}). +-spec broadcast_blocklist_event(binary(), binary(), block_event()) -> + {broadcast, {blocking, block_event()}}. broadcast_blocklist_event(LUser, LServer, Event) -> JID = jid:make(LUser, LServer, <<"">>), ejabberd_sm:route(JID, JID, {broadcast, {blocking, Event}}). +-spec process_blocklist_get(binary(), binary(), undefined | binary()) -> + {error, error()} | {result, block_list()}. process_blocklist_get(LUser, LServer, Lang) -> Mod = db_mod(LServer), case Mod:process_blocklist_get(LUser, LServer) of error -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)}; List -> - JIDs = list_to_blocklist_jids(List, []), - Items = lists:map(fun (JID) -> - ?DEBUG("JID: ~p", [JID]), - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - jid:to_string(JID)}], - children = []} - end, - JIDs), - {result, - [#xmlel{name = <<"blocklist">>, - attrs = [{<<"xmlns">>, ?NS_BLOCKING}], - children = Items}]} + LJIDs = list_to_blocklist_jids(List, []), + Items = [jid:make(J) || J <- LJIDs], + {result, #block_list{items = Items}} end. +-spec db_mod(binary()) -> module(). db_mod(LServer) -> DBType = gen_mod:db_type(LServer, mod_privacy), gen_mod:db_mod(DBType, ?MODULE). diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index e88c1fb5b..f61ba31d4 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -100,7 +100,7 @@ stop(Host) -> process_iq(IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed()). --spec process_iq_get({error, error()} | iq(), +-spec process_iq_get({error, error()} | {result, xmpp_element() | undefined}, iq(), userlist()) -> {error, error()} | {result, privacy_query()}. process_iq_get(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{lists = Lists}]}, @@ -215,7 +215,8 @@ decode_value(Type, Value) -> end. -spec process_iq_set({error, error()} | - {result, privacy_query() | undefined, userlist()}, + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}, iq()) -> {error, error()} | {result, undefined, userlist()}. process_iq_set(_, #iq{from = From, lang = Lang, diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 976a7bfeb..f6e5f0f1a 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -1899,7 +1899,7 @@ encode({block, _} = Block) -> encode({unblock, _} = Unblock) -> encode_unblock(Unblock, [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); -encode({block_list} = Blocklist) -> +encode({block_list, _} = Blocklist) -> encode_block_list(Blocklist, [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); encode({identity, _, _, _, _} = Identity) -> @@ -2351,7 +2351,7 @@ get_name({privacy_list, _, _}) -> <<"list">>; get_name({privacy_query, _, _, _}) -> <<"query">>; get_name({block, _}) -> <<"block">>; get_name({unblock, _}) -> <<"unblock">>; -get_name({block_list}) -> <<"blocklist">>; +get_name({block_list, _}) -> <<"blocklist">>; get_name({identity, _, _, _, _}) -> <<"identity">>; get_name({disco_info, _, _, _, _}) -> <<"query">>; get_name({disco_item, _, _, _}) -> <<"item">>; @@ -2520,7 +2520,7 @@ get_ns({privacy_query, _, _, _}) -> <<"jabber:iq:privacy">>; get_ns({block, _}) -> <<"urn:xmpp:blocking">>; get_ns({unblock, _}) -> <<"urn:xmpp:blocking">>; -get_ns({block_list}) -> <<"urn:xmpp:blocking">>; +get_ns({block_list, _}) -> <<"urn:xmpp:blocking">>; get_ns({identity, _, _, _, _}) -> <<"http://jabber.org/protocol/disco#info">>; get_ns({disco_info, _, _, _, _}) -> @@ -2796,7 +2796,7 @@ pp(privacy_list, 2) -> [name, items]; pp(privacy_query, 3) -> [lists, default, active]; pp(block, 1) -> [items]; pp(unblock, 1) -> [items]; -pp(block_list, 0) -> []; +pp(block_list, 1) -> [items]; pp(identity, 4) -> [category, type, lang, name]; pp(disco_info, 4) -> [node, identities, features, xdata]; @@ -22454,13 +22454,52 @@ encode_disco_identity_attr_name(_val, _acc) -> decode_block_list(__TopXMLNS, __IgnoreEls, {xmlel, <<"blocklist">>, _attrs, _els}) -> - {block_list}. + Items = decode_block_list_els(__TopXMLNS, __IgnoreEls, + _els, []), + {block_list, Items}. -encode_block_list({block_list}, _xmlns_attrs) -> - _els = [], +decode_block_list_els(__TopXMLNS, __IgnoreEls, [], + Items) -> + lists:reverse(Items); +decode_block_list_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> + decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(__TopXMLNS, __IgnoreEls, + _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + <<"urn:xmpp:blocking">> -> + decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, + case decode_block_item(<<"urn:xmpp:blocking">>, + __IgnoreEls, _el) + of + undefined -> Items; + _new_el -> [_new_el | Items] + end); + _ -> + decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, + Items) + end; +decode_block_list_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items) -> + decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, + Items). + +encode_block_list({block_list, Items}, _xmlns_attrs) -> + _els = lists:reverse('encode_block_list_$items'(Items, + [])), _attrs = _xmlns_attrs, {xmlel, <<"blocklist">>, _attrs, _els}. +'encode_block_list_$items'([], _acc) -> _acc; +'encode_block_list_$items'([Items | _els], _acc) -> + 'encode_block_list_$items'(_els, + [encode_block_item(Items, []) | _acc]). + decode_unblock(__TopXMLNS, __IgnoreEls, {xmlel, <<"unblock">>, _attrs, _els}) -> Items = decode_unblock_els(__TopXMLNS, __IgnoreEls, -- cgit v1.2.3 From 5d90292849029c2f2e35d61840d85678d4644e21 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 19 Jul 2016 15:33:17 +0300 Subject: Fix hooks de-registration --- src/mod_vcard.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index de9fce00d..f738648d6 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -115,9 +115,9 @@ loop(Host, ServerHost) -> loop(Host, ServerHost); stop -> ejabberd_router:unregister_route(Host), - ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50), - ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50), - ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50), + ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 100), + ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 100), + ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 100), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SEARCH), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), -- cgit v1.2.3 From 179fcd9521ef8db4626ca110ba80c502d810c814 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 25 Jul 2016 13:50:30 +0300 Subject: Rewrite mod_mam and mod_muc to use XML generator --- src/ejabberd_router.erl | 31 +- src/mod_disco.erl | 4 +- src/mod_last.erl | 2 +- src/mod_mam.erl | 715 ++++---- src/mod_mam_mnesia.erl | 28 +- src/mod_mam_sql.erl | 71 +- src/mod_muc.erl | 677 +++---- src/mod_muc_admin.erl | 12 +- src/mod_muc_log.erl | 36 +- src/mod_muc_room.erl | 4469 ++++++++++++++++++++--------------------------- src/mod_private.erl | 2 +- src/xmpp.erl | 240 ++- src/xmpp_codec.erl | 2404 +++++++++++++++++++------ src/xmpp_util.erl | 14 +- 14 files changed, 4574 insertions(+), 4131 deletions(-) (limited to 'src') diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 5924d92c0..83ffd932b 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -72,7 +72,7 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). --spec route(jid(), jid(), xmlel() | xmpp_element()) -> ok. +-spec route(jid(), jid(), xmlel() | stanza()) -> ok. route(From, To, Packet) -> case catch do_route(From, To, Packet) of @@ -85,13 +85,21 @@ route(From, To, Packet) -> %% Route the error packet only if the originating packet is not an error itself. %% RFC3920 9.3.1 --spec route_error(jid(), jid(), xmlel(), xmlel()) -> ok. +-spec route_error(jid(), jid(), xmlel(), xmlel()) -> ok; + (jid(), jid(), stanza(), error()) -> ok. -route_error(From, To, ErrPacket, OrigPacket) -> +route_error(From, To, #xmlel{} = ErrPacket, #xmlel{} = OrigPacket) -> #xmlel{attrs = Attrs} = OrigPacket, case <<"error">> == fxml:get_attr_s(<<"type">>, Attrs) of false -> route(From, To, ErrPacket); true -> ok + end; +route_error(From, To, Packet, #error{} = Err) -> + Type = xmpp:get_type(Packet), + if Type == error; Type == result -> + ok; + true -> + ejabberd_router:route(From, To, xmpp:make_error(Packet, Err)) end. -spec register_route(binary()) -> term(). @@ -406,11 +414,16 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> end. -spec do_route(jid(), jid(), xmlel() | xmpp_element(), #route{}) -> any(). -do_route(From, To, Packet, - #route{local_hint = {apply, Module, Function}, pid = Pid}) - when is_pid(Pid) andalso node(Pid) == node() -> - try - Module:Function(From, To, xmpp:decode(Packet, [ignore_els])) +do_route(From, To, Packet, #route{local_hint = LocalHint, + pid = Pid}) when is_pid(Pid) -> + try xmpp:decode(Packet, [ignore_els]) of + Pkt -> + case LocalHint of + {apply, Module, Function} when node(Pid) == node() -> + Module:Function(From, To, Pkt); + _ -> + Pid ! {route, From, To, Pkt} + end catch error:{xmpp_codec, Why} -> ?ERROR_MSG("failed to decode xml element ~p when " "routing from ~s to ~s: ~s", @@ -418,8 +431,6 @@ do_route(From, To, Packet, xmpp:format_error(Why)]), drop end; -do_route(From, To, Packet, #route{pid = Pid}) when is_pid(Pid) -> - Pid ! {route, From, To, xmpp:encode(Packet)}; do_route(_From, _To, _Packet, _Route) -> drop. diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 03fdab209..0d3f242a0 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -295,7 +295,7 @@ process_sm_iq_items(#iq{type = get, lang = Lang, end; false -> Txt = <<"Not subscribed">>, - xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)) + xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang)) end. -spec get_sm_items({error, error()} | {result, [disco_item()]} | empty, @@ -371,7 +371,7 @@ process_sm_iq_info(#iq{type = get, lang = Lang, end; false -> Txt = <<"Not subscribed">>, - xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)) + xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang)) end. -spec get_sm_identity([identity()], jid(), jid(), diff --git a/src/mod_last.erl b/src/mod_last.erl index b267aa89b..6d0edebf0 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -140,7 +140,7 @@ process_sm_iq(#iq{from = From, to = To, lang = Lang} = IQ) -> end; true -> Txt = <<"Not subscribed">>, - xmpp:make_error(IQ, xmpp:err_not_subscribed(Txt, Lang)) + xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang)) end. %% @spec (LUser::string(), LServer::string()) -> diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 10eb098da..b4ee17720 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -34,12 +34,12 @@ -export([start/2, stop/1, depends/2]). -export([user_send_packet/4, user_send_packet_strip_tag/4, user_receive_packet/5, - process_iq_v0_2/3, process_iq_v0_3/3, disco_sm_features/5, - remove_user/2, remove_room/3, mod_opt_type/1, muc_process_iq/4, + process_iq_v0_2/1, process_iq_v0_3/1, disco_sm_features/5, + remove_user/2, remove_room/3, mod_opt_type/1, muc_process_iq/2, muc_filter_message/5, message_is_archived/5, delete_old_messages/2, get_commands_spec/0, msg_to_el/4, get_room_config/4, set_room_option/4]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("logger.hrl"). -include("mod_muc_room.hrl"). -include("ejabberd_commands.hrl"). @@ -54,17 +54,12 @@ -callback delete_old_messages(binary() | global, erlang:timestamp(), all | chat | groupchat) -> any(). --callback extended_fields() -> [xmlel()]. +-callback extended_fields() -> [xdata_field()]. -callback store(xmlel(), binary(), {binary(), binary()}, chat | groupchat, jid(), binary(), recv | send) -> {ok, binary()} | any(). -callback write_prefs(binary(), binary(), #archive_prefs{}, binary()) -> ok | any(). -callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error. --callback select(binary(), jid(), jid(), - none | erlang:timestamp(), - none | erlang:timestamp(), - none | ljid() | {text, binary()}, - none | #rsm_in{}, - chat | groupchat) -> +-callback select(binary(), jid(), jid(), mam_query(), chat | groupchat) -> {[{binary(), non_neg_integer(), xmlel()}], boolean(), non_neg_integer()}. %%%=================================================================== @@ -200,14 +195,10 @@ get_room_config(X, RoomState, _From, Lang) -> true -> <<"1">>; _ -> <<"0">> end, - XField = #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"boolean">>}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}, + XField = #xdata_field{type = boolean, + label = translate:translate(Lang, Label), + var = Var, + values = [Val]}, X ++ [XField]. set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) -> @@ -222,7 +213,7 @@ set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) -> catch _:{case_clause, _} -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_BAD_REQUEST(Lang, ErrTxt)} + {error, xmpp:err_bad_request(Lang, ErrTxt)} end; set_room_option(Acc, _Opt, _Vals, _Lang) -> Acc. @@ -236,16 +227,7 @@ user_receive_packet(Pkt, C2SState, JID, Peer, To) -> NewPkt = strip_my_archived_tag(Pkt, LServer), case store_msg(C2SState, NewPkt, LUser, LServer, Peer, recv) of {ok, ID} -> - Archived = #xmlel{name = <<"archived">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_MAM_TMP}, - {<<"id">>, ID}]}, - StanzaID = #xmlel{name = <<"stanza-id">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_SID_0}, - {<<"id">>, ID}]}, - NewEls = [Archived, StanzaID|NewPkt#xmlel.children], - NewPkt#xmlel{children = NewEls}; + set_stanza_id(NewPkt, LServer, ID); _ -> NewPkt end; @@ -259,19 +241,10 @@ user_send_packet(Pkt, C2SState, JID, Peer) -> case should_archive(Pkt, LServer) of true -> NewPkt = strip_my_archived_tag(Pkt, LServer), - case store_msg(C2SState, jlib:replace_from_to(JID, Peer, NewPkt), + case store_msg(C2SState, xmpp:set_from_to(NewPkt, JID, Peer), LUser, LServer, Peer, send) of {ok, ID} -> - Archived = #xmlel{name = <<"archived">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_MAM_TMP}, - {<<"id">>, ID}]}, - StanzaID = #xmlel{name = <<"stanza-id">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_SID_0}, - {<<"id">>, ID}]}, - NewEls = [Archived, StanzaID|NewPkt#xmlel.children], - NewPkt#xmlel{children = NewEls}; + set_stanza_id(NewPkt, LServer, ID); _ -> NewPkt end; @@ -291,16 +264,7 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, StorePkt = strip_x_jid_tags(NewPkt), case store_muc(MUCState, StorePkt, RoomJID, From, FromNick) of {ok, ID} -> - Archived = #xmlel{name = <<"archived">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_MAM_TMP}, - {<<"id">>, ID}]}, - StanzaID = #xmlel{name = <<"stanza-id">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_SID_0}, - {<<"id">>, ID}]}, - NewEls = [Archived, StanzaID|NewPkt#xmlel.children], - NewPkt#xmlel{children = NewEls}; + set_stanza_id(NewPkt, LServer, ID); _ -> NewPkt end; @@ -308,71 +272,98 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, Pkt end. +set_stanza_id(Pkt, LServer, ID) -> + Archived = #mam_archived{by = jid:make(LServer), id = ID}, + StanzaID = #stanza_id{by = jid:make(LServer), id = ID}, + NewEls = [Archived, StanzaID|xmpp:get_els(Pkt)], + xmpp:set_els(Pkt, NewEls). + % Query archive v0.2 -process_iq_v0_2(#jid{lserver = LServer} = From, - #jid{lserver = LServer} = To, - #iq{type = get, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> - Fs = parse_query_v0_2(SubEl), - process_iq(LServer, From, To, IQ, SubEl, Fs, chat); -process_iq_v0_2(From, To, IQ) -> - process_iq(From, To, IQ). +process_iq_v0_2(#iq{from = #jid{lserver = LServer}, + to = #jid{lserver = LServer}, + type = get, sub_els = [#mam_query{}]} = IQ) -> + process_iq(LServer, IQ, chat); +process_iq_v0_2(IQ) -> + process_iq(IQ). % Query archive v0.3 -process_iq_v0_3(#jid{lserver = LServer} = From, - #jid{lserver = LServer} = To, - #iq{type = set, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> - process_iq(LServer, From, To, IQ, SubEl, get_xdata_fields(SubEl), chat); -process_iq_v0_3(#jid{lserver = LServer}, - #jid{lserver = LServer}, - #iq{type = get, sub_el = #xmlel{name = <<"query">>}} = IQ) -> +process_iq_v0_3(#iq{from = #jid{lserver = LServer}, + to = #jid{lserver = LServer}, + type = set, sub_els = [#mam_query{}]} = IQ) -> + process_iq(LServer, IQ, chat); +process_iq_v0_3(#iq{from = #jid{lserver = LServer}, + to = #jid{lserver = LServer}, + type = get, sub_els = [#mam_query{}]} = IQ) -> process_iq(LServer, IQ); -process_iq_v0_3(From, To, IQ) -> - process_iq(From, To, IQ). - -muc_process_iq(#iq{type = set, - sub_el = #xmlel{name = <<"query">>, - attrs = Attrs} = SubEl} = IQ, - MUCState, From, To) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - NS when NS == ?NS_MAM_0; NS == ?NS_MAM_1 -> - muc_process_iq(IQ, MUCState, From, To, get_xdata_fields(SubEl)); - _ -> - IQ - end; -muc_process_iq(#iq{type = get, - sub_el = #xmlel{name = <<"query">>, - attrs = Attrs} = SubEl} = IQ, - MUCState, From, To) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MAM_TMP -> - muc_process_iq(IQ, MUCState, From, To, parse_query_v0_2(SubEl)); - NS when NS == ?NS_MAM_0; NS == ?NS_MAM_1 -> +process_iq_v0_3(IQ) -> + process_iq(IQ). + +muc_process_iq(#iq{type = T, lang = Lang, + from = From, + sub_els = [#mam_query{xmlns = NS}]} = IQ, + MUCState) + when (T == set andalso (NS == ?NS_MAM_0 orelse NS == ?NS_MAM_1)) orelse + (T == get andalso NS == ?NS_MAM_TMP) -> + case may_enter_room(From, MUCState) of + true -> LServer = MUCState#state.server_host, - process_iq(LServer, IQ); - _ -> - IQ + Role = mod_muc_room:get_role(From, MUCState), + process_iq(LServer, IQ, {groupchat, Role, MUCState}); + false -> + Text = <<"Only members may query archives of this room">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Text, Lang)) end; -muc_process_iq(IQ, _MUCState, _From, _To) -> +muc_process_iq(#iq{type = get, + sub_els = [#mam_query{xmlns = NS}]} = IQ, + MUCState) when NS == ?NS_MAM_0; NS == ?NS_MAM_1 -> + LServer = MUCState#state.server_host, + process_iq(LServer, IQ); +muc_process_iq(IQ, _MUCState) -> IQ. -get_xdata_fields(SubEl) -> - case {fxml:get_subtag_with_xmlns(SubEl, <<"x">>, ?NS_XDATA), - fxml:get_subtag_with_xmlns(SubEl, <<"set">>, ?NS_RSM)} of - {#xmlel{} = XData, false} -> - jlib:parse_xdata_submit(XData); - {#xmlel{} = XData, #xmlel{}} -> - [{<<"set">>, SubEl} | jlib:parse_xdata_submit(XData)]; - {false, #xmlel{}} -> - [{<<"set">>, SubEl}]; - {false, false} -> - [] - end. +parse_query(#mam_query{xdata = #xdata{fields = Fs}} = Query, Lang) -> + try + lists:foldl( + fun(#xdata_field{var = <<"start">>, values = [Data|_]}, Q) -> + case jlib:datetime_string_to_timestamp(Data) of + undefined -> throw({error, <<"start">>}); + {_, _, _} = TS -> Q#mam_query{start = TS} + end; + (#xdata_field{var = <<"end">>, values = [Data|_]}, Q) -> + case jlib:datetime_string_to_timestamp(Data) of + undefined -> throw({error, <<"end">>}); + {_, _, _} = TS -> Q#mam_query{'end' = TS} + end; + (#xdata_field{var = <<"with">>, values = [Data|_]}, Q) -> + case jid:from_string(Data) of + error -> throw({error, <<"with">>}); + J -> Q#mam_query{with = J} + end; + (#xdata_field{var = <<"withtext">>, values = [Data|_]}, Q) -> + case Data of + <<"">> -> throw({error, <<"withtext">>}); + _ -> Q#mam_query{withtext = Data} + end; + (#xdata_field{var = <<"FORM_TYPE">>, values = [NS|_]}, Q) -> + case Query#mam_query.xmlns of + NS -> Q; + _ -> throw({error, <<"FORM_TYPE">>}) + end; + (#xdata_field{}, Acc) -> + Acc + end, Query, Fs) + catch throw:{error, Var} -> + Txt = io_lib:format("Incorrect value of field '~s'", [Var]), + {error, xmpp:err_bad_request(iolist_to_binary(Txt), Lang)} + end; +parse_query(Query, _Lang) -> + Query. disco_sm_features(empty, From, To, Node, Lang) -> disco_sm_features({result, []}, From, To, Node, Lang); disco_sm_features({result, OtherFeatures}, #jid{luser = U, lserver = S}, - #jid{luser = U, lserver = S}, <<>>, _Lang) -> + #jid{luser = U, lserver = S}, undefined, _Lang) -> {result, [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1 | OtherFeatures]}; disco_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. @@ -440,210 +431,155 @@ delete_old_messages(_TypeBin, _Days) -> %%% Internal functions %%%=================================================================== -process_iq(LServer, #iq{sub_el = #xmlel{attrs = Attrs}} = IQ) -> - NS = case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MAM_0 -> - ?NS_MAM_0; - _ -> - ?NS_MAM_1 - end, - CommonFields = [#xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"hidden">>}, - {<<"var">>, <<"FORM_TYPE">>}], - children = [#xmlel{name = <<"value">>, - children = [{xmlcdata, NS}]}]}, - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"jid-single">>}, - {<<"var">>, <<"with">>}]}, - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"text-single">>}, - {<<"var">>, <<"start">>}]}, - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"text-single">>}, - {<<"var">>, <<"end">>}]}], +process_iq(LServer, #iq{sub_els = [#mam_query{xmlns = NS}]} = IQ) -> + CommonFields = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [NS]}, + #xdata_field{type = 'jid-single', var = <<"with">>}, + #xdata_field{type = 'text-single', var = <<"start">>}, + #xdata_field{type = 'text-single', var = <<"end">>}], Mod = gen_mod:db_mod(LServer, ?MODULE), ExtendedFields = Mod:extended_fields(), - Fields = ExtendedFields ++ CommonFields, - Form = #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = Fields}, - IQ#iq{type = result, - sub_el = [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, NS}], - children = [Form]}]}. + Fields = CommonFields ++ ExtendedFields, + Form = #xdata{type = form, fields = Fields}, + xmpp:make_iq_result(IQ, #mam_query{xmlns = NS, xdata = Form}). % Preference setting (both v0.2 & v0.3) -process_iq(#jid{luser = LUser, lserver = LServer}, - #jid{lserver = LServer}, - #iq{type = set, lang = Lang, sub_el = #xmlel{name = <<"prefs">>} = SubEl} = IQ) -> - try {case fxml:get_tag_attr_s(<<"default">>, SubEl) of - <<"always">> -> always; - <<"never">> -> never; - <<"roster">> -> roster - end, - lists:foldl( - fun(#xmlel{name = <<"always">>, children = Els}, {A, N}) -> - {get_jids(Els) ++ A, N}; - (#xmlel{name = <<"never">>, children = Els}, {A, N}) -> - {A, get_jids(Els) ++ N}; - (_, {A, N}) -> - {A, N} - end, {[], []}, SubEl#xmlel.children)} of - {Default, {Always0, Never0}} -> - Always = lists:usort(Always0), - Never = lists:usort(Never0), - case write_prefs(LUser, LServer, LServer, Default, Always, Never) of - ok -> - NewPrefs = prefs_el(Default, Always, Never, IQ#iq.xmlns), - IQ#iq{type = result, sub_el = [NewPrefs]}; - _Err -> - Txt = <<"Database failure">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]} - end - catch _:_ -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} +process_iq(#iq{type = set, lang = Lang, + sub_els = [#mam_prefs{default = undefined, xmlns = NS}]} = IQ) -> + Why = {missing_attr, <<"default">>, <<"prefs">>, NS}, + ErrTxt = xmpp:format_error(Why), + xmpp:make_error(IQ, xmpp:err_bad_request(ErrTxt, Lang)); +process_iq(#iq{from = #jid{luser = LUser, lserver = LServer}, + to = #jid{lserver = LServer}, + type = set, lang = Lang, + sub_els = [#mam_prefs{xmlns = NS, + default = Default, + always = Always0, + never = Never0}]} = IQ) -> + Always = lists:usort(get_jids(Always0)), + Never = lists:usort(get_jids(Never0)), + case write_prefs(LUser, LServer, LServer, Default, Always, Never) of + ok -> + NewPrefs = prefs_el(Default, Always, Never, NS), + xmpp:make_iq_result(IQ, NewPrefs); + _Err -> + Txt = <<"Database failure">>, + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)) end; -process_iq(#jid{luser = LUser, lserver = LServer}, - #jid{lserver = LServer}, - #iq{type = get, sub_el = #xmlel{name = <<"prefs">>}} = IQ) -> +process_iq(#iq{from = #jid{luser = LUser, lserver = LServer}, + to = #jid{lserver = LServer}, + type = get, sub_els = [#mam_prefs{xmlns = NS}]} = IQ) -> Prefs = get_prefs(LUser, LServer), PrefsEl = prefs_el(Prefs#archive_prefs.default, Prefs#archive_prefs.always, Prefs#archive_prefs.never, - IQ#iq.xmlns), - IQ#iq{type = result, sub_el = [PrefsEl]}; -process_iq(_, _, #iq{sub_el = SubEl} = IQ) -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. + NS), + xmpp:make_iq_result(IQ, PrefsEl); +process_iq(IQ) -> + xmpp:make_error(IQ, xmpp:err_not_allowed()). -process_iq(LServer, #jid{luser = LUser} = From, To, IQ, SubEl, Fs, MsgType) -> +process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang, + sub_els = [SubEl]} = IQ, MsgType) -> case MsgType of chat -> maybe_activate_mam(LUser, LServer); {groupchat, _Role, _MUCState} -> ok end, - case catch lists:foldl( - fun({<<"start">>, [Data|_]}, {_, End, With, RSM}) -> - {{_, _, _} = jlib:datetime_string_to_timestamp(Data), - End, With, RSM}; - ({<<"end">>, [Data|_]}, {Start, _, With, RSM}) -> - {Start, - {_, _, _} = jlib:datetime_string_to_timestamp(Data), - With, RSM}; - ({<<"with">>, [Data|_]}, {Start, End, _, RSM}) -> - {Start, End, jid:tolower(jid:from_string(Data)), RSM}; - ({<<"withtext">>, [Data|_]}, {Start, End, _, RSM}) -> - {Start, End, {text, Data}, RSM}; - ({<<"set">>, El}, {Start, End, With, _}) -> - {Start, End, With, jlib:rsm_decode(El)}; - (_, Acc) -> - Acc - end, {none, [], none, none}, Fs) of - {'EXIT', _} -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; - {_Start, _End, _With, #rsm_in{index = Index}} when is_integer(Index) -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}; - {Start, End, With, RSM} -> - NS = fxml:get_tag_attr_s(<<"xmlns">>, SubEl), - select_and_send(LServer, From, To, Start, End, - With, limit_max(RSM, NS), IQ, MsgType) + case parse_query(SubEl, Lang) of + #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) -> + xmpp:make_error(IQ, xmpp:err_feature_not_implemented()); + #mam_query{rsm = RSM, xmlns = NS} = Query -> + NewRSM = limit_max(RSM, NS), + NewQuery = Query#mam_query{rsm = NewRSM}, + select_and_send(LServer, NewQuery, IQ, MsgType); + {error, Err} -> + xmpp:make_error(IQ, Err) end. -muc_process_iq(#iq{lang = Lang, sub_el = SubEl} = IQ, MUCState, From, To, Fs) -> - case may_enter_room(From, MUCState) of +should_archive(#message{type = T}, _LServer) when T == error; T == result -> + false; +should_archive(#message{body = Body} = Pkt, LServer) -> + case is_resent(Pkt, LServer) of true -> - LServer = MUCState#state.server_host, - Role = mod_muc_room:get_role(From, MUCState), - process_iq(LServer, From, To, IQ, SubEl, Fs, - {groupchat, Role, MUCState}); - false -> - Text = <<"Only members may query archives of this room">>, - Error = ?ERRT_FORBIDDEN(Lang, Text), - IQ#iq{type = error, sub_el = [SubEl, Error]} - end. - -parse_query_v0_2(Query) -> - lists:flatmap( - fun (#xmlel{name = <<"start">>} = El) -> - [{<<"start">>, [fxml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"end">>} = El) -> - [{<<"end">>, [fxml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"with">>} = El) -> - [{<<"with">>, [fxml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"withtext">>} = El) -> - [{<<"withtext">>, [fxml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"set">>}) -> - [{<<"set">>, Query}]; - (_) -> - [] - end, Query#xmlel.children). - -should_archive(#xmlel{name = <<"message">>} = Pkt, LServer) -> - case fxml:get_attr_s(<<"type">>, Pkt#xmlel.attrs) of - <<"error">> -> false; - <<"groupchat">> -> - false; - _ -> - case is_resent(Pkt, LServer) of - true -> + false -> + case check_store_hint(Pkt) of + store -> + true; + no_store -> false; - false -> - case check_store_hint(Pkt) of - store -> - true; - no_store -> + none -> + case xmpp:get_text(Body) of + <<>> -> + %% Empty body false; - none -> - case fxml:get_subtag_cdata(Pkt, <<"body">>) of - <<>> -> - %% Empty body - false; - _ -> - true - end + _ -> + true end end end; -should_archive(#xmlel{}, _LServer) -> +should_archive(_, _LServer) -> false. strip_my_archived_tag(Pkt, LServer) -> + NewPkt = xmpp:decode_els( + Pkt, fun(El) -> + case xmpp:get_name(El) of + <<"archived">> -> + xmpp:get_ns(El) == ?NS_MAM_TMP; + <<"stanza-id">> -> + xmpp:get_ns(El) == ?NS_SID_0; + _ -> + false + end + end), NewEls = lists:filter( - fun(#xmlel{name = Tag, attrs = Attrs}) - when Tag == <<"archived">>; Tag == <<"stanza-id">> -> - case catch jid:nameprep( - fxml:get_attr_s( - <<"by">>, Attrs)) of - LServer -> - false; - _ -> - true - end; - (_) -> - true - end, Pkt#xmlel.children), - Pkt#xmlel{children = NewEls}. + fun(#mam_archived{by = #jid{luser = <<>>} = By}) -> + By#jid.lserver /= LServer; + (#stanza_id{by = #jid{luser = <<>>} = By}) -> + By#jid.lserver /= LServer; + (_) -> + true + end, xmpp:get_els(NewPkt)), + xmpp:set_els(NewPkt, NewEls). strip_x_jid_tags(Pkt) -> + NewPkt = xmpp:decode_els( + Pkt, fun(El) -> + case xmpp:get_name(El) of + <<"x">> -> + case xmpp:get_ns(El) of + ?NS_MUC_USER -> true; + ?NS_MUC_ADMIN -> true; + ?NS_MUC_OWNER -> true; + _ -> false + end; + _ -> + false + end + end), NewEls = lists:filter( - fun(#xmlel{name = <<"x">>} = XEl) -> - not lists:any(fun(ItemEl) -> - fxml:get_tag_attr(<<"jid">>, ItemEl) - /= false - end, fxml:get_subtags(XEl, <<"item">>)); - (_) -> - true - end, Pkt#xmlel.children), - Pkt#xmlel{children = NewEls}. + fun(El) -> + Items = case El of + #muc_user{items = Is} -> Is; + #muc_admin{items = Is} -> Is; + #muc_owner{items = Is} -> Is; + _ -> [] + end, + not lists:any(fun(#muc_item{jid = JID}) -> + JID /= undefined + end, Items) + end, xmpp:get_els(NewPkt)), + xmpp:set_els(NewPkt, NewEls). should_archive_peer(C2SState, #archive_prefs{default = Default, always = Always, never = Never}, Peer) -> - LPeer = jid:tolower(Peer), + LPeer = jid:remove_resource(jid:tolower(Peer)), case lists:member(LPeer, Always) of true -> true; @@ -667,30 +603,30 @@ should_archive_peer(C2SState, end end. -should_archive_muc(Pkt) -> - case fxml:get_attr_s(<<"type">>, Pkt#xmlel.attrs) of - <<"groupchat">> -> - case check_store_hint(Pkt) of - store -> - true; - no_store -> - false; - none -> - case fxml:get_subtag_cdata(Pkt, <<"body">>) of - <<>> -> - case fxml:get_subtag_cdata(Pkt, <<"subject">>) of - <<>> -> - false; - _ -> - true - end; +should_archive_muc(#message{type = groupchat, + body = Body, subject = Subj} = Pkt) -> + case check_store_hint(Pkt) of + store -> + true; + no_store -> + false; + none -> + case xmpp:get_text(Body) of + <<"">> -> + case xmpp:get_text(Subj) of + <<"">> -> + false; _ -> true - end + end; + _ -> + true end; _ -> false - end. + end; +should_archive_muc(_) -> + false. check_store_hint(Pkt) -> case has_store_hint(Pkt) of @@ -705,30 +641,24 @@ check_store_hint(Pkt) -> end end. + +-spec has_store_hint(message()) -> boolean(). has_store_hint(Message) -> - fxml:get_subtag_with_xmlns(Message, <<"store">>, ?NS_HINTS) - /= false. + xmpp:has_subtag(Message, #hint{type = 'store'}). +-spec has_no_store_hint(message()) -> boolean(). has_no_store_hint(Message) -> - fxml:get_subtag_with_xmlns(Message, <<"no-store">>, ?NS_HINTS) - /= false orelse - fxml:get_subtag_with_xmlns(Message, <<"no-storage">>, ?NS_HINTS) - /= false orelse - fxml:get_subtag_with_xmlns(Message, <<"no-permanent-store">>, ?NS_HINTS) - /= false orelse - fxml:get_subtag_with_xmlns(Message, <<"no-permanent-storage">>, ?NS_HINTS) - /= false. + xmpp:has_subtag(Message, #hint{type = 'no-store'}) orelse + xmpp:has_subtag(Message, #hint{type = 'no-storage'}) orelse + xmpp:has_subtag(Message, #hint{type = 'no-permanent-store'}) orelse + xmpp:has_subtag(Message, #hint{type = 'no-permanent-storage'}). +-spec is_resent(message(), binary()) -> boolean(). is_resent(Pkt, LServer) -> - case fxml:get_subtag_with_xmlns(Pkt, <<"stanza-id">>, ?NS_SID_0) of - #xmlel{attrs = Attrs} -> - case fxml:get_attr(<<"by">>, Attrs) of - {value, LServer} -> - true; - _ -> - false - end; - false -> + case xmpp:get_subtag(Pkt, #stanza_id{}) of + #stanza_id{by = #jid{luser = <<>>, lserver = LServer}} -> + true; + _ -> false end. @@ -744,7 +674,8 @@ store_msg(C2SState, Pkt, LUser, LServer, Peer, Dir) -> true -> US = {LUser, LServer}, Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:store(Pkt, LServer, US, chat, Peer, <<"">>, Dir); + El = xmpp:encode(Pkt), + Mod:store(El, LServer, US, chat, Peer, <<"">>, Dir); false -> pass end. @@ -755,7 +686,8 @@ store_muc(MUCState, Pkt, RoomJID, Peer, Nick) -> LServer = MUCState#state.server_host, {U, S, _} = jid:tolower(RoomJID), Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:store(Pkt, LServer, {U, S}, groupchat, Peer, Nick, recv); + El = xmpp:encode(Pkt), + Mod:store(El, LServer, {U, S}, groupchat, Peer, Nick, recv); false -> pass end. @@ -796,20 +728,10 @@ get_prefs(LUser, LServer) -> end. prefs_el(Default, Always, Never, NS) -> - Default1 = jlib:atom_to_binary(Default), - JFun = fun(L) -> - [#xmlel{name = <<"jid">>, - children = [{xmlcdata, jid:to_string(J)}]} - || J <- L] - end, - Always1 = #xmlel{name = <<"always">>, - children = JFun(Always)}, - Never1 = #xmlel{name = <<"never">>, - children = JFun(Never)}, - #xmlel{name = <<"prefs">>, - attrs = [{<<"xmlns">>, NS}, - {<<"default">>, Default1}], - children = [Always1, Never1]}. + #mam_prefs{default = Default, + always = [jid:make(LJ) || LJ <- Always], + never = [jid:make(LJ) || LJ <- Never], + xmlns = NS}. maybe_activate_mam(LUser, LServer) -> ActivateOpt = gen_mod:get_module_opt(LServer, ?MODULE, @@ -838,21 +760,19 @@ maybe_activate_mam(LUser, LServer) -> ok end. -select_and_send(LServer, From, To, Start, End, With, RSM, IQ, MsgType) -> - {Msgs, IsComplete, Count} = select_and_start(LServer, From, To, Start, End, - With, RSM, MsgType), +select_and_send(LServer, Query, #iq{from = From, to = To} = IQ, MsgType) -> + {Msgs, IsComplete, Count} = + case MsgType of + chat -> + select(LServer, From, From, Query, MsgType); + {groupchat, _Role, _MUCState} -> + select(LServer, From, To, Query, MsgType) + end, SortedMsgs = lists:keysort(2, Msgs), - send(From, To, SortedMsgs, RSM, Count, IsComplete, IQ). + send(SortedMsgs, Count, IsComplete, IQ). -select_and_start(LServer, From, To, Start, End, With, RSM, MsgType) -> - case MsgType of - chat -> - select(LServer, From, From, Start, End, With, RSM, MsgType); - {groupchat, _Role, _MUCState} -> - select(LServer, From, To, Start, End, With, RSM, MsgType) - end. - -select(_LServer, JidRequestor, JidArchive, Start, End, _With, RSM, +select(_LServer, JidRequestor, JidArchive, + #mam_query{start = Start, 'end' = End, rsm = RSM}, {groupchat, _Role, #state{config = #config{mam = false}, history = History}} = MsgType) -> #lqueue{len = L, queue = Q} = History, @@ -864,7 +784,7 @@ select(_LServer, JidRequestor, JidArchive, Start, End, _With, RSM, case match_interval(Now, Start, End) and match_rsm(Now, RSM) of true -> - {[{jlib:integer_to_binary(TS), TS, + {[{integer_to_binary(TS), TS, msg_to_el(#archive_msg{ type = groupchat, timestamp = Now, @@ -879,31 +799,27 @@ select(_LServer, JidRequestor, JidArchive, Start, End, _With, RSM, end, 0, queue:to_list(Q)), Msgs = lists:flatten(Msgs0), case RSM of - #rsm_in{max = Max, direction = before} -> + #rsm_set{max = Max, before = Before} when is_binary(Before) -> {NewMsgs, IsComplete} = filter_by_max(lists:reverse(Msgs), Max), {NewMsgs, IsComplete, L}; - #rsm_in{max = Max} -> + #rsm_set{max = Max} -> {NewMsgs, IsComplete} = filter_by_max(Msgs, Max), {NewMsgs, IsComplete, L}; _ -> {Msgs, true, L} end; -select(LServer, JidRequestor, JidArchive, Start, End, With, RSM, MsgType) -> +select(LServer, JidRequestor, JidArchive, Query, MsgType) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:select(LServer, JidRequestor, JidArchive, Start, End, With, RSM, - MsgType). + Mod:select(LServer, JidRequestor, JidArchive, Query, MsgType). msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, MsgType, JidRequestor, #jid{lserver = LServer} = JidArchive) -> Pkt2 = maybe_update_from_to(Pkt1, JidRequestor, JidArchive, Peer, MsgType, Nick), - Pkt3 = #xmlel{name = <<"forwarded">>, - attrs = [{<<"xmlns">>, ?NS_FORWARD}], - children = [fxml:replace_tag_attr( - <<"xmlns">>, <<"jabber:client">>, Pkt2)]}, - jlib:add_delay_info(Pkt3, LServer, TS). + #forwarded{sub_els = [Pkt2], + delay = #delay{stamp = TS, from = jid:make(LServer)}}. -maybe_update_from_to(#xmlel{children = Els} = Pkt, JidRequestor, JidArchive, +maybe_update_from_to(#message{sub_els = Els} = Pkt, JidRequestor, JidArchive, Peer, {groupchat, Role, #state{config = #config{anonymous = Anon}}}, Nick) -> @@ -919,18 +835,13 @@ maybe_update_from_to(#xmlel{children = Els} = Pkt, JidRequestor, JidArchive, end, Items = case ExposeJID of true -> - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}], - children = - [#xmlel{name = <<"item">>, - attrs = [{<<"jid">>, - jid:to_string(Peer)}]}]}]; + [#muc_user{items = [#muc_item{jid = Peer}]}]; false -> [] end, - Pkt1 = Pkt#xmlel{children = Items ++ Els}, - Pkt2 = jlib:replace_from(jid:replace_resource(JidArchive, Nick), Pkt1), - jlib:remove_attr(<<"to">>, Pkt2); + Pkt#message{from = jid:replace_resource(JidArchive, Nick), + to = undefined, + sub_els = Items ++ Els}; maybe_update_from_to(Pkt, _JidRequestor, _JidArchive, _Peer, chat, _Nick) -> Pkt. @@ -966,62 +877,46 @@ is_bare_copy(#jid{luser = U, lserver = S, lresource = R}, To) -> false end. -send(From, To, Msgs, RSM, Count, IsComplete, #iq{sub_el = SubEl} = IQ) -> - QID = fxml:get_tag_attr_s(<<"queryid">>, SubEl), - NS = fxml:get_tag_attr_s(<<"xmlns">>, SubEl), - QIDAttr = if QID /= <<>> -> - [{<<"queryid">>, QID}]; - true -> - [] - end, - CompleteAttr = if NS == ?NS_MAM_TMP -> - []; - NS == ?NS_MAM_0; NS == ?NS_MAM_1 -> - [{<<"complete">>, jlib:atom_to_binary(IsComplete)}] - end, +-spec send([{binary(), integer(), xmlel()}], + non_neg_integer(), boolean(), iq()) -> iq() | ignore. +send(Msgs, Count, IsComplete, + #iq{from = From, to = To, + sub_els = [#mam_query{id = QID, xmlns = NS}]} = IQ) -> Els = lists:map( fun({ID, _IDInt, El}) -> - #xmlel{name = <<"message">>, - children = [#xmlel{name = <<"result">>, - attrs = [{<<"xmlns">>, NS}, - {<<"id">>, ID}|QIDAttr], - children = [El]}]} + #message{sub_els = [#mam_result{xmlns = NS, + id = ID, + queryid = QID, + sub_els = [El]}]} end, Msgs), - RSMOut = make_rsm_out(Msgs, RSM, Count, QIDAttr ++ CompleteAttr, NS), + RSMOut = make_rsm_out(Msgs, Count), + Result = if NS == ?NS_MAM_TMP -> + #mam_query{xmlns = NS, id = QID, rsm = RSMOut}; + true -> + #mam_fin{id = QID, rsm = RSMOut, complete = IsComplete} + end, if NS == ?NS_MAM_TMP; NS == ?NS_MAM_1 -> lists:foreach( fun(El) -> ejabberd_router:route(To, From, El) end, Els), - IQ#iq{type = result, sub_el = RSMOut}; + xmpp:make_iq_result(IQ, Result); NS == ?NS_MAM_0 -> - ejabberd_router:route( - To, From, jlib:iq_to_xml(IQ#iq{type = result, sub_el = []})), + ejabberd_router:route(To, From, xmpp:make_iq_result(IQ)), lists:foreach( fun(El) -> ejabberd_router:route(To, From, El) end, Els), - ejabberd_router:route( - To, From, #xmlel{name = <<"message">>, - children = RSMOut}), + ejabberd_router:route(To, From, #message{sub_els = [Result]}), ignore end. -make_rsm_out([], _, Count, Attrs, NS) -> - Tag = if NS == ?NS_MAM_TMP -> <<"query">>; - true -> <<"fin">> - end, - [#xmlel{name = Tag, attrs = [{<<"xmlns">>, NS}|Attrs], - children = jlib:rsm_encode(#rsm_out{count = Count})}]; -make_rsm_out([{FirstID, _, _}|_] = Msgs, _, Count, Attrs, NS) -> +-spec make_rsm_out([{binary(), integer(), xmlel()}], non_neg_integer()) -> rsm_set(). +make_rsm_out([], Count) -> + #rsm_set{count = Count}; +make_rsm_out([{FirstID, _, _}|_] = Msgs, Count) -> {LastID, _, _} = lists:last(Msgs), - Tag = if NS == ?NS_MAM_TMP -> <<"query">>; - true -> <<"fin">> - end, - [#xmlel{name = Tag, attrs = [{<<"xmlns">>, NS}|Attrs], - children = jlib:rsm_encode( - #rsm_out{first = FirstID, count = Count, - last = LastID})}]. + #rsm_set{first = #rsm_first{data = FirstID}, last = LastID, count = Count}. filter_by_max(Msgs, undefined) -> {Msgs, true}; @@ -1030,23 +925,24 @@ filter_by_max(Msgs, Len) when is_integer(Len), Len >= 0 -> filter_by_max(_Msgs, _Junk) -> {[], true}. +-spec limit_max(rsm_set(), binary()) -> rsm_set(). limit_max(RSM, ?NS_MAM_TMP) -> RSM; % XEP-0313 v0.2 doesn't require clients to support RSM. -limit_max(#rsm_in{max = Max} = RSM, _NS) when not is_integer(Max) -> - RSM#rsm_in{max = ?DEF_PAGE_SIZE}; -limit_max(#rsm_in{max = Max} = RSM, _NS) when Max > ?MAX_PAGE_SIZE -> - RSM#rsm_in{max = ?MAX_PAGE_SIZE}; +limit_max(#rsm_set{max = Max} = RSM, _NS) when not is_integer(Max) -> + RSM#rsm_set{max = ?DEF_PAGE_SIZE}; +limit_max(#rsm_set{max = Max} = RSM, _NS) when Max > ?MAX_PAGE_SIZE -> + RSM#rsm_set{max = ?MAX_PAGE_SIZE}; limit_max(RSM, _NS) -> RSM. match_interval(Now, Start, End) -> (Now >= Start) and (Now =< End). -match_rsm(Now, #rsm_in{id = ID, direction = aft}) when ID /= <<"">> -> - Now1 = (catch usec_to_now(jlib:binary_to_integer(ID))), +match_rsm(Now, #rsm_set{'after' = ID}) when is_binary(ID), ID /= <<"">> -> + Now1 = (catch usec_to_now(binary_to_integer(ID))), Now > Now1; -match_rsm(Now, #rsm_in{id = ID, direction = before}) when ID /= <<"">> -> - Now1 = (catch usec_to_now(jlib:binary_to_integer(ID))), +match_rsm(Now, #rsm_set{before = ID}) when is_binary(ID), ID /= <<"">> -> + Now1 = (catch usec_to_now(binary_to_integer(ID))), Now < Now1; match_rsm(_Now, _) -> true. @@ -1066,15 +962,10 @@ datetime_to_now(DateTime, USecs) -> calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}), {Seconds div 1000000, Seconds rem 1000000, USecs}. -get_jids(Els) -> - lists:flatmap( - fun(#xmlel{name = <<"jid">>} = El) -> - J = jid:from_string(fxml:get_tag_cdata(El)), - [jid:tolower(jid:remove_resource(J)), - jid:tolower(J)]; - (_) -> - [] - end, Els). +get_jids(undefined) -> + []; +get_jids(Js) -> + [jid:tolower(jid:remove_resource(J)) || J <- Js]. get_commands_spec() -> [#ejabberd_commands{name = delete_old_mam_messages, tags = [purge], diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl index be14d0fff..cbe7c336c 100644 --- a/src/mod_mam_mnesia.erl +++ b/src/mod_mam_mnesia.erl @@ -12,10 +12,10 @@ %% API -export([init/2, remove_user/2, remove_room/3, delete_old_messages/3, - extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/8]). + extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/5]). -include_lib("stdlib/include/ms_transform.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("logger.hrl"). -include("mod_mam.hrl"). @@ -132,7 +132,8 @@ get_prefs(LUser, LServer) -> select(_LServer, JidRequestor, #jid{luser = LUser, lserver = LServer} = JidArchive, - Start, End, With, RSM, MsgType) -> + #mam_query{start = Start, 'end' = End, + with = With, rsm = RSM}, MsgType) -> MS = make_matchspec(LUser, LServer, Start, End, With), Msgs = mnesia:dirty_select(archive_msg, MS), SortedMsgs = lists:keysort(#archive_msg.timestamp, Msgs), @@ -174,7 +175,7 @@ make_matchspec(LUser, LServer, Start, End, {_, _, _} = With) -> Peer == With -> Msg end); -make_matchspec(LUser, LServer, Start, End, none) -> +make_matchspec(LUser, LServer, Start, End, undefined) -> ets:fun2ms( fun(#archive_msg{timestamp = TS, us = US, @@ -184,28 +185,27 @@ make_matchspec(LUser, LServer, Start, End, none) -> Msg end). -filter_by_rsm(Msgs, none) -> +filter_by_rsm(Msgs, undefined) -> {Msgs, true}; -filter_by_rsm(_Msgs, #rsm_in{max = Max}) when Max < 0 -> +filter_by_rsm(_Msgs, #rsm_set{max = Max}) when Max < 0 -> {[], true}; -filter_by_rsm(Msgs, #rsm_in{max = Max, direction = Direction, id = ID}) -> - NewMsgs = case Direction of - aft when ID /= <<"">> -> +filter_by_rsm(Msgs, #rsm_set{max = Max, before = Before, 'after' = After}) -> + NewMsgs = if is_binary(After), After /= <<"">> -> lists:filter( fun(#archive_msg{id = I}) -> - ?BIN_GREATER_THAN(I, ID) + ?BIN_GREATER_THAN(I, After) end, Msgs); - before when ID /= <<"">> -> + is_binary(Before), Before /= <<"">> -> lists:foldl( fun(#archive_msg{id = I} = Msg, Acc) - when ?BIN_LESS_THAN(I, ID) -> + when ?BIN_LESS_THAN(I, Before) -> [Msg|Acc]; (_, Acc) -> Acc end, [], Msgs); - before when ID == <<"">> -> + is_binary(Before), Before == <<"">> -> lists:reverse(Msgs); - _ -> + true -> Msgs end, filter_by_max(NewMsgs, Max). diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 20ed8d4f1..6e5231989 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -14,10 +14,10 @@ %% API -export([init/2, remove_user/2, remove_room/3, delete_old_messages/3, - extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/8]). + extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/5]). -include_lib("stdlib/include/ms_transform.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_mam.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). @@ -51,9 +51,7 @@ delete_old_messages(ServerHost, TimeStamp, Type) -> ok. extended_fields() -> - [#xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"text-single">>}, - {<<"var">>, <<"withtext">>}]}]. + [#xdata_field{type = 'text-single', var = <<"withtext">>}]. store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir) -> TSinteger = p1_time_compat:system_time(micro_seconds), @@ -126,13 +124,12 @@ get_prefs(LUser, LServer) -> end. select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, - Start, End, With, RSM, MsgType) -> + MAMQuery, MsgType) -> User = case MsgType of chat -> LUser; {groupchat, _Role, _MUCState} -> jid:to_string(JidArchive) end, - {Query, CountQuery} = make_sql_query(User, LServer, - Start, End, With, RSM), + {Query, CountQuery} = make_sql_query(User, LServer, MAMQuery), % TODO from XEP-0313 v0.2: "To conserve resources, a server MAY place a % reasonable limit on how many stanzas may be pushed to a client in one % request. If a query returns a number of stanzas greater than this limit @@ -142,10 +139,7 @@ select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, case {ejabberd_sql:sql_query(LServer, Query), ejabberd_sql:sql_query(LServer, CountQuery)} of {{selected, _, Res}, {selected, _, [[Count]]}} -> - {Max, Direction} = case RSM of - #rsm_in{max = M, direction = D} -> {M, D}; - _ -> {undefined, undefined} - end, + {Max, Direction, _} = get_max_direction_id(MAMQuery#mam_query.rsm), {Res1, IsComplete} = if Max >= 0 andalso Max /= undefined andalso length(Res) > Max -> if Direction == before -> @@ -200,15 +194,10 @@ usec_to_now(Int) -> Sec = Secs rem 1000000, {MSec, Sec, USec}. -make_sql_query(User, LServer, Start, End, With, RSM) -> - {Max, Direction, ID} = case RSM of - #rsm_in{} -> - {RSM#rsm_in.max, - RSM#rsm_in.direction, - RSM#rsm_in.id}; - none -> - {none, none, <<>>} - end, +make_sql_query(User, LServer, + #mam_query{start = Start, 'end' = End, with = With, + withtext = WithText, rsm = RSM}) -> + {Max, Direction, ID} = get_max_direction_id(RSM), ODBCType = ejabberd_config:get_option( {sql_type, LServer}, ejabberd_sql:opt_type(sql_type)), @@ -228,12 +217,16 @@ make_sql_query(User, LServer, Start, End, With, RSM) -> true -> [] end, - WithClause = case With of - {text, <<>>} -> - []; - {text, Txt} -> - [<<" and match (txt) against ('">>, - Escape(Txt), <<"')">>]; + WithTextClause = case WithText of + {text, <<>>} -> + []; + {text, Txt} -> + [<<" and match (txt) against ('">>, + Escape(Txt), <<"')">>]; + undefined -> + [] + end, + WithClause = case catch jid:tolower(With) of {_, _, <<>>} -> [<<" and bare_peer='">>, Escape(jid:to_string(With)), @@ -242,7 +235,7 @@ make_sql_query(User, LServer, Start, End, With, RSM) -> [<<" and peer='">>, Escape(jid:to_string(With)), <<"'">>]; - none -> + _ -> [] end, PageClause = case catch jlib:binary_to_integer(ID) of @@ -250,7 +243,7 @@ make_sql_query(User, LServer, Start, End, With, RSM) -> case Direction of before -> [<<" AND timestamp < ">>, ID]; - aft -> + 'after' -> [<<" AND timestamp > ">>, ID]; _ -> [] @@ -276,7 +269,7 @@ make_sql_query(User, LServer, Start, End, With, RSM) -> Query = [<<"SELECT ">>, TopClause, <<" timestamp, xml, peer, kind, nick" " FROM archive WHERE username='">>, - SUser, <<"'">>, WithClause, StartClause, EndClause, + SUser, <<"'">>, WithClause, WithTextClause, StartClause, EndClause, PageClause], QueryPage = @@ -294,4 +287,20 @@ make_sql_query(User, LServer, Start, End, With, RSM) -> end, {QueryPage, [<<"SELECT COUNT(*) FROM archive WHERE username='">>, - SUser, <<"'">>, WithClause, StartClause, EndClause, <<";">>]}. + SUser, <<"'">>, WithClause, WithTextClause, StartClause, EndClause, <<";">>]}. + +-spec get_max_direction_id(rsm_set() | undefined) -> + {integer() | undefined, + before | 'after' | undefined, + binary()}. +get_max_direction_id(RSM) -> + case RSM of + #rsm_set{max = Max, before = Before} when is_binary(Before) -> + {Max, before, Before}; + #rsm_set{max = Max, 'after' = After} when is_binary(After) -> + {Max, 'after', After}; + #rsm_set{max = Max} -> + {Max, undefined, <<>>}; + _ -> + {undefined, undefined, <<>>} + end. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index a86f580d3..294456ee2 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -43,7 +43,12 @@ forget_room/3, create_room/5, shutdown_rooms/1, - process_iq_disco_items/4, + process_disco_info/1, + process_disco_items/1, + process_vcard/1, + process_register/1, + process_muc_unique/1, + process_mucsub/1, broadcast_service_message/2, export/1, import/1, @@ -58,7 +63,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_muc.hrl"). -record(state, @@ -154,17 +159,6 @@ forget_room(ServerHost, Host, Name) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:forget_room(LServer, Host, Name). -process_iq_disco_items(Host, From, To, - #iq{lang = Lang} = IQ) -> - Rsm = jlib:rsm_decode(IQ), - DiscoNode = fxml:get_tag_attr_s(<<"node">>, IQ#iq.sub_el), - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}], - children = iq_disco_items(Host, From, Lang, DiscoNode, Rsm)}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(Res)). - can_use_nick(_ServerHost, _Host, _JID, <<"">>) -> false; can_use_nick(ServerHost, Host, JID, Nick) -> LServer = jid:nameprep(ServerHost), @@ -176,6 +170,8 @@ can_use_nick(ServerHost, Host, JID, Nick) -> %%==================================================================== init([Host, Opts]) -> + IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, + one_queue), MyHost = gen_mod:get_opt_host(Host, Opts, <<"conference.@HOST@">>), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), @@ -255,6 +251,18 @@ init([Host, Opts]) -> RoomShaper = gen_mod:get_opt(room_shaper, Opts, fun(A) when is_atom(A) -> A end, none), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER, + ?MODULE, process_register, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD, + ?MODULE, process_vcard, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_MUCSUB, + ?MODULE, process_mucsub, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_MUC_UNIQUE, + ?MODULE, process_muc_unique, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, + ?MODULE, process_disco_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS, + ?MODULE, process_disco_items, IQDisc), ejabberd_router:register_route(MyHost, Host), load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin, AccessPersistent}, @@ -314,8 +322,14 @@ handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -terminate(_Reason, State) -> - ejabberd_router:unregister_route(State#state.host), +terminate(_Reason, #state{host = MyHost}) -> + ejabberd_router:unregister_route(MyHost), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_MUCSUB), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_MUC_UNIQUE), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -331,197 +345,162 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper, allow -> do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts); - _ -> - #xmlel{attrs = Attrs} = Packet, - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), + deny -> + Lang = xmpp:get_lang(Packet), ErrText = <<"Access denied by service policy">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, ErrText)), - ejabberd_router:route_error(To, From, Err, Packet) + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end. - +do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, + From, #jid{luser = <<"">>, lresource = <<"">>} = To, + #iq{} = IQ, _DefRoomOpts) -> + ejabberd_local:process_iq(From, To, IQ); +do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper, + From, #jid{luser = <<"">>, lresource = <<"">>} = To, + #message{lang = Lang, body = Body, type = Type} = Packet, _) -> + {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = Access, + if Type == error -> + ok; + true -> + case acl:match_rule(ServerHost, AccessAdmin, From) of + allow -> + Msg = xmpp:get_text(Body), + broadcast_service_message(Host, Msg); + deny -> + ErrText = <<"Only service administrators are allowed " + "to send service messages">>, + Err = xmpp:make_error( + Packet, xmpp:err_forbidden(ErrText, Lang)), + ejabberd_router:route(To, From, Err) + end + end; +do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, + From, #jid{luser = <<"">>} = To, Packet, _DefRoomOpts) -> + Err = xmpp:err_item_not_found(), + ejabberd_router:route_error(To, From, Packet, Err); do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> - {_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access, + {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent} = Access, {Room, _, Nick} = jid:tolower(To), - #xmlel{name = Name, attrs = Attrs} = Packet, - case Room of - <<"">> -> - case Nick of - <<"">> -> - case Name of - <<"iq">> -> - case jlib:iq_query_info(Packet) of - #iq{type = get, xmlns = (?NS_DISCO_INFO) = XMLNS, - sub_el = _SubEl, lang = Lang} = - IQ -> - Info = ejabberd_hooks:run_fold(disco_info, - ServerHost, [], - [ServerHost, ?MODULE, - <<"">>, <<"">>]), - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, XMLNS}], - children = - iq_disco_info( - ServerHost, Lang) ++ - Info}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ -> - spawn(?MODULE, process_iq_disco_items, - [Host, From, To, IQ]); - #iq{type = get, xmlns = (?NS_REGISTER) = XMLNS, - lang = Lang, sub_el = _SubEl} = - IQ -> - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, XMLNS}], - children = - iq_get_register_info(ServerHost, - Host, - From, - Lang)}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{type = set, xmlns = (?NS_REGISTER) = XMLNS, - lang = Lang, sub_el = SubEl} = - IQ -> - case process_iq_register_set(ServerHost, Host, From, - SubEl, Lang) - of - {result, IQRes} -> - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - XMLNS}], - children = IQRes}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - {error, Error} -> - Err = jlib:make_error_reply(Packet, Error), - ejabberd_router:route(To, From, Err) - end; - #iq{type = get, xmlns = (?NS_VCARD) = XMLNS, - lang = Lang, sub_el = _SubEl} = - IQ -> - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = - [{<<"xmlns">>, XMLNS}], - children = - iq_get_vcard(Lang)}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{type = get, xmlns = ?NS_MUCSUB, - sub_el = #xmlel{name = <<"subscriptions">>} = SubEl} = IQ -> - RoomJIDs = get_subscribed_rooms(ServerHost, Host, From), - Subs = lists:map( - fun(J) -> - #xmlel{name = <<"subscription">>, - attrs = [{<<"jid">>, - jid:to_string(J)}]} - end, RoomJIDs), - Res = IQ#iq{type = result, - sub_el = [SubEl#xmlel{children = Subs}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); - #iq{type = get, xmlns = ?NS_MUC_UNIQUE} = IQ -> - Res = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"unique">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_UNIQUE}], - children = - [iq_get_unique(From)]}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{} -> - Err = jlib:make_error_reply(Packet, - ?ERR_FEATURE_NOT_IMPLEMENTED), - ejabberd_router:route(To, From, Err); - _ -> ok - end; - <<"message">> -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - _ -> - case acl:match_rule(ServerHost, AccessAdmin, From) - of - allow -> - Msg = fxml:get_path_s(Packet, - [{elem, <<"body">>}, - cdata]), - broadcast_service_message(Host, Msg); - _ -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - ErrText = - <<"Only service administrators are allowed " - "to send service messages">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, - ErrText)), - ejabberd_router:route(To, From, Err) - end - end; - <<"presence">> -> ok - end; - _ -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - <<"result">> -> ok; - _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_ITEM_NOT_FOUND), - ejabberd_router:route(To, From, Err) - end - end; - _ -> - case mnesia:dirty_read(muc_online_room, {Room, Host}) of - [] -> - Type = fxml:get_attr_s(<<"type">>, Attrs), - case {Name, Type} of - {<<"presence">>, <<"">>} -> - case check_user_can_create_room(ServerHost, - AccessCreate, From, Room) and - check_create_roomid(ServerHost, Room) of - true -> - {ok, Pid} = start_new_room(Host, ServerHost, Access, - Room, HistorySize, - RoomShaper, From, Nick, DefRoomOpts), - register_room(Host, Room, Pid), - mod_muc_room:route(Pid, From, Nick, Packet), - ok; - false -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - ErrText = <<"Room creation is denied by service policy">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), - ejabberd_router:route(To, From, Err) - end; - _ -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - ErrText = <<"Conference room does not exist">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), + case mnesia:dirty_read(muc_online_room, {Room, Host}) of + [] -> + case Packet of + #presence{type = available, lang = Lang} -> + case check_user_can_create_room( + ServerHost, AccessCreate, From, Room) and + check_create_roomid(ServerHost, Room) of + true -> + {ok, Pid} = start_new_room( + Host, ServerHost, Access, + Room, HistorySize, + RoomShaper, From, Nick, DefRoomOpts), + register_room(Host, Room, Pid), + mod_muc_room:route(Pid, From, Nick, Packet), + ok; + false -> + ErrText = <<"Room creation is denied by service policy">>, + Err = xmpp:make_error( + Packet, xmpp:err_forbidden(ErrText, Lang)), ejabberd_router:route(To, From, Err) end; - [R] -> - Pid = R#muc_online_room.pid, - ?DEBUG("MUC: send to process ~p~n", [Pid]), - mod_muc_room:route(Pid, From, Nick, Packet), - ok - end + _ -> + Lang = xmpp:get_lang(Packet), + ErrText = <<"Conference room does not exist">>, + Err = xmpp:err_item_not_found(ErrText, Lang), + ejabberd_router:route_error(To, From, Packet, Err) + end; + [R] -> + Pid = R#muc_online_room.pid, + ?DEBUG("MUC: send to process ~p~n", [Pid]), + mod_muc_room:route(Pid, From, Nick, Packet), + ok + end. + +-spec process_vcard(iq()) -> iq(). +process_vcard(#iq{type = get, lang = Lang} = IQ) -> + Desc = translate:translate(Lang, <<"ejabberd MUC module">>), + Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, + xmpp:make_iq_result( + IQ, #vcard_temp{fn = <<"ejabberd/mod_muc">>, + url = ?EJABBERD_URI, + desc = <>}); +process_vcard(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). + +-spec process_register(iq()) -> iq(). +process_register(#iq{type = get, from = From, to = To, lang = Lang} = IQ) -> + Host = To#jid.lserver, + ServerHost = ejabberd_router:host_of_route(Host), + xmpp:make_iq_result(IQ, iq_get_register_info(ServerHost, Host, From, Lang)); +process_register(#iq{type = set, from = From, to = To, + lang = Lang, sub_els = [El]} = IQ) -> + Host = To#jid.lserver, + ServerHost = ejabberd_router:host_of_route(Host), + case process_iq_register_set(ServerHost, Host, From, El, Lang) of + {result, Result} -> + xmpp:make_iq_result(IQ, Result); + {error, Err} -> + xmpp:make_error(IQ, Err) end. +-spec process_disco_info(iq()) -> iq(). +process_disco_info(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_disco_info(#iq{type = get, to = To, lang = Lang, + sub_els = [#disco_info{node = undefined}]} = IQ) -> + ServerHost = ejabberd_router:host_of_route(To#jid.lserver), + X = ejabberd_hooks:run_fold(disco_info, ServerHost, [], + [ServerHost, ?MODULE, undefined, Lang]), + MAMFeatures = case gen_mod:is_loaded(ServerHost, mod_mam) of + true -> [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1]; + false -> [] + end, + Features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, + ?NS_REGISTER, ?NS_MUC, ?NS_RSM, + ?NS_VCARD, ?NS_MUCSUB, ?NS_MUC_UNIQUE | MAMFeatures], + Identity = #identity{category = <<"conference">>, + type = <<"text">>, + name = translate:translate(Lang, <<"Chatrooms">>)}, + xmpp:make_iq_result( + IQ, #disco_info{features = Features, + identities = [Identity], + xdata = X}); +process_disco_info(#iq{type = get, lang = Lang} = IQ) -> + xmpp:make_error(IQ, xmpp:err_item_not_found(<<"No info available">>, Lang)). + +-spec process_disco_items(iq()) -> iq(). +process_disco_items(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_disco_items(#iq{type = get, from = From, to = To, lang = Lang, + sub_els = [#disco_items{node = Node, rsm = RSM}]} = IQ) -> + Host = To#jid.lserver, + xmpp:make_iq_result( + IQ, #disco_items{node = Node, + items = iq_disco_items(Host, From, Lang, Node, RSM)}). + +-spec process_muc_unique(iq()) -> iq(). +process_muc_unique(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_muc_unique(#iq{from = From, type = get} = IQ) -> + Name = p1_sha:sha(term_to_binary([From, p1_time_compat:timestamp(), + randoms:get_string()])), + xmpp:make_iq_result(IQ, #muc_unique{name = Name}). + +-spec process_mucsub(iq()) -> iq(). +process_mucsub(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_mucsub(#iq{type = get, from = From, to = To} = IQ) -> + Host = To#jid.lserver, + ServerHost = ejabberd_router:host_of_route(Host), + RoomJIDs = get_subscribed_rooms(ServerHost, Host, From), + xmpp:make_iq_result(IQ, #muc_subscriptions{list = RoomJIDs}). + check_user_can_create_room(ServerHost, AccessCreate, From, _RoomID) -> case acl:match_rule(ServerHost, AccessCreate, From) of @@ -583,61 +562,21 @@ register_room(Host, Room, Pid) -> end, mnesia:transaction(F). - -iq_disco_info(ServerHost, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"conference">>}, - {<<"type">>, <<"text">>}, - {<<"name">>, - translate:translate(Lang, <<"Chatrooms">>)}], - children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_DISCO_INFO}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_DISCO_ITEMS}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MUC}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MUC_UNIQUE}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_REGISTER}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_RSM}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MUCSUB}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_VCARD}], children = []}] ++ - case gen_mod:is_loaded(ServerHost, mod_mam) of - true -> - [#xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MAM_TMP}]}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MAM_0}]}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MAM_1}]}]; - false -> - [] - end. - -iq_disco_items(Host, From, Lang, <<>>, none) -> +iq_disco_items(Host, From, Lang, undefined, undefined) -> Rooms = get_vh_rooms(Host), case erlang:length(Rooms) < ?MAX_ROOMS_DISCOITEMS of true -> iq_disco_items_list(Host, Rooms, {get_disco_item, all, From, Lang}); false -> - iq_disco_items(Host, From, Lang, <<"nonemptyrooms">>, none) + iq_disco_items(Host, From, Lang, <<"nonemptyrooms">>, undefined) end; -iq_disco_items(Host, From, Lang, <<"nonemptyrooms">>, none) -> - XmlEmpty = #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, <<"conference.localhost">>}, - {<<"node">>, <<"emptyrooms">>}, - {<<"name">>, translate:translate(Lang, <<"Empty Rooms">>)}], - children = []}, +iq_disco_items(Host, From, Lang, <<"nonemptyrooms">>, undefined) -> + Empty = #disco_item{jid = jid:make(<<"conference.localhost">>), + node = <<"emptyrooms">>, + name = translate:translate(Lang, <<"Empty Rooms">>)}, Query = {get_disco_item, only_non_empty, From, Lang}, - [XmlEmpty | iq_disco_items_list(Host, get_vh_rooms(Host), Query)]; -iq_disco_items(Host, From, Lang, <<"emptyrooms">>, none) -> + [Empty | iq_disco_items_list(Host, get_vh_rooms(Host), Query)]; +iq_disco_items(Host, From, Lang, <<"emptyrooms">>, undefined) -> iq_disco_items_list(Host, get_vh_rooms(Host), {get_disco_item, 0, From, Lang}); iq_disco_items(Host, From, Lang, _DiscoNode, Rsm) -> {Rooms, RsmO} = get_vh_rooms(Host, Rsm), @@ -645,62 +584,55 @@ iq_disco_items(Host, From, Lang, _DiscoNode, Rsm) -> iq_disco_items_list(Host, Rooms, {get_disco_item, all, From, Lang}) ++ RsmOut. iq_disco_items_list(Host, Rooms, Query) -> - lists:zf(fun (#muc_online_room{name_host = - {Name, _Host}, - pid = Pid}) -> - case catch gen_fsm:sync_send_all_state_event(Pid, - Query, - 100) - of - {item, Desc} -> - flush(), - {true, - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - jid:to_string({Name, Host, - <<"">>})}, - {<<"name">>, Desc}], - children = []}}; - _ -> false - end - end, Rooms). - -get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})-> - AllRooms = lists:sort(get_vh_rooms(Host)), - Count = erlang:length(AllRooms), - Guard = case Direction of - _ when Index =/= undefined -> [{'==', {element, 2, '$1'}, Host}]; - aft -> [{'==', {element, 2, '$1'}, Host}, {'>=',{element, 1, '$1'} ,I}]; - before when I =/= []-> [{'==', {element, 2, '$1'}, Host}, {'=<',{element, 1, '$1'} ,I}]; - _ -> [{'==', {element, 2, '$1'}, Host}] - end, - L = lists:sort( - mnesia:dirty_select(muc_online_room, - [{#muc_online_room{name_host = '$1', _ = '_'}, - Guard, - ['$_']}])), - L2 = if - Index == undefined andalso Direction == before -> - lists:reverse(lists:sublist(lists:reverse(L), 1, M)); - Index == undefined -> - lists:sublist(L, 1, M); - Index > Count orelse Index < 0 -> - []; - true -> - lists:sublist(L, Index+1, M) - end, - if L2 == [] -> {L2, #rsm_out{count = Count}}; - true -> - H = hd(L2), - NewIndex = get_room_pos(H, AllRooms), - T = lists:last(L2), - {F, _} = H#muc_online_room.name_host, - {Last, _} = T#muc_online_room.name_host, - {L2, - #rsm_out{first = F, last = Last, count = Count, - index = NewIndex}} - end. + lists:zf( + fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> + case catch gen_fsm:sync_send_all_state_event(Pid, Query, 100) of + {item, Desc} -> + flush(), + {true, #disco_item{jid = jid:make(Name, Host), + name = Desc}}; + _ -> + false + end + end, Rooms). + +get_vh_rooms(_, _) -> + todo. +%% get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})-> +%% AllRooms = lists:sort(get_vh_rooms(Host)), +%% Count = erlang:length(AllRooms), +%% Guard = case Direction of +%% _ when Index =/= undefined -> [{'==', {element, 2, '$1'}, Host}]; +%% aft -> [{'==', {element, 2, '$1'}, Host}, {'>=',{element, 1, '$1'} ,I}]; +%% before when I =/= []-> [{'==', {element, 2, '$1'}, Host}, {'=<',{element, 1, '$1'} ,I}]; +%% _ -> [{'==', {element, 2, '$1'}, Host}] +%% end, +%% L = lists:sort( +%% mnesia:dirty_select(muc_online_room, +%% [{#muc_online_room{name_host = '$1', _ = '_'}, +%% Guard, +%% ['$_']}])), +%% L2 = if +%% Index == undefined andalso Direction == before -> +%% lists:reverse(lists:sublist(lists:reverse(L), 1, M)); +%% Index == undefined -> +%% lists:sublist(L, 1, M); +%% Index > Count orelse Index < 0 -> +%% []; +%% true -> +%% lists:sublist(L, Index+1, M) +%% end, +%% if L2 == [] -> {L2, #rsm_out{count = Count}}; +%% true -> +%% H = hd(L2), +%% NewIndex = get_room_pos(H, AllRooms), +%% T = lists:last(L2), +%% {F, _} = H#muc_online_room.name_host, +%% {Last, _} = T#muc_online_room.name_host, +%% {L2, +%% #rsm_out{first = F, last = Last, count = Count, +%% index = NewIndex}} +%% end. get_subscribed_rooms(ServerHost, Host, From) -> Rooms = get_rooms(ServerHost, Host), @@ -730,60 +662,32 @@ get_room_pos(Desired, [_ | Rooms], HeadPosition) -> flush() -> receive _ -> flush() after 0 -> ok end. --define(XFIELD(Type, Label, Var, Val), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). - -iq_get_unique(From) -> - {xmlcdata, - p1_sha:sha(term_to_binary([From, p1_time_compat:timestamp(), - randoms:get_string()]))}. - get_nick(ServerHost, Host, From) -> LServer = jid:nameprep(ServerHost), Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_nick(LServer, Host, From). iq_get_register_info(ServerHost, Host, From, Lang) -> - {Nick, Registered} = case get_nick(ServerHost, Host, - From) - of - error -> {<<"">>, []}; - N -> - {N, - [#xmlel{name = <<"registered">>, attrs = [], - children = []}]} + {Nick, Registered} = case get_nick(ServerHost, Host, From) of + error -> {<<"">>, false}; + N -> {N, true} end, - Registered ++ - [#xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"You need a client that supports x:data " - "to register the nickname">>)}]}, - #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Nickname Registration at ">>))/binary, - Host/binary>>}]}, - #xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Enter nickname you want to register">>)}]}, - ?XFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>, - Nick)]}]. + Title = <<(translate:translate( + Lang, <<"Nickname Registration at ">>))/binary, Host/binary>>, + Inst = translate:translate(Lang, <<"Enter nickname you want to register">>), + Field = #xdata_field{type = 'text-single', + label = translate:translate(Lang, <<"Nickname">>), + var = <<"nick">>, + values = [Nick]}, + X = #xdata{type = form, title = Title, + instructions = [Inst], fields = [Field]}, + #register{nick = Nick, + registered = Registered, + instructions = + translate:translate( + Lang, <<"You need a client that supports x:data " + "to register the nickname">>), + xdata = X}. set_nick(ServerHost, Host, From, Nick) -> LServer = jid:nameprep(ServerHost), @@ -793,66 +697,43 @@ set_nick(ServerHost, Host, From, Nick) -> iq_set_register_info(ServerHost, Host, From, Nick, Lang) -> case set_nick(ServerHost, Host, From, Nick) of - {atomic, ok} -> {result, []}; + {atomic, ok} -> {result, undefined}; {atomic, false} -> ErrText = <<"That nickname is registered by another " "person">>, - {error, ?ERRT_CONFLICT(Lang, ErrText)}; + {error, xmpp:err_conflict(ErrText, Lang)}; _ -> Txt = <<"Database failure">>, - {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)} + {error, xmpp:err_internal_server_error(Txt, Lang)} end. -process_iq_register_set(ServerHost, Host, From, SubEl, - Lang) -> - #xmlel{children = Els} = SubEl, - case fxml:get_subtag(SubEl, <<"remove">>) of - false -> - case fxml:remove_cdata(Els) of - [#xmlel{name = <<"x">>} = XEl] -> - case {fxml:get_tag_attr_s(<<"xmlns">>, XEl), - fxml:get_tag_attr_s(<<"type">>, XEl)} - of - {?NS_XDATA, <<"cancel">>} -> {result, []}; - {?NS_XDATA, <<"submit">>} -> - XData = jlib:parse_xdata_submit(XEl), - case XData of - invalid -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - _ -> - case lists:keysearch(<<"nick">>, 1, XData) of - {value, {_, [Nick]}} when Nick /= <<"">> -> - iq_set_register_info(ServerHost, Host, From, - Nick, Lang); - _ -> - ErrText = - <<"You must fill in field \"Nickname\" " - "in the form">>, - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)} - end - end; - _ -> {error, ?ERR_BAD_REQUEST} - end; - _ -> {error, ?ERR_BAD_REQUEST} - end; - _ -> - iq_set_register_info(ServerHost, Host, From, <<"">>, - Lang) +process_iq_register_set(ServerHost, Host, From, + #register{remove = true}, Lang) -> + iq_set_register_info(ServerHost, Host, From, <<"">>, Lang); +process_iq_register_set(_ServerHost, _Host, _From, + #register{xdata = #xdata{type = cancel}}, _Lang) -> + {result, undefined}; +process_iq_register_set(ServerHost, Host, From, + #register{nick = Nick, xdata = XData}, Lang) -> + case XData of + #xdata{type = submit, fields = Fs} -> + case lists:keyfind(<<"nick">>, #xdata_field.var, Fs) of + #xdata_field{values = [N]} -> + iq_set_register_info(ServerHost, Host, From, N, Lang); + _ -> + ErrText = <<"You must fill in field \"Nickname\" in the form">>, + {error, xmpp:err_not_acceptable(ErrText, Lang)} + end; + #xdata{} -> + Txt = <<"Incorrect data form">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + _ when is_binary(Nick), Nick /= <<"">> -> + iq_set_register_info(ServerHost, Host, From, Nick, Lang); + _ -> + ErrText = <<"You must fill in field \"Nickname\" in the form">>, + {error, xmpp:err_not_acceptable(ErrText, Lang)} end. -iq_get_vcard(Lang) -> - [#xmlel{name = <<"FN">>, attrs = [], - children = [{xmlcdata, <<"ejabberd/mod_muc">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"ejabberd MUC module">>))/binary, - "\nCopyright (c) 2003-2016 ProcessOne">>}]}]. - broadcast_service_message(Host, Msg) -> lists:foreach( fun(#muc_online_room{pid = Pid}) -> diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 0b5e79f60..a7ba16138 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -24,7 +24,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_muc_room.hrl"). -include("mod_muc.hrl"). -include("ejabberd_http.hrl"). @@ -241,7 +241,7 @@ web_menu_host(Acc, _Host, Lang) -> -define(TDTD(L, N), ?XE(<<"tr">>, [?XCT(<<"td">>, L), - ?XC(<<"td">>, jlib:integer_to_binary(N)) + ?XC(<<"td">>, integer_to_binary(N)) ])). web_page_main(_, #request{path=[<<"muc">>], lang = Lang} = _Request) -> @@ -283,7 +283,7 @@ get_sort_query(Q) -> get_sort_query2(Q) -> {value, {_, String}} = lists:keysearch(<<"sort">>, 1, Q), - Integer = jlib:binary_to_integer(String), + Integer = binary_to_integer(String), case Integer >= 0 of true -> {ok, {normal, Integer}}; false -> {ok, {reverse, abs(Integer)}} @@ -309,7 +309,7 @@ make_rooms_page(Host, Lang, {Sort_direction, Sort_column}) -> {Titles_TR, _} = lists:mapfoldl( fun(Title, Num_column) -> - NCS = jlib:integer_to_binary(Num_column), + NCS = integer_to_binary(Num_column), TD = ?XE(<<"td">>, [?CT(Title), ?C(<<" ">>), ?AC(<<"?sort=", NCS/binary>>, <<"<">>), @@ -383,7 +383,7 @@ prepare_room_info(Room_info) -> Just_created, Title} = Room_info, [NameHost, - jlib:integer_to_binary(Num_participants), + integer_to_binary(Num_participants), Ts_last_message, jlib:atom_to_binary(Public), jlib:atom_to_binary(Persistent), @@ -830,7 +830,7 @@ get_options(Config) -> Fields = [jlib:atom_to_binary(Field) || Field <- record_info(fields, config)], [config | ValuesRaw] = tuple_to_list(Config), Values = lists:map(fun(V) when is_atom(V) -> jlib:atom_to_binary(V); - (V) when is_integer(V) -> jlib:integer_to_binary(V); + (V) when is_integer(V) -> integer_to_binary(V); (V) when is_tuple(V); is_list(V) -> list_to_binary(hd(io_lib:format("~w", [V]))); (V) -> V end, ValuesRaw), lists:zip(Fields, Values). diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index ec4711b43..4b129ce81 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -46,7 +46,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_muc.hrl"). -include("mod_muc_room.hrl"). @@ -196,15 +196,13 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. add_to_log2(text, {Nick, Packet}, Room, Opts, State) -> case has_no_permanent_store_hint(Packet) of false -> - case {fxml:get_subtag(Packet, <<"subject">>), - fxml:get_subtag(Packet, <<"body">>)} - of - {false, false} -> ok; - {false, SubEl} -> - Message = {body, fxml:get_tag_cdata(SubEl)}, + case {Packet#message.subject, Packet#message.body} of + {[], []} -> ok; + {[], Body} -> + Message = {body, xmpp:get_text(Body)}, add_message_to_log(Nick, Message, Room, Opts, State); - {SubEl, _} -> - Message = {subject, fxml:get_tag_cdata(SubEl)}, + {Subj, _} -> + Message = {subject, xmpp:get_text(Subj)}, add_message_to_log(Nick, Message, Room, Opts, State) end; true -> ok @@ -1035,7 +1033,7 @@ roomconfig_to_string(Options, Lang, FileFormat) -> max_users -> <<"
", OptText/binary, ": \"", - (htmlize(jlib:integer_to_binary(T), + (htmlize(integer_to_binary(T), FileFormat))/binary, "\"
">>; title -> @@ -1053,7 +1051,7 @@ roomconfig_to_string(Options, Lang, FileFormat) -> allow_private_messages_from_visitors -> <<"
", OptText/binary, ": \"", - (htmlize(?T((jlib:atom_to_binary(T))), + (htmlize(?T(jlib:atom_to_binary(T)), FileFormat))/binary, "\"
">>; _ -> <<"\"", T/binary, "\"">> @@ -1168,7 +1166,7 @@ get_room_occupants(RoomJIDString) -> [{U#user.jid, U#user.nick, U#user.role} || {_, U} <- (?DICT):to_list(StateData#state.users)]. --spec get_room_state(binary(), binary()) -> muc_room_state(). +-spec get_room_state(binary(), binary()) -> mod_muc_room:state(). get_room_state(RoomName, MucService) -> case mnesia:dirty_read(muc_online_room, @@ -1180,7 +1178,7 @@ get_room_state(RoomName, MucService) -> [] -> #state{} end. --spec get_room_state(pid()) -> muc_room_state(). +-spec get_room_state(pid()) -> mod_muc_room:state(). get_room_state(RoomPid) -> {ok, R} = gen_fsm:sync_send_all_state_event(RoomPid, @@ -1204,14 +1202,10 @@ fjoin(FileList) -> list_to_binary(filename:join([binary_to_list(File) || File <- FileList])). has_no_permanent_store_hint(Packet) -> - fxml:get_subtag_with_xmlns(Packet, <<"no-store">>, ?NS_HINTS) - =/= false orelse - fxml:get_subtag_with_xmlns(Packet, <<"no-storage">>, ?NS_HINTS) - =/= false orelse - fxml:get_subtag_with_xmlns(Packet, <<"no-permanent-store">>, ?NS_HINTS) - =/= false orelse - fxml:get_subtag_with_xmlns(Packet, <<"no-permanent-storage">>, ?NS_HINTS) - =/= false. + xmpp:has_subtag(Packet, #hint{type = 'no-store'}) orelse + xmpp:has_subtag(Packet, #hint{type = 'no-storage'}) orelse + xmpp:has_subtag(Packet, #hint{type = 'no-permanent-store'}) orelse + xmpp:has_subtag(Packet, #hint{type = 'no-permanent-storage'}). mod_opt_type(access_log) -> fun (A) when is_atom(A) -> A end; diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 773953c4a..29b7942cf 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -51,7 +51,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_muc_room.hrl"). @@ -72,6 +72,18 @@ -endif. +-type state() :: #state{}. +-type fsm_stop() :: {stop, normal, state()}. +-type fsm_next() :: {next_state, normal_state, state()}. +-type fsm_transition() :: fsm_stop() | fsm_next(). +-type history_element() :: {binary(), %% nick + message(), %% message itself + boolean(), %% have subject + erlang:timestamp(), + non_neg_integer()}. + +-export_type([state/0]). + %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- @@ -133,349 +145,187 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) -> {ok, normal_state, State}. normal_state({route, From, <<"">>, - #xmlel{name = <<"message">>, attrs = Attrs, - children = Els} = - Packet}, - StateData) -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), + #message{type = Type, lang = Lang} = Packet}, StateData) -> case is_user_online(From, StateData) orelse - is_user_allowed_message_nonparticipant(From, StateData) - of - true -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"groupchat">> -> - Activity = get_user_activity(From, StateData), - Now = p1_time_compat:system_time(micro_seconds), - MinMessageInterval = - trunc(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, min_message_interval, fun(MMI) when is_number(MMI) -> MMI end, 0) - * 1000000), - Size = element_size(Packet), - {MessageShaper, MessageShaperInterval} = - shaper:update(Activity#activity.message_shaper, Size), - if Activity#activity.message /= undefined -> - ErrText = <<"Traffic rate limit is exceeded">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_RESOURCE_CONSTRAINT(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, From, Err), - {next_state, normal_state, StateData}; - Now >= - Activity#activity.message_time + MinMessageInterval, - MessageShaperInterval == 0 -> - {RoomShaper, RoomShaperInterval} = - shaper:update(StateData#state.room_shaper, Size), - RoomQueueEmpty = - queue:is_empty(StateData#state.room_queue), - if RoomShaperInterval == 0, RoomQueueEmpty -> - NewActivity = Activity#activity{message_time = - Now, - message_shaper = - MessageShaper}, - StateData1 = store_user_activity(From, - NewActivity, - StateData), - StateData2 = StateData1#state{room_shaper = - RoomShaper}, - process_groupchat_message(From, Packet, - StateData2); - true -> - StateData1 = if RoomQueueEmpty -> - erlang:send_after(RoomShaperInterval, - self(), - process_room_queue), - StateData#state{room_shaper = - RoomShaper}; - true -> StateData - end, - NewActivity = Activity#activity{message_time = - Now, - message_shaper = - MessageShaper, - message = Packet}, - RoomQueue = queue:in({message, From}, - StateData#state.room_queue), - StateData2 = store_user_activity(From, - NewActivity, - StateData1), - StateData3 = StateData2#state{room_queue = - RoomQueue}, - {next_state, normal_state, StateData3} - end; - true -> - MessageInterval = (Activity#activity.message_time + - MinMessageInterval - - Now) - div 1000, - Interval = lists:max([MessageInterval, - MessageShaperInterval]), - erlang:send_after(Interval, self(), - {process_user_message, From}), - NewActivity = Activity#activity{message = Packet, - message_shaper = - MessageShaper}, - StateData1 = store_user_activity(From, NewActivity, - StateData), - {next_state, normal_state, StateData1} - end; - <<"error">> -> - case is_user_online(From, StateData) of - true -> - ErrorText = <<"It is not allowed to send error messages to the" - " room. The participant (~s) has sent an error " - "message (~s) and got kicked from the room">>, - NewState = expulse_participant(Packet, From, StateData, - translate:translate(Lang, - ErrorText)), - close_room_if_temporary_and_empty(NewState); - _ -> {next_state, normal_state, StateData} - end; - <<"chat">> -> - ErrText = - <<"It is not allowed to send private messages " - "to the conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, From, Err), - {next_state, normal_state, StateData}; - Type when (Type == <<"">>) or (Type == <<"normal">>) -> - IsInvitation = is_invitation(Els), - IsVoiceRequest = is_voice_request(Els) and - is_visitor(From, StateData), - IsVoiceApprovement = is_voice_approvement(Els) and - not is_visitor(From, StateData), - if IsInvitation -> - case catch check_invitation(From, Packet, Lang, StateData) - of - {error, Error} -> - Err = jlib:make_error_reply(Packet, Error), - ejabberd_router:route(StateData#state.jid, From, Err), - {next_state, normal_state, StateData}; - IJID -> - Config = StateData#state.config, - case Config#config.members_only of - true -> - case get_affiliation(IJID, StateData) of - none -> - NSD = set_affiliation(IJID, member, - StateData), - send_affiliation(IJID, member, - StateData), - store_room(NSD), - {next_state, normal_state, NSD}; - _ -> {next_state, normal_state, StateData} - end; - false -> {next_state, normal_state, StateData} - end - end; - IsVoiceRequest -> - NewStateData = case - (StateData#state.config)#config.allow_voice_requests - of - true -> - MinInterval = - (StateData#state.config)#config.voice_request_min_interval, - BareFrom = - jid:remove_resource(jid:tolower(From)), - NowPriority = -p1_time_compat:system_time(micro_seconds), - CleanPriority = NowPriority + - MinInterval * - 1000000, - Times = - clean_treap(StateData#state.last_voice_request_time, - CleanPriority), - case treap:lookup(BareFrom, Times) - of - error -> - Times1 = - treap:insert(BareFrom, - NowPriority, - true, Times), - NSD = - StateData#state{last_voice_request_time - = - Times1}, - send_voice_request(From, NSD), - NSD; - {ok, _, _} -> - ErrText = - <<"Please, wait for a while before sending " - "new voice request">>, - Err = - jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, - From, Err), - StateData#state{last_voice_request_time - = Times} - end; - false -> - ErrText = - <<"Voice requests are disabled in this " - "conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, - From, Err), - StateData - end, - {next_state, normal_state, NewStateData}; - IsVoiceApprovement -> - NewStateData = case is_moderator(From, StateData) of - true -> - case - extract_jid_from_voice_approvement(Els) - of - error -> - ErrText = - <<"Failed to extract JID from your voice " - "request approval">>, - Err = - jlib:make_error_reply(Packet, - ?ERRT_BAD_REQUEST(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, - From, Err), - StateData; - {ok, TargetJid} -> - case is_visitor(TargetJid, - StateData) - of - true -> - Reason = <<>>, - NSD = - set_role(TargetJid, - participant, - StateData), - catch - send_new_presence(TargetJid, - Reason, - NSD, - StateData), - NSD; - _ -> StateData - end - end; - _ -> - ErrText = - <<"Only moderators can approve voice requests">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ALLOWED(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, - From, Err), - StateData - end, - {next_state, normal_state, NewStateData}; - true -> {next_state, normal_state, StateData} - end; - _ -> - ErrText = <<"Improper message type">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, - ErrText)), - ejabberd_router:route(StateData#state.jid, From, Err), - {next_state, normal_state, StateData} - end; - _ -> - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - _ -> - handle_roommessage_from_nonparticipant(Packet, Lang, - StateData, From) - end, - {next_state, normal_state, StateData} - end; -normal_state({route, From, <<"">>, - #xmlel{name = <<"iq">>} = Packet}, - StateData) -> - case jlib:iq_query_info(Packet) of - reply -> - {next_state, normal_state, StateData}; - IQ0 -> - case ejabberd_hooks:run_fold( - muc_process_iq, - StateData#state.server_host, - IQ0, [StateData, From, StateData#state.jid]) of - ignore -> - {next_state, normal_state, StateData}; - #iq{type = T} = IQRes when T == error; T == result -> - ejabberd_router:route(StateData#state.jid, From, jlib:iq_to_xml(IQRes)), + is_user_allowed_message_nonparticipant(From, StateData) of + true when Type == groupchat -> + Activity = get_user_activity(From, StateData), + Now = p1_time_compat:system_time(micro_seconds), + MinMessageInterval = trunc(gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, min_message_interval, + fun(MMI) when is_number(MMI) -> MMI end, 0) + * 1000000), + Size = element_size(Packet), + {MessageShaper, MessageShaperInterval} = + shaper:update(Activity#activity.message_shaper, Size), + if Activity#activity.message /= undefined -> + ErrText = <<"Traffic rate limit is exceeded">>, + Err = xmpp:make_error( + Packet, + xmpp:err_resource_constraint(ErrText, Lang)), + ejabberd_router:route(StateData#state.jid, From, Err), {next_state, normal_state, StateData}; - #iq{type = Type, xmlns = XMLNS, lang = Lang, - sub_el = #xmlel{name = SubElName, attrs = Attrs} = SubEl} = IQ - when (XMLNS == (?NS_MUC_ADMIN)) or - (XMLNS == (?NS_MUC_OWNER)) - or (XMLNS == (?NS_DISCO_INFO)) - or (XMLNS == (?NS_DISCO_ITEMS)) - or (XMLNS == (?NS_VCARD)) - or (XMLNS == (?NS_MUCSUB)) - or (XMLNS == (?NS_CAPTCHA)) -> - Res1 = case XMLNS of - ?NS_MUC_ADMIN -> - process_iq_admin(From, Type, Lang, SubEl, StateData); - ?NS_MUC_OWNER -> - process_iq_owner(From, Type, Lang, SubEl, StateData); - ?NS_DISCO_INFO -> - case fxml:get_attr(<<"node">>, Attrs) of - false -> process_iq_disco_info(From, Type, Lang, StateData); - {value, _} -> - Txt = <<"Disco info is not available for this node">>, - {error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)} - end; - ?NS_DISCO_ITEMS -> - process_iq_disco_items(From, Type, Lang, StateData); - ?NS_VCARD -> - process_iq_vcard(From, Type, Lang, SubEl, StateData); - ?NS_MUCSUB -> - process_iq_mucsub(From, Packet, IQ, StateData); - ?NS_CAPTCHA -> - process_iq_captcha(From, Type, Lang, SubEl, StateData) - end, - {IQRes, NewStateData} = - case Res1 of - {result, Res, SD} -> - {IQ#iq{type = result, - sub_el = - [#xmlel{name = SubElName, - attrs = - [{<<"xmlns">>, - XMLNS}], - children = Res}]}, - SD}; - {ignore, SD} -> {ignore, SD}; - {error, Error, ResStateData} -> - {IQ#iq{type = error, - sub_el = [SubEl, Error]}, - ResStateData}; - {error, Error} -> - {IQ#iq{type = error, - sub_el = [SubEl, Error]}, - StateData} - end, - if IQRes /= ignore -> - ejabberd_router:route( - StateData#state.jid, From, jlib:iq_to_xml(IQRes)); + Now >= Activity#activity.message_time + MinMessageInterval, + MessageShaperInterval == 0 -> + {RoomShaper, RoomShaperInterval} = + shaper:update(StateData#state.room_shaper, Size), + RoomQueueEmpty = queue:is_empty(StateData#state.room_queue), + if RoomShaperInterval == 0, RoomQueueEmpty -> + NewActivity = Activity#activity{ + message_time = Now, + message_shaper = MessageShaper}, + StateData1 = store_user_activity(From, + NewActivity, + StateData), + StateData2 = StateData1#state{room_shaper = + RoomShaper}, + process_groupchat_message(From, Packet, + StateData2); true -> - ok - end, - case NewStateData of - stop -> {stop, normal, StateData}; - _ -> {next_state, normal_state, NewStateData} + StateData1 = if RoomQueueEmpty -> + erlang:send_after(RoomShaperInterval, + self(), + process_room_queue), + StateData#state{room_shaper = + RoomShaper}; + true -> StateData + end, + NewActivity = Activity#activity{ + message_time = Now, + message_shaper = MessageShaper, + message = Packet}, + RoomQueue = queue:in({message, From}, + StateData#state.room_queue), + StateData2 = store_user_activity(From, + NewActivity, + StateData1), + StateData3 = StateData2#state{room_queue = RoomQueue}, + {next_state, normal_state, StateData3} end; + true -> + MessageInterval = (Activity#activity.message_time + + MinMessageInterval - Now) div 1000, + Interval = lists:max([MessageInterval, + MessageShaperInterval]), + erlang:send_after(Interval, self(), + {process_user_message, From}), + NewActivity = Activity#activity{ + message = Packet, + message_shaper = MessageShaper}, + StateData1 = store_user_activity(From, NewActivity, StateData), + {next_state, normal_state, StateData1} + end; + true when Type == error -> + case is_user_online(From, StateData) of + true -> + ErrorText = <<"It is not allowed to send error messages to the" + " room. The participant (~s) has sent an error " + "message (~s) and got kicked from the room">>, + NewState = expulse_participant(Packet, From, StateData, + translate:translate(Lang, + ErrorText)), + close_room_if_temporary_and_empty(NewState); _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_FEATURE_NOT_IMPLEMENTED), - ejabberd_router:route(StateData#state.jid, From, Err), {next_state, normal_state, StateData} - end + end; + true when Type == chat -> + ErrText = <<"It is not allowed to send private messages " + "to the conference">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error(StateData#state.jid, From, Packet, Err), + {next_state, normal_state, StateData}; + true when Type == normal -> + {next_state, normal_state, + try xmpp:decode_els(Packet) of + Pkt -> process_normal_message(From, Pkt, StateData) + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + Err = xmpp:err_bad_request(Txt, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Packet, Err), + StateData + end}; + true -> + ErrText = <<"Improper message type">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error(StateData#state.jid, From, Packet, Err), + {next_state, normal_state, StateData}; + false when Type /= error -> + handle_roommessage_from_nonparticipant(Packet, StateData, From); + false -> + {next_state, normal_state, StateData} end; -normal_state({route, From, Nick, - #xmlel{name = <<"presence">>} = Packet}, - StateData) -> +normal_state({route, From, <<"">>, + #iq{type = Type, lang = Lang, sub_els = [_]} = IQ0}, + StateData) when Type == get; Type == set -> + try + case ejabberd_hooks:run_fold( + muc_process_iq, + StateData#state.server_host, + xmpp:set_from_to(xmpp:decode_els(IQ0), + From, StateData#state.jid), + [StateData]) of + ignore -> + {next_state, normal_state, StateData}; + #iq{type = T} = IQRes when T == error; T == result -> + ejabberd_router:route(StateData#state.jid, From, IQRes), + {next_state, normal_state, StateData}; + #iq{sub_els = [SubEl]} = IQ -> + Res1 = case xmpp:get_ns(SubEl) of + ?NS_MUC_ADMIN -> + process_iq_admin(From, IQ, StateData); + ?NS_MUC_OWNER -> + process_iq_owner(From, IQ, StateData); + ?NS_DISCO_INFO when SubEl#disco_info.node == undefined -> + process_iq_disco_info(From, IQ, StateData); + ?NS_DISCO_INFO -> + Txt = <<"Disco info is not available for this node">>, + {error, xmpp:err_service_unavailable(Txt, Lang)}; + ?NS_DISCO_ITEMS -> + process_iq_disco_items(From, IQ, StateData); + ?NS_VCARD -> + process_iq_vcard(From, IQ, StateData); + ?NS_MUCSUB -> + process_iq_mucsub(From, IQ, StateData); + ?NS_CAPTCHA -> + process_iq_captcha(From, IQ, StateData); + _ -> + {error, xmpp:err_feature_not_implemented()} + end, + {IQRes, NewStateData} = + case Res1 of + {result, Res, SD} -> + {xmpp:make_iq_result(IQ, Res), SD}; + {result, Res} -> + {xmpp:make_iq_result(IQ, Res), StateData}; + {ignore, SD} -> + {ignore, SD}; + {error, Error, ResStateData} -> + {xmpp:make_error(IQ0, Error), ResStateData}; + {error, Error} -> + {xmpp:make_error(IQ0, Error), StateData} + end, + if IQRes /= ignore -> + ejabberd_router:route(StateData#state.jid, From, IQRes); + true -> + ok + end, + case NewStateData of + stop -> {stop, normal, StateData}; + _ -> {next_state, normal_state, NewStateData} + end + end + catch _:{xmpp_codec, Why} -> + ErrTxt = xmpp:format_error(Why), + Err = xmpp:make_error(IQ0, xmpp:err_bad_request(ErrTxt, Lang)), + ejabberd_router:route(StateData#state.jid, From, Err) + end; +normal_state({route, From, <<"">>, #iq{} = IQ}, StateData) -> + Err = xmpp:err_bad_request(), + ejabberd_router:route_error(StateData#state.jid, From, IQ, Err), + {next_state, normal_state, StateData}; +normal_state({route, From, Nick, #presence{} = Packet}, StateData) -> Activity = get_user_activity(From, StateData), Now = p1_time_compat:system_time(micro_seconds), MinPresenceInterval = @@ -485,185 +335,135 @@ normal_state({route, From, Nick, I end, 0) * 1000000), - if (Now >= - Activity#activity.presence_time + MinPresenceInterval) - and (Activity#activity.presence == undefined) -> - NewActivity = Activity#activity{presence_time = Now}, - StateData1 = store_user_activity(From, NewActivity, - StateData), - process_presence(From, Nick, Packet, StateData1); + if (Now >= Activity#activity.presence_time + MinPresenceInterval) + and (Activity#activity.presence == undefined) -> + NewActivity = Activity#activity{presence_time = Now}, + StateData1 = store_user_activity(From, NewActivity, + StateData), + process_presence(From, Nick, Packet, StateData1); true -> - if Activity#activity.presence == undefined -> - Interval = (Activity#activity.presence_time + - MinPresenceInterval - - Now) - div 1000, - erlang:send_after(Interval, self(), - {process_user_presence, From}); - true -> ok - end, - NewActivity = Activity#activity{presence = - {Nick, Packet}}, - StateData1 = store_user_activity(From, NewActivity, - StateData), - {next_state, normal_state, StateData1} + if Activity#activity.presence == undefined -> + Interval = (Activity#activity.presence_time + + MinPresenceInterval - Now) div 1000, + erlang:send_after(Interval, self(), + {process_user_presence, From}); + true -> ok + end, + NewActivity = Activity#activity{presence = {Nick, Packet}}, + StateData1 = store_user_activity(From, NewActivity, + StateData), + {next_state, normal_state, StateData1} end; normal_state({route, From, ToNick, - #xmlel{name = <<"message">>, attrs = Attrs} = Packet}, + #message{type = Type, lang = Lang} = Packet}, StateData) -> - Type = fxml:get_attr_s(<<"type">>, Attrs), - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - case decide_fate_message(Type, Packet, From, StateData) - of - {expulse_sender, Reason} -> - ?DEBUG(Reason, []), - ErrorText = <<"It is not allowed to send error messages to the" - " room. The participant (~s) has sent an error " - "message (~s) and got kicked from the room">>, - NewState = expulse_participant(Packet, From, StateData, - translate:translate(Lang, ErrorText)), - {next_state, normal_state, NewState}; - forget_message -> {next_state, normal_state, StateData}; - continue_delivery -> - case - {(StateData#state.config)#config.allow_private_messages, - is_user_online(From, StateData)} - of - {true, true} -> - case Type of - <<"groupchat">> -> - ErrText = - <<"It is not allowed to send private messages " - "of type \"groupchat\"">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_BAD_REQUEST(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err); - _ -> - case find_jids_by_nick(ToNick, StateData) of - false -> - ErrText = - <<"Recipient is not in the conference room">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_ITEM_NOT_FOUND(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err); + case decide_fate_message(Packet, From, StateData) of + {expulse_sender, Reason} -> + ?DEBUG(Reason, []), + ErrorText = <<"It is not allowed to send error messages to the" + " room. The participant (~s) has sent an error " + "message (~s) and got kicked from the room">>, + NewState = expulse_participant(Packet, From, StateData, + translate:translate(Lang, ErrorText)), + {next_state, normal_state, NewState}; + forget_message -> + {next_state, normal_state, StateData}; + continue_delivery -> + case {(StateData#state.config)#config.allow_private_messages, + is_user_online(From, StateData)} of + {true, true} when Type == groupchat -> + ErrText = <<"It is not allowed to send private messages " + "of type \"groupchat\"">>, + Err = xmpp:err_bad_request(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err); + {true, true} -> + case find_jids_by_nick(ToNick, StateData) of + [] -> + ErrText = <<"Recipient is not in the conference room">>, + Err = xmpp:err_item_not_found(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err); ToJIDs -> SrcIsVisitor = is_visitor(From, StateData), - DstIsModerator = is_moderator(hd(ToJIDs), - StateData), + DstIsModerator = is_moderator(hd(ToJIDs), StateData), PmFromVisitors = (StateData#state.config)#config.allow_private_messages_from_visitors, if SrcIsVisitor == false; PmFromVisitors == anyone; (PmFromVisitors == moderators) and - DstIsModerator -> - {ok, #user{nick = FromNick}} = - (?DICT):find(jid:tolower(From), - StateData#state.users), - FromNickJID = - jid:replace_resource(StateData#state.jid, - FromNick), - X = #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}]}, - PrivMsg = fxml:append_subtags(Packet, [X]), - [ejabberd_router:route(FromNickJID, ToJID, PrivMsg) - || ToJID <- ToJIDs]; + DstIsModerator -> + {ok, #user{nick = FromNick}} = + (?DICT):find(jid:tolower(From), + StateData#state.users), + FromNickJID = + jid:replace_resource(StateData#state.jid, + FromNick), + X = #muc_user{}, + PrivMsg = xmpp:set_subtag(Packet, X), + [ejabberd_router:route(FromNickJID, ToJID, PrivMsg) + || ToJID <- ToJIDs]; true -> - ErrText = - <<"It is not allowed to send private messages">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err) + ErrText = <<"It is not allowed to send private messages">>, + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err) end - end - end; - {true, false} -> - ErrText = - <<"Only occupants are allowed to send messages " - "to the conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err); - {false, _} -> - ErrText = - <<"It is not allowed to send private messages">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err) - end, + end; + {true, false} -> + ErrText = <<"Only occupants are allowed to send messages " + "to the conference">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err); + {false, _} -> + ErrText = <<"It is not allowed to send private messages">>, + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err) + end, {next_state, normal_state, StateData} end; normal_state({route, From, ToNick, - #xmlel{name = <<"iq">>, attrs = Attrs} = Packet}, + #iq{id = StanzaId, lang = Lang} = Packet}, StateData) -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - StanzaId = fxml:get_attr_s(<<"id">>, Attrs), case {(StateData#state.config)#config.allow_query_users, - is_user_online_iq(StanzaId, From, StateData)} - of - {true, {true, NewId, FromFull}} -> - case find_jid_by_nick(ToNick, StateData) of - false -> - case jlib:iq_query_info(Packet) of - reply -> ok; - _ -> - ErrText = <<"Recipient is not in the conference room">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_ITEM_NOT_FOUND(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err) - end; - ToJID -> - {ok, #user{nick = FromNick}} = - (?DICT):find(jid:tolower(FromFull), - StateData#state.users), - {ToJID2, Packet2} = handle_iq_vcard(FromFull, ToJID, - StanzaId, NewId, Packet), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - FromNick), - ToJID2, Packet2) - end; - {_, {false, _, _}} -> - case jlib:iq_query_info(Packet) of - reply -> ok; - _ -> - ErrText = - <<"Only occupants are allowed to send queries " - "to the conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err) - end; - _ -> - case jlib:iq_query_info(Packet) of - reply -> ok; - _ -> - ErrText = <<"Queries to the conference members are " - "not allowed in this room">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ALLOWED(Lang, ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - ToNick), - From, Err) - end + is_user_online_iq(StanzaId, From, StateData)} of + {true, {true, NewId, FromFull}} -> + case find_jid_by_nick(ToNick, StateData) of + false -> + ErrText = <<"Recipient is not in the conference room">>, + Err = xmpp:err_item_not_found(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err); + ToJID -> + {ok, #user{nick = FromNick}} = + (?DICT):find(jid:tolower(FromFull), StateData#state.users), + {ToJID2, Packet2} = handle_iq_vcard(ToJID, NewId, Packet), + ejabberd_router:route( + jid:replace_resource(StateData#state.jid, FromNick), + ToJID2, Packet2) + end; + {_, {false, _, _}} -> + ErrText = <<"Only occupants are allowed to send queries " + "to the conference">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err); + _ -> + ErrText = <<"Queries to the conference members are " + "not allowed in this room">>, + Err = xmpp:err_not_allowed(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, ToNick), + From, Packet, Err) end, {next_state, normal_state, StateData}; normal_state(_Event, StateData) -> @@ -671,11 +471,7 @@ normal_state(_Event, StateData) -> handle_event({service_message, Msg}, _StateName, StateData) -> - MessagePkt = #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"groupchat">>}], - children = - [#xmlel{name = <<"body">>, attrs = [], - children = [{xmlcdata, Msg}]}]}, + MessagePkt = #message{type = groupchat, body = xmpp:mk_text(Msg)}, send_wrapped_multiple( StateData#state.jid, StateData#state.users, @@ -687,22 +483,9 @@ handle_event({service_message, Msg}, _StateName, {next_state, normal_state, NSD}; handle_event({destroy, Reason}, _StateName, StateData) -> - {result, [], stop} = destroy_room(#xmlel{name = - <<"destroy">>, - attrs = - [{<<"xmlns">>, ?NS_MUC_OWNER}], - children = - case Reason of - none -> []; - _Else -> - [#xmlel{name = - <<"reason">>, - attrs = [], - children = - [{xmlcdata, - Reason}]}] - end}, - StateData), + {result, undefined, stop} = + destroy_room(#muc_destroy{xmlns = ?NS_MUC_OWNER, reason = Reason}, + StateData), ?INFO_MSG("Destroyed MUC room ~s with reason: ~p", [jid:to_string(StateData#state.jid), Reason]), add_to_log(room_existence, destroyed, StateData), @@ -710,7 +493,7 @@ handle_event({destroy, Reason}, _StateName, handle_event(destroy, StateName, StateData) -> ?INFO_MSG("Destroyed MUC room ~s", [jid:to_string(StateData#state.jid)]), - handle_event({destroy, none}, StateName, StateData); + handle_event({destroy, undefined}, StateName, StateData); handle_event({set_affiliations, Affiliations}, StateName, StateData) -> {next_state, StateName, @@ -741,7 +524,7 @@ handle_sync_event(get_state, _From, StateName, {reply, {ok, StateData}, StateName, StateData}; handle_sync_event({change_config, Config}, _From, StateName, StateData) -> - {result, [], NSD} = change_config(Config, StateData), + {result, undefined, NSD} = change_config(Config, StateData), {reply, {ok, NSD#state.config}, StateName, NSD}; handle_sync_event({change_state, NewStateData}, _From, StateName, _StateData) -> @@ -821,12 +604,11 @@ handle_info({captcha_failed, From}, normal_state, {ok, {Nick, Packet}} -> Robots = (?DICT):erase(From, StateData#state.robots), Txt = <<"The CAPTCHA verification has failed">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_NOT_AUTHORIZED(?MYLANG, Txt)), - ejabberd_router:route % TODO: s/Nick/""/ - (jid:replace_resource(StateData#state.jid, - Nick), - From, Err), + Lang = xmpp:get_lang(Packet), + Err = xmpp:err_not_authorized(Txt, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, Nick), + From, Packet, Err), StateData#state{robots = Robots}; _ -> StateData end, @@ -845,22 +627,12 @@ terminate(Reason, _StateName, StateData) -> "because of a system shutdown">>; _ -> <<"Room terminates">> end, - ItemAttrs = [{<<"affiliation">>, <<"none">>}, - {<<"role">>, <<"none">>}], - ReasonEl = #xmlel{name = <<"reason">>, attrs = [], - children = [{xmlcdata, ReasonT}]}, - Packet = #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"unavailable">>}], - children = - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}], - children = - [#xmlel{name = <<"item">>, - attrs = ItemAttrs, - children = [ReasonEl]}, - #xmlel{name = <<"status">>, - attrs = [{<<"code">>, <<"332">>}], - children = []}]}]}, + Packet = #presence{ + type = unavailable, + sub_els = [#muc_user{items = [#muc_item{affiliation = none, + reason = ReasonT, + role = none}], + status_codes = [332]}]}, (?DICT):fold(fun (LJID, Info, _) -> Nick = Info#user.nick, case Reason of @@ -883,14 +655,12 @@ terminate(Reason, _StateName, StateData) -> %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- - +-spec route(pid(), jid(), binary(), stanza()) -> ok. route(Pid, From, ToNick, Packet) -> gen_fsm:send_event(Pid, {route, From, ToNick, Packet}). -process_groupchat_message(From, - #xmlel{name = <<"message">>, attrs = Attrs} = Packet, - StateData) -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), +-spec process_groupchat_message(jid(), message(), state()) -> fsm_next(). +process_groupchat_message(From, #message{lang = Lang} = Packet, StateData) -> case is_user_online(From, StateData) orelse is_user_allowed_message_nonparticipant(From, StateData) of @@ -932,7 +702,7 @@ process_groupchat_message(From, drop -> {next_state, normal_state, StateData}; NewPacket1 -> - NewPacket = fxml:remove_subtags(NewPacket1, <<"nick">>, {<<"xmlns">>, ?NS_NICK}), + NewPacket = xmpp:remove_subtag(NewPacket1, #nick{}), Node = if Subject == false -> ?NS_MUCSUB_NODES_MESSAGES; true -> ?NS_MUCSUB_NODES_SUBJECT end, @@ -951,41 +721,136 @@ process_groupchat_message(From, {next_state, normal_state, NewStateData2} end; _ -> - Err = case - (StateData#state.config)#config.allow_change_subj - of + Err = case (StateData#state.config)#config.allow_change_subj of true -> - ?ERRT_FORBIDDEN(Lang, - <<"Only moderators and participants are " - "allowed to change the subject in this " - "room">>); + xmpp:err_forbidden( + <<"Only moderators and participants are " + "allowed to change the subject in this " + "room">>, Lang); _ -> - ?ERRT_FORBIDDEN(Lang, - <<"Only moderators are allowed to change " - "the subject in this room">>) + xmpp:err_forbidden( + <<"Only moderators are allowed to change " + "the subject in this room">>, Lang) end, - ejabberd_router:route(StateData#state.jid, From, - jlib:make_error_reply(Packet, Err)), + ejabberd_router:route_error( + StateData#state.jid, From, Packet, Err), {next_state, normal_state, StateData} end; true -> ErrText = <<"Visitors are not allowed to send messages " "to all occupants">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, ErrText)), - ejabberd_router:route(StateData#state.jid, From, Err), + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Packet, Err), {next_state, normal_state, StateData} end; false -> - ErrText = - <<"Only occupants are allowed to send messages " - "to the conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), - ejabberd_router:route(StateData#state.jid, From, Err), + ErrText = <<"Only occupants are allowed to send messages " + "to the conference">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error(StateData#state.jid, From, Packet, Err), {next_state, normal_state, StateData} end. +-spec process_normal_message(jid(), message(), state()) -> state(). +process_normal_message(From, #message{lang = Lang} = Pkt, StateData) -> + IsInvitation = is_invitation(Pkt), + IsVoiceRequest = is_voice_request(Pkt) and + is_visitor(From, StateData), + IsVoiceApprovement = is_voice_approvement(Pkt) and + not is_visitor(From, StateData), + if IsInvitation -> + case check_invitation(From, Pkt, StateData) of + {error, Error} -> + ejabberd_router:route_error(StateData#state.jid, From, Pkt, Error), + StateData; + IJID -> + Config = StateData#state.config, + case Config#config.members_only of + true -> + case get_affiliation(IJID, StateData) of + none -> + NSD = set_affiliation(IJID, member, StateData), + send_affiliation(IJID, member, StateData), + store_room(NSD), + NSD; + _ -> + StateData + end; + false -> + StateData + end + end; + IsVoiceRequest -> + case (StateData#state.config)#config.allow_voice_requests of + true -> + MinInterval = (StateData#state.config)#config.voice_request_min_interval, + BareFrom = jid:remove_resource(jid:tolower(From)), + NowPriority = -p1_time_compat:system_time(micro_seconds), + CleanPriority = NowPriority + MinInterval * 1000000, + Times = clean_treap(StateData#state.last_voice_request_time, + CleanPriority), + case treap:lookup(BareFrom, Times) of + error -> + Times1 = treap:insert(BareFrom, + NowPriority, + true, Times), + NSD = StateData#state{last_voice_request_time = Times1}, + send_voice_request(From, Lang, NSD), + NSD; + {ok, _, _} -> + ErrText = <<"Please, wait for a while before sending " + "new voice request">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), + StateData#state{last_voice_request_time = Times} + end; + false -> + ErrText = <<"Voice requests are disabled in this conference">>, + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), + StateData + end; + IsVoiceApprovement -> + case is_moderator(From, StateData) of + true -> + case extract_jid_from_voice_approvement(Pkt) of + error -> + ErrText = <<"Failed to extract JID from your voice " + "request approval">>, + Err = xmpp:err_bad_request(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), + StateData; + TargetJid -> + case is_visitor(TargetJid, StateData) of + true -> + Reason = <<>>, + NSD = set_role(TargetJid, + participant, + StateData), + catch send_new_presence(TargetJid, + Reason, + NSD, + StateData), + NSD; + _ -> + StateData + end + end; + _ -> + ErrText = <<"Only moderators can approve voice requests">>, + Err = xmpp:err_not_allowed(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), + StateData + end; + true -> + StateData + end. + %% @doc Check if this non participant can send message to room. %% %% XEP-0045 v1.23: @@ -993,6 +858,7 @@ process_groupchat_message(From, %% an implementation MAY allow users with certain privileges %% (e.g., a room owner, room admin, or service-level admin) %% to send messages to the room even if those users are not occupants. +-spec is_user_allowed_message_nonparticipant(jid(), state()) -> boolean(). is_user_allowed_message_nonparticipant(JID, StateData) -> case get_service_affiliation(JID, StateData) of @@ -1002,6 +868,7 @@ is_user_allowed_message_nonparticipant(JID, %% @doc Get information of this participant, or default values. %% If the JID is not a participant, return values for a service message. +-spec get_participant_data(jid(), state()) -> {binary(), role(), boolean()}. get_participant_data(From, StateData) -> case (?DICT):find(jid:tolower(From), StateData#state.users) @@ -1011,14 +878,11 @@ get_participant_data(From, StateData) -> error -> {<<"">>, moderator, false} end. -process_presence(From, Nick, - #xmlel{name = <<"presence">>, attrs = Attrs0} = Packet0, - StateData) -> - Type0 = fxml:get_attr_s(<<"type">>, Attrs0), +-spec process_presence(jid(), binary(), presence(), state()) -> fsm_transition(). +process_presence(From, Nick, #presence{type = Type0} = Packet0, StateData) -> IsOnline = is_user_online(From, StateData), - IsSubscriber = is_subscriber(From, StateData), - if Type0 == <<"">>; - IsOnline and ((Type0 == <<"unavailable">>) or (Type0 == <<"error">>)) -> + if Type0 == available; + IsOnline and ((Type0 == unavailable) or (Type0 == error)) -> case ejabberd_hooks:run_fold(muc_filter_presence, StateData#state.server_host, Packet0, @@ -1027,119 +891,104 @@ process_presence(From, Nick, From, Nick]) of drop -> {next_state, normal_state, StateData}; - #xmlel{attrs = Attrs} = Packet -> - Type = fxml:get_attr_s(<<"type">>, Attrs), - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), - StateData1 = case Type of - <<"unavailable">> -> - NewPacket = case - {(StateData#state.config)#config.allow_visitor_status, - is_visitor(From, StateData)} - of - {false, true} -> - strip_status(Packet); - _ -> Packet - end, - NewState = add_user_presence_un(From, NewPacket, - StateData), - case (?DICT):find(Nick, StateData#state.nicks) of - {ok, [_, _ | _]} -> ok; - _ -> send_new_presence(From, NewState, StateData) - end, - Reason = case fxml:get_subtag(NewPacket, - <<"status">>) - of - false -> <<"">>; - Status_el -> - fxml:get_tag_cdata(Status_el) - end, - remove_online_user(From, NewState, IsSubscriber, Reason); - <<"error">> -> - ErrorText = <<"It is not allowed to send error messages to the" - " room. The participant (~s) has sent an error " - "message (~s) and got kicked from the room">>, - expulse_participant(Packet, From, StateData, - translate:translate(Lang, - ErrorText)); - <<"">> -> - if not IsOnline -> - add_new_user(From, Nick, Packet, StateData); - true -> - case is_nick_change(From, Nick, StateData) of - true -> - case {nick_collision(From, Nick, StateData), - mod_muc:can_use_nick(StateData#state.server_host, - StateData#state.host, - From, Nick), - {(StateData#state.config)#config.allow_visitor_nickchange, - is_visitor(From, StateData)}} - of - {_, _, {false, true}} -> - ErrText = - <<"Visitors are not allowed to change their " - "nicknames in this room">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ALLOWED(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - Nick), - From, Err), - StateData; - {true, _, _} -> - Lang = fxml:get_attr_s(<<"xml:lang">>, - Attrs), - ErrText = - <<"That nickname is already in use by another " - "occupant">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_CONFLICT(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - Nick), % TODO: s/Nick/""/ - From, Err), - StateData; - {_, false, _} -> - ErrText = - <<"That nickname is registered by another " - "person">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_CONFLICT(Lang, - ErrText)), - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - Nick), - From, Err), - StateData; - _ -> - case is_initial_presence(From, StateData) of - true -> - subscriber_becomes_available( - From, Nick, Packet, StateData); - false -> - change_nick(From, Nick, StateData) - end - end; - _NotNickChange -> - case is_initial_presence(From, StateData) of - true -> - subscriber_becomes_available( - From, Nick, Packet, StateData); - false -> - Stanza = maybe_strip_status_from_presence( - From, Packet, StateData), - NewState = add_user_presence(From, Stanza, - StateData), - send_new_presence(From, NewState, StateData), - NewState - end - end - end - end, - close_room_if_temporary_and_empty(StateData1) + #presence{} = Packet -> + close_room_if_temporary_and_empty( + do_process_presence(From, Nick, Packet, StateData)) end; true -> - {next_state, normal_state, StateData} + {next_state, normal_state, StateData} end. +-spec do_process_presence(jid(), binary(), presence(), state()) -> + state(). +do_process_presence(From, Nick, #presence{type = available, lang = Lang} = Packet, + StateData) -> + case is_user_online(From, StateData) of + false -> + add_new_user(From, Nick, Packet, StateData); + true -> + case is_nick_change(From, Nick, StateData) of + true -> + case {nick_collision(From, Nick, StateData), + mod_muc:can_use_nick(StateData#state.server_host, + StateData#state.host, + From, Nick), + {(StateData#state.config)#config.allow_visitor_nickchange, + is_visitor(From, StateData)}} of + {_, _, {false, true}} -> + ErrText = <<"Visitors are not allowed to change their " + "nicknames in this room">>, + Err = xmpp:err_not_allowed(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, Nick), + From, Packet, Err), + StateData; + {true, _, _} -> + ErrText = <<"That nickname is already in use by another " + "occupant">>, + Err = xmpp:err_conflict(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, Nick), + From, Packet, Err), + StateData; + {_, false, _} -> + ErrText = <<"That nickname is registered by another " + "person">>, + Err = xmpp:err_conflict(ErrText, Lang), + ejabberd_router:route_error( + jid:replace_resource(StateData#state.jid, Nick), + From, Packet, Err), + StateData; + _ -> + case is_initial_presence(From, StateData) of + true -> + subscriber_becomes_available( + From, Nick, Packet, StateData); + false -> + change_nick(From, Nick, StateData) + end + end; + _NotNickChange -> + case is_initial_presence(From, StateData) of + true -> + subscriber_becomes_available( + From, Nick, Packet, StateData); + false -> + Stanza = maybe_strip_status_from_presence( + From, Packet, StateData), + NewState = add_user_presence(From, Stanza, + StateData), + send_new_presence(From, NewState, StateData), + NewState + end + end + end; +do_process_presence(From, Nick, #presence{type = unavailable} = Packet, + StateData) -> + IsSubscriber = is_subscriber(From, StateData), + NewPacket = case {(StateData#state.config)#config.allow_visitor_status, + is_visitor(From, StateData)} of + {false, true} -> + strip_status(Packet); + _ -> Packet + end, + NewState = add_user_presence_un(From, NewPacket, StateData), + case (?DICT):find(Nick, StateData#state.nicks) of + {ok, [_, _ | _]} -> ok; + _ -> send_new_presence(From, NewState, StateData) + end, + Reason = xmpp:get_text(NewPacket#presence.status), + remove_online_user(From, NewState, IsSubscriber, Reason); +do_process_presence(From, _Nick, #presence{type = error, lang = Lang} = Packet, + StateData) -> + ErrorText = <<"It is not allowed to send error messages to the" + " room. The participant (~s) has sent an error " + "message (~s) and got kicked from the room">>, + expulse_participant(Packet, From, StateData, + translate:translate(Lang, ErrorText)). + +-spec maybe_strip_status_from_presence(jid(), presence(), + state()) -> presence(). maybe_strip_status_from_presence(From, Packet, StateData) -> case {(StateData#state.config)#config.allow_visitor_status, is_visitor(From, StateData)} of @@ -1148,6 +997,8 @@ maybe_strip_status_from_presence(From, Packet, StateData) -> _Allowed -> Packet end. +-spec subscriber_becomes_available(jid(), binary(), presence(), + state()) -> state(). subscriber_becomes_available(From, Nick, Packet, StateData) -> Stanza = maybe_strip_status_from_presence(From, Packet, StateData), State1 = add_user_presence(From, Stanza, StateData), @@ -1159,9 +1010,10 @@ subscriber_becomes_available(From, Nick, Packet, StateData) -> send_initial_presence(From, State3, StateData), State3. +-spec close_room_if_temporary_and_empty(state()) -> fsm_transition(). close_room_if_temporary_and_empty(StateData1) -> case not (StateData1#state.config)#config.persistent - andalso (?DICT):to_list(StateData1#state.users) == [] + andalso (?DICT):size(StateData1#state.users) == 0 of true -> ?INFO_MSG("Destroyed MUC room ~s because it's temporary " @@ -1172,10 +1024,12 @@ close_room_if_temporary_and_empty(StateData1) -> _ -> {next_state, normal_state, StateData1} end. +-spec is_user_online(jid(), state()) -> boolean(). is_user_online(JID, StateData) -> LJID = jid:tolower(JID), (?DICT):is_key(LJID, StateData#state.users). +-spec is_subscriber(jid(), state()) -> boolean(). is_subscriber(JID, StateData) -> LJID = jid:tolower(JID), case (?DICT):find(LJID, StateData#state.users) of @@ -1186,6 +1040,7 @@ is_subscriber(JID, StateData) -> end. %% Check if the user is occupant of the room, or at least is an admin or owner. +-spec is_occupant_or_admin(jid(), state()) -> boolean(). is_occupant_or_admin(JID, StateData) -> FAffiliation = get_affiliation(JID, StateData), FRole = get_role(JID, StateData), @@ -1200,6 +1055,8 @@ is_occupant_or_admin(JID, StateData) -> %%% %%% Handle IQ queries of vCard %%% +-spec is_user_online_iq(binary(), jid(), state()) -> + {boolean(), binary(), jid()}. is_user_online_iq(StanzaId, JID, StateData) when JID#jid.lresource /= <<"">> -> {is_user_online(JID, StateData), StanzaId, JID}; @@ -1207,93 +1064,55 @@ is_user_online_iq(StanzaId, JID, StateData) when JID#jid.lresource == <<"">> -> try stanzaid_unpack(StanzaId) of {OriginalId, Resource} -> - JIDWithResource = jid:replace_resource(JID, - Resource), + JIDWithResource = jid:replace_resource(JID, Resource), {is_user_online(JIDWithResource, StateData), OriginalId, JIDWithResource} catch _:_ -> {is_user_online(JID, StateData), StanzaId, JID} end. -handle_iq_vcard(FromFull, ToJID, StanzaId, NewId, - Packet) -> +-spec handle_iq_vcard(jid(), binary(), iq()) -> {jid(), iq()}. +handle_iq_vcard(ToJID, NewId, #iq{type = Type, sub_els = SubEls} = IQ) -> ToBareJID = jid:remove_resource(ToJID), - IQ = jlib:iq_query_info(Packet), - handle_iq_vcard2(FromFull, ToJID, ToBareJID, StanzaId, - NewId, IQ, Packet). - -handle_iq_vcard2(_FromFull, ToJID, ToBareJID, StanzaId, - _NewId, #iq{type = get, xmlns = ?NS_VCARD}, Packet) - when ToBareJID /= ToJID -> - {ToBareJID, change_stanzaid(StanzaId, ToJID, Packet)}; -handle_iq_vcard2(_FromFull, ToJID, _ToBareJID, - _StanzaId, NewId, _IQ, Packet) -> - {ToJID, change_stanzaid(NewId, Packet)}. + case SubEls of + [SubEl] when Type == get, ToBareJID /= ToJID -> + case xmpp:get_ns(SubEl) of + ?NS_VCARD -> + {ToBareJID, change_stanzaid(ToJID, IQ)}; + _ -> + {ToJID, xmpp:set_id(IQ, NewId)} + end; + _ -> + {ToJID, xmpp:set_id(IQ, NewId)} + end. +-spec stanzaid_pack(binary(), binary()) -> binary(). stanzaid_pack(OriginalId, Resource) -> <<"berd", (jlib:encode_base64(<<"ejab\000", OriginalId/binary, "\000", Resource/binary>>))/binary>>. +-spec stanzaid_unpack(binary()) -> {binary(), binary()}. stanzaid_unpack(<<"berd", StanzaIdBase64/binary>>) -> StanzaId = jlib:decode_base64(StanzaIdBase64), [<<"ejab">>, OriginalId, Resource] = str:tokens(StanzaId, <<"\000">>), {OriginalId, Resource}. -change_stanzaid(NewId, Packet) -> - #xmlel{name = Name, attrs = Attrs, children = Els} = - jlib:remove_attr(<<"id">>, Packet), - #xmlel{name = Name, attrs = [{<<"id">>, NewId} | Attrs], - children = Els}. - -change_stanzaid(PreviousId, ToJID, Packet) -> +-spec change_stanzaid(jid(), iq()) -> iq(). +change_stanzaid(ToJID, #iq{id = PreviousId} = Packet) -> NewId = stanzaid_pack(PreviousId, ToJID#jid.lresource), - change_stanzaid(NewId, Packet). - -%%% -%%% - -role_to_list(Role) -> - case Role of - moderator -> <<"moderator">>; - participant -> <<"participant">>; - visitor -> <<"visitor">>; - none -> <<"none">> - end. - -affiliation_to_list(Affiliation) -> - case Affiliation of - owner -> <<"owner">>; - admin -> <<"admin">>; - member -> <<"member">>; - outcast -> <<"outcast">>; - none -> <<"none">> - end. - -list_to_role(Role) -> - case Role of - <<"moderator">> -> moderator; - <<"participant">> -> participant; - <<"visitor">> -> visitor; - <<"none">> -> none - end. - -list_to_affiliation(Affiliation) -> - case Affiliation of - <<"owner">> -> owner; - <<"admin">> -> admin; - <<"member">> -> member; - <<"outcast">> -> outcast; - <<"none">> -> none - end. + xmpp:set_id(Packet, NewId). %% Decide the fate of the message and its sender %% Returns: continue_delivery | forget_message | {expulse_sender, Reason} -decide_fate_message(<<"error">>, Packet, From, - StateData) -> - PD = case check_error_kick(Packet) of +-spec decide_fate_message(message(), jid(), state()) -> + continue_delivery | forget_message | + {expulse_sender, binary()}. +decide_fate_message(#message{type = error, error = Err}, + From, StateData) -> + PD = case check_error_kick(Err) of %% If this is an error stanza and its condition matches a criteria true -> Reason = @@ -1311,67 +1130,61 @@ decide_fate_message(<<"error">>, Packet, From, end; Other -> Other end; -decide_fate_message(_, _, _, _) -> continue_delivery. +decide_fate_message(_, _, _) -> continue_delivery. %% Check if the elements of this error stanza indicate %% that the sender is a dead participant. %% If so, return true to kick the participant. -check_error_kick(Packet) -> - case get_error_condition(Packet) of - <<"gone">> -> true; - <<"internal-server-error">> -> true; - <<"item-not-found">> -> true; - <<"jid-malformed">> -> true; - <<"recipient-unavailable">> -> true; - <<"redirect">> -> true; - <<"remote-server-not-found">> -> true; - <<"remote-server-timeout">> -> true; - <<"service-unavailable">> -> true; - _ -> false - end. - -get_error_condition(Packet) -> - case catch get_error_condition2(Packet) of - {condition, ErrorCondition} -> ErrorCondition; - {'EXIT', _} -> <<"badformed error stanza">> - end. +-spec check_error_kick(error()) -> boolean(). +check_error_kick(#error{reason = Reason}) -> + case Reason of + #gone{} -> true; + 'internal-server-error' -> true; + 'item-not-found' -> true; + 'jid-malformed' -> true; + 'recipient-unavailable' -> true; + #redirect{} -> true; + 'remote-server-not-found' -> true; + 'remote-server-timeout' -> true; + 'service-unavailable' -> true; + _ -> false + end; +check_error_kick(undefined) -> + false. -get_error_condition2(Packet) -> - #xmlel{children = EEls} = fxml:get_subtag(Packet, - <<"error">>), - [Condition] = [Name - || #xmlel{name = Name, - attrs = [{<<"xmlns">>, ?NS_STANZAS}], - children = []} - <- EEls], - {condition, Condition}. +-spec get_error_condition(error()) -> string(). +get_error_condition(#error{reason = Reason}) -> + case Reason of + #gone{} -> "gone"; + #redirect{} -> "redirect"; + Atom -> atom_to_list(Atom) + end; +get_error_condition(undefined) -> + "undefined". +-spec make_reason(stanza(), jid(), state(), binary()) -> binary(). make_reason(Packet, From, StateData, Reason1) -> {ok, #user{nick = FromNick}} = (?DICT):find(jid:tolower(From), StateData#state.users), - Condition = get_error_condition(Packet), + Condition = get_error_condition(xmpp:get_error(Packet)), iolist_to_binary(io_lib:format(Reason1, [FromNick, Condition])). +-spec expulse_participant(stanza(), jid(), state(), binary()) -> + state(). expulse_participant(Packet, From, StateData, Reason1) -> IsSubscriber = is_subscriber(From, StateData), Reason2 = make_reason(Packet, From, StateData, Reason1), NewState = add_user_presence_un(From, - #xmlel{name = <<"presence">>, - attrs = - [{<<"type">>, - <<"unavailable">>}], - children = - [#xmlel{name = <<"status">>, - attrs = [], - children = - [{xmlcdata, - Reason2}]}]}, + #presence{type = unavailable, + status = xmpp:mk_text(Reason2)}, StateData), send_new_presence(From, NewState, StateData), remove_online_user(From, NewState, IsSubscriber). +-spec set_affiliation(jid(), affiliation(), state()) -> state(). set_affiliation(JID, Affiliation, StateData) -> set_affiliation(JID, Affiliation, StateData, <<"">>). +-spec set_affiliation(jid(), affiliation(), state(), binary()) -> state(). set_affiliation(JID, Affiliation, StateData, Reason) -> LJID = jid:remove_resource(jid:tolower(JID)), Affiliations = case Affiliation of @@ -1383,6 +1196,7 @@ set_affiliation(JID, Affiliation, StateData, Reason) -> end, StateData#state{affiliations = Affiliations}. +-spec get_affiliation(jid(), state()) -> affiliation(). get_affiliation(JID, StateData) -> {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = @@ -1423,6 +1237,7 @@ get_affiliation(JID, StateData) -> _ -> Res end. +-spec get_service_affiliation(jid(), state()) -> owner | none. get_service_affiliation(JID, StateData) -> {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = @@ -1434,6 +1249,7 @@ get_service_affiliation(JID, StateData) -> _ -> none end. +-spec set_role(jid(), role(), state()) -> state(). set_role(JID, Role, StateData) -> LJID = jid:tolower(JID), LJIDs = case LJID of @@ -1482,6 +1298,7 @@ set_role(JID, Role, StateData) -> end, StateData#state{users = Users, nicks = Nicks}. +-spec get_role(jid(), state()) -> role(). get_role(JID, StateData) -> LJID = jid:tolower(JID), case (?DICT):find(LJID, StateData#state.users) of @@ -1489,6 +1306,7 @@ get_role(JID, StateData) -> _ -> none end. +-spec get_default_role(affiliation(), state()) -> role(). get_default_role(Affiliation, StateData) -> case Affiliation of owner -> moderator; @@ -1507,12 +1325,15 @@ get_default_role(Affiliation, StateData) -> end end. +-spec is_visitor(jid(), state()) -> boolean(). is_visitor(Jid, StateData) -> get_role(Jid, StateData) =:= visitor. +-spec is_moderator(jid(), state()) -> boolean(). is_moderator(Jid, StateData) -> get_role(Jid, StateData) =:= moderator. +-spec get_max_users(state()) -> non_neg_integer(). get_max_users(StateData) -> MaxUsers = (StateData#state.config)#config.max_users, ServiceMaxUsers = get_service_max_users(StateData), @@ -1520,18 +1341,21 @@ get_max_users(StateData) -> true -> ServiceMaxUsers end. +-spec get_service_max_users(state()) -> pos_integer(). get_service_max_users(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_users, fun(I) when is_integer(I), I>0 -> I end, ?MAX_USERS_DEFAULT). +-spec get_max_users_admin_threshold(state()) -> pos_integer(). get_max_users_admin_threshold(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_users_admin_threshold, fun(I) when is_integer(I), I>0 -> I end, 5). +-spec get_user_activity(jid(), state()) -> #activity{}. get_user_activity(JID, StateData) -> case treap:lookup(jid:tolower(JID), StateData#state.activity) @@ -1552,6 +1376,7 @@ get_user_activity(JID, StateData) -> presence_shaper = PresenceShaper} end. +-spec store_user_activity(jid(), #activity{}, state()) -> state(). store_user_activity(JID, UserActivity, StateData) -> MinMessageInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, @@ -1613,6 +1438,7 @@ store_user_activity(JID, UserActivity, StateData) -> end, StateData1. +-spec clean_treap(treap:treap(), integer()) -> treap:treap(). clean_treap(Treap, CleanPriority) -> case treap:is_empty(Treap) of true -> Treap; @@ -1624,6 +1450,7 @@ clean_treap(Treap, CleanPriority) -> end end. +-spec prepare_room_queue(state()) -> state(). prepare_room_queue(StateData) -> case queue:out(StateData#state.room_queue) of {{value, {message, From}}, _RoomQueue} -> @@ -1647,6 +1474,7 @@ prepare_room_queue(StateData) -> {empty, _} -> StateData end. +-spec update_online_user(jid(), #user{}, state()) -> state(). update_online_user(JID, #user{nick = Nick, subscriptions = Nodes, is_subscriber = IsSubscriber} = User, StateData) -> LJID = jid:tolower(JID), @@ -1681,6 +1509,7 @@ update_online_user(JID, #user{nick = Nick, subscriptions = Nodes, end, NewStateData. +-spec add_online_user(jid(), binary(), role(), boolean(), [binary()], state()) -> state(). add_online_user(JID, Nick, Role, IsSubscriber, Nodes, StateData) -> tab_add_online_user(JID, StateData), User = #user{jid = JID, nick = Nick, role = Role, @@ -1693,9 +1522,11 @@ add_online_user(JID, Nick, Role, IsSubscriber, Nodes, StateData) -> end, StateData1. +-spec remove_online_user(jid(), state(), boolean()) -> state(). remove_online_user(JID, StateData, IsSubscriber) -> remove_online_user(JID, StateData, IsSubscriber, <<"">>). +-spec remove_online_user(jid(), state(), boolean(), binary()) -> state(). remove_online_user(JID, StateData, _IsSubscriber = true, _Reason) -> LJID = jid:tolower(JID), Users = case (?DICT):find(LJID, StateData#state.users) of @@ -1723,38 +1554,23 @@ remove_online_user(JID, StateData, _IsSubscriber, Reason) -> end, StateData#state{users = Users, nicks = Nicks}. -filter_presence(#xmlel{name = <<"presence">>, - attrs = Attrs, children = Els}) -> - FEls = lists:filter(fun (El) -> - case El of - {xmlcdata, _} -> false; - #xmlel{attrs = Attrs1} -> - XMLNS = fxml:get_attr_s(<<"xmlns">>, - Attrs1), - NS_MUC = ?NS_MUC, - Size = byte_size(NS_MUC), - case XMLNS of - <> -> - false; - _ -> - true - end - end - end, - Els), - #xmlel{name = <<"presence">>, attrs = Attrs, - children = FEls}. - -strip_status(#xmlel{name = <<"presence">>, - attrs = Attrs, children = Els}) -> - FEls = lists:filter(fun (#xmlel{name = <<"status">>}) -> - false; - (_) -> true - end, - Els), - #xmlel{name = <<"presence">>, attrs = Attrs, - children = FEls}. - +-spec filter_presence(presence()) -> presence(). +filter_presence(Presence) -> + Els = lists:filter( + fun(El) -> + XMLNS = xmpp:get_ns(El), + case catch binary:part(XMLNS, 0, size(?NS_MUC)) of + ?NS_MUC -> false; + _ -> true + end + end, xmpp:get_els(Presence)), + xmpp:set_els(Presence, Els). + +-spec strip_status(presence()) -> presence(). +strip_status(Presence) -> + Presence#presence{status = []}. + +-spec add_user_presence(jid(), presence(), state()) -> state(). add_user_presence(JID, Presence, StateData) -> LJID = jid:tolower(JID), FPresence = filter_presence(Presence), @@ -1765,6 +1581,7 @@ add_user_presence(JID, Presence, StateData) -> StateData#state.users), StateData#state{users = Users}. +-spec add_user_presence_un(jid(), presence(), state()) -> state(). add_user_presence_un(JID, Presence, StateData) -> LJID = jid:tolower(JID), FPresence = filter_presence(Presence), @@ -1778,15 +1595,17 @@ add_user_presence_un(JID, Presence, StateData) -> %% Find and return a list of the full JIDs of the users of Nick. %% Return jid record. +-spec find_jids_by_nick(binary(), state()) -> [jid()]. find_jids_by_nick(Nick, StateData) -> case (?DICT):find(Nick, StateData#state.nicks) of {ok, [User]} -> [jid:make(User)]; {ok, Users} -> [jid:make(LJID) || LJID <- Users]; - error -> false + error -> [] end. %% Find and return the full JID of the user of Nick with %% highest-priority presence. Return jid record. +-spec find_jid_by_nick(binary(), state()) -> jid() | false. find_jid_by_nick(Nick, StateData) -> case (?DICT):find(Nick, StateData#state.nicks) of {ok, [User]} -> jid:make(User); @@ -1811,6 +1630,8 @@ find_jid_by_nick(Nick, StateData) -> error -> false end. +-spec higher_presence(undefined | presence(), + undefined | presence()) -> boolean(). higher_presence(Pres1, Pres2) when Pres1 /= undefined, Pres2 /= undefined -> Pri1 = get_priority_from_presence(Pres1), Pri2 = get_priority_from_presence(Pres2), @@ -1818,26 +1639,20 @@ higher_presence(Pres1, Pres2) when Pres1 /= undefined, Pres2 /= undefined -> higher_presence(Pres1, Pres2) -> Pres1 > Pres2. -get_priority_from_presence(PresencePacket) -> - case fxml:get_subtag(PresencePacket, <<"priority">>) of - false -> 0; - SubEl -> - case catch - jlib:binary_to_integer(fxml:get_tag_cdata(SubEl)) - of - P when is_integer(P) -> P; - _ -> 0 - end +-spec get_priority_from_presence(presence()) -> integer(). +get_priority_from_presence(#presence{priority = Prio}) -> + case Prio of + undefined -> 0; + _ -> Prio end. -find_nick_by_jid(Jid, StateData) -> - [{_, #user{nick = Nick}}] = lists:filter(fun ({_, - #user{jid = FJid}}) -> - FJid == Jid - end, - (?DICT):to_list(StateData#state.users)), +-spec find_nick_by_jid(jid(), state()) -> binary(). +find_nick_by_jid(JID, StateData) -> + LJID = jid:tolower(JID), + {ok, #user{nick = Nick}} = (?DICT):find(LJID, StateData#state.users), Nick. +-spec is_nick_change(jid(), binary(), state()) -> boolean(). is_nick_change(JID, Nick, StateData) -> LJID = jid:tolower(JID), case Nick of @@ -1848,16 +1663,20 @@ is_nick_change(JID, Nick, StateData) -> Nick /= OldNick end. +-spec nick_collision(jid(), binary(), state()) -> boolean(). nick_collision(User, Nick, StateData) -> UserOfNick = find_jid_by_nick(Nick, StateData), (UserOfNick /= false andalso jid:remove_resource(jid:tolower(UserOfNick)) /= jid:remove_resource(jid:tolower(User))). -add_new_user(From, Nick, - #xmlel{name = Name, attrs = Attrs, children = Els} = Packet, - StateData) -> - Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs), +-spec add_new_user(jid(), binary(), presence() | iq(), state()) -> + state() | + {error, error()} | + {ignore, state()} | + {result, xmpp_element(), state()}. +add_new_user(From, Nick, Packet, StateData) -> + Lang = xmpp:get_lang(Packet), UserRoomJID = jid:replace_resource(StateData#state.jid, Nick), MaxUsers = get_max_users(StateData), MaxAdminUsers = MaxUsers + @@ -1874,7 +1693,7 @@ add_new_user(From, Nick, fun(I) when is_integer(I), I>0 -> I end, 10), Collision = nick_collision(From, Nick, StateData), - IsSubscribeRequest = Name /= <<"presence">>, + IsSubscribeRequest = not is_record(Packet, presence), case {(ServiceAffiliation == owner orelse ((Affiliation == admin orelse Affiliation == owner) andalso NUsers < MaxAdminUsers) @@ -1887,72 +1706,72 @@ add_new_user(From, Nick, of {false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers -> Txt = <<"Too many users in this conference">>, - Err = ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_resource_constraint(Txt, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {false, _, _, _} when NConferences >= MaxConferences -> Txt = <<"You have joined too many conferences">>, - Err = ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_resource_constraint(Txt, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {false, _, _, _} -> - Err = ?ERR_SERVICE_UNAVAILABLE, - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_service_unavailable(), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {_, _, _, none} -> Err = case Affiliation of outcast -> ErrText = <<"You have been banned from this room">>, - ?ERRT_FORBIDDEN(Lang, ErrText); + xmpp:err_forbidden(ErrText, Lang); _ -> ErrText = <<"Membership is required to enter this room">>, - ?ERRT_REGISTRATION_REQUIRED(Lang, ErrText) + xmpp:err_registration_required(ErrText, Lang) end, - ErrPacket = jlib:make_error_reply(Packet, Err), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {_, true, _, _} -> ErrText = <<"That nickname is already in use by another occupant">>, - Err = ?ERRT_CONFLICT(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_conflict(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {_, _, false, _} -> ErrText = <<"That nickname is registered by another person">>, - Err = ?ERRT_CONFLICT(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_conflict(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; {_, _, _, Role} -> case check_password(ServiceAffiliation, Affiliation, - Els, From, StateData) + Packet, From, StateData) of true -> Nodes = get_subscription_nodes(Packet), @@ -1965,7 +1784,7 @@ add_new_user(From, Nick, Nodes, StateData)), send_existing_presences(From, NewState), send_initial_presence(From, NewState, StateData), - Shift = count_stanza_shift(Nick, Els, NewState), + Shift = count_stanza_shift(Nick, Packet, NewState), case send_history(From, Shift, NewState) of true -> ok; _ -> send_subject(From, StateData) @@ -1985,20 +1804,20 @@ add_new_user(From, Nick, NewStateData#state{robots = Robots} end, if not IsSubscribeRequest -> ResultState; - true -> {result, subscription_nodes_to_events(Nodes), ResultState} + true -> {result, subscribe_result(Packet), ResultState} end; nopass -> ErrText = <<"A password is required to enter this room">>, - Err = ?ERRT_NOT_AUTHORIZED(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_not_authorized(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; captcha_required -> - SID = fxml:get_attr_s(<<"id">>, Attrs), + SID = xmpp:get_id(Packet), RoomJID = StateData#state.jid, To = jid:replace_resource(RoomJID, Nick), Limiter = {From#jid.luser, From#jid.lserver}, @@ -2006,9 +1825,7 @@ add_new_user(From, Nick, Lang, Limiter, From) of {ok, ID, CaptchaEls} -> - MsgPkt = #xmlel{name = <<"message">>, - attrs = [{<<"id">>, ID}], - children = CaptchaEls}, + MsgPkt = #message{id = ID, sub_els = CaptchaEls}, Robots = (?DICT):store(From, {Nick, Packet}, StateData#state.robots), ejabberd_router:route(RoomJID, From, MsgPkt), @@ -2020,49 +1837,51 @@ add_new_user(From, Nick, end; {error, limit} -> ErrText = <<"Too many CAPTCHA requests">>, - Err = ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_resource_constraint(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end; _ -> ErrText = <<"Unable to generate a CAPTCHA">>, - Err = ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_internal_server_error(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end end; _ -> ErrText = <<"Incorrect password">>, - Err = ?ERRT_NOT_AUTHORIZED(Lang, ErrText), - ErrPacket = jlib:make_error_reply(Packet, Err), + Err = xmpp:err_not_authorized(ErrText, Lang), + ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> ejabberd_router:route(UserRoomJID, From, ErrPacket), StateData; true -> - {error, Err, StateData} + {error, Err} end end end. -check_password(owner, _Affiliation, _Els, _From, +-spec check_password(affiliation(), affiliation(), + stanza(), jid(), state()) -> boolean() | nopass. +check_password(owner, _Affiliation, _Packet, _From, _StateData) -> %% Don't check pass if user is owner in MUC service (access_admin option) true; -check_password(_ServiceAffiliation, Affiliation, Els, +check_password(_ServiceAffiliation, Affiliation, Packet, From, StateData) -> case (StateData#state.config)#config.password_protected of false -> check_captcha(Affiliation, From, StateData); true -> - Pass = extract_password(Els), + Pass = extract_password(Packet), case Pass of false -> nopass; _ -> @@ -2073,6 +1892,7 @@ check_password(_ServiceAffiliation, Affiliation, Els, end end. +-spec check_captcha(affiliation(), jid(), state()) -> true | captcha_required. check_captcha(Affiliation, From, StateData) -> case (StateData#state.config)#config.captcha_protected andalso ejabberd_captcha:is_feature_available() @@ -2101,47 +1921,52 @@ check_captcha(Affiliation, From, StateData) -> _ -> true end. -extract_password([]) -> false; -extract_password([#xmlel{attrs = Attrs} = El | Els]) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MUC -> - case fxml:get_subtag(El, <<"password">>) of - false -> false; - SubEl -> fxml:get_tag_cdata(SubEl) - end; - _ -> extract_password(Els) - end; -extract_password([_ | Els]) -> extract_password(Els). +-spec extract_password(stanza()) -> binary() | false. +extract_password(Packet) -> + case xmpp:get_subtag(Packet, #muc{}) of + #muc{password = Password} when is_binary(Password) -> + Password; + _ -> + false + end. -count_stanza_shift(Nick, Els, StateData) -> - HL = lqueue_to_list(StateData#state.history), - Since = extract_history(Els, <<"since">>), - Shift0 = case Since of - false -> 0; - _ -> - Sin = calendar:datetime_to_gregorian_seconds(Since), - count_seconds_shift(Sin, HL) - end, - Seconds = extract_history(Els, <<"seconds">>), - Shift1 = case Seconds of - false -> 0; - _ -> - Sec = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) - - Seconds, - count_seconds_shift(Sec, HL) - end, - MaxStanzas = extract_history(Els, <<"maxstanzas">>), - Shift2 = case MaxStanzas of - false -> 0; - _ -> count_maxstanzas_shift(MaxStanzas, HL) - end, - MaxChars = extract_history(Els, <<"maxchars">>), - Shift3 = case MaxChars of - false -> 0; - _ -> count_maxchars_shift(Nick, MaxChars, HL) - end, - lists:max([Shift0, Shift1, Shift2, Shift3]). +-spec count_stanza_shift(binary(), stanza(), state()) -> non_neg_integer(). +count_stanza_shift(Nick, Packet, StateData) -> + case xmpp:get_subtag(Packet, #muc_history{}) of + #muc_history{since = Since, + seconds = Seconds, + maxstanzas = MaxStanzas, + maxchars = MaxChars} -> + HL = lqueue_to_list(StateData#state.history), + Shift0 = case Since of + undefined -> 0; + _ -> + Sin = calendar:datetime_to_gregorian_seconds( + calendar:now_to_datetime(Since)), + count_seconds_shift(Sin, HL) + end, + Shift1 = case Seconds of + undefined -> 0; + _ -> + Sec = calendar:datetime_to_gregorian_seconds( + calendar:universal_time()) - Seconds, + count_seconds_shift(Sec, HL) + end, + Shift2 = case MaxStanzas of + undefined -> 0; + _ -> count_maxstanzas_shift(MaxStanzas, HL) + end, + Shift3 = case MaxChars of + undefined -> 0; + _ -> count_maxchars_shift(Nick, MaxChars, HL) + end, + lists:max([Shift0, Shift1, Shift2, Shift3]); + false -> + 0 + end. +-spec count_seconds_shift(non_neg_integer(), + [history_element()]) -> non_neg_integer(). count_seconds_shift(Seconds, HistoryList) -> lists:sum(lists:map(fun ({_Nick, _Packet, _HaveSubject, TimeStamp, _Size}) -> @@ -2153,12 +1978,16 @@ count_seconds_shift(Seconds, HistoryList) -> end, HistoryList)). +-spec count_maxstanzas_shift(non_neg_integer(), + [history_element()]) -> non_neg_integer(). count_maxstanzas_shift(MaxStanzas, HistoryList) -> S = length(HistoryList) - MaxStanzas, if S =< 0 -> 0; true -> S end. +-spec count_maxchars_shift(binary(), non_neg_integer(), + [history_element()]) -> integer(). count_maxchars_shift(Nick, MaxSize, HistoryList) -> NLen = byte_size(Nick) + 1, Sizes = lists:map(fun ({_Nick, _Packet, _HaveSubject, @@ -2168,41 +1997,20 @@ count_maxchars_shift(Nick, MaxSize, HistoryList) -> HistoryList), calc_shift(MaxSize, Sizes). +-spec calc_shift(non_neg_integer(), [non_neg_integer()]) -> integer(). calc_shift(MaxSize, Sizes) -> Total = lists:sum(Sizes), calc_shift(MaxSize, Total, 0, Sizes). +-spec calc_shift(non_neg_integer(), integer(), integer(), + [non_neg_integer()]) -> integer(). calc_shift(_MaxSize, _Size, Shift, []) -> Shift; calc_shift(MaxSize, Size, Shift, [S | TSizes]) -> if MaxSize >= Size -> Shift; true -> calc_shift(MaxSize, Size - S, Shift + 1, TSizes) end. -extract_history([], _Type) -> false; -extract_history([#xmlel{attrs = Attrs} = El | Els], - Type) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MUC -> - AttrVal = fxml:get_path_s(El, - [{elem, <<"history">>}, {attr, Type}]), - case Type of - <<"since">> -> - case jlib:datetime_string_to_timestamp(AttrVal) of - undefined -> false; - TS -> calendar:now_to_universal_time(TS) - end; - _ -> - case catch jlib:binary_to_integer(AttrVal) of - IntVal when is_integer(IntVal) and (IntVal >= 0) -> - IntVal; - _ -> false - end - end; - _ -> extract_history(Els, Type) - end; -extract_history([_ | Els], Type) -> - extract_history(Els, Type). - +-spec is_room_overcrowded(state()) -> boolean(). is_room_overcrowded(StateData) -> MaxUsersPresence = gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_users_presence, @@ -2210,10 +2018,12 @@ is_room_overcrowded(StateData) -> ?DEFAULT_MAX_USERS_PRESENCE), (?DICT):size(StateData#state.users) > MaxUsersPresence. +-spec presence_broadcast_allowed(jid(), state()) -> boolean(). presence_broadcast_allowed(JID, StateData) -> Role = get_role(JID, StateData), lists:member(Role, (StateData#state.config)#config.presence_broadcast). +-spec is_initial_presence(jid(), state()) -> boolean(). is_initial_presence(From, StateData) -> LJID = jid:tolower(From), case (?DICT):find(LJID, StateData#state.users) of @@ -2223,18 +2033,22 @@ is_initial_presence(From, StateData) -> true end. +-spec send_initial_presence(jid(), state(), state()) -> ok. send_initial_presence(NJID, StateData, OldStateData) -> send_new_presence1(NJID, <<"">>, true, StateData, OldStateData). +-spec send_update_presence(jid(), state(), state()) -> ok. send_update_presence(JID, StateData, OldStateData) -> send_update_presence(JID, <<"">>, StateData, OldStateData). +-spec send_update_presence(jid(), binary(), state(), state()) -> ok. send_update_presence(JID, Reason, StateData, OldStateData) -> case is_room_overcrowded(StateData) of true -> ok; false -> send_update_presence1(JID, Reason, StateData, OldStateData) end. +-spec send_update_presence1(jid(), binary(), state(), state()) -> ok. send_update_presence1(JID, Reason, StateData, OldStateData) -> LJID = jid:tolower(JID), LJIDs = case LJID of @@ -2258,12 +2072,15 @@ send_update_presence1(JID, Reason, StateData, OldStateData) -> end, LJIDs). +-spec send_new_presence(jid(), state(), state()) -> ok. send_new_presence(NJID, StateData, OldStateData) -> send_new_presence(NJID, <<"">>, false, StateData, OldStateData). +-spec send_new_presence(jid(), binary(), state(), state()) -> ok. send_new_presence(NJID, Reason, StateData, OldStateData) -> send_new_presence(NJID, Reason, false, StateData, OldStateData). +-spec send_new_presence(jid(), binary(), boolean(), state(), state()) -> ok. send_new_presence(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> case is_room_overcrowded(StateData) of true -> ok; @@ -2271,6 +2088,7 @@ send_new_presence(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> OldStateData) end. +-spec is_ra_changed(jid() | ljid(), boolean(), state(), state()) -> boolean(). is_ra_changed(_, _IsInitialPresence = true, _, _) -> false; is_ra_changed(LJID, _IsInitialPresence = false, NewStateData, OldStateData) -> @@ -2289,6 +2107,7 @@ is_ra_changed(LJID, _IsInitialPresence = false, NewStateData, OldStateData) -> (NewRole /= OldRole) or (NewAff /= OldAff) end. +-spec send_new_presence1(jid(), binary(), boolean(), state(), state()) -> ok. send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> LNJID = jid:tolower(NJID), #user{nick = Nick} = (?DICT):fetch(LNJID, StateData#state.users), @@ -2301,15 +2120,9 @@ send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> {Role1, Presence1} = case presence_broadcast_allowed(NJID, StateData) of true -> {Role0, Presence0}; - false -> - {none, - #xmlel{name = <<"presence">>, - attrs = [{<<"type">>, <<"unavailable">>}], - children = []} - } + false -> {none, #presence{type = unavailable}} end, Affiliation = get_affiliation(LJID, StateData), - SAffiliation = affiliation_to_list(Affiliation), UserList = case not (presence_broadcast_allowed(NJID, StateData) orelse presence_broadcast_allowed(NJID, OldStateData)) of @@ -2323,59 +2136,38 @@ send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> {Role, Presence} = if LNJID == LUJID -> {Role0, Presence0}; true -> {Role1, Presence1} end, - SRole = role_to_list(Role), - ItemAttrs = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false - of - true -> - [{<<"jid">>, - jid:to_string(RealJID)}, - {<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}]; - _ -> - [{<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}] - end, - ItemEls = case Reason of - <<"">> -> []; - _ -> - [#xmlel{name = <<"reason">>, - attrs = [], - children = - [{xmlcdata, Reason}]}] - end, - StatusEls = status_els(IsInitialPresence, NJID, Info, - StateData), - Pres = if Presence == undefined -> #xmlel{name = <<"presence">>}; + Item0 = #muc_item{affiliation = Affiliation, + role = Role}, + Item1 = case Info#user.role == moderator orelse + (StateData#state.config)#config.anonymous + == false of + true -> Item0#muc_item{jid = RealJID}; + false -> Item0 + end, + Item = if is_binary(Reason), Reason /= <<"">> -> + Item1#muc_item{reason = Reason}; + true -> + Item1 + end, + StatusCodes = status_codes(IsInitialPresence, NJID, Info, + StateData), + Pres = if Presence == undefined -> #presence{}; true -> Presence end, - Packet = fxml:append_subtags(Pres, - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name = - <<"item">>, - attrs - = - ItemAttrs, - children - = - ItemEls} - | StatusEls]}]), + Packet = xmpp:set_subtag( + Pres, #muc_user{items = [Item], + status_codes = StatusCodes}), Node1 = case is_ra_changed(NJID, IsInitialPresence, StateData, OldStateData) of true -> ?NS_MUCSUB_NODES_AFFILIATIONS; false -> ?NS_MUCSUB_NODES_PRESENCE end, send_wrapped(jid:replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet, Node1, StateData), - Type = fxml:get_tag_attr_s(<<"type">>, Packet), + Type = xmpp:get_type(Packet), IsSubscriber = Info#user.is_subscriber, IsOccupant = Info#user.last_presence /= undefined, if (IsSubscriber and not IsOccupant) and - (IsInitialPresence or (Type == <<"unavailable">>)) -> + (IsInitialPresence or (Type == unavailable)) -> Node2 = ?NS_MUCSUB_NODES_PARTICIPANTS, send_wrapped(jid:replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet, Node2, StateData); @@ -2385,12 +2177,14 @@ send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> end, UserList). +-spec send_existing_presences(jid(), state()) -> ok. send_existing_presences(ToJID, StateData) -> case is_room_overcrowded(StateData) of true -> ok; false -> send_existing_presences1(ToJID, StateData) end. +-spec send_existing_presences1(jid(), state()) -> ok. send_existing_presences1(ToJID, StateData) -> LToJID = jid:tolower(ToJID), {ok, #user{jid = RealToJID, role = Role}} = @@ -2410,46 +2204,23 @@ send_existing_presences1(ToJID, StateData) -> {_, false} -> ok; _ -> FromAffiliation = get_affiliation(LJID, StateData), - ItemAttrs = case Role == moderator orelse - (StateData#state.config)#config.anonymous - == false - of - true -> - [{<<"jid">>, - jid:to_string(FromJID)}, - {<<"affiliation">>, - affiliation_to_list(FromAffiliation)}, - {<<"role">>, - role_to_list(FromRole)}]; - _ -> - [{<<"affiliation">>, - affiliation_to_list(FromAffiliation)}, - {<<"role">>, - role_to_list(FromRole)}] - end, - Packet = fxml:append_subtags( - Presence, - [#xmlel{name = - <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name - = - <<"item">>, - attrs - = - ItemAttrs, - children - = - []}]}]), + Item0 = #muc_item{affiliation = FromAffiliation, + role = FromRole}, + Item = case Role == moderator orelse + (StateData#state.config)#config.anonymous + == false of + true -> Item0#muc_item{jid = FromJID}; + false -> Item0 + end, + Packet = xmpp:set_subtag( + Presence, #muc_user{items = [Item]}), send_wrapped(jid:replace_resource(StateData#state.jid, FromNick), RealToJID, Packet, ?NS_MUCSUB_NODES_PRESENCE, StateData) end end, (?DICT):to_list(StateData#state.nicks)). +-spec set_nick(jid(), binary(), state()) -> state(). set_nick(JID, Nick, State) -> LJID = jid:tolower(JID), {ok, #user{nick = OldNick}} = (?DICT):find(LJID, State#state.users), @@ -2472,6 +2243,7 @@ set_nick(JID, Nick, State) -> end, State#state{users = Users, nicks = Nicks}. +-spec change_nick(jid(), binary(), state()) -> state(). change_nick(JID, Nick, StateData) -> LJID = jid:tolower(JID), {ok, #user{nick = OldNick}} = (?DICT):find(LJID, StateData#state.users), @@ -2492,6 +2264,7 @@ change_nick(JID, Nick, StateData) -> add_to_log(nickchange, {OldNick, Nick}, StateData), NewStateData. +-spec send_nick_changing(jid(), binary(), state(), boolean(), boolean()) -> ok. send_nick_changing(JID, OldNick, StateData, SendOldUnavailable, SendNewAvailable) -> {ok, @@ -2500,104 +2273,52 @@ send_nick_changing(JID, OldNick, StateData, (?DICT):find(jid:tolower(JID), StateData#state.users), Affiliation = get_affiliation(JID, StateData), - SAffiliation = affiliation_to_list(Affiliation), - SRole = role_to_list(Role), - lists:foreach(fun ({_LJID, Info}) when Presence /= undefined -> - ItemAttrs1 = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false - of - true -> - [{<<"jid">>, - jid:to_string(RealJID)}, - {<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}, - {<<"nick">>, Nick}]; - _ -> - [{<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}, - {<<"nick">>, Nick}] - end, - ItemAttrs2 = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false - of - true -> - [{<<"jid">>, - jid:to_string(RealJID)}, - {<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}]; - _ -> - [{<<"affiliation">>, SAffiliation}, - {<<"role">>, SRole}] - end, - Status110 = case JID == Info#user.jid of - true -> - [#xmlel{name = <<"status">>, - attrs = [{<<"code">>, <<"110">>}] - }]; - false -> - [] - end, - Packet1 = #xmlel{name = <<"presence">>, - attrs = - [{<<"type">>, - <<"unavailable">>}], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name = - <<"item">>, - attrs = - ItemAttrs1, - children = - []}, - #xmlel{name = - <<"status">>, - attrs = - [{<<"code">>, - <<"303">>}], - children = - []}|Status110]}]}, - Packet2 = fxml:append_subtags(Presence, - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name - = - <<"item">>, - attrs - = - ItemAttrs2, - children - = - []}|Status110]}]), - if SendOldUnavailable -> - send_wrapped(jid:replace_resource(StateData#state.jid, - OldNick), - Info#user.jid, Packet1, - ?NS_MUCSUB_NODES_PRESENCE, - StateData); - true -> ok + lists:foreach( + fun({_LJID, Info}) when Presence /= undefined -> + Item0 = #muc_item{affiliation = Affiliation, role = Role}, + Item1 = case Info#user.role == moderator orelse + (StateData#state.config)#config.anonymous + == false of + true -> Item0#muc_item{jid = RealJID, nick = Nick}; + false -> Item0#muc_item{nick = Nick} + end, + Item2 = case Info#user.role == moderator orelse + (StateData#state.config)#config.anonymous + == false of + true -> Item0#muc_item{jid = RealJID}; + false -> Item0 + end, + Status110 = case JID == Info#user.jid of + true -> [110]; + false -> [] end, - if SendNewAvailable -> - send_wrapped(jid:replace_resource(StateData#state.jid, - Nick), - Info#user.jid, Packet2, - ?NS_MUCSUB_NODES_PRESENCE, - StateData); - true -> ok - end; - (_) -> - ok - end, - (?DICT):to_list(StateData#state.users)). + Packet1 = #presence{type = unavailable, + sub_els = [#muc_user{ + items = [Item1], + status_codes = [303|Status110]}]}, + Packet2 = xmpp:set_subtag(Presence, + #muc_user{items = [Item2], + status_codes = Status110}), + if SendOldUnavailable -> + send_wrapped( + jid:replace_resource(StateData#state.jid, OldNick), + Info#user.jid, Packet1, ?NS_MUCSUB_NODES_PRESENCE, + StateData); + true -> ok + end, + if SendNewAvailable -> + send_wrapped( + jid:replace_resource(StateData#state.jid, Nick), + Info#user.jid, Packet2, ?NS_MUCSUB_NODES_PRESENCE, + StateData); + true -> ok + end; + (_) -> + ok + end, + (?DICT):to_list(StateData#state.users)). +-spec maybe_send_affiliation(jid(), affiliation(), state()) -> ok. maybe_send_affiliation(JID, Affiliation, StateData) -> LJID = jid:tolower(JID), IsOccupant = case LJID of @@ -2617,18 +2338,13 @@ maybe_send_affiliation(JID, Affiliation, StateData) -> send_affiliation(LJID, Affiliation, StateData) end. +-spec send_affiliation(ljid(), affiliation(), state()) -> ok. send_affiliation(LJID, Affiliation, StateData) -> - ItemAttrs = [{<<"jid">>, jid:to_string(LJID)}, - {<<"affiliation">>, affiliation_to_list(Affiliation)}, - {<<"role">>, <<"none">>}], - Message = #xmlel{name = <<"message">>, - attrs = [{<<"id">>, randoms:get_string()}], - children = - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}], - children = - [#xmlel{name = <<"item">>, - attrs = ItemAttrs}]}]}, + Item = #muc_item{jid = jid:make(LJID), + affiliation = Affiliation, + role = none}, + Message = #message{id = randoms:get_string(), + sub_els = [#muc_user{items = [Item]}]}, Recipients = case (StateData#state.config)#config.anonymous of true -> (?DICT):filter(fun(_, #user{role = moderator}) -> @@ -2643,43 +2359,33 @@ send_affiliation(LJID, Affiliation, StateData) -> StateData#state.server_host, Recipients, Message). -status_els(IsInitialPresence, JID, #user{jid = JID}, StateData) -> - Status = case IsInitialPresence of - true -> - S1 = case StateData#state.just_created of - true -> - [#xmlel{name = <<"status">>, - attrs = [{<<"code">>, <<"201">>}], - children = []}]; - false -> [] - end, - S2 = case (StateData#state.config)#config.anonymous of - true -> S1; - false -> - [#xmlel{name = <<"status">>, - attrs = [{<<"code">>, <<"100">>}], - children = []} | S1] - end, - S3 = case (StateData#state.config)#config.logging of - true -> - [#xmlel{name = <<"status">>, - attrs = [{<<"code">>, <<"170">>}], - children = []} | S2]; - false -> S2 - end, - S3; - false -> [] - end, - [#xmlel{name = <<"status">>, - attrs = - [{<<"code">>, - <<"110">>}], - children = []} | Status]; -status_els(_IsInitialPresence, _JID, _Info, _StateData) -> []. +-spec status_codes(boolean(), jid(), #user{}, state()) -> [pos_integer()]. +status_codes(IsInitialPresence, JID, #user{jid = JID}, StateData) -> + S0 = [110], + case IsInitialPresence of + true -> + S1 = case StateData#state.just_created of + true -> [201|S0]; + false -> S0 + end, + S2 = case (StateData#state.config)#config.anonymous of + true -> S1; + false -> [100|S1] + end, + S3 = case (StateData#state.config)#config.logging of + true -> [170|S2]; + false -> S2 + end, + S3; + false -> S0 + end; +status_codes(_IsInitialPresence, _JID, _Info, _StateData) -> []. +-spec lqueue_new(non_neg_integer()) -> lqueue(). lqueue_new(Max) -> #lqueue{queue = queue:new(), len = 0, max = Max}. +-spec lqueue_in(term(), lqueue()) -> lqueue(). %% If the message queue limit is set to 0, do not store messages. lqueue_in(_Item, LQ = #lqueue{max = 0}) -> LQ; %% Otherwise, rotate messages in the queue store. @@ -2692,39 +2398,33 @@ lqueue_in(Item, true -> #lqueue{queue = Q2, len = Len + 1, max = Max} end. +-spec lqueue_cut(queue:queue(), non_neg_integer()) -> queue:queue(). lqueue_cut(Q, 0) -> Q; lqueue_cut(Q, N) -> {_, Q1} = queue:out(Q), lqueue_cut(Q1, N - 1). +-spec lqueue_to_list(lqueue()) -> list(). lqueue_to_list(#lqueue{queue = Q1}) -> queue:to_list(Q1). - +-spec add_message_to_history(binary(), jid(), message(), state()) -> state(). add_message_to_history(FromNick, FromJID, Packet, StateData) -> - HaveSubject = case fxml:get_subtag(Packet, <<"subject">>) - of - false -> false; - _ -> true - end, + HaveSubject = Packet#message.subject /= [], TimeStamp = p1_time_compat:timestamp(), AddrPacket = case (StateData#state.config)#config.anonymous of true -> Packet; false -> - Address = #xmlel{name = <<"address">>, - attrs = [{<<"type">>, <<"ofrom">>}, - {<<"jid">>, - jid:to_string(FromJID)}], - children = []}, - Addresses = #xmlel{name = <<"addresses">>, - attrs = [{<<"xmlns">>, ?NS_ADDRESS}], - children = [Address]}, - fxml:append_subtags(Packet, [Addresses]) + Addresses = #addresses{ + list = [#address{type = ofrom, + jid = FromJID}]}, + xmpp:set_subtag(Packet, Addresses) end, - TSPacket = jlib:add_delay_info(AddrPacket, StateData#state.jid, TimeStamp), - SPacket = - jlib:replace_from_to(jid:replace_resource(StateData#state.jid, - FromNick), - StateData#state.jid, TSPacket), + TSPacket = xmpp_util:add_delay_info( + AddrPacket, StateData#state.jid, TimeStamp), + SPacket = xmpp:set_from_to( + TSPacket, + jid:replace_resource(StateData#state.jid, FromNick), + StateData#state.jid), Size = element_size(SPacket), Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, calendar:now_to_universal_time(TimeStamp), Size}, @@ -2732,6 +2432,7 @@ add_message_to_history(FromNick, FromJID, Packet, StateData) -> add_to_log(text, {FromNick, Packet}, StateData), StateData#state{history = Q1}. +-spec send_history(jid(), integer(), state()) -> boolean(). send_history(JID, Shift, StateData) -> lists:foldl(fun ({Nick, Packet, HaveSubject, _TimeStamp, _Size}, @@ -2745,23 +2446,19 @@ send_history(JID, Shift, StateData) -> lists:nthtail(Shift, lqueue_to_list(StateData#state.history))). +-spec send_subject(jid(), state()) -> ok. send_subject(_JID, #state{subject_author = <<"">>}) -> ok; send_subject(JID, #state{subject_author = Nick} = StateData) -> Subject = StateData#state.subject, - Packet = #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"groupchat">>}], - children = - [#xmlel{name = <<"subject">>, attrs = [], - children = [{xmlcdata, Subject}]}]}, + Packet = #message{type = groupchat, subject = xmpp:mk_text(Subject)}, ejabberd_router:route(jid:replace_resource(StateData#state.jid, Nick), JID, Packet). -check_subject(Packet) -> - case fxml:get_subtag(Packet, <<"subject">>) of - false -> false; - SubjEl -> fxml:get_tag_cdata(SubjEl) - end. +-spec check_subject(message()) -> false | binary(). +check_subject(#message{subject = []}) -> false; +check_subject(#message{subject = Subj}) -> xmpp:get_text(Subj). +-spec can_change_subject(role(), state()) -> boolean(). can_change_subject(Role, StateData) -> case (StateData#state.config)#config.allow_change_subj of @@ -2772,99 +2469,89 @@ can_change_subject(Role, StateData) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Admin stuff -process_iq_admin(From, set, Lang, SubEl, StateData) -> - #xmlel{children = Items} = SubEl, +-spec process_iq_admin(jid(), iq(), #state{}) -> {error, error()} | + {result, undefined, #state{}} | + {result, muc_admin()}. +process_iq_admin(_From, #iq{lang = Lang, sub_els = [#muc_admin{items = []}]}, + _StateData) -> + Txt = <<"No 'item' element found">>, + {error, xmpp:err_bad_request(Txt, Lang)}; +process_iq_admin(From, #iq{type = set, lang = Lang, + sub_els = [#muc_admin{items = Items}]}, + StateData) -> process_admin_items_set(From, Items, Lang, StateData); -process_iq_admin(From, get, Lang, SubEl, StateData) -> - case fxml:get_subtag(SubEl, <<"item">>) of - false -> - Txt = <<"No 'item' element found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - Item -> - FAffiliation = get_affiliation(From, StateData), - FRole = get_role(From, StateData), - case fxml:get_tag_attr(<<"role">>, Item) of - false -> - case fxml:get_tag_attr(<<"affiliation">>, Item) of - false -> - Txt = <<"No 'affiliation' attribute found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - {value, StrAffiliation} -> - case catch list_to_affiliation(StrAffiliation) of - {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; - SAffiliation -> - if (FAffiliation == owner) or - (FAffiliation == admin) or - ((FAffiliation == member) and not - (StateData#state.config)#config.anonymous) -> - Items = items_with_affiliation(SAffiliation, - StateData), - {result, Items, StateData}; - true -> - ErrText = - <<"Administrator privileges required">>, - {error, ?ERRT_FORBIDDEN(Lang, ErrText)} - end - end - end; - {value, StrRole} -> - case catch list_to_role(StrRole) of - {'EXIT', _} -> - Txt = <<"Incorrect value of 'role' attribute">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - SRole -> - if FRole == moderator -> - Items = items_with_role(SRole, StateData), - {result, Items, StateData}; - true -> - ErrText = <<"Moderator privileges required">>, - {error, ?ERRT_FORBIDDEN(Lang, ErrText)} - end - end - end - end. +process_iq_admin(From, #iq{type = get, lang = Lang, + sub_els = [#muc_admin{items = [Item]}]}, + StateData) -> + FAffiliation = get_affiliation(From, StateData), + FRole = get_role(From, StateData), + case Item of + #muc_item{role = undefined, affiliation = undefined} -> + Txt = <<"Neither 'role' nor 'affiliation' attribute found">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + #muc_item{role = undefined, affiliation = Affiliation} -> + if (FAffiliation == owner) or + (FAffiliation == admin) or + ((FAffiliation == member) and + not (StateData#state.config)#config.anonymous) -> + Items = items_with_affiliation(Affiliation, StateData), + {result, #muc_admin{items = Items}}; + true -> + ErrText = <<"Administrator privileges required">>, + {error, xmpp:err_forbidden(ErrText, Lang)} + end; + #muc_item{role = Role} -> + if FRole == moderator -> + Items = items_with_role(Role, StateData), + {result, #muc_admin{items = Items}}; + true -> + ErrText = <<"Moderator privileges required">>, + {error, xmpp:err_forbidden(ErrText, Lang)} + end + end; +process_iq_admin(_From, #iq{type = get, lang = Lang}, _StateData) -> + ErrText = <<"Too many elements">>, + {error, xmpp:err_bad_request(ErrText, Lang)}. +-spec items_with_role(role(), state()) -> [muc_item()]. items_with_role(SRole, StateData) -> lists:map(fun ({_, U}) -> user_to_item(U, StateData) end, search_role(SRole, StateData)). +-spec items_with_affiliation(affiliation(), state()) -> [muc_item()]. items_with_affiliation(SAffiliation, StateData) -> - lists:map(fun ({JID, {Affiliation, Reason}}) -> - #xmlel{name = <<"item">>, - attrs = - [{<<"affiliation">>, - affiliation_to_list(Affiliation)}, - {<<"jid">>, jid:to_string(JID)}], - children = - [#xmlel{name = <<"reason">>, attrs = [], - children = [{xmlcdata, Reason}]}]}; - ({JID, Affiliation}) -> - #xmlel{name = <<"item">>, - attrs = - [{<<"affiliation">>, - affiliation_to_list(Affiliation)}, - {<<"jid">>, jid:to_string(JID)}], - children = []} - end, - search_affiliation(SAffiliation, StateData)). + lists:map( + fun({JID, {Affiliation, Reason}}) -> + #muc_item{affiliation = Affiliation, jid = JID, + reason = if is_binary(Reason), Reason /= <<"">> -> + Reason; + true -> + undefined + end}; + ({JID, Affiliation}) -> + #muc_item{affiliation = Affiliation, jid = JID} + end, + search_affiliation(SAffiliation, StateData)). +-spec user_to_item(#user{}, state()) -> muc_item(). user_to_item(#user{role = Role, nick = Nick, jid = JID}, StateData) -> Affiliation = get_affiliation(JID, StateData), - #xmlel{name = <<"item">>, - attrs = - [{<<"role">>, role_to_list(Role)}, - {<<"affiliation">>, affiliation_to_list(Affiliation)}, - {<<"nick">>, Nick}, - {<<"jid">>, jid:to_string(JID)}], - children = []}. + #muc_item{role = Role, + affiliation = Affiliation, + nick = Nick, + jid = JID}. +-spec search_role(role(), state()) -> [{ljid(), #user{}}]. search_role(Role, StateData) -> lists:filter(fun ({_, #user{role = R}}) -> Role == R end, (?DICT):to_list(StateData#state.users)). +-spec search_affiliation(affiliation(), state()) -> + [{ljid(), + affiliation() | {affiliation(), binary()}}]. search_affiliation(Affiliation, StateData) -> lists:filter(fun ({_, A}) -> case A of @@ -2874,11 +2561,14 @@ search_affiliation(Affiliation, StateData) -> end, (?DICT):to_list(StateData#state.affiliations)). +-spec process_admin_items_set(jid(), [muc_item()], binary() | undefined, + #state{}) -> {result, undefined, #state{}} | + {error, error()}. process_admin_items_set(UJID, Items, Lang, StateData) -> UAffiliation = get_affiliation(UJID, StateData), URole = get_role(UJID, StateData), - case find_changed_items(UJID, UAffiliation, URole, - Items, Lang, StateData, []) + case catch find_changed_items(UJID, UAffiliation, URole, + Items, Lang, StateData, []) of {result, Res} -> ?INFO_MSG("Processing MUC admin query from ~s in " @@ -2888,249 +2578,161 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> NSD = lists:foldl(process_item_change(UJID), StateData, lists:flatten(Res)), store_room(NSD), - {result, [], NSD}; - Err -> Err + {result, undefined, NSD}; + {error, Err} -> {error, Err} end. +-spec process_item_change(jid()) -> function(). process_item_change(UJID) -> fun(E, SD) -> process_item_change(E, SD, UJID) end. -process_item_change(E, SD, UJID) -> - case catch case E of - {JID, affiliation, owner, _} when JID#jid.luser == <<"">> -> - %% If the provided JID does not have username, - %% forget the affiliation completely - SD; - {JID, role, none, Reason} -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"307">>, - SD), - set_role(JID, none, SD); - {JID, affiliation, none, Reason} -> - case (SD#state.config)#config.members_only of - true -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"321">>, - none, - SD), - maybe_send_affiliation(JID, none, SD), - SD1 = set_affiliation(JID, none, SD), - set_role(JID, none, SD1); - _ -> - SD1 = set_affiliation(JID, none, SD), - send_update_presence(JID, SD1, SD), - maybe_send_affiliation(JID, none, SD1), - SD1 - end; - {JID, affiliation, outcast, Reason} -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"301">>, - outcast, - SD), - maybe_send_affiliation(JID, outcast, SD), - set_affiliation(JID, - outcast, - set_role(JID, none, SD), - Reason); - {JID, affiliation, A, Reason} - when (A == admin) or (A == owner) -> - SD1 = set_affiliation(JID, A, SD, Reason), - SD2 = set_role(JID, moderator, SD1), - send_update_presence(JID, Reason, SD2, SD), - maybe_send_affiliation(JID, A, SD2), - SD2; - {JID, affiliation, member, Reason} -> - SD1 = set_affiliation(JID, member, SD, Reason), - SD2 = set_role(JID, participant, SD1), - send_update_presence(JID, Reason, SD2, SD), - maybe_send_affiliation(JID, member, SD2), - SD2; - {JID, role, Role, Reason} -> - SD1 = set_role(JID, Role, SD), - catch - send_new_presence(JID, Reason, SD1, SD), - SD1; - {JID, affiliation, A, _Reason} -> - SD1 = set_affiliation(JID, A, SD), - send_update_presence(JID, SD1, SD), - maybe_send_affiliation(JID, A, SD1), - SD1 - end - of - {'EXIT', ErrReason} -> - ?ERROR_MSG("MUC ITEMS SET ERR: ~p~n", [ErrReason]), - SD; - NSD -> NSD +-type admin_action() :: {jid(), affiliation | role, + affiliation() | role(), binary()}. + +-spec process_item_change(admin_action(), state(), jid()) -> state(). +process_item_change(Item, SD, UJID) -> + try case Item of + {JID, affiliation, owner, _} when JID#jid.luser == <<"">> -> + %% If the provided JID does not have username, + %% forget the affiliation completely + SD; + {JID, role, none, Reason} -> + catch send_kickban_presence(UJID, JID, Reason, 307, SD), + set_role(JID, none, SD); + {JID, affiliation, none, Reason} -> + case (SD#state.config)#config.members_only of + true -> + catch send_kickban_presence(UJID, JID, Reason, 321, none, SD), + maybe_send_affiliation(JID, none, SD), + SD1 = set_affiliation(JID, none, SD), + set_role(JID, none, SD1); + _ -> + SD1 = set_affiliation(JID, none, SD), + send_update_presence(JID, SD1, SD), + maybe_send_affiliation(JID, none, SD1), + SD1 + end; + {JID, affiliation, outcast, Reason} -> + catch send_kickban_presence(UJID, JID, Reason, 301, outcast, SD), + maybe_send_affiliation(JID, outcast, SD), + set_affiliation(JID, outcast, set_role(JID, none, SD), Reason); + {JID, affiliation, A, Reason} when (A == admin) or (A == owner) -> + SD1 = set_affiliation(JID, A, SD, Reason), + SD2 = set_role(JID, moderator, SD1), + send_update_presence(JID, Reason, SD2, SD), + maybe_send_affiliation(JID, A, SD2), + SD2; + {JID, affiliation, member, Reason} -> + SD1 = set_affiliation(JID, member, SD, Reason), + SD2 = set_role(JID, participant, SD1), + send_update_presence(JID, Reason, SD2, SD), + maybe_send_affiliation(JID, member, SD2), + SD2; + {JID, role, Role, Reason} -> + SD1 = set_role(JID, Role, SD), + catch send_new_presence(JID, Reason, SD1, SD), + SD1; + {JID, affiliation, A, _Reason} -> + SD1 = set_affiliation(JID, A, SD), + send_update_presence(JID, SD1, SD), + maybe_send_affiliation(JID, A, SD1), + SD1 + end + catch E:R -> + ?ERROR_MSG("failed to set item ~p from ~s: ~p", + [Item, jid:to_string(UJID), + {E, {R, erlang:get_stacktrace()}}]), + SD end. +-spec find_changed_items(jid(), affiliation(), role(), + [muc_item()], binary(), state(), [admin_action()]) -> + {result, [admin_action()]}. find_changed_items(_UJID, _UAffiliation, _URole, [], _Lang, _StateData, Res) -> {result, Res}; +find_changed_items(_UJID, _UAffiliation, _URole, + [#muc_item{jid = undefined, nick = undefined}|_], + Lang, _StateData, _Res) -> + Txt = <<"Neither 'jid' nor 'nick' attribute found">>, + throw({error, xmpp:err_bad_request(Txt, Lang)}); +find_changed_items(_UJID, _UAffiliation, _URole, + [#muc_item{role = undefined, affiliation = undefined}|_], + Lang, _StateData, _Res) -> + Txt = <<"Neither 'role' nor 'affiliation' attribute found">>, + throw({error, xmpp:err_bad_request(Txt, Lang)}); find_changed_items(UJID, UAffiliation, URole, - [{xmlcdata, _} | Items], Lang, StateData, Res) -> - find_changed_items(UJID, UAffiliation, URole, Items, - Lang, StateData, Res); -find_changed_items(UJID, UAffiliation, URole, - [#xmlel{name = <<"item">>, attrs = Attrs} = Item - | Items], + [#muc_item{jid = J, nick = Nick, reason = Reason0, + role = Role, affiliation = Affiliation}|Items], Lang, StateData, Res) -> - TJID = case fxml:get_attr(<<"jid">>, Attrs) of - {value, S} -> - case jid:from_string(S) of - error -> - ErrText = iolist_to_binary( - io_lib:format(translate:translate( - Lang, - <<"Jabber ID ~s is invalid">>), - [S])), - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; - J -> {value, [J]} - end; - _ -> - case fxml:get_attr(<<"nick">>, Attrs) of - {value, N} -> - case find_jids_by_nick(N, StateData) of - false -> - ErrText = iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"Nickname ~s does not exist in the room">>), - [N])), - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; - J -> {value, J} - end; - _ -> - Txt1 = <<"No 'nick' attribute found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt1)} - end - end, - case TJID of - {value, [JID | _] = JIDs} -> - TAffiliation = get_affiliation(JID, StateData), - TRole = get_role(JID, StateData), - case fxml:get_attr(<<"role">>, Attrs) of - false -> - case fxml:get_attr(<<"affiliation">>, Attrs) of - false -> - Txt2 = <<"No 'affiliation' attribute found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt2)}; - {value, StrAffiliation} -> - case catch list_to_affiliation(StrAffiliation) of - {'EXIT', _} -> - ErrText1 = iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"Invalid affiliation: ~s">>), - [StrAffiliation])), - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText1)}; - SAffiliation -> - ServiceAf = get_service_affiliation(JID, StateData), - CanChangeRA = case can_change_ra(UAffiliation, - URole, - TAffiliation, - TRole, affiliation, - SAffiliation, - ServiceAf) - of - nothing -> nothing; - true -> true; - check_owner -> - case search_affiliation(owner, - StateData) - of - [{OJID, _}] -> - jid:remove_resource(OJID) - /= - jid:tolower(jid:remove_resource(UJID)); - _ -> true - end; - _ -> false - end, - case CanChangeRA of - nothing -> - find_changed_items(UJID, UAffiliation, URole, - Items, Lang, StateData, - Res); - true -> - Reason = fxml:get_path_s(Item, - [{elem, <<"reason">>}, - cdata]), - MoreRes = [{jid:remove_resource(Jidx), - affiliation, SAffiliation, Reason} - || Jidx <- JIDs], - find_changed_items(UJID, UAffiliation, URole, - Items, Lang, StateData, - [MoreRes | Res]); - false -> - Txt3 = <<"Changing role/affiliation is not allowed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt3)} - end - end - end; - {value, StrRole} -> - case catch list_to_role(StrRole) of - {'EXIT', _} -> - ErrText1 = iolist_to_binary( - io_lib:format(translate:translate( - Lang, - <<"Invalid role: ~s">>), - [StrRole])), - {error, ?ERRT_BAD_REQUEST(Lang, ErrText1)}; - SRole -> - ServiceAf = get_service_affiliation(JID, StateData), - CanChangeRA = case can_change_ra(UAffiliation, URole, - TAffiliation, TRole, - role, SRole, ServiceAf) - of - nothing -> nothing; - true -> true; - check_owner -> - case search_affiliation(owner, - StateData) - of - [{OJID, _}] -> - jid:remove_resource(OJID) - /= - jid:tolower(jid:remove_resource(UJID)); - _ -> true - end; - _ -> false - end, - case CanChangeRA of - nothing -> - find_changed_items(UJID, UAffiliation, URole, Items, - Lang, StateData, Res); - true -> - Reason = fxml:get_path_s(Item, - [{elem, <<"reason">>}, - cdata]), - MoreRes = [{Jidx, role, SRole, Reason} - || Jidx <- JIDs], - find_changed_items(UJID, UAffiliation, URole, Items, - Lang, StateData, - [MoreRes | Res]); - _ -> - Txt4 = <<"Changing role/affiliation is not allowed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt4)} - end + [JID | _] = JIDs = + if J /= undefined -> + [J]; + Nick /= undefined -> + case find_jids_by_nick(Nick, StateData) of + [] -> + ErrText = iolist_to_binary( + io_lib:format( + translate:translate( + Lang, + <<"Nickname ~s does not exist in the room">>), + [Nick])), + throw({error, xmpp:err_not_acceptable(ErrText, Lang)}); + JIDList -> + JIDList end - end; - Err -> Err - end; -find_changed_items(_UJID, _UAffiliation, _URole, _Items, - _Lang, _StateData, _Res) -> - {error, ?ERR_BAD_REQUEST}. + end, + {RoleOrAff, RoleOrAffValue} = if Role == undefined -> + {affiliation, Affiliation}; + true -> + {role, Role} + end, + TAffiliation = get_affiliation(JID, StateData), + TRole = get_role(JID, StateData), + ServiceAf = get_service_affiliation(JID, StateData), + CanChangeRA = case can_change_ra(UAffiliation, + URole, + TAffiliation, + TRole, RoleOrAff, RoleOrAffValue, + ServiceAf) of + nothing -> nothing; + true -> true; + check_owner -> + case search_affiliation(owner, StateData) of + [{OJID, _}] -> + jid:remove_resource(OJID) + /= + jid:tolower(jid:remove_resource(UJID)); + _ -> true + end; + _ -> false + end, + case CanChangeRA of + nothing -> + find_changed_items(UJID, UAffiliation, URole, + Items, Lang, StateData, + Res); + true -> + Reason = if is_binary(Reason0) -> Reason0; + true -> <<"">> + end, + MoreRes = [{jid:remove_resource(Jidx), + RoleOrAff, RoleOrAffValue, Reason} + || Jidx <- JIDs], + find_changed_items(UJID, UAffiliation, URole, + Items, Lang, StateData, + [MoreRes | Res]); + false -> + Txt = <<"Changing role/affiliation is not allowed">>, + throw({error, xmpp:err_not_allowed(Txt, Lang)}) + end. +-spec can_change_ra(affiliation(), role(), affiliation(), role(), + affiliation, affiliation(), affiliation()) -> boolean(); + (affiliation(), role(), affiliation(), role(), + role, role(), affiliation()) -> boolean(). can_change_ra(_FAffiliation, _FRole, owner, _TRole, affiliation, owner, owner) -> %% A room owner tries to add as persistent owner a @@ -3255,11 +2857,15 @@ can_change_ra(_FAffiliation, _FRole, _TAffiliation, _TRole, role, _Value, _ServiceAf) -> false. +-spec send_kickban_presence(jid(), jid(), binary(), + pos_integer(), state()) -> ok. send_kickban_presence(UJID, JID, Reason, Code, StateData) -> NewAffiliation = get_affiliation(JID, StateData), send_kickban_presence(UJID, JID, Reason, Code, NewAffiliation, StateData). +-spec send_kickban_presence(jid(), jid(), binary(), pos_integer(), + affiliation(), state()) -> ok. send_kickban_presence(UJID, JID, Reason, Code, NewAffiliation, StateData) -> LJID = jid:tolower(JID), @@ -3288,77 +2894,51 @@ send_kickban_presence(UJID, JID, Reason, Code, NewAffiliation, end, LJIDs). +-spec send_kickban_presence1(jid(), jid(), binary(), pos_integer(), + affiliation(), state()) -> ok. send_kickban_presence1(MJID, UJID, Reason, Code, Affiliation, StateData) -> {ok, #user{jid = RealJID, nick = Nick}} = (?DICT):find(jid:tolower(UJID), StateData#state.users), - SAffiliation = affiliation_to_list(Affiliation), - BannedJIDString = jid:to_string(RealJID), ActorNick = get_actor_nick(MJID, StateData), - lists:foreach(fun ({_LJID, Info}) -> - JidAttrList = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false - of - true -> - [{<<"jid">>, BannedJIDString}]; - false -> [] - end, - ItemAttrs = [{<<"affiliation">>, SAffiliation}, - {<<"role">>, <<"none">>}] - ++ JidAttrList, - ItemEls = case Reason of - <<"">> -> []; - _ -> - [#xmlel{name = <<"reason">>, - attrs = [], - children = - [{xmlcdata, Reason}]}] - end, - ItemElsActor = case MJID of - <<"">> -> []; - _ -> [#xmlel{name = <<"actor">>, - attrs = - [{<<"nick">>, ActorNick}]}] - end, - Packet = #xmlel{name = <<"presence">>, - attrs = - [{<<"type">>, <<"unavailable">>}], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name = - <<"item">>, - attrs = - ItemAttrs, - children = - ItemElsActor ++ ItemEls}, - #xmlel{name = - <<"status">>, - attrs = - [{<<"code">>, - Code}], - children = - []}]}]}, - RoomJIDNick = jid:replace_resource( - StateData#state.jid, Nick), - send_wrapped(RoomJIDNick, Info#user.jid, Packet, - ?NS_MUCSUB_NODES_AFFILIATIONS, StateData), - IsSubscriber = Info#user.is_subscriber, - IsOccupant = Info#user.last_presence /= undefined, - if (IsSubscriber and not IsOccupant) -> - send_wrapped(RoomJIDNick, Info#user.jid, Packet, - ?NS_MUCSUB_NODES_PARTICIPANTS, StateData); - true -> - ok - end - end, - (?DICT):to_list(StateData#state.users)). + lists:foreach( + fun({_LJID, Info}) -> + Item0 = #muc_item{affiliation = Affiliation, + role = none}, + Item1 = case Info#user.role == moderator orelse + (StateData#state.config)#config.anonymous + == false of + true -> Item0#muc_item{jid = RealJID}; + false -> Item0 + end, + Item2 = if is_binary(Reason), Reason /= <<"">> -> + Item1#muc_item{reason = Reason}; + true -> + Item1 + end, + Item = case ActorNick of + <<"">> -> Item2; + _ -> Item2#muc_item{actor = #muc_actor{nick = ActorNick}} + end, + Packet = #presence{type = unavailable, + sub_els = [#muc_user{items = [Item], + status_codes = [Code]}]}, + RoomJIDNick = jid:replace_resource(StateData#state.jid, Nick), + send_wrapped(RoomJIDNick, Info#user.jid, Packet, + ?NS_MUCSUB_NODES_AFFILIATIONS, StateData), + IsSubscriber = Info#user.is_subscriber, + IsOccupant = Info#user.last_presence /= undefined, + if (IsSubscriber and not IsOccupant) -> + send_wrapped(RoomJIDNick, Info#user.jid, Packet, + ?NS_MUCSUB_NODES_PARTICIPANTS, StateData); + true -> + ok + end + end, + (?DICT):to_list(StateData#state.users)). +-spec get_actor_nick(binary() | jid(), state()) -> binary(). get_actor_nick(<<"">>, _StateData) -> <<"">>; get_actor_nick(MJID, StateData) -> @@ -3369,97 +2949,86 @@ get_actor_nick(MJID, StateData) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Owner stuff - -process_iq_owner(From, set, Lang, SubEl, StateData) -> +-spec process_iq_owner(jid(), iq(), state()) -> + {result, undefined | muc_owner()} | + {result, undefined | muc_owner(), state() | stop} | + {error, error()}. +process_iq_owner(From, #iq{type = set, lang = Lang, + sub_els = [#muc_owner{destroy = Destroy, + config = Config, + items = Items}]}, + StateData) -> FAffiliation = get_affiliation(From, StateData), - case FAffiliation of - owner -> - #xmlel{children = Els} = SubEl, - case fxml:remove_cdata(Els) of - [#xmlel{name = <<"x">>} = XEl] -> - case {fxml:get_tag_attr_s(<<"xmlns">>, XEl), - fxml:get_tag_attr_s(<<"type">>, XEl)} - of - {?NS_XDATA, <<"cancel">>} -> {result, [], StateData}; - {?NS_XDATA, <<"submit">>} -> - case is_allowed_log_change(XEl, StateData, From) andalso - is_allowed_persistent_change(XEl, StateData, From) - andalso - is_allowed_room_name_desc_limits(XEl, StateData) - andalso - is_password_settings_correct(XEl, StateData) - of - true -> set_config(XEl, StateData, Lang); - false -> {error, ?ERR_NOT_ACCEPTABLE} - end; - _ -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} - end; - [#xmlel{name = <<"destroy">>} = SubEl1] -> - ?INFO_MSG("Destroyed MUC room ~s by the owner ~s", - [jid:to_string(StateData#state.jid), - jid:to_string(From)]), - add_to_log(room_existence, destroyed, StateData), - destroy_room(SubEl1, StateData); - Items -> - process_admin_items_set(From, Items, Lang, StateData) - end; - _ -> - ErrText = <<"Owner privileges required">>, - {error, ?ERRT_FORBIDDEN(Lang, ErrText)} + if FAffiliation /= owner -> + ErrText = <<"Owner privileges required">>, + {error, xmpp:err_forbidden(ErrText, Lang)}; + Destroy /= undefined, Config == undefined, Items == [] -> + ?INFO_MSG("Destroyed MUC room ~s by the owner ~s", + [jid:to_string(StateData#state.jid), jid:to_string(From)]), + add_to_log(room_existence, destroyed, StateData), + destroy_room(Destroy, StateData); + Config /= undefined, Destroy == undefined, Items == [] -> + case Config of + #xdata{type = cancel} -> + {result, undefined}; + #xdata{type = submit} -> + case is_allowed_log_change(Config, StateData, From) andalso + is_allowed_persistent_change(Config, StateData, From) andalso + is_allowed_room_name_desc_limits(Config, StateData) andalso + is_password_settings_correct(Config, StateData) of + true -> set_config(Config, StateData, Lang); + false -> {error, xmpp:err_not_acceptable()} + end; + _ -> + Txt = <<"Incorrect data form">>, + {error, xmpp:err_bad_request(Txt, Lang)} + end; + Items /= [], Config == undefined, Destroy == undefined -> + process_admin_items_set(From, Items, Lang, StateData); + true -> + {error, xmpp:err_bad_request()} end; -process_iq_owner(From, get, Lang, SubEl, StateData) -> +process_iq_owner(From, #iq{type = get, lang = Lang, + sub_els = [#muc_owner{destroy = Destroy, + config = Config, + items = Items}]}, + StateData) -> FAffiliation = get_affiliation(From, StateData), - case FAffiliation of - owner -> - #xmlel{children = Els} = SubEl, - case fxml:remove_cdata(Els) of - [] -> get_config(Lang, StateData, From); - [Item] -> - case fxml:get_tag_attr(<<"affiliation">>, Item) of - false -> - Txt = <<"No 'affiliation' attribute found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - {value, StrAffiliation} -> - case catch list_to_affiliation(StrAffiliation) of - {'EXIT', _} -> - ErrText = iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"Invalid affiliation: ~s">>), - [StrAffiliation])), - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; - SAffiliation -> - Items = items_with_affiliation(SAffiliation, - StateData), - {result, Items, StateData} - end - end; - _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} - end; - _ -> - ErrText = <<"Owner privileges required">>, - {error, ?ERRT_FORBIDDEN(Lang, ErrText)} + if FAffiliation /= owner -> + ErrText = <<"Owner privileges required">>, + {error, xmpp:err_forbidden(ErrText, Lang)}; + Destroy == undefined, Config == undefined -> + case Items of + [] -> + {result, + #muc_owner{config = get_config(Lang, StateData, From)}}; + [#muc_item{affiliation = undefined}] -> + Txt = <<"No 'affiliation' attribute found">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + [#muc_item{affiliation = Affiliation}] -> + Items = items_with_affiliation(Affiliation, StateData), + {result, #muc_owner{items = Items}}; + [_|_] -> + Txt = <<"Too many elements">>, + {error, xmpp:err_bad_request(Txt, Lang)} + end; + true -> + {error, xmpp:err_bad_request()} end. -is_allowed_log_change(XEl, StateData, From) -> - case lists:keymember(<<"muc#roomconfig_enablelogging">>, - 1, jlib:parse_xdata_submit(XEl)) - of - false -> true; - true -> - allow == - mod_muc_log:check_access_log(StateData#state.server_host, - From) +-spec is_allowed_log_change(xdata(), state(), jid()) -> boolean(). +is_allowed_log_change(X, StateData, From) -> + case xmpp_util:has_xdata_var(<<"muc#roomconfig_enablelogging">>, X) of + false -> true; + true -> + allow == + mod_muc_log:check_access_log(StateData#state.server_host, + From) end. -is_allowed_persistent_change(XEl, StateData, From) -> - case - lists:keymember(<<"muc#roomconfig_persistentroom">>, 1, - jlib:parse_xdata_submit(XEl)) - of +-spec is_allowed_persistent_change(xdata(), state(), jid()) -> boolean(). +is_allowed_persistent_change(X, StateData, From) -> + case xmpp_util:has_xdata_var(<<"muc#roomconfig_persistentroom">>, X) of false -> true; true -> {_AccessRoute, _AccessCreate, _AccessAdmin, @@ -3472,58 +3041,57 @@ is_allowed_persistent_change(XEl, StateData, From) -> %% Check if the Room Name and Room Description defined in the Data Form %% are conformant to the configured limits -is_allowed_room_name_desc_limits(XEl, StateData) -> - IsNameAccepted = case - lists:keysearch(<<"muc#roomconfig_roomname">>, 1, - jlib:parse_xdata_submit(XEl)) - of - {value, {_, [N]}} -> - byte_size(N) =< - gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_room_name, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> I - end, infinity); - _ -> true +-spec is_allowed_room_name_desc_limits(xdata(), state()) -> boolean(). +is_allowed_room_name_desc_limits(XData, StateData) -> + IsNameAccepted = case xmpp_util:get_xdata_values( + <<"muc#roomconfig_roomname">>, XData) of + [N] -> + byte_size(N) =< + gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, max_room_name, + fun(infinity) -> infinity; + (I) when is_integer(I), + I>0 -> I + end, infinity); + _ -> + true end, - IsDescAccepted = case - lists:keysearch(<<"muc#roomconfig_roomdesc">>, 1, - jlib:parse_xdata_submit(XEl)) - of - {value, {_, [D]}} -> - byte_size(D) =< - gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_room_desc, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> - I - end, infinity); - _ -> true + IsDescAccepted = case xmpp_util:get_xdata_values( + <<"muc#roomconfig_roomdesc">>, XData) of + [D] -> + byte_size(D) =< + gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, max_room_desc, + fun(infinity) -> infinity; + (I) when is_integer(I), + I>0 -> + I + end, infinity); + _ -> true end, IsNameAccepted and IsDescAccepted. %% Return false if: %% "the password for a password-protected room is blank" -is_password_settings_correct(XEl, StateData) -> +-spec is_password_settings_correct(xdata(), state()) -> boolean(). +is_password_settings_correct(XData, StateData) -> Config = StateData#state.config, OldProtected = Config#config.password_protected, OldPassword = Config#config.password, - NewProtected = case - lists:keysearch(<<"muc#roomconfig_passwordprotectedroom">>, - 1, jlib:parse_xdata_submit(XEl)) - of - {value, {_, [<<"1">>]}} -> true; - {value, {_, [<<"0">>]}} -> false; - _ -> undefined + NewProtected = case xmpp_util:get_xdata_values( + <<"muc#roomconfig_passwordprotectedroom">>, XData) of + [<<"1">>] -> true; + [<<"true">>] -> true; + [<<"0">>] -> false; + [<<"false">>] -> false; + _ -> undefined end, - NewPassword = case - lists:keysearch(<<"muc#roomconfig_roomsecret">>, 1, - jlib:parse_xdata_submit(XEl)) - of - {value, {_, [P]}} -> P; - _ -> undefined + NewPassword = case xmpp_util:get_xdata_values( + <<"muc#roomconfig_roomsecret">>, XData) of + [P] -> P; + _ -> undefined end, case {OldProtected, NewProtected, OldPassword, NewPassword} @@ -3535,40 +3103,35 @@ is_password_settings_correct(XEl, StateData) -> _ -> true end. --define(XFIELD(Type, Label, Var, Val), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). +-define(XFIELD(Type, Label, Var, Vals), + #xdata_field{type = Type, + label = translate:translate(Lang, Label), + var = Var, + values = Vals}). -define(BOOLXFIELD(Label, Var, Val), - ?XFIELD(<<"boolean">>, Label, Var, + ?XFIELD(boolean, Label, Var, case Val of - true -> <<"1">>; - _ -> <<"0">> + true -> [<<"1">>]; + _ -> [<<"0">>] end)). -define(STRINGXFIELD(Label, Var, Val), - ?XFIELD(<<"text-single">>, Label, Var, Val)). + ?XFIELD('text-single', Label, Var, [Val])). -define(PRIVATEXFIELD(Label, Var, Val), - ?XFIELD(<<"text-private">>, Label, Var, Val)). + ?XFIELD('text-private', Label, Var, [Val])). -define(JIDMULTIXFIELD(Label, Var, JIDList), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"jid-multi">>}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, jid:to_string(JID)}]} - || JID <- JIDList]}). + ?XFIELD('jid-multi', Label, Var, + [jid:to_string(JID) || JID <- JIDList])). +-spec make_options([{binary(), binary()}], binary()) -> [xdata_option()]. +make_options(Options, Lang) -> + [#xdata_option{label = translate:translate(Lang, Label), + value = Value} || {Label, Value} <- Options]. + +-spec get_default_room_maxusers(state()) -> non_neg_integer(). get_default_room_maxusers(RoomState) -> DefRoomOpts = gen_mod:get_module_opt(RoomState#state.server_host, @@ -3578,342 +3141,193 @@ get_default_room_maxusers(RoomState) -> RoomState2 = set_opts(DefRoomOpts, RoomState), (RoomState2#state.config)#config.max_users. +-spec get_config(binary(), state(), jid()) -> xdata(). get_config(Lang, StateData, From) -> - {_AccessRoute, _AccessCreate, _AccessAdmin, - AccessPersistent} = + {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent} = StateData#state.access, ServiceMaxUsers = get_service_max_users(StateData), - DefaultRoomMaxUsers = - get_default_room_maxusers(StateData), + DefaultRoomMaxUsers = get_default_room_maxusers(StateData), Config = StateData#state.config, - {MaxUsersRoomInteger, MaxUsersRoomString} = case - get_max_users(StateData) - of - N when is_integer(N) -> - {N, - jlib:integer_to_binary(N)}; - _ -> {0, <<"none">>} - end, - Res = [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"Configuration of room ~s">>), - [jid:to_string(StateData#state.jid)]))}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"hidden">>}, - {<<"var">>, <<"FORM_TYPE">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"http://jabber.org/protocol/muc#roomconfig">>}]}]}, - ?STRINGXFIELD(<<"Room title">>, - <<"muc#roomconfig_roomname">>, (Config#config.title)), - ?STRINGXFIELD(<<"Room description">>, - <<"muc#roomconfig_roomdesc">>, - (Config#config.description))] - ++ - case acl:match_rule(StateData#state.server_host, - AccessPersistent, From) - of - allow -> - [?BOOLXFIELD(<<"Make room persistent">>, - <<"muc#roomconfig_persistentroom">>, - (Config#config.persistent))]; - _ -> [] - end - ++ - [?BOOLXFIELD(<<"Make room public searchable">>, - <<"muc#roomconfig_publicroom">>, - (Config#config.public)), - ?BOOLXFIELD(<<"Make participants list public">>, - <<"public_list">>, (Config#config.public_list)), - ?BOOLXFIELD(<<"Make room password protected">>, - <<"muc#roomconfig_passwordprotectedroom">>, - (Config#config.password_protected)), - ?PRIVATEXFIELD(<<"Password">>, - <<"muc#roomconfig_roomsecret">>, - case Config#config.password_protected of - true -> Config#config.password; - false -> <<"">> - end), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"list-single">>}, - {<<"label">>, - translate:translate(Lang, - <<"Maximum Number of Occupants">>)}, - {<<"var">>, <<"muc#roomconfig_maxusers">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, MaxUsersRoomString}]}] - ++ - if is_integer(ServiceMaxUsers) -> []; - true -> - [#xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"No limit">>)}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, - <<"none">>}]}]}] - end - ++ - [#xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - jlib:integer_to_binary(N)}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, - jlib:integer_to_binary(N)}]}]} - || N - <- lists:usort([ServiceMaxUsers, - DefaultRoomMaxUsers, - MaxUsersRoomInteger - | ?MAX_USERS_DEFAULT_LIST]), - N =< ServiceMaxUsers]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"list-single">>}, - {<<"label">>, - translate:translate(Lang, - <<"Present real Jabber IDs to">>)}, - {<<"var">>, <<"muc#roomconfig_whois">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - if Config#config.anonymous -> - <<"moderators">>; - true -> <<"anyone">> - end}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"moderators only">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"moderators">>}]}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"anyone">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"anyone">>}]}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"list-multi">>}, - {<<"label">>, - translate:translate(Lang, - <<"Roles for which Presence is Broadcasted">>)}, - {<<"var">>, <<"muc#roomconfig_presencebroadcast">>}], - children = - lists:map( - fun(Role) -> - #xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - atom_to_binary(Role, utf8)}]} - end, Config#config.presence_broadcast - ) ++ - [#xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"Moderator">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"moderator">>}]}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"Participant">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"participant">>}]}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"Visitor">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"visitor">>}]}]} - ]}, - ?BOOLXFIELD(<<"Make room members-only">>, - <<"muc#roomconfig_membersonly">>, - (Config#config.members_only)), - ?BOOLXFIELD(<<"Make room moderated">>, - <<"muc#roomconfig_moderatedroom">>, - (Config#config.moderated)), - ?BOOLXFIELD(<<"Default users as participants">>, - <<"members_by_default">>, - (Config#config.members_by_default)), - ?BOOLXFIELD(<<"Allow users to change the subject">>, - <<"muc#roomconfig_changesubject">>, - (Config#config.allow_change_subj)), - ?BOOLXFIELD(<<"Allow users to send private messages">>, - <<"allow_private_messages">>, - (Config#config.allow_private_messages)), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"list-single">>}, - {<<"label">>, - translate:translate(Lang, - <<"Allow visitors to send private messages to">>)}, - {<<"var">>, - <<"allow_private_messages_from_visitors">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - case - Config#config.allow_private_messages_from_visitors - of - anyone -> <<"anyone">>; - moderators -> <<"moderators">>; - nobody -> <<"nobody">> - end}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"nobody">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, <<"nobody">>}]}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"moderators only">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"moderators">>}]}]}, - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, - translate:translate(Lang, - <<"anyone">>)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"anyone">>}]}]}]}, - ?BOOLXFIELD(<<"Allow users to query other users">>, - <<"allow_query_users">>, - (Config#config.allow_query_users)), - ?BOOLXFIELD(<<"Allow users to send invites">>, - <<"muc#roomconfig_allowinvites">>, - (Config#config.allow_user_invites)), - ?BOOLXFIELD(<<"Allow visitors to send status text in " - "presence updates">>, - <<"muc#roomconfig_allowvisitorstatus">>, - (Config#config.allow_visitor_status)), - ?BOOLXFIELD(<<"Allow visitors to change nickname">>, - <<"muc#roomconfig_allowvisitornickchange">>, - (Config#config.allow_visitor_nickchange)), - ?BOOLXFIELD(<<"Allow visitors to send voice requests">>, - <<"muc#roomconfig_allowvoicerequests">>, - (Config#config.allow_voice_requests)), - ?BOOLXFIELD(<<"Allow subscription">>, - <<"muc#roomconfig_allow_subscription">>, - (Config#config.allow_subscription)), - ?STRINGXFIELD(<<"Minimum interval between voice requests " - "(in seconds)">>, - <<"muc#roomconfig_voicerequestmininterval">>, - (jlib:integer_to_binary(Config#config.voice_request_min_interval)))] - ++ - case ejabberd_captcha:is_feature_available() of - true -> - [?BOOLXFIELD(<<"Make room CAPTCHA protected">>, - <<"captcha_protected">>, - (Config#config.captcha_protected))]; - false -> [] - end ++ - [?JIDMULTIXFIELD(<<"Exclude Jabber IDs from CAPTCHA challenge">>, - <<"muc#roomconfig_captcha_whitelist">>, - ((?SETS):to_list(Config#config.captcha_whitelist)))] - ++ - case - mod_muc_log:check_access_log(StateData#state.server_host, - From) - of - allow -> - [?BOOLXFIELD(<<"Enable logging">>, - <<"muc#roomconfig_enablelogging">>, - (Config#config.logging))]; - _ -> [] - end, - X = ejabberd_hooks:run_fold(get_room_config, - StateData#state.server_host, - Res, - [StateData, From, Lang]), - {result, - [#xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"You need an x:data capable client to " - "configure room">>)}]}, - #xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = X}], - StateData}. - -set_config(XEl, StateData, Lang) -> - XData = jlib:parse_xdata_submit(XEl), - case XData of - invalid -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)}; - _ -> - case set_xoption(XData, StateData#state.config, - StateData#state.server_host, Lang) of - #config{} = Config -> - Res = change_config(Config, StateData), - {result, _, NSD} = Res, - Type = case {(StateData#state.config)#config.logging, - Config#config.logging} - of - {true, false} -> roomconfig_change_disabledlogging; - {false, true} -> roomconfig_change_enabledlogging; - {_, _} -> roomconfig_change - end, - Users = [{U#user.jid, U#user.nick, U#user.role} - || {_, U} <- (?DICT):to_list(StateData#state.users)], - add_to_log(Type, Users, NSD), - Res; - Err -> Err - end + {MaxUsersRoomInteger, MaxUsersRoomString} = + case get_max_users(StateData) of + N when is_integer(N) -> + {N, integer_to_binary(N)}; + _ -> {0, <<"none">>} + end, + Title = iolist_to_binary( + io_lib:format( + translate:translate(Lang, <<"Configuration of room ~s">>), + [jid:to_string(StateData#state.jid)])), + Fs = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [<<"http://jabber.org/protocol/muc#roomconfig">>]}, + ?STRINGXFIELD(<<"Room title">>, + <<"muc#roomconfig_roomname">>, (Config#config.title)), + ?STRINGXFIELD(<<"Room description">>, + <<"muc#roomconfig_roomdesc">>, + (Config#config.description))] ++ + case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of + allow -> + [?BOOLXFIELD(<<"Make room persistent">>, + <<"muc#roomconfig_persistentroom">>, + (Config#config.persistent))]; + deny -> [] + end ++ + [?BOOLXFIELD(<<"Make room public searchable">>, + <<"muc#roomconfig_publicroom">>, + (Config#config.public)), + ?BOOLXFIELD(<<"Make participants list public">>, + <<"public_list">>, (Config#config.public_list)), + ?BOOLXFIELD(<<"Make room password protected">>, + <<"muc#roomconfig_passwordprotectedroom">>, + (Config#config.password_protected)), + ?PRIVATEXFIELD(<<"Password">>, + <<"muc#roomconfig_roomsecret">>, + case Config#config.password_protected of + true -> Config#config.password; + false -> <<"">> + end), + #xdata_field{type = 'list-single', + label = translate:translate( + Lang, <<"Maximum Number of Occupants">>), + var = <<"muc#roomconfig_maxusers">>, + values = [MaxUsersRoomString], + options = + if is_integer(ServiceMaxUsers) -> []; + true -> make_options( + [{<<"No limit">>, <<"none">>}], + Lang) + end ++ + make_options( + [{integer_to_binary(N), integer_to_binary(N)} + || N <- lists:usort([ServiceMaxUsers, + DefaultRoomMaxUsers, + MaxUsersRoomInteger + | ?MAX_USERS_DEFAULT_LIST]), + N =< ServiceMaxUsers], + Lang)}, + #xdata_field{type = 'list-single', + label = translate:translate( + Lang, <<"Present real Jabber IDs to">>), + var = <<"muc#roomconfig_whois">>, + values = [if Config#config.anonymous -> <<"moderators">>; + true -> <<"anyone">> + end], + options = make_options( + [{<<"moderators only">>, <<"moderators">>}, + {<<"anyone">>, <<"anyone">>}], + Lang)}, + #xdata_field{type = 'list-multi', + label = translate:translate( + Lang, + <<"Roles for which Presence is Broadcasted">>), + var = <<"muc#roomconfig_presencebroadcast">>, + values = [atom_to_binary(Role, utf8) + || Role <- Config#config.presence_broadcast], + options = make_options( + [{<<"Moderator">>, <<"moderator">>}, + {<<"Participant">>, <<"participant">>}, + {<<"Visitor">>, <<"visitor">>}], + Lang)}, + ?BOOLXFIELD(<<"Make room members-only">>, + <<"muc#roomconfig_membersonly">>, + (Config#config.members_only)), + ?BOOLXFIELD(<<"Make room moderated">>, + <<"muc#roomconfig_moderatedroom">>, + (Config#config.moderated)), + ?BOOLXFIELD(<<"Default users as participants">>, + <<"members_by_default">>, + (Config#config.members_by_default)), + ?BOOLXFIELD(<<"Allow users to change the subject">>, + <<"muc#roomconfig_changesubject">>, + (Config#config.allow_change_subj)), + ?BOOLXFIELD(<<"Allow users to send private messages">>, + <<"allow_private_messages">>, + (Config#config.allow_private_messages)), + #xdata_field{type = 'list-single', + label = translate:translate( + Lang, + <<"Allow visitors to send private messages to">>), + var = <<"allow_private_messages_from_visitors">>, + values = [case Config#config.allow_private_messages_from_visitors of + anyone -> <<"anyone">>; + moderators -> <<"moderators">>; + nobody -> <<"nobody">> + end], + options = make_options( + [{<<"nobody">>, <<"nobody">>}, + {<<"moderators only">>, <<"moderators">>}, + {<<"anyone">>, <<"anyone">>}], + Lang)}, + ?BOOLXFIELD(<<"Allow users to query other users">>, + <<"allow_query_users">>, + (Config#config.allow_query_users)), + ?BOOLXFIELD(<<"Allow users to send invites">>, + <<"muc#roomconfig_allowinvites">>, + (Config#config.allow_user_invites)), + ?BOOLXFIELD(<<"Allow visitors to send status text in " + "presence updates">>, + <<"muc#roomconfig_allowvisitorstatus">>, + (Config#config.allow_visitor_status)), + ?BOOLXFIELD(<<"Allow visitors to change nickname">>, + <<"muc#roomconfig_allowvisitornickchange">>, + (Config#config.allow_visitor_nickchange)), + ?BOOLXFIELD(<<"Allow visitors to send voice requests">>, + <<"muc#roomconfig_allowvoicerequests">>, + (Config#config.allow_voice_requests)), + ?BOOLXFIELD(<<"Allow subscription">>, + <<"muc#roomconfig_allow_subscription">>, + (Config#config.allow_subscription)), + ?STRINGXFIELD(<<"Minimum interval between voice requests " + "(in seconds)">>, + <<"muc#roomconfig_voicerequestmininterval">>, + integer_to_binary(Config#config.voice_request_min_interval))] + ++ + case ejabberd_captcha:is_feature_available() of + true -> + [?BOOLXFIELD(<<"Make room CAPTCHA protected">>, + <<"captcha_protected">>, + (Config#config.captcha_protected))]; + false -> [] + end ++ + [?JIDMULTIXFIELD(<<"Exclude Jabber IDs from CAPTCHA challenge">>, + <<"muc#roomconfig_captcha_whitelist">>, + ((?SETS):to_list(Config#config.captcha_whitelist)))] + ++ + case mod_muc_log:check_access_log(StateData#state.server_host, From) of + allow -> + [?BOOLXFIELD(<<"Enable logging">>, + <<"muc#roomconfig_enablelogging">>, + (Config#config.logging))]; + deny -> [] + end, + Fields = ejabberd_hooks:run_fold(get_room_config, + StateData#state.server_host, + Fs, + [StateData, From, Lang]), + #xdata{type = form, title = Title, fields = Fields}. + +-spec set_config(xdata(), state(), binary()) -> {error, error()} | + {result, undefined, state()}. +set_config(#xdata{fields = Fields}, StateData, Lang) -> + Options = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- Fields], + case set_xoption(Options, StateData#state.config, + StateData#state.server_host, Lang) of + #config{} = Config -> + Res = change_config(Config, StateData), + {result, _, NSD} = Res, + Type = case {(StateData#state.config)#config.logging, + Config#config.logging} + of + {true, false} -> roomconfig_change_disabledlogging; + {false, true} -> roomconfig_change_enabledlogging; + {_, _} -> roomconfig_change + end, + Users = [{U#user.jid, U#user.nick, U#user.role} + || {_, U} <- (?DICT):to_list(StateData#state.users)], + add_to_log(Type, Users, NSD), + Res; + Err -> Err end. -define(SET_BOOL_XOPT(Opt, Val), @@ -3928,21 +3342,32 @@ set_config(XEl, StateData, Lang) -> _ -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_BAD_REQUEST(Lang, ErrTxt)} + {error, xmpp:err_bad_request(ErrTxt, Lang)} end). -define(SET_NAT_XOPT(Opt, Val), - case catch jlib:binary_to_integer(Val) of + case catch binary_to_integer(Val) of I when is_integer(I), I > 0 -> set_xoption(Opts, Config#config{Opt = I}, ServerHost, Lang); _ -> Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_BAD_REQUEST(Lang, ErrTxt)} + {error, xmpp:err_bad_request(ErrTxt, Lang)} end). --define(SET_STRING_XOPT(Opt, Val), - set_xoption(Opts, Config#config{Opt = Val}, ServerHost, Lang)). +-define(SET_STRING_XOPT(Opt, Vals), + try + V = case Vals of + [] -> <<"">>; + [Val] -> Val; + _ when is_atom(Vals) -> Vals + end, + set_xoption(Opts, Config#config{Opt = V}, ServerHost, Lang) + catch _:_ -> + Txt = <<"Incorrect value of option '~s'">>, + ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + {error, xmpp:err_bad_request(ErrTxt, Lang)} + end). -define(SET_JIDMULTI_XOPT(Opt, Vals), begin @@ -3957,15 +3382,17 @@ set_config(XEl, StateData, Lang) -> set_xoption(Opts, Config#config{Opt = Set}, ServerHost, Lang) end). +-spec set_xoption([{binary(), [binary()]}], #config{}, + binary(), binary()) -> #config{} | {error, error()}. set_xoption([], Config, _ServerHost, _Lang) -> Config; -set_xoption([{<<"muc#roomconfig_roomname">>, [Val]} +set_xoption([{<<"muc#roomconfig_roomname">>, Vals} | Opts], Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(title, Val); -set_xoption([{<<"muc#roomconfig_roomdesc">>, [Val]} + ?SET_STRING_XOPT(title, Vals); +set_xoption([{<<"muc#roomconfig_roomdesc">>, Vals} | Opts], Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(description, Val); + ?SET_STRING_XOPT(description, Vals); set_xoption([{<<"muc#roomconfig_changesubject">>, [Val]} | Opts], Config, ServerHost, Lang) -> @@ -3994,7 +3421,7 @@ set_xoption([{<<"allow_private_messages_from_visitors">>, _ -> Txt = <<"Value of 'allow_private_messages_from_visitors' " "should be anyone|moderators|nobody">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + {error, xmpp:err_bad_request(Txt, Lang)} end; set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>, [Val]} @@ -4045,10 +3472,10 @@ set_xoption([{<<"muc#roomconfig_passwordprotectedroom">>, | Opts], Config, ServerHost, Lang) -> ?SET_BOOL_XOPT(password_protected, Val); -set_xoption([{<<"muc#roomconfig_roomsecret">>, [Val]} +set_xoption([{<<"muc#roomconfig_roomsecret">>, Vals} | Opts], Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(password, Val); + ?SET_STRING_XOPT(password, Vals); set_xoption([{<<"anonymous">>, [Val]} | Opts], Config, ServerHost, Lang) -> ?SET_BOOL_XOPT(anonymous, Val); @@ -4069,7 +3496,7 @@ set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts], error -> Txt = <<"Value of 'muc#roomconfig_presencebroadcast' should " "be moderator|participant|visitor">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; + {error, xmpp:err_bad_request(Txt, Lang)}; {M, P, V} -> Res = if M -> [moderator]; true -> [] end ++ @@ -4101,7 +3528,7 @@ set_xoption([{<<"muc#roomconfig_whois">>, [Val]} _ -> Txt = <<"Value of 'muc#roomconfig_whois' should be " "moderators|anyone">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + {error, xmpp:err_bad_request(Txt, Lang)} end; set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]} | Opts], @@ -4125,7 +3552,7 @@ set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config, ServerHost, Lang) -> set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) -> Txt = <<"Unknown option '~s'">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - Err = {error, ?ERRT_BAD_REQUEST(Lang, ErrTxt)}, + Err = {error, xmpp:err_bad_request(ErrTxt, Lang)}, case ejabberd_hooks:run_fold(set_room_option, ServerHost, Err, @@ -4136,6 +3563,7 @@ set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) -> set_xoption(Opts, setelement(Pos, Config, Val), ServerHost, Lang) end. +-spec change_config(#config{}, state()) -> {result, undefined, state()}. change_config(Config, StateData) -> send_config_change_info(Config, StateData), NSD = remove_subscriptions(StateData#state{config = Config}), @@ -4154,57 +3582,54 @@ change_config(Config, StateData) -> Config#config.members_only} of {false, true} -> - NSD1 = remove_nonmembers(NSD), {result, [], NSD1}; - _ -> {result, [], NSD} + NSD1 = remove_nonmembers(NSD), {result, undefined, NSD1}; + _ -> {result, undefined, NSD} end. +-spec send_config_change_info(#config{}, state()) -> ok. send_config_change_info(Config, #state{config = Config}) -> ok; send_config_change_info(New, #state{config = Old} = StateData) -> Codes = case {Old#config.logging, New#config.logging} of - {false, true} -> [<<"170">>]; - {true, false} -> [<<"171">>]; + {false, true} -> [170]; + {true, false} -> [171]; _ -> [] end ++ case {Old#config.anonymous, New#config.anonymous} of - {true, false} -> [<<"172">>]; - {false, true} -> [<<"173">>]; + {true, false} -> [172]; + {false, true} -> [173]; _ -> [] end ++ case Old#config{anonymous = New#config.anonymous, logging = New#config.logging} of New -> []; - _ -> [<<"104">>] + _ -> [104] end, - StatusEls = [#xmlel{name = <<"status">>, - attrs = [{<<"code">>, Code}], - children = []} || Code <- Codes], - Message = #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"groupchat">>}, - {<<"id">>, randoms:get_string()}], - children = [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}], - children = StatusEls}]}, + Message = #message{type = groupchat, + id = randoms:get_string(), + sub_els = [#muc_user{status_codes = Codes}]}, send_wrapped_multiple(StateData#state.jid, StateData#state.users, Message, ?NS_MUCSUB_NODES_CONFIG, StateData). +-spec remove_nonmembers(state()) -> state(). remove_nonmembers(StateData) -> lists:foldl(fun ({_LJID, #user{jid = JID}}, SD) -> Affiliation = get_affiliation(JID, SD), case Affiliation of none -> catch send_kickban_presence(<<"">>, JID, <<"">>, - <<"322">>, SD), + 322, SD), set_role(JID, none, SD); _ -> SD end end, StateData, (?DICT):to_list(StateData#state.users)). +-spec set_opts([{atom(), any()}], state()) -> state(). set_opts([], StateData) -> StateData; set_opts([{Opt, Val} | Opts], StateData) -> NSD = case Opt of @@ -4342,7 +3767,7 @@ set_opts([{Opt, Val} | Opts], StateData) -> -define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}). - +-spec make_opts(state()) -> [{atom(), any()}]. make_opts(StateData) -> Config = StateData#state.config, Subscribers = (?DICT):fold( @@ -4381,243 +3806,221 @@ make_opts(StateData) -> {subject_author, StateData#state.subject_author}, {subscribers, Subscribers}]. +-spec destroy_room(muc_destroy(), state()) -> {result, undefined, stop}. destroy_room(DEl, StateData) -> - lists:foreach(fun ({_LJID, Info}) -> - Nick = Info#user.nick, - ItemAttrs = [{<<"affiliation">>, <<"none">>}, - {<<"role">>, <<"none">>}], - Packet = #xmlel{name = <<"presence">>, - attrs = - [{<<"type">>, <<"unavailable">>}], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_MUC_USER}], - children = - [#xmlel{name = - <<"item">>, - attrs = - ItemAttrs, - children = - []}, - DEl]}]}, - send_wrapped(jid:replace_resource(StateData#state.jid, - Nick), - Info#user.jid, Packet, - ?NS_MUCSUB_NODES_CONFIG, StateData) - end, - (?DICT):to_list(StateData#state.users)), + Destroy = DEl#muc_destroy{xmlns = ?NS_MUC_USER}, + lists:foreach( + fun({_LJID, Info}) -> + Nick = Info#user.nick, + Item = #muc_item{affiliation = none, + role = none}, + Packet = #presence{ + type = unavailable, + sub_els = [#muc_user{items = [Item], + destroy = Destroy}]}, + send_wrapped(jid:replace_resource(StateData#state.jid, Nick), + Info#user.jid, Packet, + ?NS_MUCSUB_NODES_CONFIG, StateData) + end, + (?DICT):to_list(StateData#state.users)), case (StateData#state.config)#config.persistent of true -> mod_muc:forget_room(StateData#state.server_host, StateData#state.host, StateData#state.room); false -> ok end, - {result, [], stop}. + {result, undefined, stop}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Disco --define(FEATURE(Var), - #xmlel{name = <<"feature">>, attrs = [{<<"var">>, Var}], - children = []}). - -define(CONFIG_OPT_TO_FEATURE(Opt, Fiftrue, Fiffalse), case Opt of - true -> ?FEATURE(Fiftrue); - false -> ?FEATURE(Fiffalse) + true -> Fiftrue; + false -> Fiffalse end). -process_iq_disco_info(_From, set, Lang, _StateData) -> +-spec process_iq_disco_info(jid(), iq(), state()) -> + {result, disco_info()} | {error, error()}. +process_iq_disco_info(_From, #iq{type = set, lang = Lang}, _StateData) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}; -process_iq_disco_info(_From, get, Lang, StateData) -> + {error, xmpp:err_not_allowed(Txt, Lang)}; +process_iq_disco_info(_From, #iq{type = get, lang = Lang}, StateData) -> Config = StateData#state.config, - {result, - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"conference">>}, - {<<"type">>, <<"text">>}, - {<<"name">>, get_title(StateData)}], - children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_VCARD}], children = []}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_MUC}], children = []}, - ?CONFIG_OPT_TO_FEATURE((Config#config.public), - <<"muc_public">>, <<"muc_hidden">>), - ?CONFIG_OPT_TO_FEATURE((Config#config.persistent), - <<"muc_persistent">>, <<"muc_temporary">>), - ?CONFIG_OPT_TO_FEATURE((Config#config.members_only), - <<"muc_membersonly">>, <<"muc_open">>), - ?CONFIG_OPT_TO_FEATURE((Config#config.anonymous), - <<"muc_semianonymous">>, <<"muc_nonanonymous">>), - ?CONFIG_OPT_TO_FEATURE((Config#config.moderated), - <<"muc_moderated">>, <<"muc_unmoderated">>), - ?CONFIG_OPT_TO_FEATURE((Config#config.password_protected), - <<"muc_passwordprotected">>, <<"muc_unsecured">>)] - ++ case Config#config.allow_subscription of - true -> [?FEATURE(?NS_MUCSUB)]; - false -> [] - end - ++ case {gen_mod:is_loaded(StateData#state.server_host, mod_mam), - Config#config.mam} of - {true, true} -> - [?FEATURE(?NS_MAM_TMP), - ?FEATURE(?NS_MAM_0), - ?FEATURE(?NS_MAM_1)]; - _ -> - [] - end - ++ iq_disco_info_extras(Lang, StateData), - StateData}. - --define(RFIELDT(Type, Var, Val), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, Type}, {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). - --define(RFIELD(Label, Var, Val), - #xmlel{name = <<"field">>, - attrs = - [{<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). - + Feats = [?NS_VCARD, ?NS_MUC, + ?CONFIG_OPT_TO_FEATURE((Config#config.public), + <<"muc_public">>, <<"muc_hidden">>), + ?CONFIG_OPT_TO_FEATURE((Config#config.persistent), + <<"muc_persistent">>, <<"muc_temporary">>), + ?CONFIG_OPT_TO_FEATURE((Config#config.members_only), + <<"muc_membersonly">>, <<"muc_open">>), + ?CONFIG_OPT_TO_FEATURE((Config#config.anonymous), + <<"muc_semianonymous">>, <<"muc_nonanonymous">>), + ?CONFIG_OPT_TO_FEATURE((Config#config.moderated), + <<"muc_moderated">>, <<"muc_unmoderated">>), + ?CONFIG_OPT_TO_FEATURE((Config#config.password_protected), + <<"muc_passwordprotected">>, <<"muc_unsecured">>)] + ++ case Config#config.allow_subscription of + true -> [?NS_MUCSUB]; + false -> [] + end + ++ case {gen_mod:is_loaded(StateData#state.server_host, mod_mam), + Config#config.mam} of + {true, true} -> + [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1]; + _ -> + [] + end, + {result, #disco_info{xdata = [iq_disco_info_extras(Lang, StateData)], + identities = [#identity{category = <<"conference">>, + type = <<"text">>, + name = get_title(StateData)}], + features = Feats}}. + +-spec mk_rfieldt('boolean' | 'fixed' | 'hidden' | + 'jid-multi' | 'jid-single' | 'list-multi' | + 'list-single' | 'text-multi' | 'text-private' | + 'text-single', binary(), binary()) -> xdata_field(). +mk_rfieldt(Type, Var, Val) -> + #xdata_field{type = Type, var = Var, values = [Val]}. + +-spec mk_rfield(binary(), binary(), binary(), binary()) -> xdata_field(). +mk_rfield(Label, Var, Val, Lang) -> + #xdata_field{type = 'text-single', + label = translate:translate(Lang, Label), + var = Var, + values = [Val]}. + +-spec iq_disco_info_extras(binary(), state()) -> xdata(). iq_disco_info_extras(Lang, StateData) -> Len = (?DICT):size(StateData#state.users), - RoomDescription = - (StateData#state.config)#config.description, - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}], - children = - [?RFIELDT(<<"hidden">>, <<"FORM_TYPE">>, - <<"http://jabber.org/protocol/muc#roominfo">>), - ?RFIELD(<<"Room description">>, - <<"muc#roominfo_description">>, RoomDescription), - ?RFIELD(<<"Number of occupants">>, - <<"muc#roominfo_occupants">>, - (iolist_to_binary(integer_to_list(Len))))]}]. - -process_iq_disco_items(_From, set, Lang, _StateData) -> + RoomDescription = (StateData#state.config)#config.description, + #xdata{type = result, + fields = [mk_rfieldt(hidden, <<"FORM_TYPE">>, + "http://jabber.org/protocol/muc#roominfo"), + mk_rfield(<<"Room description">>, + <<"muc#roominfo_description">>, + RoomDescription, Lang), + mk_rfield(<<"Number of occupants">>, + <<"muc#roominfo_occupants">>, + integer_to_binary(Len), Lang)]}. + +-spec process_iq_disco_items(jid(), iq(), state()) -> + {error, error()} | {result, disco_items()}. +process_iq_disco_items(_From, #iq{type = set, lang = Lang}, _StateData) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}; -process_iq_disco_items(From, get, Lang, StateData) -> + {error, xmpp:err_not_allowed(Txt, Lang)}; +process_iq_disco_items(From, #iq{type = get, lang = Lang}, StateData) -> case (StateData#state.config)#config.public_list of true -> - {result, get_mucroom_disco_items(StateData), StateData}; + {result, get_mucroom_disco_items(StateData)}; _ -> case is_occupant_or_admin(From, StateData) of true -> - {result, get_mucroom_disco_items(StateData), StateData}; + {result, get_mucroom_disco_items(StateData)}; _ -> Txt = <<"Only occupants or administrators can perform this query">>, - {error, ?ERRT_FORBIDDEN(Lang, Txt)} + {error, xmpp:err_forbidden(Txt, Lang)} end end. -process_iq_captcha(_From, get, Lang, _SubEl, - _StateData) -> +-spec process_iq_captcha(jid(), iq(), state()) -> {error, error()} | + {result, undefined}. +process_iq_captcha(_From, #iq{type = get, lang = Lang}, _StateData) -> Txt = <<"Value 'get' of 'type' attribute is not allowed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}; -process_iq_captcha(_From, set, Lang, SubEl, - StateData) -> + {error, xmpp:err_not_allowed(Txt, Lang)}; +process_iq_captcha(_From, #iq{type = set, lang = Lang, sub_els = [SubEl]}, + _StateData) -> case ejabberd_captcha:process_reply(SubEl) of - ok -> {result, [], StateData}; + ok -> {result, undefined}; {error, malformed} -> Txt = <<"Incorrect CAPTCHA submit">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; + {error, xmpp:err_bad_request(Txt, Lang)}; _ -> Txt = <<"The CAPTCHA verification has failed">>, - {error, ?ERRT_NOT_ALLOWED(Lang, Txt)} + {error, xmpp:err_not_allowed(Txt, Lang)} end. -process_iq_vcard(_From, get, _Lang, _SubEl, StateData) -> +-spec process_iq_vcard(jid(), iq(), state()) -> + {result, vcard_temp() | xmlel()} | + {result, undefined, state()} | + {error, error()}. +process_iq_vcard(_From, #iq{type = get}, StateData) -> #state{config = #config{vcard = VCardRaw}} = StateData, case fxml_stream:parse_element(VCardRaw) of - #xmlel{children = VCardEls} -> - {result, VCardEls, StateData}; + #xmlel{} = VCard -> + {result, VCard}; {error, _} -> - {result, [], StateData} + {result, #vcard_temp{}} end; -process_iq_vcard(From, set, Lang, SubEl, StateData) -> +process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [SubEl]}, + StateData) -> case get_affiliation(From, StateData) of owner -> - VCardRaw = fxml:element_to_binary(SubEl), + VCardRaw = fxml:element_to_binary(xmpp:encode(SubEl)), Config = StateData#state.config, NewConfig = Config#config{vcard = VCardRaw}, change_config(NewConfig, StateData); _ -> ErrText = <<"Owner privileges required">>, - {error, ?ERRT_FORBIDDEN(Lang, ErrText)} + {error, xmpp:err_forbidden(ErrText, Lang)} end. -process_iq_mucsub(From, Packet, +-spec process_iq_mucsub(jid(), iq(), state()) -> + {error, error()} | + {result, undefined | muc_subscribe(), state()} | + {ignore, state()}. +process_iq_mucsub(_From, #iq{type = set, lang = Lang, + sub_els = [#muc_subscribe{}]}, + #state{config = #config{allow_subscription = false}}) -> + {error, xmpp:err_not_allowed(<<"Subscriptions are not allowed">>, Lang)}; +process_iq_mucsub(From, #iq{type = set, lang = Lang, - sub_el = #xmlel{name = <<"subscribe">>} = SubEl}, - #state{config = Config} = StateData) -> - case fxml:get_tag_attr_s(<<"nick">>, SubEl) of - <<"">> -> - Err = ?ERRT_BAD_REQUEST(Lang, <<"Missing 'nick' attribute">>), - {error, Err}; - Nick when Config#config.allow_subscription -> - LJID = jid:tolower(From), - case (?DICT):find(LJID, StateData#state.users) of - {ok, #user{role = Role, nick = Nick1}} when Nick1 /= Nick -> - Nodes = get_subscription_nodes(Packet), - case {nick_collision(From, Nick, StateData), - mod_muc:can_use_nick(StateData#state.server_host, - StateData#state.host, - From, Nick)} of - {true, _} -> - ErrText = <<"That nickname is already in use by another occupant">>, - {error, ?ERRT_CONFLICT(Lang, ErrText)}; - {_, false} -> - ErrText = <<"That nickname is registered by another person">>, - {error, ?ERRT_CONFLICT(Lang, ErrText)}; - _ -> - NewStateData = add_online_user( - From, Nick, Role, true, Nodes, StateData), - {result, subscription_nodes_to_events(Nodes), NewStateData} - end; - {ok, #user{role = Role}} -> - Nodes = get_subscription_nodes(Packet), + sub_els = [#muc_subscribe{nick = Nick}]} = Packet, + StateData) -> + LJID = jid:tolower(From), + case (?DICT):find(LJID, StateData#state.users) of + {ok, #user{role = Role, nick = Nick1}} when Nick1 /= Nick -> + Nodes = get_subscription_nodes(Packet), + case {nick_collision(From, Nick, StateData), + mod_muc:can_use_nick(StateData#state.server_host, + StateData#state.host, + From, Nick)} of + {true, _} -> + ErrText = <<"That nickname is already in use by another occupant">>, + {error, xmpp:err_conflict(ErrText, Lang)}; + {_, false} -> + ErrText = <<"That nickname is registered by another person">>, + {error, xmpp:err_conflict(ErrText, Lang)}; + _ -> NewStateData = add_online_user( From, Nick, Role, true, Nodes, StateData), - {result, subscription_nodes_to_events(Nodes), NewStateData}; - error -> - add_new_user(From, Nick, Packet, StateData) + {result, subscribe_result(Packet), NewStateData} end; - _ -> - Err = ?ERRT_NOT_ALLOWED(Lang, <<"Subscriptions are not allowed">>), - {error, Err} + {ok, #user{role = Role}} -> + Nodes = get_subscription_nodes(Packet), + NewStateData = add_online_user( + From, Nick, Role, true, Nodes, StateData), + {result, subscribe_result(Packet), NewStateData}; + error -> + add_new_user(From, Nick, Packet, StateData) end; -process_iq_mucsub(From, _Packet, - #iq{type = set, - sub_el = #xmlel{name = <<"unsubscribe">>}}, +process_iq_mucsub(From, #iq{type = set, sub_els = [#muc_unsubscribe{}]}, StateData) -> LJID = jid:tolower(From), case ?DICT:find(LJID, StateData#state.users) of {ok, #user{is_subscriber = true} = User} -> NewStateData = remove_subscription(From, User, StateData), store_room(NewStateData), - {result, [], NewStateData}; + {result, undefined, NewStateData}; _ -> - {result, [], StateData} + {result, undefined, StateData} end; -process_iq_mucsub(_From, _Packet, #iq{type = set, lang = Lang}, _StateData) -> - Txt = <<"Unrecognized subscription command">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; -process_iq_mucsub(_From, _Packet, #iq{type = get, lang = Lang}, _StateData) -> +process_iq_mucsub(_From, #iq{type = get, lang = Lang}, _StateData) -> Txt = <<"Value 'get' of 'type' attribute is not allowed">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}. + {error, xmpp:err_bad_request(Txt, Lang)}. +-spec remove_subscription(jid(), #user{}, state()) -> state(). remove_subscription(JID, #user{is_subscriber = true} = User, StateData) -> case User#user.last_presence of undefined -> @@ -4631,6 +4034,7 @@ remove_subscription(JID, #user{is_subscriber = true} = User, StateData) -> remove_subscription(_JID, #user{}, StateData) -> StateData. +-spec remove_subscriptions(state()) -> state(). remove_subscriptions(StateData) -> if not (StateData#state.config)#config.allow_subscription -> dict:fold( @@ -4641,41 +4045,32 @@ remove_subscriptions(StateData) -> StateData end. -get_subscription_nodes(#xmlel{name = <<"iq">>} = Packet) -> - case fxml:get_subtag_with_xmlns(Packet, <<"subscribe">>, ?NS_MUCSUB) of - #xmlel{children = Els} -> - lists:flatmap( - fun(#xmlel{name = <<"event">>, attrs = Attrs}) -> - Node = fxml:get_attr_s(<<"node">>, Attrs), - case lists:member(Node, [?NS_MUCSUB_NODES_PRESENCE, - ?NS_MUCSUB_NODES_MESSAGES, - ?NS_MUCSUB_NODES_AFFILIATIONS, - ?NS_MUCSUB_NODES_SUBJECT, - ?NS_MUCSUB_NODES_CONFIG, - ?NS_MUCSUB_NODES_PARTICIPANTS]) of - true -> - [Node]; - false -> - [] - end; - (_) -> - [] - end, Els); - false -> - [] - end; +-spec get_subscription_nodes(iq()) -> [binary()]. +get_subscription_nodes(#iq{sub_els = [#muc_subscribe{events = Nodes}]}) -> + lists:filter( + fun(Node) -> + lists:member(Node, [?NS_MUCSUB_NODES_PRESENCE, + ?NS_MUCSUB_NODES_MESSAGES, + ?NS_MUCSUB_NODES_AFFILIATIONS, + ?NS_MUCSUB_NODES_SUBJECT, + ?NS_MUCSUB_NODES_CONFIG, + ?NS_MUCSUB_NODES_PARTICIPANTS]) + end, Nodes); get_subscription_nodes(_) -> []. -subscription_nodes_to_events(Nodes) -> - [#xmlel{name = <<"event">>, attrs = [{<<"node">>, Node}]} || Node <- Nodes]. +-spec subscribe_result(iq()) -> muc_subscribe(). +subscribe_result(#iq{sub_els = [#muc_subscribe{nick = Nick}]} = Packet) -> + #muc_subscribe{nick = Nick, events = get_subscription_nodes(Packet)}. +-spec get_title(state()) -> binary(). get_title(StateData) -> case (StateData#state.config)#config.title of <<"">> -> StateData#state.room; Name -> Name end. +-spec get_roomdesc_reply(jid(), state(), binary()) -> {item, binary()} | false. get_roomdesc_reply(JID, StateData, Tail) -> IsOccupantOrAdmin = is_occupant_or_admin(JID, StateData), @@ -4689,352 +4084,215 @@ get_roomdesc_reply(JID, StateData, Tail) -> true -> false end. +-spec get_roomdesc_tail(state(), binary()) -> binary(). get_roomdesc_tail(StateData, Lang) -> Desc = case (StateData#state.config)#config.public of true -> <<"">>; _ -> translate:translate(Lang, <<"private, ">>) end, - Len = (?DICT):fold(fun (_, _, Acc) -> Acc + 1 end, 0, - StateData#state.users), + Len = (?DICT):size(StateData#state.users), <<" (", Desc/binary, (iolist_to_binary(integer_to_list(Len)))/binary, ")">>. +-spec get_mucroom_disco_items(state()) -> disco_items(). get_mucroom_disco_items(StateData) -> - lists:map(fun ({_LJID, Info}) -> + Items = lists:map( + fun({_LJID, Info}) -> Nick = Info#user.nick, - #xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, - jid:to_string({StateData#state.room, - StateData#state.host, - Nick})}, - {<<"name">>, Nick}], - children = []} + #disco_item{jid = jid:make(StateData#state.room, + StateData#state.host, + Nick), + name = Nick} end, - (?DICT):to_list(StateData#state.users)). + (?DICT):to_list(StateData#state.users)), + #disco_items{items = Items}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Voice request support -is_voice_request(Els) -> - lists:foldl(fun (#xmlel{name = <<"x">>, attrs = Attrs} = - El, - false) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_XDATA -> - case jlib:parse_xdata_submit(El) of - [_ | _] = Fields -> - case {lists:keysearch(<<"FORM_TYPE">>, 1, - Fields), - lists:keysearch(<<"muc#role">>, 1, - Fields)} - of - {{value, - {_, - [<<"http://jabber.org/protocol/muc#request">>]}}, - {value, {_, [<<"participant">>]}}} -> - true; - _ -> false - end; - _ -> false - end; - _ -> false - end; - (_, Acc) -> Acc - end, - false, Els). +-spec is_voice_request(message()) -> boolean(). +is_voice_request(Packet) -> + Els = xmpp:get_els(Packet), + lists:any( + fun(#xdata{} = X) -> + case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), + xmpp_util:get_xdata_values(<<"muc#role">>, X)} of + {[<<"http://jabber.org/protocol/muc#request">>], + [<<"participant">>]} -> + true; + _ -> + false + end; + (_) -> + false + end, Els). +-spec prepare_request_form(jid(), binary(), binary()) -> message(). prepare_request_form(Requester, Nick, Lang) -> - #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"normal">>}], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Voice request">>)}]}, - #xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Either approve or decline the voice " - "request.">>)}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"http://jabber.org/protocol/muc#request">>}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"muc#role">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, - <<"participant">>}]}]}, - ?STRINGXFIELD(<<"User JID">>, <<"muc#jid">>, - (jid:to_string(Requester))), - ?STRINGXFIELD(<<"Nickname">>, <<"muc#roomnick">>, - Nick), - ?BOOLXFIELD(<<"Grant voice to this person?">>, - <<"muc#request_allow">>, - (jlib:binary_to_atom(<<"false">>)))]}]}. - -send_voice_request(From, StateData) -> + Title = translate:translate(Lang, <<"Voice request">>), + Instruction = translate:translate( + Lang, <<"Either approve or decline the voice request.">>), + Fs = [#xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = [<<"http://jabber.org/protocol/muc#request">>]}, + #xdata_field{var = <<"muc#role">>, + type = hidden, + values = [<<"participant">>]}, + ?STRINGXFIELD(<<"User JID">>, <<"muc#jid">>, + jid:to_string(Requester)), + ?STRINGXFIELD(<<"Nickname">>, <<"muc#roomnick">>, Nick), + ?BOOLXFIELD(<<"Grant voice to this person?">>, + <<"muc#request_allow">>, false)], + #message{type = normal, + sub_els = [#xdata{type = form, + title = Title, + instructions = [Instruction], + fields = Fs}]}. + +-spec send_voice_request(jid(), binary(), state()) -> ok. +send_voice_request(From, Lang, StateData) -> Moderators = search_role(moderator, StateData), FromNick = find_nick_by_jid(From, StateData), lists:foreach(fun ({_, User}) -> ejabberd_router:route( StateData#state.jid, User#user.jid, - prepare_request_form(From, FromNick, <<"">>)) + prepare_request_form(From, FromNick, Lang)) end, Moderators). -is_voice_approvement(Els) -> - lists:foldl(fun (#xmlel{name = <<"x">>, attrs = Attrs} = - El, - false) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_XDATA -> - case jlib:parse_xdata_submit(El) of - [_ | _] = Fs -> - case {lists:keysearch(<<"FORM_TYPE">>, 1, - Fs), - lists:keysearch(<<"muc#role">>, 1, - Fs), - lists:keysearch(<<"muc#request_allow">>, - 1, Fs)} - of - {{value, - {_, - [<<"http://jabber.org/protocol/muc#request">>]}}, - {value, {_, [<<"participant">>]}}, - {value, {_, [Flag]}}} - when Flag == <<"true">>; - Flag == <<"1">> -> - true; - _ -> false - end; - _ -> false - end; - _ -> false - end; - (_, Acc) -> Acc - end, - false, Els). - -extract_jid_from_voice_approvement(Els) -> - lists:foldl(fun (#xmlel{name = <<"x">>} = El, error) -> - Fields = case jlib:parse_xdata_submit(El) of - invalid -> []; - Res -> Res - end, - lists:foldl(fun ({<<"muc#jid">>, [JIDStr]}, error) -> - case jid:from_string(JIDStr) of - error -> error; - J -> {ok, J} - end; - (_, Acc) -> Acc - end, - error, Fields); - (_, Acc) -> Acc - end, - error, Els). +-spec is_voice_approvement(message()) -> boolean(). +is_voice_approvement(Packet) -> + Els = xmpp:get_els(Packet), + lists:any( + fun(#xdata{} = X) -> + case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), + xmpp_util:get_xdata_values(<<"muc#role">>, X), + xmpp_util:get_xdata_values(<<"muc#request_allow">>, X)} of + {[<<"http://jabber.org/protocol/muc#request">>], + [<<"participant">>], [Flag]} when Flag == <<"true">>; + Flag == <<"1">> -> + true; + _ -> + false + end; + (_) -> + false + end, Els). + +-spec extract_jid_from_voice_approvement(message()) -> jid() | error. +extract_jid_from_voice_approvement(Packet) -> + Els = xmpp:get_els(Packet), + lists:foldl( + fun(#xdata{} = X, error) -> + case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), + xmpp_util:get_xdata_values(<<"muc#role">>, X), + xmpp_util:get_xdata_values(<<"muc#request_allow">>, X), + xmpp_util:get_xdata_values(<<"muc#jid">>, X)} of + {[<<"http://jabber.org/protocol/muc#request">>], + [<<"participant">>], [Flag], [J]} when Flag == <<"true">>; + Flag == <<"1">> -> + jid:from_string(J); + _ -> + error + end; + (_, Acc) -> + Acc + end, error, Els). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Invitation support -is_invitation(Els) -> - lists:foldl(fun (#xmlel{name = <<"x">>, attrs = Attrs} = - El, - false) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_MUC_USER -> - case fxml:get_subtag(El, <<"invite">>) of - false -> false; - _ -> true - end; - _ -> false - end; - (_, Acc) -> Acc - end, - false, Els). - -check_invitation(From, Packet, Lang, StateData) -> +-spec is_invitation(message()) -> boolean(). +is_invitation(Packet) -> + Els = xmpp:get_els(Packet), + lists:any( + fun(#muc_user{invites = [_|_]}) -> true; + (_) -> false + end, Els). + +-spec check_invitation(jid(), message(), state()) -> {error, error()} | jid(). +check_invitation(From, Packet, StateData) -> + Lang = xmpp:get_lang(Packet), FAffiliation = get_affiliation(From, StateData), - CanInvite = - (StateData#state.config)#config.allow_user_invites - orelse - FAffiliation == admin orelse FAffiliation == owner, - InviteEl = case fxml:get_subtag_with_xmlns(Packet, <<"x">>, ?NS_MUC_USER) of - false -> - Txt1 = <<"No 'x' element found">>, - throw({error, ?ERRT_BAD_REQUEST(Lang, Txt1)}); - XEl -> - case fxml:get_subtag(XEl, <<"invite">>) of - false -> - Txt2 = <<"No 'invite' element found">>, - throw({error, ?ERRT_BAD_REQUEST(Lang, Txt2)}); - InviteEl1 -> - InviteEl1 - end - end, - JID = case - jid:from_string(fxml:get_tag_attr_s(<<"to">>, - InviteEl)) - of - error -> - Txt = <<"Incorrect value of 'to' attribute">>, - throw({error, ?ERRT_JID_MALFORMED(Lang, Txt)}); - JID1 -> JID1 - end, + CanInvite = (StateData#state.config)#config.allow_user_invites + orelse + FAffiliation == admin orelse FAffiliation == owner, case CanInvite of - false -> - Txt3 = <<"Invitations are not allowed in this conference">>, - throw({error, ?ERRT_NOT_ALLOWED(Lang, Txt3)}); - true -> - Reason = fxml:get_path_s(InviteEl, - [{elem, <<"reason">>}, cdata]), - ContinueEl = case fxml:get_path_s(InviteEl, - [{elem, <<"continue">>}]) - of - <<>> -> []; - Continue1 -> [Continue1] - end, - IEl = [#xmlel{name = <<"invite">>, - attrs = [{<<"from">>, jid:to_string(From)}], - children = - [#xmlel{name = <<"reason">>, attrs = [], - children = [{xmlcdata, Reason}]}] - ++ ContinueEl}], - PasswdEl = case - (StateData#state.config)#config.password_protected - of - true -> - [#xmlel{name = <<"password">>, attrs = [], - children = - [{xmlcdata, - (StateData#state.config)#config.password}]}]; - _ -> [] - end, - Body = #xmlel{name = <<"body">>, attrs = [], - children = - [{xmlcdata, - iolist_to_binary( - [io_lib:format( - translate:translate( - Lang, - <<"~s invites you to the room ~s">>), - [jid:to_string(From), - jid:to_string({StateData#state.room, - StateData#state.host, - <<"">>})]), - case - (StateData#state.config)#config.password_protected - of + false -> + Txt = <<"Invitations are not allowed in this conference">>, + {error, xmpp:err_not_allowed(Txt, Lang)}; + true -> + case xmpp:get_subtag(Packet, #muc_user{}) of + #muc_user{invites = [#muc_invite{to = undefined}]} -> + Txt = <<"No 'to' attribute found">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + #muc_user{invites = [#muc_invite{to = JID, reason = Reason} = I]} -> + Invite = I#muc_invite{to = undefined, from = From}, + Password = case (StateData#state.config)#config.password_protected of + true -> + (StateData#state.config)#config.password; + false -> + undefined + end, + XUser = #muc_user{password = Password, invites = [Invite]}, + XConference = #x_conference{jid = jid:make(StateData#state.room, + StateData#state.host), + reason = Reason}, + Body = iolist_to_binary( + [io_lib:format( + translate:translate( + Lang, + <<"~s invites you to the room ~s">>), + [jid:to_string(From), + jid:to_string({StateData#state.room, + StateData#state.host, + <<"">>})]), + case (StateData#state.config)#config.password_protected of true -> <<", ", - (translate:translate(Lang, - <<"the password is">>))/binary, + (translate:translate( + Lang, <<"the password is">>))/binary, " '", ((StateData#state.config)#config.password)/binary, "'">>; _ -> <<"">> - end - , - case Reason of - <<"">> -> <<"">>; - _ -> <<" (", Reason/binary, ") ">> - end])}]}, - Msg = #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"normal">>}], - children = - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_MUC_USER}], - children = IEl ++ PasswdEl}, - #xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XCONFERENCE}, - {<<"jid">>, - jid:to_string({StateData#state.room, - StateData#state.host, - <<"">>})}], - children = [{xmlcdata, Reason}]}, - Body]}, - ejabberd_router:route(StateData#state.jid, JID, Msg), - JID + end, + case Reason of + <<"">> -> <<"">>; + _ -> <<" (", Reason/binary, ") ">> + end]), + Msg = #message{type = normal, + body = xmpp:mk_text(Body), + sub_els = [XUser, XConference]}, + ejabberd_router:route(StateData#state.jid, JID, Msg), + JID; + #muc_user{invites = [_|_]} -> + Txt = <<"Multiple elements are not allowed">>, + {error, xmpp:err_forbidden(Txt, Lang)}; + _ -> + Txt = <<"No element found">>, + {error, xmpp:err_bad_request(Txt, Lang)} + end end. %% Handle a message sent to the room by a non-participant. %% If it is a decline, send to the inviter. %% Otherwise, an error message is sent to the sender. -handle_roommessage_from_nonparticipant(Packet, Lang, - StateData, From) -> - case catch check_decline_invitation(Packet) of - {true, Decline_data} -> - send_decline_invitation(Decline_data, - StateData#state.jid, From); - _ -> - send_error_only_occupants(Packet, Lang, - StateData#state.jid, From) +-spec handle_roommessage_from_nonparticipant(message(), state(), jid()) -> ok. +handle_roommessage_from_nonparticipant(Packet, StateData, From) -> + case xmpp:get_subtag(Packet, #muc_user{}) of + #muc_user{decline = #muc_decline{to = #jid{} = To} = Decline} = XUser -> + NewDecline = Decline#muc_decline{to = undefined, from = From}, + NewXUser = XUser#muc_user{decline = NewDecline}, + NewPacket = xmpp:set_subtag(Packet, NewXUser), + ejabberd_router:route(StateData#state.jid, To, NewPacket); + _ -> + ErrText = <<"Only occupants are allowed to send messages " + "to the conference">>, + Err = xmpp:err_not_acceptable(ErrText, xmpp:get_lang(Packet)), + ejabberd_router:route_error(StateData#state.jid, From, Packet, Err) end. -%% Check in the packet is a decline. -%% If so, also returns the splitted packet. -%% This function must be catched, -%% because it crashes when the packet is not a decline message. -check_decline_invitation(Packet) -> - #xmlel{name = <<"message">>} = Packet, - XEl = fxml:get_subtag(Packet, <<"x">>), - (?NS_MUC_USER) = fxml:get_tag_attr_s(<<"xmlns">>, XEl), - DEl = fxml:get_subtag(XEl, <<"decline">>), - ToString = fxml:get_tag_attr_s(<<"to">>, DEl), - ToJID = jid:from_string(ToString), - {true, {Packet, XEl, DEl, ToJID}}. - -%% Send the decline to the inviter user. -%% The original stanza must be slightly modified. -send_decline_invitation({Packet, XEl, DEl, ToJID}, - RoomJID, FromJID) -> - FromString = - jid:to_string(jid:remove_resource(FromJID)), - #xmlel{name = <<"decline">>, attrs = DAttrs, - children = DEls} = - DEl, - DAttrs2 = lists:keydelete(<<"to">>, 1, DAttrs), - DAttrs3 = [{<<"from">>, FromString} | DAttrs2], - DEl2 = #xmlel{name = <<"decline">>, attrs = DAttrs3, - children = DEls}, - XEl2 = replace_subelement(XEl, DEl2), - Packet2 = replace_subelement(Packet, XEl2), - ejabberd_router:route(RoomJID, ToJID, Packet2). - -%% Given an element and a new subelement, -%% replace the instance of the subelement in element with the new subelement. -replace_subelement(#xmlel{name = Name, attrs = Attrs, - children = SubEls}, - NewSubEl) -> - {_, NameNewSubEl, _, _} = NewSubEl, - SubEls2 = lists:keyreplace(NameNewSubEl, 2, SubEls, NewSubEl), - #xmlel{name = Name, attrs = Attrs, children = SubEls2}. - -send_error_only_occupants(Packet, Lang, RoomJID, From) -> - ErrText = - <<"Only occupants are allowed to send messages " - "to the conference">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), - ejabberd_router:route(RoomJID, From, Err). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Logging @@ -5055,6 +4313,7 @@ add_to_log(Type, Data, StateData) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Users number checking +-spec tab_add_online_user(jid(), state()) -> ok. tab_add_online_user(JID, StateData) -> {LUser, LServer, LResource} = jid:tolower(JID), US = {LUser, LServer}, @@ -5062,8 +4321,10 @@ tab_add_online_user(JID, StateData) -> Host = StateData#state.host, catch ets:insert(muc_online_users, #muc_online_users{us = US, resource = LResource, - room = Room, host = Host}). + room = Room, host = Host}), + ok. +-spec tab_remove_online_user(jid(), state()) -> ok. tab_remove_online_user(JID, StateData) -> {LUser, LServer, LResource} = jid:tolower(JID), US = {LUser, LServer}, @@ -5071,8 +4332,10 @@ tab_remove_online_user(JID, StateData) -> Host = StateData#state.host, catch ets:delete_object(muc_online_users, #muc_online_users{us = US, resource = LResource, - room = Room, host = Host}). + room = Room, host = Host}), + ok. +-spec tab_count_user(jid()) -> non_neg_integer(). tab_count_user(JID) -> {LUser, LServer, _} = jid:tolower(JID), US = {LUser, LServer}, @@ -5083,9 +4346,11 @@ tab_count_user(JID) -> _ -> 0 end. +-spec element_size(stanza()) -> non_neg_integer(). element_size(El) -> - byte_size(fxml:element_to_binary(El)). + byte_size(fxml:element_to_binary(xmpp:encode(El))). +-spec store_room(state()) -> ok. store_room(StateData) -> if (StateData#state.config)#config.persistent -> mod_muc:store_room(StateData#state.server_host, @@ -5095,6 +4360,7 @@ store_room(StateData) -> ok end. +-spec send_wrapped(jid(), jid(), stanza(), binary(), state()) -> ok. send_wrapped(From, To, Packet, Node, State) -> LTo = jid:tolower(To), case ?DICT:find(LTo, State#state.users) of @@ -5112,27 +4378,26 @@ send_wrapped(From, To, Packet, Node, State) -> ejabberd_router:route(From, To, Packet) end. +-spec wrap(jid(), jid(), stanza(), binary()) -> message(). wrap(From, To, Packet, Node) -> - Pkt1 = jlib:replace_from_to(From, To, Packet), - Pkt2 = #xmlel{attrs = Attrs} = jlib:remove_attr(<<"xmlns">>, Pkt1), - Pkt3 = Pkt2#xmlel{attrs = [{<<"xmlns">>, <<"jabber:client">>}|Attrs]}, - Item = #xmlel{name = <<"item">>, - attrs = [{<<"id">>, randoms:get_string()}], - children = [Pkt3]}, - Items = #xmlel{name = <<"items">>, attrs = [{<<"node">>, Node}], - children = [Item]}, - Event = #xmlel{name = <<"event">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_EVENT}], - children = [Items]}, - #xmlel{name = <<"message">>, children = [Event]}. + El = xmpp:encode(xmpp:set_from_to(Packet, From, To)), + #message{ + sub_els = [#pubsub_event{ + items = [#pubsub_event_items{ + node = Node, + items = [#pubsub_event_item{ + id = randoms:get_string(), + xml_els = [El]}]}]}]}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Multicast +-spec send_multiple(jid(), binary(), [#user{}], stanza()) -> ok. send_multiple(From, Server, Users, Packet) -> JIDs = [ User#user.jid || {_, User} <- ?DICT:to_list(Users)], ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet). +-spec send_wrapped_multiple(jid(), [#user{}], stanza(), binary(), state()) -> ok. send_wrapped_multiple(From, Users, Packet, Node, State) -> lists:foreach( fun({_, #user{jid = To}}) -> @@ -5141,10 +4406,6 @@ send_wrapped_multiple(From, Users, Packet, Node, State) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Detect messange stanzas that don't have meaninful content - -has_body_or_subject(Packet) -> - [] /= lists:dropwhile(fun - (#xmlel{name = <<"body">>}) -> false; - (#xmlel{name = <<"subject">>}) -> false; - (_) -> true - end, Packet#xmlel.children). +-spec has_body_or_subject(message()) -> boolean(). +has_body_or_subject(#message{body = Body, subject = Subj}) -> + Body /= [] orelse Subj /= []. diff --git a/src/mod_private.erl b/src/mod_private.erl index 28d49bb3f..e6d0fd7cd 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -72,7 +72,7 @@ process_sm_iq(#iq{type = Type, lang = Lang, case filter_xmlels(Els0) of [] -> Txt = <<"No private data found in this query">>, - xmpp:make_error(IQ, xmpp:err_bad_format(Txt, Lang)); + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); Data when Type == set -> set_data(LUser, LServer, Data), xmpp:make_iq_result(IQ); diff --git a/src/xmpp.erl b/src/xmpp.erl index f17eefa21..369fb90c5 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -16,22 +16,33 @@ set_type/2, set_to/2, set_from/2, set_id/2, set_lang/2, set_error/2, set_els/2, set_from_to/3, format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, - remove_subtag/2, has_subtag/2, decode_els/1, pp/1, - get_name/1, get_text/1, mk_text/1, mk_text/2]). + remove_subtag/2, has_subtag/2, decode_els/1, decode_els/2, + pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2]). %% XMPP errors -export([err_bad_request/0, err_bad_request/2, - err_bad_format/0, err_bad_format/2, - err_not_allowed/0, err_not_allowed/2, - err_conflict/0, err_conflict/2, - err_forbidden/0, err_forbidden/2, - err_not_acceptable/0, err_not_acceptable/2, - err_internal_server_error/0, err_internal_server_error/2, - err_service_unavailable/0, err_service_unavailable/2, - err_item_not_found/0, err_item_not_found/2, - err_jid_malformed/0, err_jid_malformed/2, - err_not_authorized/0, err_not_authorized/2, - err_feature_not_implemented/0, err_feature_not_implemented/2]). + err_conflict/0, err_conflict/2, + err_feature_not_implemented/0, err_feature_not_implemented/2, + err_forbidden/0, err_forbidden/2, + err_gone/0, err_gone/2, + err_internal_server_error/0, err_internal_server_error/2, + err_item_not_found/0, err_item_not_found/2, + err_jid_malformed/0, err_jid_malformed/2, + err_not_acceptable/0, err_not_acceptable/2, + err_not_allowed/0, err_not_allowed/2, + err_not_authorized/0, err_not_authorized/2, + err_payment_required/0, err_payment_required/2, + err_policy_violation/0, err_policy_violation/2, + err_recipient_unavailable/0, err_recipient_unavailable/2, + err_redirect/0, err_redirect/2, + err_registration_required/0, err_registration_required/2, + err_remote_server_not_found/0, err_remote_server_not_found/2, + err_remote_server_timeout/0, err_remote_server_timeout/2, + err_resource_constraint/0, err_resource_constraint/2, + err_service_unavailable/0, err_service_unavailable/2, + err_subscription_required/0, err_subscription_required/2, + err_undefined_condition/0, err_undefined_condition/2, + err_unexpected_request/0, err_unexpected_request/2]). %% XMPP stream errors -export([serr_bad_format/0, serr_bad_format/2, @@ -246,9 +257,12 @@ decode(Pkt, _Opts) -> (message()) -> message(); (presence()) -> presence(). decode_els(Stanza) -> + decode_els(Stanza, fun xmpp_codec:is_known_tag/1). + +decode_els(Stanza, MatchFun) -> Els = lists:map( fun(#xmlel{} = El) -> - case xmpp_codec:is_known_tag(El) of + case MatchFun(El) of true -> decode(El); false -> El end; @@ -287,10 +301,10 @@ set_subtag(Stanza, Tag) -> set_els(Stanza, NewEls). set_subtag([El|Els], Tag, TagName, XMLNS) -> - case {get_name(El), get_ns(El)} of - {TagName, XMLNS} -> + case match_tag(El, TagName, XMLNS) of + true -> [Tag|Els]; - _ -> + false -> [El|set_subtag(Els, Tag, TagName, XMLNS)] end; set_subtag([], Tag, _, _) -> @@ -304,14 +318,14 @@ get_subtag(Stanza, Tag) -> get_subtag(Els, TagName, XMLNS). get_subtag([El|Els], TagName, XMLNS) -> - case {get_name(El), get_ns(El)} of - {TagName, XMLNS} -> + case match_tag(El, TagName, XMLNS) of + true -> try decode(El) catch _:{xmpp_codec, _Why} -> get_subtag(Els, TagName, XMLNS) end; - _ -> + false -> get_subtag(Els, TagName, XMLNS) end; get_subtag([], _, _) -> @@ -328,10 +342,10 @@ remove_subtag(Stanza, Tag) -> set_els(Stanza, NewEls). remove_subtag([El|Els], TagName, XMLNS) -> - case {get_name(El), get_ns(El)} of - {TagName, XMLNS} -> + case match_tag(El, TagName, XMLNS) of + true -> remove_subtag(Els, TagName, XMLNS); - _ -> + false -> [El|remove_subtag(Els, TagName, XMLNS)] end; remove_subtag([], _, _) -> @@ -345,10 +359,10 @@ has_subtag(Stanza, Tag) -> has_subtag(Els, TagName, XMLNS). has_subtag([El|Els], TagName, XMLNS) -> - case {get_name(El), get_ns(El)} of - {TagName, XMLNS} -> + case match_tag(El, TagName, XMLNS) of + true -> true; - _ -> + false -> has_subtag(Els, TagName, XMLNS) end; has_subtag([], _, _) -> @@ -385,14 +399,6 @@ err_bad_request() -> err_bad_request(Text, Lang) -> err(modify, 'bad-request', 400, Text, Lang). --spec err_bad_format() -> error(). -err_bad_format() -> - err(modify, 'bad-format', 406). - --spec err_bad_format(binary(), binary() | undefined) -> error(). -err_bad_format(Text, Lang) -> - err(modify, 'bad-format', 406, Text, Lang). - -spec err_conflict() -> error(). err_conflict() -> err(cancel, 'conflict', 409). @@ -401,14 +407,6 @@ err_conflict() -> err_conflict(Text, Lang) -> err(cancel, 'conflict', 409, Text, Lang). --spec err_not_allowed() -> error(). -err_not_allowed() -> - err(cancel, 'not-allowed', 405). - --spec err_not_allowed(binary(), binary() | undefined) -> error(). -err_not_allowed(Text, Lang) -> - err(cancel, 'not-allowed', 405, Text, Lang). - -spec err_feature_not_implemented() -> error(). err_feature_not_implemented() -> err(cancel, 'feature-not-implemented', 501). @@ -417,14 +415,6 @@ err_feature_not_implemented() -> err_feature_not_implemented(Text, Lang) -> err(cancel, 'feature-not-implemented', 501, Text, Lang). --spec err_item_not_found() -> error(). -err_item_not_found() -> - err(cancel, 'item-not-found', 404). - --spec err_item_not_found(binary(), binary() | undefined) -> error(). -err_item_not_found(Text, Lang) -> - err(cancel, 'item-not-found', 404, Text, Lang). - -spec err_forbidden() -> error(). err_forbidden() -> err(auth, 'forbidden', 403). @@ -433,14 +423,18 @@ err_forbidden() -> err_forbidden(Text, Lang) -> err(auth, 'forbidden', 403, Text, Lang). --spec err_not_acceptable() -> error(). -err_not_acceptable() -> - err(modify, 'not-acceptable', 406). +%% RFC 6120 says error type SHOULD be "cancel". +%% RFC 3920 and XEP-0082 says it SHOULD be "modify". +-spec err_gone() -> error(). +err_gone() -> + err(modify, 'gone', 302). --spec err_not_acceptable(binary(), binary() | undefined) -> error(). -err_not_acceptable(Text, Lang) -> - err(modify, 'not-acceptable', 406, Text, Lang). +-spec err_gone(binary(), binary() | undefined) -> error(). +err_gone(Text, Lang) -> + err(modify, 'gone', 302, Text, Lang). +%% RFC 6120 sasy error type SHOULD be "cancel". +%% RFC 3920 and XEP-0082 says it SHOULD be "wait". -spec err_internal_server_error() -> error(). err_internal_server_error() -> err(wait, 'internal-server-error', 500). @@ -449,13 +443,13 @@ err_internal_server_error() -> err_internal_server_error(Text, Lang) -> err(wait, 'internal-server-error', 500, Text, Lang). --spec err_service_unavailable() -> error(). -err_service_unavailable() -> - err(cancel, 'service-unavailable', 503). +-spec err_item_not_found() -> error(). +err_item_not_found() -> + err(cancel, 'item-not-found', 404). --spec err_service_unavailable(binary(), binary() | undefined) -> error(). -err_service_unavailable(Text, Lang) -> - err(cancel, 'service-unavailable', 503, Text, Lang). +-spec err_item_not_found(binary(), binary() | undefined) -> error(). +err_item_not_found(Text, Lang) -> + err(cancel, 'item-not-found', 404, Text, Lang). -spec err_jid_malformed() -> error(). err_jid_malformed() -> @@ -465,6 +459,22 @@ err_jid_malformed() -> err_jid_malformed(Text, Lang) -> err(modify, 'jid-malformed', 400, Text, Lang). +-spec err_not_acceptable() -> error(). +err_not_acceptable() -> + err(modify, 'not-acceptable', 406). + +-spec err_not_acceptable(binary(), binary() | undefined) -> error(). +err_not_acceptable(Text, Lang) -> + err(modify, 'not-acceptable', 406, Text, Lang). + +-spec err_not_allowed() -> error(). +err_not_allowed() -> + err(cancel, 'not-allowed', 405). + +-spec err_not_allowed(binary(), binary() | undefined) -> error(). +err_not_allowed(Text, Lang) -> + err(cancel, 'not-allowed', 405, Text, Lang). + -spec err_not_authorized() -> error(). err_not_authorized() -> err(auth, 'not-authorized', 401). @@ -473,6 +483,108 @@ err_not_authorized() -> err_not_authorized(Text, Lang) -> err(auth, 'not-authorized', 401, Text, Lang). +-spec err_payment_required() -> error(). +err_payment_required() -> + err(auth, 'not-authorized', 402). + +-spec err_payment_required(binary(), binary() | undefined) -> error(). +err_payment_required(Text, Lang) -> + err(auth, 'not-authorized', 402, Text, Lang). + +%% is defined in neither RFC 3920 nor XEP-0086. +%% We choose '403' error code (as in ). +-spec err_policy_violation() -> error(). +err_policy_violation() -> + err(modify, 'policy-violation', 403). + +-spec err_policy_violation(binary(), binary() | undefined) -> error(). +err_policy_violation(Text, Lang) -> + err(modify, 'policy-violation', 403, Text, Lang). + +-spec err_recipient_unavailable() -> error(). +err_recipient_unavailable() -> + err(wait, 'recipient-unavailable', 404). + +-spec err_recipient_unavailable(binary(), binary() | undefined) -> error(). +err_recipient_unavailable(Text, Lang) -> + err(wait, 'recipient-unavailable', 404, Text, Lang). + +-spec err_redirect() -> error(). +err_redirect() -> + err(modify, 'redirect', 302). + +-spec err_redirect(binary(), binary() | undefined) -> error(). +err_redirect(Text, Lang) -> + err(modify, 'redirect', 302, Text, Lang). + +-spec err_registration_required() -> error(). +err_registration_required() -> + err(auth, 'registration-required', 407). + +-spec err_registration_required(binary(), binary() | undefined) -> error(). +err_registration_required(Text, Lang) -> + err(auth, 'registration-required', 407, Text, Lang). + +-spec err_remote_server_not_found() -> error(). +err_remote_server_not_found() -> + err(cancel, 'remote-server-not-found', 404). + +-spec err_remote_server_not_found(binary(), binary() | undefined) -> error(). +err_remote_server_not_found(Text, Lang) -> + err(cancel, 'remote-server-not-found', 404, Text, Lang). + +-spec err_remote_server_timeout() -> error(). +err_remote_server_timeout() -> + err(wait, 'remote-server-timeout', 504). + +-spec err_remote_server_timeout(binary(), binary() | undefined) -> error(). +err_remote_server_timeout(Text, Lang) -> + err(wait, 'remote-server-timeout', 504, Text, Lang). + +-spec err_resource_constraint() -> error(). +err_resource_constraint() -> + err(wait, 'resource-constraint', 500). + +-spec err_resource_constraint(binary(), binary() | undefined) -> error(). +err_resource_constraint(Text, Lang) -> + err(wait, 'resource-constraint', 500, Text, Lang). + +-spec err_service_unavailable() -> error(). +err_service_unavailable() -> + err(cancel, 'service-unavailable', 503). + +-spec err_service_unavailable(binary(), binary() | undefined) -> error(). +err_service_unavailable(Text, Lang) -> + err(cancel, 'service-unavailable', 503, Text, Lang). + +-spec err_subscription_required() -> error(). +err_subscription_required() -> + err(auth, 'subscription-required', 407). + +-spec err_subscription_required(binary(), binary() | undefined) -> error(). +err_subscription_required(Text, Lang) -> + err(auth, 'subscription-required', 407, Text, Lang). + +%% No error type is defined for . +%% We choose "modify" as it's used in RFC 6120 example. +-spec err_undefined_condition() -> error(). +err_undefined_condition() -> + err(modify, 'undefined-condition', 500). + +-spec err_undefined_condition(binary(), binary() | undefined) -> error(). +err_undefined_condition(Text, Lang) -> + err(modify, 'undefined-condition', 500, Text, Lang). + +%% RFC 6120 says error type SHOULD be "wait" or "modify". +%% RFC 3920 and XEP-0082 says it SHOULD be "wait". +-spec err_unexpected_request() -> error(). +err_unexpected_request() -> + err(wait, 'unexpected-request', 400). + +-spec err_unexpected_request(binary(), binary() | undefined) -> error(). +err_unexpected_request(Text, Lang) -> + err(wait, 'unexpected-request', 400, Text, Lang). + %%%=================================================================== %%% Functions to construct stream errors %%%=================================================================== @@ -712,3 +824,7 @@ add_ns(#xmlel{name = Name} = El) when Name == <<"message">>; El#xmlel{attrs = Attrs}; add_ns(El) -> El. + +-spec match_tag(xmlel() | xmpp_element(), binary(), binary()) -> boolean(). +match_tag(El, TagName, XMLNS) -> + get_name(El) == TagName andalso get_ns(El) == XMLNS. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index f6e5f0f1a..c59c347f9 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,21 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> + decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); + {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> + decode_stanza_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); + {<<"addresses">>, + <<"http://jabber.org/protocol/address">>} -> + decode_addresses(<<"http://jabber.org/protocol/address">>, + IgnoreEls, _el); + {<<"address">>, + <<"http://jabber.org/protocol/address">>} -> + decode_address(<<"http://jabber.org/protocol/address">>, + IgnoreEls, _el); + {<<"nick">>, <<"http://jabber.org/protocol/nick">>} -> + decode_nick(<<"http://jabber.org/protocol/nick">>, + IgnoreEls, _el); {<<"x">>, <<"jabber:x:expire">>} -> decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); {<<"x">>, <<"jabber:x:event">>} -> @@ -53,6 +68,9 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> {<<"instructions">>, <<"jabber:iq:search">>} -> decode_search_instructions(<<"jabber:iq:search">>, IgnoreEls, _el); + {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>} -> + decode_hint_no_permanent_storage(<<"urn:xmpp:hints">>, + IgnoreEls, _el); {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); @@ -160,12 +178,24 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); + {<<"always">>, <<"urn:xmpp:mam:0">>} -> + decode_mam_always(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"always">>, <<"urn:xmpp:mam:1">>} -> + decode_mam_always(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); {<<"always">>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); + {<<"never">>, <<"urn:xmpp:mam:0">>} -> + decode_mam_never(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"never">>, <<"urn:xmpp:mam:1">>} -> + decode_mam_never(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); {<<"never">>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); + {<<"jid">>, <<"urn:xmpp:mam:0">>} -> + decode_mam_jid(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"jid">>, <<"urn:xmpp:mam:1">>} -> + decode_mam_jid(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); {<<"jid">>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_jid(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); {<<"result">>, <<"urn:xmpp:mam:0">>} -> @@ -185,6 +215,9 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> {<<"query">>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); + {<<"withtext">>, <<"urn:xmpp:mam:tmp">>} -> + decode_mam_withtext(<<"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">>} -> @@ -216,6 +249,28 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> {<<"after">>, <<"http://jabber.org/protocol/rsm">>} -> decode_rsm_after(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); + {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_unsubscribe(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, + _el); + {<<"event">>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscriptions(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscription">>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"x">>, <<"jabber:x:conference">>} -> + decode_x_conference(<<"jabber:x:conference">>, + IgnoreEls, _el); + {<<"unique">>, + <<"http://jabber.org/protocol/muc#unique">>} -> + decode_muc_unique(<<"http://jabber.org/protocol/muc#unique">>, + IgnoreEls, _el); {<<"x">>, <<"http://jabber.org/protocol/muc">>} -> decode_muc(<<"http://jabber.org/protocol/muc">>, IgnoreEls, _el); @@ -223,10 +278,6 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); - {<<"reason">>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_admin_reason(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); {<<"continue">>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, @@ -239,22 +290,26 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); + {<<"item">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); {<<"query">>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); - {<<"destroy">>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_owner_destroy(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"reason">>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_owner_reason(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); {<<"password">>, <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_owner_password(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); + decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"password">>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"password">>, + <<"http://jabber.org/protocol/muc">>} -> + decode_muc_password(<<"http://jabber.org/protocol/muc">>, + IgnoreEls, _el); {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); @@ -280,16 +335,28 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls, _el); {<<"destroy">>, <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_destroy(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); + decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); {<<"decline">>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"reason">>, <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> decode_muc_history(<<"http://jabber.org/protocol/muc">>, IgnoreEls, _el); @@ -1002,6 +1069,10 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); + {<<"payment-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); {<<"not-authorized">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, @@ -1183,6 +1254,16 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> true; + {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> true; + {<<"addresses">>, + <<"http://jabber.org/protocol/address">>} -> + true; + {<<"address">>, + <<"http://jabber.org/protocol/address">>} -> + true; + {<<"nick">>, <<"http://jabber.org/protocol/nick">>} -> + true; {<<"x">>, <<"jabber:x:expire">>} -> true; {<<"x">>, <<"jabber:x:event">>} -> true; {<<"id">>, <<"jabber:x:event">>} -> true; @@ -1197,6 +1278,8 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"last">>, <<"jabber:iq:search">>} -> true; {<<"first">>, <<"jabber:iq:search">>} -> true; {<<"instructions">>, <<"jabber:iq:search">>} -> true; + {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>} -> + true; {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> true; {<<"store">>, <<"urn:xmpp:hints">>} -> true; @@ -1248,8 +1331,14 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> true; {<<"prefs">>, <<"urn:xmpp:mam:1">>} -> true; {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"always">>, <<"urn:xmpp:mam:0">>} -> true; + {<<"always">>, <<"urn:xmpp:mam:1">>} -> true; {<<"always">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"never">>, <<"urn:xmpp:mam:0">>} -> true; + {<<"never">>, <<"urn:xmpp:mam:1">>} -> true; {<<"never">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"jid">>, <<"urn:xmpp:mam:0">>} -> true; + {<<"jid">>, <<"urn:xmpp:mam:1">>} -> true; {<<"jid">>, <<"urn:xmpp:mam:tmp">>} -> true; {<<"result">>, <<"urn:xmpp:mam:0">>} -> true; {<<"result">>, <<"urn:xmpp:mam:1">>} -> true; @@ -1258,6 +1347,7 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"query">>, <<"urn:xmpp:mam:0">>} -> true; {<<"query">>, <<"urn:xmpp:mam:1">>} -> true; {<<"query">>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"withtext">>, <<"urn:xmpp:mam:tmp">>} -> true; {<<"with">>, <<"urn:xmpp:mam:tmp">>} -> true; {<<"end">>, <<"urn:xmpp:mam:tmp">>} -> true; {<<"start">>, <<"urn:xmpp:mam:tmp">>} -> true; @@ -1277,13 +1367,19 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> true; {<<"after">>, <<"http://jabber.org/protocol/rsm">>} -> true; + {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"event">>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"subscription">>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"x">>, <<"jabber:x:conference">>} -> true; + {<<"unique">>, + <<"http://jabber.org/protocol/muc#unique">>} -> + true; {<<"x">>, <<"http://jabber.org/protocol/muc">>} -> true; {<<"query">>, <<"http://jabber.org/protocol/muc#admin">>} -> true; - {<<"reason">>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; {<<"continue">>, <<"http://jabber.org/protocol/muc#admin">>} -> true; @@ -1293,17 +1389,20 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"item">>, <<"http://jabber.org/protocol/muc#admin">>} -> true; - {<<"query">>, + {<<"item">>, <<"http://jabber.org/protocol/muc#owner">>} -> true; - {<<"destroy">>, + {<<"query">>, <<"http://jabber.org/protocol/muc#owner">>} -> true; - {<<"reason">>, + {<<"password">>, <<"http://jabber.org/protocol/muc#owner">>} -> true; {<<"password">>, - <<"http://jabber.org/protocol/muc#owner">>} -> + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"password">>, + <<"http://jabber.org/protocol/muc">>} -> true; {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> true; @@ -1325,12 +1424,21 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"destroy">>, <<"http://jabber.org/protocol/muc#user">>} -> true; + {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; {<<"decline">>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"reason">>, <<"http://jabber.org/protocol/muc#user">>} -> true; + {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>} -> + true; + {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>} -> + true; {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> true; {<<"query">>, @@ -1773,6 +1881,9 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"policy-violation">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; + {<<"payment-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> + true; {<<"not-authorized">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; @@ -1914,7 +2025,7 @@ encode({disco_item, _, _, _} = Item) -> encode_disco_item(Item, [{<<"xmlns">>, <<"http://jabber.org/protocol/disco#items">>}]); -encode({disco_items, _, _} = Query) -> +encode({disco_items, _, _, _} = Query) -> encode_disco_items(Query, [{<<"xmlns">>, <<"http://jabber.org/protocol/disco#items">>}]); @@ -2107,6 +2218,9 @@ encode({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, encode({vcard_xupdate, undefined, _} = X) -> encode_vcard_xupdate(X, [{<<"xmlns">>, <<"vcard-temp:x:update">>}]); +encode({xdata_option, _, _} = Option) -> + encode_xdata_field_option(Option, + [{<<"xmlns">>, <<"jabber:x:data">>}]); encode({xdata_field, _, _, _, _, _, _, _} = Field) -> encode_xdata_field(Field, [{<<"xmlns">>, <<"jabber:x:data">>}]); @@ -2206,11 +2320,9 @@ encode({muc_decline, _, _, _} = Decline) -> encode_muc_user_decline(Decline, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_user_destroy, _, _} = Destroy) -> - encode_muc_user_destroy(Destroy, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_invite, _, _, _} = Invite) -> +encode({muc_destroy, _, _, _, _} = Destroy) -> + encode_muc_destroy(Destroy, []); +encode({muc_invite, _, _, _, _} = Invite) -> encode_muc_user_invite(Invite, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc#user">>}]); @@ -2218,11 +2330,7 @@ encode({muc_user, _, _, _, _, _, _} = X) -> encode_muc_user(X, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_owner_destroy, _, _, _} = Destroy) -> - encode_muc_owner_destroy(Destroy, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#owner">>}]); -encode({muc_owner, _, _} = Query) -> +encode({muc_owner, _, _, _} = Query) -> encode_muc_owner(Query, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc#owner">>}]); @@ -2237,13 +2345,29 @@ encode({muc_admin, _} = Query) -> encode({muc, _, _} = X) -> encode_muc(X, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]); +encode({muc_unique, _} = Unique) -> + encode_muc_unique(Unique, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#unique">>}]); +encode({x_conference, _, _, _, _, _} = X) -> + encode_x_conference(X, + [{<<"xmlns">>, <<"jabber:x:conference">>}]); +encode({muc_subscriptions, _} = Subscriptions) -> + encode_muc_subscriptions(Subscriptions, + [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); +encode({muc_subscribe, _, _} = Subscribe) -> + encode_muc_subscribe(Subscribe, + [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); +encode({muc_unsubscribe} = Unsubscribe) -> + encode_muc_unsubscribe(Unsubscribe, + [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); 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_query(Query, []); encode({mam_archived, _, _} = Archived) -> encode_mam_archived(Archived, @@ -2328,6 +2452,10 @@ encode({hint, 'no-permanent-store'} = No_permanent_store) -> encode_hint_no_permanent_store(No_permanent_store, [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); +encode({hint, 'no-permanent-storage'} = + No_permanent_storage) -> + encode_hint_no_permanent_storage(No_permanent_storage, + [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); encode({search_item, _, _, _, _, _} = Item) -> encode_search_item(Item, [{<<"xmlns">>, <<"jabber:iq:search">>}]); @@ -2338,7 +2466,24 @@ encode({xevent, _, _, _, _, _} = X) -> encode_xevent(X, [{<<"xmlns">>, <<"jabber:x:event">>}]); encode({expire, _, _} = X) -> encode_expire(X, - [{<<"xmlns">>, <<"jabber:x:expire">>}]). + [{<<"xmlns">>, <<"jabber:x:expire">>}]); +encode({nick, _} = Nick) -> + encode_nick(Nick, + [{<<"xmlns">>, <<"http://jabber.org/protocol/nick">>}]); +encode({address, _, _, _, _, _} = Address) -> + encode_address(Address, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/address">>}]); +encode({addresses, _} = Addresses) -> + encode_addresses(Addresses, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/address">>}]); +encode({stanza_id, _, _} = Stanza_id) -> + encode_stanza_id(Stanza_id, + [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]); +encode({client_id, _} = Client_id) -> + encode_client_id(Client_id, + [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2355,7 +2500,7 @@ get_name({block_list, _}) -> <<"blocklist">>; get_name({identity, _, _, _, _}) -> <<"identity">>; get_name({disco_info, _, _, _, _}) -> <<"query">>; get_name({disco_item, _, _, _}) -> <<"item">>; -get_name({disco_items, _, _}) -> <<"query">>; +get_name({disco_items, _, _, _}) -> <<"query">>; get_name({private, _}) -> <<"query">>; get_name({bookmark_conference, _, _, _, _, _}) -> <<"conference">>; @@ -2424,6 +2569,7 @@ get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"vCard">>; get_name({vcard_xupdate, undefined, _}) -> <<"x">>; +get_name({xdata_option, _, _}) -> <<"option">>; get_name({xdata_field, _, _, _, _, _, _, _}) -> <<"field">>; get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; @@ -2456,18 +2602,22 @@ get_name({bytestreams, _, _, _, _, _, _}) -> <<"query">>; get_name({muc_history, _, _, _, _}) -> <<"history">>; get_name({muc_decline, _, _, _}) -> <<"decline">>; -get_name({muc_user_destroy, _, _}) -> <<"destroy">>; -get_name({muc_invite, _, _, _}) -> <<"invite">>; +get_name({muc_destroy, _, _, _, _}) -> <<"destroy">>; +get_name({muc_invite, _, _, _, _}) -> <<"invite">>; get_name({muc_user, _, _, _, _, _, _}) -> <<"x">>; -get_name({muc_owner_destroy, _, _, _}) -> <<"destroy">>; -get_name({muc_owner, _, _}) -> <<"query">>; +get_name({muc_owner, _, _, _}) -> <<"query">>; get_name({muc_item, _, _, _, _, _, _, _}) -> <<"item">>; get_name({muc_actor, _, _}) -> <<"actor">>; get_name({muc_admin, _}) -> <<"query">>; get_name({muc, _, _}) -> <<"x">>; +get_name({muc_unique, _}) -> <<"unique">>; +get_name({x_conference, _, _, _, _, _}) -> <<"x">>; +get_name({muc_subscriptions, _}) -> <<"subscriptions">>; +get_name({muc_subscribe, _, _}) -> <<"subscribe">>; +get_name({muc_unsubscribe}) -> <<"unsubscribe">>; get_name({rsm_first, _, _}) -> <<"first">>; get_name({rsm_set, _, _, _, _, _, _, _}) -> <<"set">>; -get_name({mam_query, _, _, _, _, _, _, _}) -> +get_name({mam_query, _, _, _, _, _, _, _, _}) -> <<"query">>; get_name({mam_archived, _, _}) -> <<"archived">>; get_name({mam_result, _, _, _, _}) -> <<"result">>; @@ -2501,10 +2651,17 @@ get_name({hint, 'no-storage'}) -> <<"no-storage">>; get_name({hint, store}) -> <<"store">>; get_name({hint, 'no-permanent-store'}) -> <<"no-permanent-store">>; +get_name({hint, 'no-permanent-storage'}) -> + <<"no-permanent-storage">>; get_name({search_item, _, _, _, _, _}) -> <<"item">>; get_name({search, _, _, _, _, _, _, _}) -> <<"query">>; get_name({xevent, _, _, _, _, _}) -> <<"x">>; -get_name({expire, _, _}) -> <<"x">>. +get_name({expire, _, _}) -> <<"x">>; +get_name({nick, _}) -> <<"nick">>; +get_name({address, _, _, _, _, _}) -> <<"address">>; +get_name({addresses, _}) -> <<"addresses">>; +get_name({stanza_id, _, _}) -> <<"stanza-id">>; +get_name({client_id, _}) -> <<"client-id">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -2527,7 +2684,7 @@ get_ns({disco_info, _, _, _, _}) -> <<"http://jabber.org/protocol/disco#info">>; get_ns({disco_item, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; -get_ns({disco_items, _, _}) -> +get_ns({disco_items, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; get_ns({private, _}) -> <<"jabber:iq:private">>; get_ns({bookmark_conference, _, _, _, _, _}) -> @@ -2624,6 +2781,7 @@ get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, <<"vcard-temp">>; get_ns({vcard_xupdate, undefined, _}) -> <<"vcard-temp:x:update">>; +get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>; get_ns({xdata_field, _, _, _, _, _, _, _}) -> <<"jabber:x:data">>; get_ns({xdata, _, _, _, _, _, _}) -> @@ -2675,25 +2833,32 @@ get_ns({muc_history, _, _, _, _}) -> <<"http://jabber.org/protocol/muc">>; get_ns({muc_decline, _, _, _}) -> <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_user_destroy, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_invite, _, _, _}) -> +get_ns({muc_destroy, Xmlns, _, _, _}) -> Xmlns; +get_ns({muc_invite, _, _, _, _}) -> <<"http://jabber.org/protocol/muc#user">>; get_ns({muc_user, _, _, _, _, _, _}) -> <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_owner_destroy, _, _, _}) -> - <<"http://jabber.org/protocol/muc#owner">>; -get_ns({muc_owner, _, _}) -> +get_ns({muc_owner, _, _, _}) -> <<"http://jabber.org/protocol/muc#owner">>; get_ns({muc_admin, _}) -> <<"http://jabber.org/protocol/muc#admin">>; get_ns({muc, _, _}) -> <<"http://jabber.org/protocol/muc">>; +get_ns({muc_unique, _}) -> + <<"http://jabber.org/protocol/muc#unique">>; +get_ns({x_conference, _, _, _, _, _}) -> + <<"jabber:x:conference">>; +get_ns({muc_subscriptions, _}) -> + <<"urn:xmpp:mucsub:0">>; +get_ns({muc_subscribe, _, _}) -> + <<"urn:xmpp:mucsub:0">>; +get_ns({muc_unsubscribe}) -> <<"urn:xmpp:mucsub:0">>; get_ns({rsm_first, _, _}) -> <<"http://jabber.org/protocol/rsm">>; get_ns({rsm_set, _, _, _, _, _, _, _}) -> <<"http://jabber.org/protocol/rsm">>; -get_ns({mam_query, Xmlns, _, _, _, _, _, _}) -> Xmlns; +get_ns({mam_query, Xmlns, _, _, _, _, _, _, _}) -> + Xmlns; get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; get_ns({mam_result, Xmlns, _, _, _}) -> Xmlns; get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; @@ -2729,12 +2894,22 @@ get_ns({hint, 'no-storage'}) -> <<"urn:xmpp:hints">>; get_ns({hint, store}) -> <<"urn:xmpp:hints">>; get_ns({hint, 'no-permanent-store'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-permanent-storage'}) -> + <<"urn:xmpp:hints">>; get_ns({search_item, _, _, _, _, _}) -> <<"jabber:iq:search">>; get_ns({search, _, _, _, _, _, _, _}) -> <<"jabber:iq:search">>; get_ns({xevent, _, _, _, _, _}) -> <<"jabber:x:event">>; -get_ns({expire, _, _}) -> <<"jabber:x:expire">>. +get_ns({expire, _, _}) -> <<"jabber:x:expire">>; +get_ns({nick, _}) -> + <<"http://jabber.org/protocol/nick">>; +get_ns({address, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/address">>; +get_ns({addresses, _}) -> + <<"http://jabber.org/protocol/address">>; +get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; +get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -2801,7 +2976,7 @@ pp(identity, 4) -> [category, type, lang, name]; pp(disco_info, 4) -> [node, identities, features, xdata]; pp(disco_item, 3) -> [jid, name, node]; -pp(disco_items, 2) -> [node, items]; +pp(disco_items, 3) -> [node, items, rsm]; pp(private, 1) -> [xml_els]; pp(bookmark_conference, 5) -> [name, jid, autojoin, nick, password]; @@ -2876,6 +3051,7 @@ pp(vcard_temp, 29) -> org, categories, note, prodid, rev, sort_string, sound, uid, url, class, key, desc]; pp(vcard_xupdate, 2) -> [us, hash]; +pp(xdata_option, 2) -> [label, value]; pp(xdata_field, 7) -> [label, type, var, required, desc, values, options]; pp(xdata, 6) -> @@ -2905,23 +3081,28 @@ pp(bytestreams, 6) -> pp(muc_history, 4) -> [maxchars, maxstanzas, seconds, since]; pp(muc_decline, 3) -> [reason, from, to]; -pp(muc_user_destroy, 2) -> [reason, jid]; -pp(muc_invite, 3) -> [reason, from, to]; +pp(muc_destroy, 4) -> [xmlns, jid, reason, password]; +pp(muc_invite, 4) -> [reason, from, to, continue]; pp(muc_user, 6) -> [decline, destroy, invites, items, status_codes, password]; -pp(muc_owner_destroy, 3) -> [jid, reason, password]; -pp(muc_owner, 2) -> [destroy, config]; +pp(muc_owner, 3) -> [destroy, config, items]; pp(muc_item, 7) -> [actor, continue, reason, affiliation, role, jid, nick]; pp(muc_actor, 2) -> [jid, nick]; pp(muc_admin, 1) -> [items]; pp(muc, 2) -> [history, password]; +pp(muc_unique, 1) -> [name]; +pp(x_conference, 5) -> + [jid, password, reason, continue, thread]; +pp(muc_subscriptions, 1) -> [list]; +pp(muc_subscribe, 2) -> [nick, events]; +pp(muc_unsubscribe, 0) -> []; 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_query, 8) -> + [xmlns, id, start, 'end', with, withtext, 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]; @@ -2954,6 +3135,11 @@ pp(search, 7) -> pp(xevent, 5) -> [offline, delivered, displayed, composing, id]; pp(expire, 2) -> [seconds, stored]; +pp(nick, 1) -> [name]; +pp(address, 5) -> [type, jid, desc, node, delivered]; +pp(addresses, 1) -> [list]; +pp(stanza_id, 2) -> [by, id]; +pp(client_id, 1) -> [id]; pp(_, _) -> no. join([], _Sep) -> <<>>; @@ -3000,6 +3186,274 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_client_id(__TopXMLNS, __IgnoreEls, + {xmlel, <<"client-id">>, _attrs, _els}) -> + Id = decode_client_id_attrs(__TopXMLNS, _attrs, + undefined), + {client_id, Id}. + +decode_client_id_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id) -> + decode_client_id_attrs(__TopXMLNS, _attrs, _val); +decode_client_id_attrs(__TopXMLNS, [_ | _attrs], Id) -> + decode_client_id_attrs(__TopXMLNS, _attrs, Id); +decode_client_id_attrs(__TopXMLNS, [], Id) -> + decode_client_id_attr_id(__TopXMLNS, Id). + +encode_client_id({client_id, Id}, _xmlns_attrs) -> + _els = [], + _attrs = encode_client_id_attr_id(Id, _xmlns_attrs), + {xmlel, <<"client-id">>, _attrs, _els}. + +decode_client_id_attr_id(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"id">>, <<"client-id">>, __TopXMLNS}}); +decode_client_id_attr_id(__TopXMLNS, _val) -> _val. + +encode_client_id_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_stanza_id(__TopXMLNS, __IgnoreEls, + {xmlel, <<"stanza-id">>, _attrs, _els}) -> + {Id, By} = decode_stanza_id_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {stanza_id, By, Id}. + +decode_stanza_id_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, By) -> + decode_stanza_id_attrs(__TopXMLNS, _attrs, _val, By); +decode_stanza_id_attrs(__TopXMLNS, + [{<<"by">>, _val} | _attrs], Id, _By) -> + decode_stanza_id_attrs(__TopXMLNS, _attrs, Id, _val); +decode_stanza_id_attrs(__TopXMLNS, [_ | _attrs], Id, + By) -> + decode_stanza_id_attrs(__TopXMLNS, _attrs, Id, By); +decode_stanza_id_attrs(__TopXMLNS, [], Id, By) -> + {decode_stanza_id_attr_id(__TopXMLNS, Id), + decode_stanza_id_attr_by(__TopXMLNS, By)}. + +encode_stanza_id({stanza_id, By, Id}, _xmlns_attrs) -> + _els = [], + _attrs = encode_stanza_id_attr_by(By, + encode_stanza_id_attr_id(Id, + _xmlns_attrs)), + {xmlel, <<"stanza-id">>, _attrs, _els}. + +decode_stanza_id_attr_id(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"id">>, <<"stanza-id">>, __TopXMLNS}}); +decode_stanza_id_attr_id(__TopXMLNS, _val) -> _val. + +encode_stanza_id_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_stanza_id_attr_by(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"by">>, <<"stanza-id">>, __TopXMLNS}}); +decode_stanza_id_attr_by(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"by">>, <<"stanza-id">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_stanza_id_attr_by(_val, _acc) -> + [{<<"by">>, enc_jid(_val)} | _acc]. + +decode_addresses(__TopXMLNS, __IgnoreEls, + {xmlel, <<"addresses">>, _attrs, _els}) -> + List = decode_addresses_els(__TopXMLNS, __IgnoreEls, + _els, []), + {addresses, List}. + +decode_addresses_els(__TopXMLNS, __IgnoreEls, [], + List) -> + lists:reverse(List); +decode_addresses_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"address">>, _attrs, _} = _el | _els], + List) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/address">> -> + decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, + [decode_address(__TopXMLNS, __IgnoreEls, _el) + | List]); + <<"http://jabber.org/protocol/address">> -> + decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, + [decode_address(<<"http://jabber.org/protocol/address">>, + __IgnoreEls, _el) + | List]); + _ -> + decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, + List) + end; +decode_addresses_els(__TopXMLNS, __IgnoreEls, + [_ | _els], List) -> + decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, + List). + +encode_addresses({addresses, List}, _xmlns_attrs) -> + _els = lists:reverse('encode_addresses_$list'(List, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"addresses">>, _attrs, _els}. + +'encode_addresses_$list'([], _acc) -> _acc; +'encode_addresses_$list'([List | _els], _acc) -> + 'encode_addresses_$list'(_els, + [encode_address(List, []) | _acc]). + +decode_address(__TopXMLNS, __IgnoreEls, + {xmlel, <<"address">>, _attrs, _els}) -> + {Type, Jid, Desc, Node, Delivered} = + decode_address_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined, undefined), + {address, Type, Jid, Desc, Node, Delivered}. + +decode_address_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], _Type, Jid, Desc, Node, + Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, _val, Jid, + Desc, Node, Delivered); +decode_address_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Type, _Jid, Desc, Node, + Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, Type, _val, + Desc, Node, Delivered); +decode_address_attrs(__TopXMLNS, + [{<<"desc">>, _val} | _attrs], Type, Jid, _Desc, Node, + Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, + _val, Node, Delivered); +decode_address_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Type, Jid, Desc, _Node, + Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, + Desc, _val, Delivered); +decode_address_attrs(__TopXMLNS, + [{<<"delivered">>, _val} | _attrs], Type, Jid, Desc, + Node, _Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, + Desc, Node, _val); +decode_address_attrs(__TopXMLNS, [_ | _attrs], Type, + Jid, Desc, Node, Delivered) -> + decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, + Desc, Node, Delivered); +decode_address_attrs(__TopXMLNS, [], Type, Jid, Desc, + Node, Delivered) -> + {decode_address_attr_type(__TopXMLNS, Type), + decode_address_attr_jid(__TopXMLNS, Jid), + decode_address_attr_desc(__TopXMLNS, Desc), + decode_address_attr_node(__TopXMLNS, Node), + decode_address_attr_delivered(__TopXMLNS, Delivered)}. + +encode_address({address, Type, Jid, Desc, Node, + Delivered}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_address_attr_delivered(Delivered, + encode_address_attr_node(Node, + encode_address_attr_desc(Desc, + encode_address_attr_jid(Jid, + encode_address_attr_type(Type, + _xmlns_attrs))))), + {xmlel, <<"address">>, _attrs, _els}. + +decode_address_attr_type(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"address">>, __TopXMLNS}}); +decode_address_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [bcc, cc, noreply, ofrom, replyroom, replyto, to]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"address">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_address_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_address_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_address_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"address">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_address_attr_jid(undefined, _acc) -> _acc; +encode_address_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_address_attr_desc(__TopXMLNS, undefined) -> + undefined; +decode_address_attr_desc(__TopXMLNS, _val) -> _val. + +encode_address_attr_desc(undefined, _acc) -> _acc; +encode_address_attr_desc(_val, _acc) -> + [{<<"desc">>, _val} | _acc]. + +decode_address_attr_node(__TopXMLNS, undefined) -> + undefined; +decode_address_attr_node(__TopXMLNS, _val) -> _val. + +encode_address_attr_node(undefined, _acc) -> _acc; +encode_address_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_address_attr_delivered(__TopXMLNS, undefined) -> + undefined; +decode_address_attr_delivered(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"delivered">>, <<"address">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_address_attr_delivered(undefined, _acc) -> _acc; +encode_address_attr_delivered(_val, _acc) -> + [{<<"delivered">>, enc_bool(_val)} | _acc]. + +decode_nick(__TopXMLNS, __IgnoreEls, + {xmlel, <<"nick">>, _attrs, _els}) -> + Name = decode_nick_els(__TopXMLNS, __IgnoreEls, _els, + <<>>), + {nick, Name}. + +decode_nick_els(__TopXMLNS, __IgnoreEls, [], Name) -> + decode_nick_cdata(__TopXMLNS, Name); +decode_nick_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Name) -> + decode_nick_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_nick_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Name) -> + decode_nick_els(__TopXMLNS, __IgnoreEls, _els, Name). + +encode_nick({nick, Name}, _xmlns_attrs) -> + _els = encode_nick_cdata(Name, []), + _attrs = _xmlns_attrs, + {xmlel, <<"nick">>, _attrs, _els}. + +decode_nick_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"nick">>, __TopXMLNS}}); +decode_nick_cdata(__TopXMLNS, _val) -> _val. + +encode_nick_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + decode_expire(__TopXMLNS, __IgnoreEls, {xmlel, <<"x">>, _attrs, _els}) -> {Seconds, Stored} = decode_expire_attrs(__TopXMLNS, @@ -3745,6 +4199,19 @@ encode_search_instructions_cdata(undefined, _acc) -> encode_search_instructions_cdata(_val, _acc) -> [{xmlcdata, _val} | _acc]. +decode_hint_no_permanent_storage(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"no-permanent-storage">>, _attrs, + _els}) -> + {hint, 'no-permanent-storage'}. + +encode_hint_no_permanent_storage({hint, + 'no-permanent-storage'}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"no-permanent-storage">>, _attrs, _els}. + decode_hint_no_permanent_store(__TopXMLNS, __IgnoreEls, {xmlel, <<"no-permanent-store">>, _attrs, _els}) -> @@ -5380,7 +5847,8 @@ encode_mam_fin_attr_complete(_val, _acc) -> decode_mam_prefs(__TopXMLNS, __IgnoreEls, {xmlel, <<"prefs">>, _attrs, _els}) -> {Never, Always} = decode_mam_prefs_els(__TopXMLNS, - __IgnoreEls, _els, [], []), + __IgnoreEls, _els, undefined, + undefined), {Default, Xmlns} = decode_mam_prefs_attrs(__TopXMLNS, _attrs, undefined, undefined), {mam_prefs, Xmlns, Default, Always, Never}. @@ -5392,10 +5860,23 @@ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"always">>, _attrs, _} = _el | _els], Never, Always) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + <<"">> + when __TopXMLNS == <<"urn:xmpp:mam:1">>; + __TopXMLNS == <<"urn:xmpp:mam:0">>; + __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, Never, decode_mam_always(__TopXMLNS, __IgnoreEls, _el)); + <<"urn:xmpp:mam:0">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + Never, + decode_mam_always(<<"urn:xmpp:mam:0">>, + __IgnoreEls, _el)); + <<"urn:xmpp:mam:1">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + Never, + decode_mam_always(<<"urn:xmpp:mam:1">>, + __IgnoreEls, _el)); <<"urn:xmpp:mam:tmp">> -> decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, Never, @@ -5409,10 +5890,23 @@ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"never">>, _attrs, _} = _el | _els], Never, Always) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + <<"">> + when __TopXMLNS == <<"urn:xmpp:mam:1">>; + __TopXMLNS == <<"urn:xmpp:mam:0">>; + __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, decode_mam_never(__TopXMLNS, __IgnoreEls, _el), Always); + <<"urn:xmpp:mam:0">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + decode_mam_never(<<"urn:xmpp:mam:0">>, + __IgnoreEls, _el), + Always); + <<"urn:xmpp:mam:1">> -> + decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, + decode_mam_never(<<"urn:xmpp:mam:1">>, + __IgnoreEls, _el), + Always); <<"urn:xmpp:mam:tmp">> -> decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, decode_mam_never(<<"urn:xmpp:mam:tmp">>, @@ -5454,11 +5948,11 @@ encode_mam_prefs({mam_prefs, Xmlns, Default, Always, _xmlns_attrs)), {xmlel, <<"prefs">>, _attrs, _els}. -'encode_mam_prefs_$never'([], _acc) -> _acc; +'encode_mam_prefs_$never'(undefined, _acc) -> _acc; 'encode_mam_prefs_$never'(Never, _acc) -> [encode_mam_never(Never, []) | _acc]. -'encode_mam_prefs_$always'([], _acc) -> _acc; +'encode_mam_prefs_$always'(undefined, _acc) -> _acc; 'encode_mam_prefs_$always'(Always, _acc) -> [encode_mam_always(Always, []) | _acc]. @@ -5497,12 +5991,31 @@ decode_mam_always_els(__TopXMLNS, __IgnoreEls, [], decode_mam_always_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jids) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + <<"">> + when __TopXMLNS == <<"urn:xmpp:mam:1">>; + __TopXMLNS == <<"urn:xmpp:mam:0">>; + __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, case decode_mam_jid(__TopXMLNS, __IgnoreEls, _el) of - [] -> Jids; + undefined -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:0">> -> + decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:0">>, + __IgnoreEls, _el) + of + undefined -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:1">> -> + decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:1">>, + __IgnoreEls, _el) + of + undefined -> Jids; _new_el -> [_new_el | Jids] end); <<"urn:xmpp:mam:tmp">> -> @@ -5510,7 +6023,7 @@ decode_mam_always_els(__TopXMLNS, __IgnoreEls, case decode_mam_jid(<<"urn:xmpp:mam:tmp">>, __IgnoreEls, _el) of - [] -> Jids; + undefined -> Jids; _new_el -> [_new_el | Jids] end); _ -> @@ -5545,11 +6058,30 @@ decode_mam_never_els(__TopXMLNS, __IgnoreEls, [], decode_mam_never_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jids) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + <<"">> + when __TopXMLNS == <<"urn:xmpp:mam:1">>; + __TopXMLNS == <<"urn:xmpp:mam:0">>; + __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, case decode_mam_jid(__TopXMLNS, __IgnoreEls, _el) of - [] -> Jids; + undefined -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:0">> -> + decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:0">>, + __IgnoreEls, _el) + of + undefined -> Jids; + _new_el -> [_new_el | Jids] + end); + <<"urn:xmpp:mam:1">> -> + decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, + case decode_mam_jid(<<"urn:xmpp:mam:1">>, + __IgnoreEls, _el) + of + undefined -> Jids; _new_el -> [_new_el | Jids] end); <<"urn:xmpp:mam:tmp">> -> @@ -5557,7 +6089,7 @@ decode_mam_never_els(__TopXMLNS, __IgnoreEls, case decode_mam_jid(<<"urn:xmpp:mam:tmp">>, __IgnoreEls, _el) of - [] -> Jids; + undefined -> Jids; _new_el -> [_new_el | Jids] end); _ -> @@ -5759,104 +6291,125 @@ encode_mam_archived_attr_by(_val, _acc) -> decode_mam_query(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> - {Xdata, End, Start, With, Rsm} = + {Xdata, Withtext, End, Start, With, Rsm} = decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, undefined, undefined, undefined, undefined, - undefined), + undefined, undefined), {Id, Xmlns} = decode_mam_query_attrs(__TopXMLNS, _attrs, undefined, undefined), - {mam_query, Xmlns, Id, Start, End, With, Rsm, Xdata}. + {mam_query, Xmlns, Id, Start, End, With, Withtext, Rsm, + Xdata}. decode_mam_query_els(__TopXMLNS, __IgnoreEls, [], Xdata, - End, Start, With, Rsm) -> - {Xdata, End, Start, With, Rsm}; + Withtext, End, Start, With, Rsm) -> + {Xdata, Withtext, End, Start, With, Rsm}; decode_mam_query_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"start">>, _attrs, _} = _el | _els], Xdata, - End, Start, With, Rsm) -> + Withtext, End, Start, With, Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, + Xdata, Withtext, End, decode_mam_start(__TopXMLNS, __IgnoreEls, _el), With, Rsm); <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, + Xdata, Withtext, End, decode_mam_start(<<"urn:xmpp:mam:tmp">>, __IgnoreEls, _el), With, Rsm); _ -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm) + Xdata, Withtext, End, Start, With, Rsm) end; decode_mam_query_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"end">>, _attrs, _} = _el | _els], Xdata, - End, Start, With, Rsm) -> + Withtext, End, Start, With, Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, + Xdata, Withtext, decode_mam_end(__TopXMLNS, __IgnoreEls, _el), Start, With, Rsm); <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, + Xdata, Withtext, decode_mam_end(<<"urn:xmpp:mam:tmp">>, __IgnoreEls, _el), Start, With, Rsm); _ -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm) + Xdata, Withtext, End, Start, With, Rsm) end; decode_mam_query_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"with">>, _attrs, _} = _el | _els], Xdata, - End, Start, With, Rsm) -> + Withtext, End, Start, With, Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, + Xdata, Withtext, End, Start, decode_mam_with(__TopXMLNS, __IgnoreEls, _el), Rsm); <<"urn:xmpp:mam:tmp">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, + Xdata, Withtext, End, Start, decode_mam_with(<<"urn:xmpp:mam:tmp">>, __IgnoreEls, _el), Rsm); _ -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm) + Xdata, Withtext, End, Start, With, Rsm) + end; +decode_mam_query_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"withtext">>, _attrs, _} = _el | _els], + Xdata, Withtext, End, Start, With, Rsm) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + decode_mam_withtext(__TopXMLNS, __IgnoreEls, + _el), + End, Start, With, Rsm); + <<"urn:xmpp:mam:tmp">> -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, + __IgnoreEls, _el), + End, Start, With, Rsm); + _ -> + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Withtext, End, Start, With, Rsm) end; decode_mam_query_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"set">>, _attrs, _} = _el | _els], Xdata, - End, Start, With, Rsm) -> + Withtext, End, Start, With, Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"http://jabber.org/protocol/rsm">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, + Xdata, Withtext, End, Start, With, decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, __IgnoreEls, _el)); _ -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm) + Xdata, Withtext, End, Start, With, Rsm) end; decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, End, - Start, With, Rsm) -> + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, + Withtext, End, Start, With, Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"jabber:x:data">> -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, decode_xdata(<<"jabber:x:data">>, __IgnoreEls, _el), - End, Start, With, Rsm); + Withtext, End, Start, With, Rsm); _ -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm) + Xdata, Withtext, End, Start, With, Rsm) end; decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata, End, Start, With, Rsm) -> + [_ | _els], Xdata, Withtext, End, Start, With, Rsm) -> decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, End, Start, With, Rsm). + Xdata, Withtext, End, Start, With, Rsm). decode_mam_query_attrs(__TopXMLNS, [{<<"queryid">>, _val} | _attrs], _Id, Xmlns) -> @@ -5872,14 +6425,15 @@ decode_mam_query_attrs(__TopXMLNS, [], Id, Xmlns) -> decode_mam_query_attr_xmlns(__TopXMLNS, Xmlns)}. encode_mam_query({mam_query, Xmlns, Id, Start, End, - With, Rsm, Xdata}, + With, Withtext, 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, - [])))))), + 'encode_mam_query_$withtext'(Withtext, + '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)), @@ -5891,6 +6445,10 @@ encode_mam_query({mam_query, Xmlns, Id, Start, End, [{<<"xmlns">>, <<"jabber:x:data">>}]) | _acc]. +'encode_mam_query_$withtext'(undefined, _acc) -> _acc; +'encode_mam_query_$withtext'(Withtext, _acc) -> + [encode_mam_withtext(Withtext, []) | _acc]. + 'encode_mam_query_$end'(undefined, _acc) -> _acc; 'encode_mam_query_$end'(End, _acc) -> [encode_mam_end(End, []) | _acc]. @@ -5925,6 +6483,37 @@ encode_mam_query_attr_xmlns(undefined, _acc) -> _acc; encode_mam_query_attr_xmlns(_val, _acc) -> [{<<"xmlns">>, _val} | _acc]. +decode_mam_withtext(__TopXMLNS, __IgnoreEls, + {xmlel, <<"withtext">>, _attrs, _els}) -> + Cdata = decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_mam_withtext_cdata(__TopXMLNS, Cdata); +decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_mam_withtext(Cdata, _xmlns_attrs) -> + _els = encode_mam_withtext_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"withtext">>, _attrs, _els}. + +decode_mam_withtext_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"withtext">>, __TopXMLNS}}); +decode_mam_withtext_cdata(__TopXMLNS, _val) -> _val. + +encode_mam_withtext_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + decode_mam_with(__TopXMLNS, __IgnoreEls, {xmlel, <<"with">>, _attrs, _els}) -> Cdata = decode_mam_with_els(__TopXMLNS, __IgnoreEls, @@ -6455,10 +7044,10 @@ encode_rsm_before(Cdata, _xmlns_attrs) -> _attrs = _xmlns_attrs, {xmlel, <<"before">>, _attrs, _els}. -decode_rsm_before_cdata(__TopXMLNS, <<>>) -> none; +decode_rsm_before_cdata(__TopXMLNS, <<>>) -> <<>>; decode_rsm_before_cdata(__TopXMLNS, _val) -> _val. -encode_rsm_before_cdata(none, _acc) -> _acc; +encode_rsm_before_cdata(<<>>, _acc) -> _acc; encode_rsm_before_cdata(_val, _acc) -> [{xmlcdata, _val} | _acc]. @@ -6492,63 +7081,438 @@ 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, - undefined), - Password = decode_muc_attrs(__TopXMLNS, _attrs, - undefined), - {muc, History, Password}. +decode_muc_unsubscribe(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unsubscribe">>, _attrs, _els}) -> + {muc_unsubscribe}. -decode_muc_els(__TopXMLNS, __IgnoreEls, [], History) -> - History; +encode_muc_unsubscribe({muc_unsubscribe}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsubscribe">>, _attrs, _els}. + +decode_muc_subscribe(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscribe">>, _attrs, _els}) -> + Events = decode_muc_subscribe_els(__TopXMLNS, + __IgnoreEls, _els, []), + Nick = decode_muc_subscribe_attrs(__TopXMLNS, _attrs, + undefined), + {muc_subscribe, Nick, Events}. + +decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, [], + Events) -> + lists:reverse(Events); +decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"event">>, _attrs, _} = _el | _els], + Events) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mucsub:0">> -> + decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_subscribe_event(__TopXMLNS, + __IgnoreEls, _el) + | Events]); + <<"urn:xmpp:mucsub:0">> -> + decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, + __IgnoreEls, _el) + | Events]); + _ -> + decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, + Events) + end; +decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Events) -> + decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, + Events). + +decode_muc_subscribe_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], _Nick) -> + decode_muc_subscribe_attrs(__TopXMLNS, _attrs, _val); +decode_muc_subscribe_attrs(__TopXMLNS, [_ | _attrs], + Nick) -> + decode_muc_subscribe_attrs(__TopXMLNS, _attrs, Nick); +decode_muc_subscribe_attrs(__TopXMLNS, [], Nick) -> + decode_muc_subscribe_attr_nick(__TopXMLNS, Nick). + +encode_muc_subscribe({muc_subscribe, Nick, Events}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_subscribe_$events'(Events, + [])), + _attrs = encode_muc_subscribe_attr_nick(Nick, + _xmlns_attrs), + {xmlel, <<"subscribe">>, _attrs, _els}. + +'encode_muc_subscribe_$events'([], _acc) -> _acc; +'encode_muc_subscribe_$events'([Events | _els], _acc) -> + 'encode_muc_subscribe_$events'(_els, + [encode_muc_subscribe_event(Events, []) + | _acc]). + +decode_muc_subscribe_attr_nick(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"nick">>, <<"subscribe">>, + __TopXMLNS}}); +decode_muc_subscribe_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_subscribe_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + +decode_muc_subscribe_event(__TopXMLNS, __IgnoreEls, + {xmlel, <<"event">>, _attrs, _els}) -> + Node = decode_muc_subscribe_event_attrs(__TopXMLNS, + _attrs, undefined), + Node. + +decode_muc_subscribe_event_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_muc_subscribe_event_attrs(__TopXMLNS, _attrs, + _val); +decode_muc_subscribe_event_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_muc_subscribe_event_attrs(__TopXMLNS, _attrs, + Node); +decode_muc_subscribe_event_attrs(__TopXMLNS, [], + Node) -> + decode_muc_subscribe_event_attr_node(__TopXMLNS, Node). + +encode_muc_subscribe_event(Node, _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_subscribe_event_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"event">>, _attrs, _els}. + +decode_muc_subscribe_event_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"event">>, __TopXMLNS}}); +decode_muc_subscribe_event_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_muc_subscribe_event_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_muc_subscriptions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscriptions">>, _attrs, _els}) -> + List = decode_muc_subscriptions_els(__TopXMLNS, + __IgnoreEls, _els, []), + {muc_subscriptions, List}. + +decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + [], List) -> + lists:reverse(List); +decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscription">>, _attrs, _} = _el + | _els], + List) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:mucsub:0">> -> + decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + case decode_muc_subscription(__TopXMLNS, + __IgnoreEls, + _el) + of + undefined -> List; + _new_el -> [_new_el | List] + end); + <<"urn:xmpp:mucsub:0">> -> + decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + case + decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, + __IgnoreEls, + _el) + of + undefined -> List; + _new_el -> [_new_el | List] + end); + _ -> + decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, List) + end; +decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + [_ | _els], List) -> + decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, List). + +encode_muc_subscriptions({muc_subscriptions, List}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_subscriptions_$list'(List, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"subscriptions">>, _attrs, _els}. + +'encode_muc_subscriptions_$list'([], _acc) -> _acc; +'encode_muc_subscriptions_$list'([List | _els], _acc) -> + 'encode_muc_subscriptions_$list'(_els, + [encode_muc_subscription(List, []) + | _acc]). + +decode_muc_subscription(__TopXMLNS, __IgnoreEls, + {xmlel, <<"subscription">>, _attrs, _els}) -> + Jid = decode_muc_subscription_attrs(__TopXMLNS, _attrs, + undefined), + Jid. + +decode_muc_subscription_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid) -> + decode_muc_subscription_attrs(__TopXMLNS, _attrs, _val); +decode_muc_subscription_attrs(__TopXMLNS, [_ | _attrs], + Jid) -> + decode_muc_subscription_attrs(__TopXMLNS, _attrs, Jid); +decode_muc_subscription_attrs(__TopXMLNS, [], Jid) -> + decode_muc_subscription_attr_jid(__TopXMLNS, Jid). + +encode_muc_subscription(Jid, _xmlns_attrs) -> + _els = [], + _attrs = encode_muc_subscription_attr_jid(Jid, + _xmlns_attrs), + {xmlel, <<"subscription">>, _attrs, _els}. + +decode_muc_subscription_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"subscription">>, + __TopXMLNS}}); +decode_muc_subscription_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"subscription">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_subscription_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_x_conference(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Jid, Password, Reason, Thread, Continue} = + decode_x_conference_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined, undefined), + {x_conference, Jid, Password, Reason, Continue, Thread}. + +decode_x_conference_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Password, Reason, + Thread, Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, _val, + Password, Reason, Thread, Continue); +decode_x_conference_attrs(__TopXMLNS, + [{<<"password">>, _val} | _attrs], Jid, _Password, + Reason, Thread, Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, _val, + Reason, Thread, Continue); +decode_x_conference_attrs(__TopXMLNS, + [{<<"reason">>, _val} | _attrs], Jid, Password, + _Reason, Thread, Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, + Password, _val, Thread, Continue); +decode_x_conference_attrs(__TopXMLNS, + [{<<"thread">>, _val} | _attrs], Jid, Password, + Reason, _Thread, Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, + Password, Reason, _val, Continue); +decode_x_conference_attrs(__TopXMLNS, + [{<<"continue">>, _val} | _attrs], Jid, Password, + Reason, Thread, _Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, + Password, Reason, Thread, _val); +decode_x_conference_attrs(__TopXMLNS, [_ | _attrs], Jid, + Password, Reason, Thread, Continue) -> + decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, + Password, Reason, Thread, Continue); +decode_x_conference_attrs(__TopXMLNS, [], Jid, Password, + Reason, Thread, Continue) -> + {decode_x_conference_attr_jid(__TopXMLNS, Jid), + decode_x_conference_attr_password(__TopXMLNS, Password), + decode_x_conference_attr_reason(__TopXMLNS, Reason), + decode_x_conference_attr_thread(__TopXMLNS, Thread), + decode_x_conference_attr_continue(__TopXMLNS, + Continue)}. + +encode_x_conference({x_conference, Jid, Password, + Reason, Continue, Thread}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_x_conference_attr_continue(Continue, + encode_x_conference_attr_thread(Thread, + encode_x_conference_attr_reason(Reason, + encode_x_conference_attr_password(Password, + encode_x_conference_attr_jid(Jid, + _xmlns_attrs))))), + {xmlel, <<"x">>, _attrs, _els}. + +decode_x_conference_attr_jid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"x">>, __TopXMLNS}}); +decode_x_conference_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"x">>, __TopXMLNS}}); + _res -> _res + end. + +encode_x_conference_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_x_conference_attr_password(__TopXMLNS, + undefined) -> + <<>>; +decode_x_conference_attr_password(__TopXMLNS, _val) -> + _val. + +encode_x_conference_attr_password(<<>>, _acc) -> _acc; +encode_x_conference_attr_password(_val, _acc) -> + [{<<"password">>, _val} | _acc]. + +decode_x_conference_attr_reason(__TopXMLNS, + undefined) -> + <<>>; +decode_x_conference_attr_reason(__TopXMLNS, _val) -> + _val. + +encode_x_conference_attr_reason(<<>>, _acc) -> _acc; +encode_x_conference_attr_reason(_val, _acc) -> + [{<<"reason">>, _val} | _acc]. + +decode_x_conference_attr_thread(__TopXMLNS, + undefined) -> + <<>>; +decode_x_conference_attr_thread(__TopXMLNS, _val) -> + _val. + +encode_x_conference_attr_thread(<<>>, _acc) -> _acc; +encode_x_conference_attr_thread(_val, _acc) -> + [{<<"thread">>, _val} | _acc]. + +decode_x_conference_attr_continue(__TopXMLNS, + undefined) -> + undefined; +decode_x_conference_attr_continue(__TopXMLNS, _val) -> + case catch dec_bool(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"continue">>, <<"x">>, __TopXMLNS}}); + _res -> _res + end. + +encode_x_conference_attr_continue(undefined, _acc) -> + _acc; +encode_x_conference_attr_continue(_val, _acc) -> + [{<<"continue">>, enc_bool(_val)} | _acc]. + +decode_muc_unique(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unique">>, _attrs, _els}) -> + Name = decode_muc_unique_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {muc_unique, Name}. + +decode_muc_unique_els(__TopXMLNS, __IgnoreEls, [], + Name) -> + decode_muc_unique_cdata(__TopXMLNS, Name); +decode_muc_unique_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Name) -> + decode_muc_unique_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_muc_unique_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Name) -> + decode_muc_unique_els(__TopXMLNS, __IgnoreEls, _els, + Name). + +encode_muc_unique({muc_unique, Name}, _xmlns_attrs) -> + _els = encode_muc_unique_cdata(Name, []), + _attrs = _xmlns_attrs, + {xmlel, <<"unique">>, _attrs, _els}. + +decode_muc_unique_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_muc_unique_cdata(__TopXMLNS, _val) -> _val. + +encode_muc_unique_cdata(<<>>, _acc) -> _acc; +encode_muc_unique_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Password, History} = decode_muc_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined), + {muc, History, Password}. + +decode_muc_els(__TopXMLNS, __IgnoreEls, [], Password, + History) -> + {Password, History}; decode_muc_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"history">>, _attrs, _} = _el | _els], - History) -> + Password, History) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, decode_muc_history(__TopXMLNS, __IgnoreEls, _el)); <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, decode_muc_history(<<"http://jabber.org/protocol/muc">>, __IgnoreEls, _el)); _ -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, History) + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, + History) + end; +decode_muc_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], + Password, History) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(__TopXMLNS, __IgnoreEls, _el), + History); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el), + History); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + History); + <<"http://jabber.org/protocol/muc">> -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc">>, + __IgnoreEls, _el), + History); + _ -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, + History) end; decode_muc_els(__TopXMLNS, __IgnoreEls, [_ | _els], - History) -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, History). - -decode_muc_attrs(__TopXMLNS, - [{<<"password">>, _val} | _attrs], _Password) -> - decode_muc_attrs(__TopXMLNS, _attrs, _val); -decode_muc_attrs(__TopXMLNS, [_ | _attrs], Password) -> - decode_muc_attrs(__TopXMLNS, _attrs, Password); -decode_muc_attrs(__TopXMLNS, [], Password) -> - decode_muc_attr_password(__TopXMLNS, Password). + Password, History) -> + decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, + History). encode_muc({muc, History, Password}, _xmlns_attrs) -> - _els = lists:reverse('encode_muc_$history'(History, - [])), - _attrs = encode_muc_attr_password(Password, - _xmlns_attrs), + _els = lists:reverse('encode_muc_$password'(Password, + 'encode_muc_$history'(History, + []))), + _attrs = _xmlns_attrs, {xmlel, <<"x">>, _attrs, _els}. +'encode_muc_$password'(undefined, _acc) -> _acc; +'encode_muc_$password'(Password, _acc) -> + [encode_muc_password(Password, []) | _acc]. + 'encode_muc_$history'(undefined, _acc) -> _acc; 'encode_muc_$history'(History, _acc) -> [encode_muc_history(History, []) | _acc]. -decode_muc_attr_password(__TopXMLNS, undefined) -> - undefined; -decode_muc_attr_password(__TopXMLNS, _val) -> _val. - -encode_muc_attr_password(undefined, _acc) -> _acc; -encode_muc_attr_password(_val, _acc) -> - [{<<"password">>, _val} | _acc]. - decode_muc_admin(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> Items = decode_muc_admin_els(__TopXMLNS, __IgnoreEls, @@ -6593,37 +7557,6 @@ encode_muc_admin({muc_admin, Items}, _xmlns_attrs) -> 'encode_muc_admin_$items'(_els, [encode_muc_admin_item(Items, []) | _acc]). -decode_muc_admin_reason(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reason">>, _attrs, _els}) -> - Cdata = decode_muc_admin_reason_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_muc_admin_reason_cdata(__TopXMLNS, Cdata); -decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_admin_reason_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_muc_admin_reason(Cdata, _xmlns_attrs) -> - _els = encode_muc_admin_reason_cdata(Cdata, []), - _attrs = _xmlns_attrs, - {xmlel, <<"reason">>, _attrs, _els}. - -decode_muc_admin_reason_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_muc_admin_reason_cdata(__TopXMLNS, _val) -> _val. - -encode_muc_admin_reason_cdata(undefined, _acc) -> _acc; -encode_muc_admin_reason_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - decode_muc_admin_continue(__TopXMLNS, __IgnoreEls, {xmlel, <<"continue">>, _attrs, _els}) -> Thread = decode_muc_admin_continue_attrs(__TopXMLNS, @@ -6724,7 +7657,7 @@ decode_muc_admin_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> {Actor, Continue, Reason} = decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined), + undefined, undefined, <<>>), {Affiliation, Role, Jid, Nick} = decode_muc_admin_item_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined), @@ -6785,13 +7718,23 @@ decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, <<"http://jabber.org/protocol/muc#admin">> -> decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, - decode_muc_admin_reason(__TopXMLNS, - __IgnoreEls, _el)); + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); <<"http://jabber.org/protocol/muc#admin">> -> decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, - decode_muc_admin_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); _ -> decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, Reason) @@ -6857,10 +7800,9 @@ encode_muc_admin_item({muc_item, Actor, Continue, 'encode_muc_admin_item_$continue'(Continue, _acc) -> [encode_muc_admin_continue(Continue, []) | _acc]. -'encode_muc_admin_item_$reason'(undefined, _acc) -> - _acc; +'encode_muc_admin_item_$reason'(<<>>, _acc) -> _acc; 'encode_muc_admin_item_$reason'(Reason, _acc) -> - [encode_muc_admin_reason(Reason, []) | _acc]. + [encode_muc_reason(Reason, []) | _acc]. decode_muc_admin_item_attr_affiliation(__TopXMLNS, undefined) -> @@ -6926,306 +7868,446 @@ encode_muc_admin_item_attr_nick(undefined, _acc) -> encode_muc_admin_item_attr_nick(_val, _acc) -> [{<<"nick">>, _val} | _acc]. +decode_muc_owner_item(__TopXMLNS, __IgnoreEls, + {xmlel, <<"item">>, _attrs, _els}) -> + {Actor, Continue, Reason} = + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, <<>>), + {Affiliation, Role, Jid, Nick} = + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, undefined), + {muc_item, Actor, Continue, Reason, Affiliation, Role, + Jid, Nick}. + +decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, [], + Actor, Continue, Reason) -> + {Actor, Continue, Reason}; +decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, + Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el), + Continue, Reason); + _ -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"continue">>, _attrs, _} = _el | _els], + Actor, Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, + decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el), + Reason); + _ -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Actor, Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); + _ -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason) + end; +decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Actor, Continue, Reason) -> + decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, Reason). + +decode_muc_owner_item_attrs(__TopXMLNS, + [{<<"affiliation">>, _val} | _attrs], _Affiliation, + Role, Jid, Nick) -> + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, _val, + Role, Jid, Nick); +decode_muc_owner_item_attrs(__TopXMLNS, + [{<<"role">>, _val} | _attrs], Affiliation, _Role, + Jid, Nick) -> + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, + Affiliation, _val, Jid, Nick); +decode_muc_owner_item_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Affiliation, Role, + _Jid, Nick) -> + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, _val, Nick); +decode_muc_owner_item_attrs(__TopXMLNS, + [{<<"nick">>, _val} | _attrs], Affiliation, Role, + Jid, _Nick) -> + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, _val); +decode_muc_owner_item_attrs(__TopXMLNS, [_ | _attrs], + Affiliation, Role, Jid, Nick) -> + decode_muc_owner_item_attrs(__TopXMLNS, _attrs, + Affiliation, Role, Jid, Nick); +decode_muc_owner_item_attrs(__TopXMLNS, [], Affiliation, + Role, Jid, Nick) -> + {decode_muc_owner_item_attr_affiliation(__TopXMLNS, + Affiliation), + decode_muc_owner_item_attr_role(__TopXMLNS, Role), + decode_muc_owner_item_attr_jid(__TopXMLNS, Jid), + decode_muc_owner_item_attr_nick(__TopXMLNS, Nick)}. + +encode_muc_owner_item({muc_item, Actor, Continue, + Reason, Affiliation, Role, Jid, Nick}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_muc_owner_item_$actor'(Actor, + 'encode_muc_owner_item_$continue'(Continue, + 'encode_muc_owner_item_$reason'(Reason, + [])))), + _attrs = encode_muc_owner_item_attr_nick(Nick, + encode_muc_owner_item_attr_jid(Jid, + encode_muc_owner_item_attr_role(Role, + encode_muc_owner_item_attr_affiliation(Affiliation, + _xmlns_attrs)))), + {xmlel, <<"item">>, _attrs, _els}. + +'encode_muc_owner_item_$actor'(undefined, _acc) -> _acc; +'encode_muc_owner_item_$actor'(Actor, _acc) -> + [encode_muc_admin_actor(Actor, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#admin">>}]) + | _acc]. + +'encode_muc_owner_item_$continue'(undefined, _acc) -> + _acc; +'encode_muc_owner_item_$continue'(Continue, _acc) -> + [encode_muc_admin_continue(Continue, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/muc#admin">>}]) + | _acc]. + +'encode_muc_owner_item_$reason'(<<>>, _acc) -> _acc; +'encode_muc_owner_item_$reason'(Reason, _acc) -> + [encode_muc_reason(Reason, []) | _acc]. + +decode_muc_owner_item_attr_affiliation(__TopXMLNS, + undefined) -> + undefined; +decode_muc_owner_item_attr_affiliation(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [admin, member, none, outcast, owner]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"affiliation">>, <<"item">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_muc_owner_item_attr_affiliation(undefined, + _acc) -> + _acc; +encode_muc_owner_item_attr_affiliation(_val, _acc) -> + [{<<"affiliation">>, enc_enum(_val)} | _acc]. + +decode_muc_owner_item_attr_role(__TopXMLNS, + undefined) -> + undefined; +decode_muc_owner_item_attr_role(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [moderator, none, participant, visitor]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_owner_item_attr_role(undefined, _acc) -> + _acc; +encode_muc_owner_item_attr_role(_val, _acc) -> + [{<<"role">>, enc_enum(_val)} | _acc]. + +decode_muc_owner_item_attr_jid(__TopXMLNS, undefined) -> + undefined; +decode_muc_owner_item_attr_jid(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); + _res -> _res + end. + +encode_muc_owner_item_attr_jid(undefined, _acc) -> _acc; +encode_muc_owner_item_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_muc_owner_item_attr_nick(__TopXMLNS, + undefined) -> + undefined; +decode_muc_owner_item_attr_nick(__TopXMLNS, _val) -> + _val. + +encode_muc_owner_item_attr_nick(undefined, _acc) -> + _acc; +encode_muc_owner_item_attr_nick(_val, _acc) -> + [{<<"nick">>, _val} | _acc]. + decode_muc_owner(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> - {Config, Destroy} = decode_muc_owner_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - {muc_owner, Destroy, Config}. + {Items, Config, Destroy} = + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, [], + undefined, undefined), + {muc_owner, Destroy, Config, Items}. -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, [], +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, [], Items, Config, Destroy) -> - {Config, Destroy}; + {lists:reverse(Items), Config, Destroy}; decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], + [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], Items, Config, Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc#owner">> -> decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Config, - decode_muc_owner_destroy(__TopXMLNS, __IgnoreEls, - _el)); + Items, Config, + decode_muc_destroy(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Items, Config, + decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); <<"http://jabber.org/protocol/muc#owner">> -> decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Config, - decode_muc_owner_destroy(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); + Items, Config, + decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); _ -> decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Config, Destroy) + Items, Config, Destroy) end; decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Config, - Destroy) -> + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Items, + Config, Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"jabber:x:data">> -> decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Items, decode_xdata(<<"jabber:x:data">>, __IgnoreEls, _el), Destroy); _ -> decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Config, Destroy) + Items, Config, Destroy) end; decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Config, Destroy) -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Config, Destroy). - -encode_muc_owner({muc_owner, Destroy, Config}, - _xmlns_attrs) -> - _els = lists:reverse('encode_muc_owner_$config'(Config, - 'encode_muc_owner_$destroy'(Destroy, - []))), - _attrs = _xmlns_attrs, - {xmlel, <<"query">>, _attrs, _els}. - -'encode_muc_owner_$config'(undefined, _acc) -> _acc; -'encode_muc_owner_$config'(Config, _acc) -> - [encode_xdata(Config, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. - -'encode_muc_owner_$destroy'(undefined, _acc) -> _acc; -'encode_muc_owner_$destroy'(Destroy, _acc) -> - [encode_muc_owner_destroy(Destroy, []) | _acc]. - -decode_muc_owner_destroy(__TopXMLNS, __IgnoreEls, - {xmlel, <<"destroy">>, _attrs, _els}) -> - {Password, Reason} = - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, undefined, undefined), - Jid = decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, - undefined), - {muc_owner_destroy, Jid, Reason, Password}. - -decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - [], Password, Reason) -> - {Password, Reason}; -decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], - Password, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_owner_password(__TopXMLNS, - __IgnoreEls, - _el), - Reason); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_owner_password(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, - _el), - Reason); - _ -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Password, Reason) - end; -decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Password, Reason) -> + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, + Config, Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Password, - decode_muc_owner_reason(__TopXMLNS, - __IgnoreEls, - _el)); + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_owner_item(__TopXMLNS, __IgnoreEls, + _el) + | Items], + Config, Destroy); <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Password, - decode_muc_owner_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, - _el)); - _ -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Password, Reason) - end; -decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Password, Reason) -> - decode_muc_owner_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Password, Reason). - -decode_muc_owner_destroy_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, - _val); -decode_muc_owner_destroy_attrs(__TopXMLNS, [_ | _attrs], - Jid) -> - decode_muc_owner_destroy_attrs(__TopXMLNS, _attrs, Jid); -decode_muc_owner_destroy_attrs(__TopXMLNS, [], Jid) -> - decode_muc_owner_destroy_attr_jid(__TopXMLNS, Jid). - -encode_muc_owner_destroy({muc_owner_destroy, Jid, - Reason, Password}, - _xmlns_attrs) -> - _els = - lists:reverse('encode_muc_owner_destroy_$password'(Password, - 'encode_muc_owner_destroy_$reason'(Reason, - []))), - _attrs = encode_muc_owner_destroy_attr_jid(Jid, - _xmlns_attrs), - {xmlel, <<"destroy">>, _attrs, _els}. - -'encode_muc_owner_destroy_$password'(undefined, _acc) -> - _acc; -'encode_muc_owner_destroy_$password'(Password, _acc) -> - [encode_muc_owner_password(Password, []) | _acc]. - -'encode_muc_owner_destroy_$reason'(undefined, _acc) -> - _acc; -'encode_muc_owner_destroy_$reason'(Reason, _acc) -> - [encode_muc_owner_reason(Reason, []) | _acc]. - -decode_muc_owner_destroy_attr_jid(__TopXMLNS, - undefined) -> - undefined; -decode_muc_owner_destroy_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"destroy">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_owner_destroy_attr_jid(undefined, _acc) -> - _acc; -encode_muc_owner_destroy_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_owner_reason(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reason">>, _attrs, _els}) -> - Cdata = decode_muc_owner_reason_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_muc_owner_reason_cdata(__TopXMLNS, Cdata); -decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_owner_reason_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + [decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el) + | Items], + Config, Destroy); + _ -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Items, Config, Destroy) + end; +decode_muc_owner_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items, Config, Destroy) -> + decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, + Items, Config, Destroy). -encode_muc_owner_reason(Cdata, _xmlns_attrs) -> - _els = encode_muc_owner_reason_cdata(Cdata, []), +encode_muc_owner({muc_owner, Destroy, Config, Items}, + _xmlns_attrs) -> + _els = lists:reverse('encode_muc_owner_$items'(Items, + 'encode_muc_owner_$config'(Config, + 'encode_muc_owner_$destroy'(Destroy, + [])))), _attrs = _xmlns_attrs, - {xmlel, <<"reason">>, _attrs, _els}. + {xmlel, <<"query">>, _attrs, _els}. -decode_muc_owner_reason_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_muc_owner_reason_cdata(__TopXMLNS, _val) -> _val. +'encode_muc_owner_$items'([], _acc) -> _acc; +'encode_muc_owner_$items'([Items | _els], _acc) -> + 'encode_muc_owner_$items'(_els, + [encode_muc_owner_item(Items, []) | _acc]). -encode_muc_owner_reason_cdata(undefined, _acc) -> _acc; -encode_muc_owner_reason_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. +'encode_muc_owner_$config'(undefined, _acc) -> _acc; +'encode_muc_owner_$config'(Config, _acc) -> + [encode_xdata(Config, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. -decode_muc_owner_password(__TopXMLNS, __IgnoreEls, - {xmlel, <<"password">>, _attrs, _els}) -> - Cdata = decode_muc_owner_password_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), +'encode_muc_owner_$destroy'(undefined, _acc) -> _acc; +'encode_muc_owner_$destroy'(Destroy, _acc) -> + [encode_muc_destroy(Destroy, []) | _acc]. + +decode_muc_password(__TopXMLNS, __IgnoreEls, + {xmlel, <<"password">>, _attrs, _els}) -> + Cdata = decode_muc_password_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), Cdata. -decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_muc_owner_password_cdata(__TopXMLNS, Cdata); -decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_owner_password_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). +decode_muc_password_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_muc_password_cdata(__TopXMLNS, Cdata); +decode_muc_password_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_password_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_muc_password_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_password_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). -encode_muc_owner_password(Cdata, _xmlns_attrs) -> - _els = encode_muc_owner_password_cdata(Cdata, []), +encode_muc_password(Cdata, _xmlns_attrs) -> + _els = encode_muc_password_cdata(Cdata, []), _attrs = _xmlns_attrs, {xmlel, <<"password">>, _attrs, _els}. -decode_muc_owner_password_cdata(__TopXMLNS, <<>>) -> +decode_muc_password_cdata(__TopXMLNS, <<>>) -> undefined; -decode_muc_owner_password_cdata(__TopXMLNS, _val) -> - _val. +decode_muc_password_cdata(__TopXMLNS, _val) -> _val. -encode_muc_owner_password_cdata(undefined, _acc) -> - _acc; -encode_muc_owner_password_cdata(_val, _acc) -> +encode_muc_password_cdata(undefined, _acc) -> _acc; +encode_muc_password_cdata(_val, _acc) -> [{xmlcdata, _val} | _acc]. decode_muc_user(__TopXMLNS, __IgnoreEls, {xmlel, <<"x">>, _attrs, _els}) -> - {Status_codes, Items, Invites, Decline, Destroy} = + {Status_codes, Items, Invites, Password, Decline, + Destroy} = decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, [], - [], [], undefined, undefined), - Password = decode_muc_user_attrs(__TopXMLNS, _attrs, - undefined), + [], [], undefined, undefined, undefined), {muc_user, Decline, Destroy, Invites, Items, Status_codes, Password}. decode_muc_user_els(__TopXMLNS, __IgnoreEls, [], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> {lists:reverse(Status_codes), lists:reverse(Items), - lists:reverse(Invites), Decline, Destroy}; + lists:reverse(Invites), Password, Decline, Destroy}; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"decline">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, + Status_codes, Items, Invites, Password, decode_muc_user_decline(__TopXMLNS, __IgnoreEls, _el), Destroy); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, + Status_codes, Items, Invites, Password, decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, __IgnoreEls, _el), Destroy); _ -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy) + Status_codes, Items, Invites, Password, Decline, + Destroy) end; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, - decode_muc_user_destroy(__TopXMLNS, __IgnoreEls, - _el)); + Status_codes, Items, Invites, Password, Decline, + decode_muc_destroy(__TopXMLNS, __IgnoreEls, _el)); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, - decode_muc_user_destroy(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); + Status_codes, Items, Invites, Password, Decline, + decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Password, Decline, + decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, Password, Decline, + Destroy) + end; +decode_muc_user_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], + Status_codes, Items, Invites, Password, Decline, + Destroy) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_password(__TopXMLNS, __IgnoreEls, _el), + Decline, Destroy); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el), + Decline, Destroy); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Decline, Destroy); + <<"http://jabber.org/protocol/muc">> -> + decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, + Status_codes, Items, Invites, + decode_muc_password(<<"http://jabber.org/protocol/muc">>, + __IgnoreEls, _el), + Decline, Destroy); _ -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy) + Status_codes, Items, Invites, Password, Decline, + Destroy) end; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"invite">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == @@ -7235,21 +8317,23 @@ decode_muc_user_els(__TopXMLNS, __IgnoreEls, [decode_muc_user_invite(__TopXMLNS, __IgnoreEls, _el) | Invites], - Decline, Destroy); + Password, Decline, Destroy); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, Status_codes, Items, [decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, __IgnoreEls, _el) | Invites], - Decline, Destroy); + Password, Decline, Destroy); _ -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy) + Status_codes, Items, Invites, Password, Decline, + Destroy) end; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"item">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == @@ -7259,21 +8343,23 @@ decode_muc_user_els(__TopXMLNS, __IgnoreEls, [decode_muc_user_item(__TopXMLNS, __IgnoreEls, _el) | Items], - Invites, Decline, Destroy); + Invites, Password, Decline, Destroy); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, Status_codes, [decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, __IgnoreEls, _el) | Items], - Invites, Decline, Destroy); + Invites, Password, Decline, Destroy); _ -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy) + Status_codes, Items, Invites, Password, Decline, + Destroy) end; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"status">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == @@ -7285,7 +8371,7 @@ decode_muc_user_els(__TopXMLNS, __IgnoreEls, undefined -> Status_codes; _new_el -> [_new_el | Status_codes] end, - Items, Invites, Decline, Destroy); + Items, Invites, Password, Decline, Destroy); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, case @@ -7295,24 +8381,18 @@ decode_muc_user_els(__TopXMLNS, __IgnoreEls, undefined -> Status_codes; _new_el -> [_new_el | Status_codes] end, - Items, Invites, Decline, Destroy); + Items, Invites, Password, Decline, Destroy); _ -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy) + Status_codes, Items, Invites, Password, Decline, + Destroy) end; decode_muc_user_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Status_codes, Items, Invites, Decline, Destroy) -> + Status_codes, Items, Invites, Password, Decline, + Destroy) -> decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Decline, Destroy). - -decode_muc_user_attrs(__TopXMLNS, - [{<<"password">>, _val} | _attrs], _Password) -> - decode_muc_user_attrs(__TopXMLNS, _attrs, _val); -decode_muc_user_attrs(__TopXMLNS, [_ | _attrs], - Password) -> - decode_muc_user_attrs(__TopXMLNS, _attrs, Password); -decode_muc_user_attrs(__TopXMLNS, [], Password) -> - decode_muc_user_attr_password(__TopXMLNS, Password). + Status_codes, Items, Invites, Password, Decline, + Destroy). encode_muc_user({muc_user, Decline, Destroy, Invites, Items, Status_codes, Password}, @@ -7321,11 +8401,11 @@ encode_muc_user({muc_user, Decline, Destroy, Invites, lists:reverse('encode_muc_user_$status_codes'(Status_codes, 'encode_muc_user_$items'(Items, 'encode_muc_user_$invites'(Invites, - 'encode_muc_user_$decline'(Decline, - 'encode_muc_user_$destroy'(Destroy, - [])))))), - _attrs = encode_muc_user_attr_password(Password, - _xmlns_attrs), + 'encode_muc_user_$password'(Password, + 'encode_muc_user_$decline'(Decline, + 'encode_muc_user_$destroy'(Destroy, + []))))))), + _attrs = _xmlns_attrs, {xmlel, <<"x">>, _attrs, _els}. 'encode_muc_user_$status_codes'([], _acc) -> _acc; @@ -7345,27 +8425,23 @@ encode_muc_user({muc_user, Decline, Destroy, Invites, 'encode_muc_user_$invites'(_els, [encode_muc_user_invite(Invites, []) | _acc]). +'encode_muc_user_$password'(undefined, _acc) -> _acc; +'encode_muc_user_$password'(Password, _acc) -> + [encode_muc_password(Password, []) | _acc]. + 'encode_muc_user_$decline'(undefined, _acc) -> _acc; 'encode_muc_user_$decline'(Decline, _acc) -> [encode_muc_user_decline(Decline, []) | _acc]. 'encode_muc_user_$destroy'(undefined, _acc) -> _acc; 'encode_muc_user_$destroy'(Destroy, _acc) -> - [encode_muc_user_destroy(Destroy, []) | _acc]. - -decode_muc_user_attr_password(__TopXMLNS, undefined) -> - undefined; -decode_muc_user_attr_password(__TopXMLNS, _val) -> _val. - -encode_muc_user_attr_password(undefined, _acc) -> _acc; -encode_muc_user_attr_password(_val, _acc) -> - [{<<"password">>, _val} | _acc]. + [encode_muc_destroy(Destroy, []) | _acc]. decode_muc_user_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> {Actor, Continue, Reason} = decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined), + undefined, undefined, <<>>), {Affiliation, Role, Jid, Nick} = decode_muc_user_item_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined), @@ -7426,13 +8502,23 @@ decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, - decode_muc_user_reason(__TopXMLNS, - __IgnoreEls, _el)); + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, - decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, + Actor, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); _ -> decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, Actor, Continue, Reason) @@ -7498,9 +8584,9 @@ encode_muc_user_item({muc_item, Actor, Continue, Reason, 'encode_muc_user_item_$continue'(Continue, _acc) -> [encode_muc_user_continue(Continue, []) | _acc]. -'encode_muc_user_item_$reason'(undefined, _acc) -> _acc; +'encode_muc_user_item_$reason'(<<>>, _acc) -> _acc; 'encode_muc_user_item_$reason'(Reason, _acc) -> - [encode_muc_user_reason(Reason, []) | _acc]. + [encode_muc_reason(Reason, []) | _acc]. decode_muc_user_item_attr_affiliation(__TopXMLNS, undefined) -> @@ -7695,39 +8781,72 @@ encode_muc_user_actor_attr_nick(_val, _acc) -> decode_muc_user_invite(__TopXMLNS, __IgnoreEls, {xmlel, <<"invite">>, _attrs, _els}) -> - Reason = decode_muc_user_invite_els(__TopXMLNS, - __IgnoreEls, _els, undefined), + {Continue, Reason} = + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, undefined, <<>>), {To, From} = decode_muc_user_invite_attrs(__TopXMLNS, _attrs, undefined, undefined), - {muc_invite, Reason, From, To}. + {muc_invite, Reason, From, To, Continue}. decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - Reason; + Continue, Reason) -> + {Continue, Reason}; decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Reason) -> + Continue, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Continue, + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Continue, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); + _ -> + decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + _els, Continue, Reason) + end; +decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"continue">>, _attrs, _} = _el | _els], + Continue, Reason) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_reason(__TopXMLNS, - __IgnoreEls, _el)); + decode_muc_user_continue(__TopXMLNS, + __IgnoreEls, _el), + Reason); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); + decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Reason); _ -> decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Reason) + _els, Continue, Reason) end; decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> + [_ | _els], Continue, Reason) -> decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Reason). + _els, Continue, Reason). decode_muc_user_invite_attrs(__TopXMLNS, [{<<"to">>, _val} | _attrs], _To, From) -> @@ -7746,20 +8865,26 @@ decode_muc_user_invite_attrs(__TopXMLNS, [], To, {decode_muc_user_invite_attr_to(__TopXMLNS, To), decode_muc_user_invite_attr_from(__TopXMLNS, From)}. -encode_muc_user_invite({muc_invite, Reason, From, To}, +encode_muc_user_invite({muc_invite, Reason, From, To, + Continue}, _xmlns_attrs) -> _els = - lists:reverse('encode_muc_user_invite_$reason'(Reason, - [])), + lists:reverse('encode_muc_user_invite_$continue'(Continue, + 'encode_muc_user_invite_$reason'(Reason, + []))), _attrs = encode_muc_user_invite_attr_from(From, encode_muc_user_invite_attr_to(To, _xmlns_attrs)), {xmlel, <<"invite">>, _attrs, _els}. -'encode_muc_user_invite_$reason'(undefined, _acc) -> +'encode_muc_user_invite_$continue'(undefined, _acc) -> _acc; +'encode_muc_user_invite_$continue'(Continue, _acc) -> + [encode_muc_user_continue(Continue, []) | _acc]. + +'encode_muc_user_invite_$reason'(<<>>, _acc) -> _acc; 'encode_muc_user_invite_$reason'(Reason, _acc) -> - [encode_muc_user_reason(Reason, []) | _acc]. + [encode_muc_reason(Reason, []) | _acc]. decode_muc_user_invite_attr_to(__TopXMLNS, undefined) -> undefined; @@ -7792,69 +8917,125 @@ encode_muc_user_invite_attr_from(undefined, _acc) -> encode_muc_user_invite_attr_from(_val, _acc) -> [{<<"from">>, enc_jid(_val)} | _acc]. -decode_muc_user_destroy(__TopXMLNS, __IgnoreEls, - {xmlel, <<"destroy">>, _attrs, _els}) -> - Reason = decode_muc_user_destroy_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - Jid = decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, - undefined), - {muc_user_destroy, Reason, Jid}. +decode_muc_destroy(__TopXMLNS, __IgnoreEls, + {xmlel, <<"destroy">>, _attrs, _els}) -> + {Password, Reason} = decode_muc_destroy_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + <<>>), + {Jid, Xmlns} = decode_muc_destroy_attrs(__TopXMLNS, + _attrs, undefined, undefined), + {muc_destroy, Xmlns, Jid, Reason, Password}. -decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - Reason; -decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Reason) -> +decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, [], + Password, Reason) -> + {Password, Reason}; +decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"reason">>, _attrs, _} = _el | _els], + Password, Reason) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_user_reason(__TopXMLNS, - __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#user">>; + __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); _ -> - decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Reason) + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, Reason) end; -decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> - decode_muc_user_destroy_els(__TopXMLNS, __IgnoreEls, - _els, Reason). - -decode_muc_user_destroy_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, _val); -decode_muc_user_destroy_attrs(__TopXMLNS, [_ | _attrs], - Jid) -> - decode_muc_user_destroy_attrs(__TopXMLNS, _attrs, Jid); -decode_muc_user_destroy_attrs(__TopXMLNS, [], Jid) -> - decode_muc_user_destroy_attr_jid(__TopXMLNS, Jid). - -encode_muc_user_destroy({muc_user_destroy, Reason, Jid}, - _xmlns_attrs) -> +decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"password">>, _attrs, _} = _el | _els], + Password, Reason) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/muc#user">>; + __TopXMLNS == + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(__TopXMLNS, __IgnoreEls, + _el), + Reason); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el), + Reason); + <<"http://jabber.org/protocol/muc#user">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el), + Reason); + <<"http://jabber.org/protocol/muc">> -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + decode_muc_password(<<"http://jabber.org/protocol/muc">>, + __IgnoreEls, _el), + Reason); + _ -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, Reason) + end; +decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Password, Reason) -> + decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, + Password, Reason). + +decode_muc_destroy_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Xmlns) -> + decode_muc_destroy_attrs(__TopXMLNS, _attrs, _val, + Xmlns); +decode_muc_destroy_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Jid, _Xmlns) -> + decode_muc_destroy_attrs(__TopXMLNS, _attrs, Jid, _val); +decode_muc_destroy_attrs(__TopXMLNS, [_ | _attrs], Jid, + Xmlns) -> + decode_muc_destroy_attrs(__TopXMLNS, _attrs, Jid, + Xmlns); +decode_muc_destroy_attrs(__TopXMLNS, [], Jid, Xmlns) -> + {decode_muc_destroy_attr_jid(__TopXMLNS, Jid), + decode_muc_destroy_attr_xmlns(__TopXMLNS, Xmlns)}. + +encode_muc_destroy({muc_destroy, Xmlns, Jid, Reason, + Password}, + _xmlns_attrs) -> _els = - lists:reverse('encode_muc_user_destroy_$reason'(Reason, - [])), - _attrs = encode_muc_user_destroy_attr_jid(Jid, - _xmlns_attrs), + lists:reverse('encode_muc_destroy_$password'(Password, + 'encode_muc_destroy_$reason'(Reason, + []))), + _attrs = encode_muc_destroy_attr_xmlns(Xmlns, + encode_muc_destroy_attr_jid(Jid, + _xmlns_attrs)), {xmlel, <<"destroy">>, _attrs, _els}. -'encode_muc_user_destroy_$reason'(undefined, _acc) -> - _acc; -'encode_muc_user_destroy_$reason'(Reason, _acc) -> - [encode_muc_user_reason(Reason, []) | _acc]. +'encode_muc_destroy_$password'(undefined, _acc) -> _acc; +'encode_muc_destroy_$password'(Password, _acc) -> + [encode_muc_password(Password, []) | _acc]. -decode_muc_user_destroy_attr_jid(__TopXMLNS, - undefined) -> +'encode_muc_destroy_$reason'(<<>>, _acc) -> _acc; +'encode_muc_destroy_$reason'(Reason, _acc) -> + [encode_muc_reason(Reason, []) | _acc]. + +decode_muc_destroy_attr_jid(__TopXMLNS, undefined) -> undefined; -decode_muc_user_destroy_attr_jid(__TopXMLNS, _val) -> +decode_muc_destroy_attr_jid(__TopXMLNS, _val) -> case catch dec_jid(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, @@ -7863,15 +9044,22 @@ decode_muc_user_destroy_attr_jid(__TopXMLNS, _val) -> _res -> _res end. -encode_muc_user_destroy_attr_jid(undefined, _acc) -> - _acc; -encode_muc_user_destroy_attr_jid(_val, _acc) -> +encode_muc_destroy_attr_jid(undefined, _acc) -> _acc; +encode_muc_destroy_attr_jid(_val, _acc) -> [{<<"jid">>, enc_jid(_val)} | _acc]. +decode_muc_destroy_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_muc_destroy_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_muc_destroy_attr_xmlns(undefined, _acc) -> _acc; +encode_muc_destroy_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + decode_muc_user_decline(__TopXMLNS, __IgnoreEls, {xmlel, <<"decline">>, _attrs, _els}) -> Reason = decode_muc_user_decline_els(__TopXMLNS, - __IgnoreEls, _els, undefined), + __IgnoreEls, _els, <<>>), {To, From} = decode_muc_user_decline_attrs(__TopXMLNS, _attrs, undefined, undefined), {muc_decline, Reason, From, To}. @@ -7888,13 +9076,23 @@ decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_reason(__TopXMLNS, - __IgnoreEls, _el)); + decode_muc_reason(__TopXMLNS, __IgnoreEls, + _el)); <<"http://jabber.org/protocol/muc#user">> -> decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#admin">> -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/muc#owner">> -> + decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, + _els, + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + __IgnoreEls, _el)); _ -> decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, _els, Reason) @@ -7931,10 +9129,9 @@ encode_muc_user_decline({muc_decline, Reason, From, To}, _xmlns_attrs)), {xmlel, <<"decline">>, _attrs, _els}. -'encode_muc_user_decline_$reason'(undefined, _acc) -> - _acc; +'encode_muc_user_decline_$reason'(<<>>, _acc) -> _acc; 'encode_muc_user_decline_$reason'(Reason, _acc) -> - [encode_muc_user_reason(Reason, []) | _acc]. + [encode_muc_reason(Reason, []) | _acc]. decode_muc_user_decline_attr_to(__TopXMLNS, undefined) -> @@ -7969,35 +9166,34 @@ encode_muc_user_decline_attr_from(undefined, _acc) -> encode_muc_user_decline_attr_from(_val, _acc) -> [{<<"from">>, enc_jid(_val)} | _acc]. -decode_muc_user_reason(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reason">>, _attrs, _els}) -> - Cdata = decode_muc_user_reason_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), +decode_muc_reason(__TopXMLNS, __IgnoreEls, + {xmlel, <<"reason">>, _attrs, _els}) -> + Cdata = decode_muc_reason_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), Cdata. -decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_muc_user_reason_cdata(__TopXMLNS, Cdata); -decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_user_reason_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). +decode_muc_reason_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_muc_reason_cdata(__TopXMLNS, Cdata); +decode_muc_reason_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_muc_reason_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_muc_reason_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_muc_reason_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). -encode_muc_user_reason(Cdata, _xmlns_attrs) -> - _els = encode_muc_user_reason_cdata(Cdata, []), +encode_muc_reason(Cdata, _xmlns_attrs) -> + _els = encode_muc_reason_cdata(Cdata, []), _attrs = _xmlns_attrs, {xmlel, <<"reason">>, _attrs, _els}. -decode_muc_user_reason_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_muc_user_reason_cdata(__TopXMLNS, _val) -> _val. +decode_muc_reason_cdata(__TopXMLNS, <<>>) -> undefined; +decode_muc_reason_cdata(__TopXMLNS, _val) -> _val. -encode_muc_user_reason_cdata(undefined, _acc) -> _acc; -encode_muc_user_reason_cdata(_val, _acc) -> +encode_muc_reason_cdata(undefined, _acc) -> _acc; +encode_muc_reason_cdata(_val, _acc) -> [{xmlcdata, _val} | _acc]. decode_muc_history(__TopXMLNS, __IgnoreEls, @@ -10554,23 +11750,15 @@ decode_xdata_field_els(__TopXMLNS, __IgnoreEls, case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - case decode_xdata_field_option(__TopXMLNS, - __IgnoreEls, - _el) - of - undefined -> Options; - _new_el -> [_new_el | Options] - end, + [decode_xdata_field_option(__TopXMLNS, + __IgnoreEls, _el) + | Options], Values, Desc, Required); <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - case - decode_xdata_field_option(<<"jabber:x:data">>, - __IgnoreEls, _el) - of - undefined -> Options; - _new_el -> [_new_el | Options] - end, + [decode_xdata_field_option(<<"jabber:x:data">>, + __IgnoreEls, _el) + | Options], Values, Desc, Required); _ -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, @@ -10675,7 +11863,9 @@ decode_xdata_field_option(__TopXMLNS, __IgnoreEls, {xmlel, <<"option">>, _attrs, _els}) -> Value = decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, _els, error), - Value. + Label = decode_xdata_field_option_attrs(__TopXMLNS, + _attrs, undefined), + {xdata_option, Label, Value}. decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, [], Value) -> @@ -10712,16 +11902,42 @@ decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, _els, Value). -encode_xdata_field_option(Value, _xmlns_attrs) -> +decode_xdata_field_option_attrs(__TopXMLNS, + [{<<"label">>, _val} | _attrs], _Label) -> + decode_xdata_field_option_attrs(__TopXMLNS, _attrs, + _val); +decode_xdata_field_option_attrs(__TopXMLNS, + [_ | _attrs], Label) -> + decode_xdata_field_option_attrs(__TopXMLNS, _attrs, + Label); +decode_xdata_field_option_attrs(__TopXMLNS, [], + Label) -> + decode_xdata_field_option_attr_label(__TopXMLNS, Label). + +encode_xdata_field_option({xdata_option, Label, Value}, + _xmlns_attrs) -> _els = lists:reverse('encode_xdata_field_option_$value'(Value, [])), - _attrs = _xmlns_attrs, + _attrs = encode_xdata_field_option_attr_label(Label, + _xmlns_attrs), {xmlel, <<"option">>, _attrs, _els}. 'encode_xdata_field_option_$value'(Value, _acc) -> [encode_xdata_field_value(Value, []) | _acc]. +decode_xdata_field_option_attr_label(__TopXMLNS, + undefined) -> + undefined; +decode_xdata_field_option_attr_label(__TopXMLNS, + _val) -> + _val. + +encode_xdata_field_option_attr_label(undefined, _acc) -> + _acc; +encode_xdata_field_option_attr_label(_val, _acc) -> + [{<<"label">>, _val} | _acc]. + decode_xdata_field_value(__TopXMLNS, __IgnoreEls, {xmlel, <<"value">>, _attrs, _els}) -> Cdata = decode_xdata_field_value_els(__TopXMLNS, @@ -19881,6 +21097,19 @@ decode_error_els(__TopXMLNS, __IgnoreEls, decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, Reason) end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"payment-required">>, _attrs, _} = _el + | _els], + Text, Reason) -> + 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)); + _ -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason) + end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"policy-violation">>, _attrs, _} = _el | _els], @@ -20132,6 +21361,12 @@ encode_error({error, Type, Code, By, Reason, Text}, [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) | _acc]; +'encode_error_$reason'('payment-required' = Reason, + _acc) -> + [encode_error_payment_required(Reason, + [{<<"xmlns">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + | _acc]; 'encode_error_$reason'('policy-violation' = Reason, _acc) -> [encode_error_policy_violation(Reason, @@ -20438,6 +21673,16 @@ encode_error_policy_violation('policy-violation', _attrs = _xmlns_attrs, {xmlel, <<"policy-violation">>, _attrs, _els}. +decode_error_payment_required(__TopXMLNS, __IgnoreEls, + {xmlel, <<"payment-required">>, _attrs, _els}) -> + 'payment-required'. + +encode_error_payment_required('payment-required', + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"payment-required">>, _attrs, _els}. + decode_error_not_authorized(__TopXMLNS, __IgnoreEls, {xmlel, <<"not-authorized">>, _attrs, _els}) -> 'not-authorized'. @@ -22069,17 +23314,18 @@ encode_private({private, __Xmls}, _xmlns_attrs) -> decode_disco_items(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> - Items = decode_disco_items_els(__TopXMLNS, __IgnoreEls, - _els, []), + {Items, Rsm} = decode_disco_items_els(__TopXMLNS, + __IgnoreEls, _els, [], undefined), Node = decode_disco_items_attrs(__TopXMLNS, _attrs, undefined), - {disco_items, Node, Items}. + {disco_items, Node, Items, Rsm}. decode_disco_items_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); + Items, Rsm) -> + {lists:reverse(Items), Rsm}; decode_disco_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, + Rsm) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == @@ -22087,20 +23333,35 @@ decode_disco_items_els(__TopXMLNS, __IgnoreEls, decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, [decode_disco_item(__TopXMLNS, __IgnoreEls, _el) - | Items]); + | Items], + Rsm); <<"http://jabber.org/protocol/disco#items">> -> decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, [decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, __IgnoreEls, _el) - | Items]); + | Items], + Rsm); + _ -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + Items, Rsm) + end; +decode_disco_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"set">>, _attrs, _} = _el | _els], Items, + Rsm) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/rsm">> -> + decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el)); _ -> decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items) + Items, Rsm) end; decode_disco_items_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> + [_ | _els], Items, Rsm) -> decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items). + Items, Rsm). decode_disco_items_attrs(__TopXMLNS, [{<<"node">>, _val} | _attrs], _Node) -> @@ -22111,10 +23372,11 @@ decode_disco_items_attrs(__TopXMLNS, [_ | _attrs], decode_disco_items_attrs(__TopXMLNS, [], Node) -> decode_disco_items_attr_node(__TopXMLNS, Node). -encode_disco_items({disco_items, Node, Items}, +encode_disco_items({disco_items, Node, Items, Rsm}, _xmlns_attrs) -> _els = lists:reverse('encode_disco_items_$items'(Items, - [])), + 'encode_disco_items_$rsm'(Rsm, + []))), _attrs = encode_disco_items_attr_node(Node, _xmlns_attrs), {xmlel, <<"query">>, _attrs, _els}. @@ -22124,6 +23386,12 @@ encode_disco_items({disco_items, Node, Items}, 'encode_disco_items_$items'(_els, [encode_disco_item(Items, []) | _acc]). +'encode_disco_items_$rsm'(undefined, _acc) -> _acc; +'encode_disco_items_$rsm'(Rsm, _acc) -> + [encode_rsm_set(Rsm, + [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]) + | _acc]. + decode_disco_items_attr_node(__TopXMLNS, undefined) -> undefined; decode_disco_items_attr_node(__TopXMLNS, _val) -> _val. diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 42b251fc1..83f1f4adc 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -10,7 +10,8 @@ %% API -export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, - is_standalone_chat_state/1]). + is_standalone_chat_state/1, get_xdata_values/2, + has_xdata_var/2]). -include("xmpp.hrl"). @@ -76,6 +77,17 @@ is_standalone_chat_state(Stanza) -> false end. +-spec get_xdata_values(binary(), xdata()) -> [binary()]. +get_xdata_values(Var, #xdata{fields = Fields}) -> + case lists:keyfind(Var, #xdata_field.var, Fields) of + #xdata_field{values = Vals} -> Vals; + false -> [] + end. + +-spec has_xdata_var(binary(), xdata()) -> boolean(). +has_xdata_var(Var, #xdata{fields = Fields}) -> + lists:keymember(Var, #xdata_field.var, Fields). + %%%=================================================================== %%% Internal functions %%%=================================================================== -- cgit v1.2.3 From da310a517396bee93e96da9a3717230938064494 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 26 Jul 2016 09:52:29 +0300 Subject: Rewrite mod_adhoc and mod_announce to use XML generator --- src/mod_adhoc.erl | 138 ++++++------- src/mod_announce.erl | 355 +++++++++++++-------------------- src/xmpp_codec.erl | 544 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/xmpp_util.erl | 14 +- 4 files changed, 744 insertions(+), 307 deletions(-) (limited to 'src') diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index e12e0de1e..9c8238900 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -31,18 +31,15 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, - process_sm_iq/3, get_local_commands/5, +-export([start/2, stop/1, process_local_iq/1, + process_sm_iq/1, get_local_commands/5, get_local_identity/5, get_local_features/5, get_sm_commands/5, get_sm_identity/5, get_sm_features/5, ping_item/4, ping_command/4, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). - --include("adhoc.hrl"). +-include("xmpp.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, @@ -94,7 +91,7 @@ stop(Host) -> %------------------------------------------------------------------------- get_local_commands(Acc, _From, - #jid{server = Server, lserver = LServer} = _To, <<"">>, + #jid{server = Server, lserver = LServer} = _To, undefined, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, @@ -107,12 +104,9 @@ get_local_commands(Acc, _From, {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, Server}, {<<"node">>, ?NS_COMMANDS}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []}], + Nodes = [#disco_item{jid = jid:make(Server), + node = ?NS_COMMANDS, + name = translate:translate(Lang, <<"Commands">>)}], {result, Items ++ Nodes} end; get_local_commands(_Acc, From, @@ -128,7 +122,7 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) -> %------------------------------------------------------------------------- get_sm_commands(Acc, _From, - #jid{lserver = LServer} = To, <<"">>, Lang) -> + #jid{lserver = LServer} = To, undefined, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, fun(B) when is_boolean(B) -> B end, @@ -140,13 +134,9 @@ get_sm_commands(Acc, _From, {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, jid:to_string(To)}, - {<<"node">>, ?NS_COMMANDS}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []}], + Nodes = [#disco_item{jid = To, + node = ?NS_COMMANDS, + name = translate:translate(Lang, <<"Commands">>)}], {result, Items ++ Nodes} end; get_sm_commands(_Acc, From, @@ -160,21 +150,14 @@ get_sm_commands(Acc, _From, _To, _Node, _Lang) -> Acc. %% On disco info request to the ad-hoc node, return automation/command-list. get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-list">>}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-list">>, + name = translate:translate(Lang, <<"Commands">>)} | Acc]; get_local_identity(Acc, _From, _To, <<"ping">>, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-node">>}, - {<<"name">>, translate:translate(Lang, <<"Ping">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-node">>, + name = translate:translate(Lang, <<"Ping">>)} | Acc]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. @@ -183,13 +166,9 @@ get_local_identity(Acc, _From, _To, _Node, _Lang) -> %% On disco info request to the ad-hoc node, return automation/command-list. get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-list">>}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-list">>, + name = translate:translate(Lang, <<"Commands">>)} | Acc]; get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc. @@ -225,34 +204,29 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- -process_local_iq(From, To, IQ) -> - process_adhoc_request(From, To, IQ, - adhoc_local_commands). +process_local_iq(IQ) -> + process_adhoc_request(IQ, adhoc_local_commands). -process_sm_iq(From, To, IQ) -> - process_adhoc_request(From, To, IQ, adhoc_sm_commands). +process_sm_iq(IQ) -> + process_adhoc_request(IQ, adhoc_sm_commands). -process_adhoc_request(From, To, - #iq{sub_el = SubEl, lang = Lang} = IQ, Hook) -> - ?DEBUG("About to parse ~p...", [IQ]), - case adhoc:parse_request(IQ) of - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - #adhoc_request{} = AdhocRequest -> - Host = To#jid.lserver, - case ejabberd_hooks:run_fold(Hook, Host, empty, - [From, To, AdhocRequest]) - of - ignore -> ignore; - empty -> - Txt = <<"No hook has processed this command">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - Command -> IQ#iq{type = result, sub_el = [Command]} - end - end. +process_adhoc_request(#iq{from = From, to = To, + type = set, lang = Lang, + sub_els = [#adhoc_command{} = SubEl]} = IQ, Hook) -> + Host = To#jid.lserver, + case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, SubEl]) of + ignore -> + ignore; + empty -> + Txt = <<"No hook has processed this command">>, + xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)); + {error, Error} -> + xmpp:make_error(IQ, Error); + Command -> + xmpp:make_iq_result(IQ, Command) + end; +process_adhoc_request(#iq{} = IQ, _Hooks) -> + xmpp:make_error(IQ, xmpp:err_bad_request()). ping_item(Acc, _From, #jid{server = Server} = _To, Lang) -> @@ -260,27 +234,25 @@ ping_item(Acc, _From, #jid{server = Server} = _To, {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, Server}, {<<"node">>, <<"ping">>}, - {<<"name">>, translate:translate(Lang, <<"Ping">>)}], - children = []}], + Nodes = [#disco_item{jid = jid:make(Server), + node = <<"ping">>, + name = translate:translate(Lang, <<"Ping">>)}], {result, Items ++ Nodes}. ping_command(_Acc, _From, _To, - #adhoc_request{lang = Lang, node = <<"ping">>, - sessionid = _Sessionid, action = Action} = - Request) -> - if Action == <<"">>; Action == <<"execute">> -> - adhoc:produce_response(Request, - #adhoc_response{status = completed, - notes = - [{<<"info">>, - translate:translate(Lang, - <<"Pong">>)}]}); + #adhoc_command{lang = Lang, node = <<"ping">>, + action = Action} = Request) -> + if Action == execute -> + xmpp_util:make_adhoc_response( + Request, + #adhoc_command{ + status = completed, + notes = [#adhoc_note{ + type = info, + data = translate:translate(Lang, <<"Pong">>)}]}); true -> Txt = <<"Incorrect value of 'action' attribute">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + {error, xmpp:err_bad_request(Txt, Lang)} end; ping_command(Acc, _From, _To, _Request) -> Acc. diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 52ff2de92..4b7498447 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -39,8 +39,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). --include("adhoc.hrl"). +-include("xmpp.hrl"). -include("mod_announce.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). @@ -57,6 +56,7 @@ -define(NS_ADMINL(Sub), [<<"http:">>, <<"jabber.org">>, <<"protocol">>, <<"admin">>, <>]). +tokenize(undefined) -> []; tokenize(Node) -> str:tokens(Node, <<"/#">>). start(Host, Opts) -> @@ -131,7 +131,7 @@ stop(Host) -> {wait, Proc}. %% Announcing via messages to a custom resource -announce(From, #jid{luser = <<>>} = To, #xmlel{name = <<"message">>} = Packet) -> +announce(From, #jid{luser = <<>>} = To, #message{} = Packet) -> Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME), case To#jid.lresource of <<"announce/all">> -> @@ -173,10 +173,9 @@ announce(_From, _To, _Packet) -> %%------------------------------------------------------------------------- %% Announcing via ad-hoc commands -define(INFO_COMMAND(Lang, Node), - [#xmlel{name = <<"identity">>, - attrs = [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-node">>}, - {<<"name">>, get_title(Lang, Node)}]}]). + [#identity{category = <<"automation">>, + type = <<"command-node">>, + name = get_title(Lang, Node)}]). disco_identity(Acc, _From, _To, Node, Lang) -> LNode = tokenize(Node), @@ -210,7 +209,7 @@ disco_identity(Acc, _From, _To, Node, Lang) -> -define(INFO_RESULT(Allow, Feats, Lang), case Allow of deny -> - {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)}; + {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)}; allow -> {result, Feats} end). @@ -226,7 +225,7 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) - acl:match_rule(global, Access2, From)} of {deny, deny} -> Txt = <<"Denied by ACL">>, - {error, ?ERRT_FORBIDDEN(Lang, Txt)}; + {error, xmpp:err_forbidden(Txt, Lang)}; _ -> {result, []} end @@ -269,26 +268,19 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) -> %%------------------------------------------------------------------------- -define(NODE_TO_ITEM(Lang, Server, Node), -( - #xmlel{ - name = <<"item">>, - attrs = [ - {<<"jid">>, Server}, - {<<"node">>, Node}, - {<<"name">>, get_title(Lang, Node)} - ] - } -)). + #disco_item{jid = jid:make(Server), + node = Node, + name = get_title(Lang, Node)}). -define(ITEMS_RESULT(Allow, Items, Lang), case Allow of deny -> - {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)}; + {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)}; allow -> {result, Items} end). -disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, <<>>, Lang) -> +disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, undefined, Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; @@ -393,15 +385,15 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) commands_result(Allow, From, To, Request) -> case Allow of deny -> - Lang = Request#adhoc_request.lang, - {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)}; + Lang = Request#adhoc_command.lang, + {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)}; allow -> announce_commands(From, To, Request) end. announce_commands(Acc, From, #jid{lserver = LServer} = To, - #adhoc_request{ node = Node} = Request) -> + #adhoc_command{node = Node} = Request) -> LNode = tokenize(Node), F = fun() -> Access = get_access(global), @@ -440,59 +432,35 @@ announce_commands(Acc, From, #jid{lserver = LServer} = To, %%------------------------------------------------------------------------- announce_commands(From, To, - #adhoc_request{lang = Lang, + #adhoc_command{lang = Lang, node = Node, - action = Action, - xdata = XData} = Request) -> - %% If the "action" attribute is not present, it is - %% understood as "execute". If there was no - %% element in the first response (which there isn't in our - %% case), "execute" and "complete" are equivalent. - ActionIsExecute = lists:member(Action, [<<>>, <<"execute">>, <<"complete">>]), - if Action == <<"cancel">> -> + sid = SID, + xdata = XData, + action = Action} = Request) -> + ActionIsExecute = Action == execute orelse Action == complete, + if Action == cancel -> %% User cancels request - adhoc:produce_response(Request, #adhoc_response{status = canceled}); - XData == false, ActionIsExecute -> + #adhoc_command{status = canceled, lang = Lang, node = Node, + sid = SID}; + XData == undefined, ActionIsExecute -> %% User requests form - Elements = generate_adhoc_form(Lang, Node, To#jid.lserver), - adhoc:produce_response(Request, - #adhoc_response{status = executing,elements = [Elements]}); - XData /= false, ActionIsExecute -> - %% User returns form. - case jlib:parse_xdata_submit(XData) of - invalid -> - {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)}; - Fields -> - handle_adhoc_form(From, To, Request, Fields) - end; + Form = generate_adhoc_form(Lang, Node, To#jid.lserver), + #adhoc_command{status = executing, lang = Lang, node = Node, + sid = SID, xdata = Form}; + XData /= undefined, ActionIsExecute -> + handle_adhoc_form(From, To, Request); true -> - Txt = <<"Incorrect action or data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + Txt = <<"Unexpected action">>, + {error, xmpp:err_bad_request(Txt, Lang)} end. --define(VVALUE(Val), -( - #xmlel{ - name = <<"value">>, - children = [{xmlcdata, Val}] - } -)). - -define(TVFIELD(Type, Var, Val), -( - #xmlel{ - name = <<"field">>, - attrs = [{<<"type">>, Type}, {<<"var">>, Var}], - children = vvaluel(Val) - } -)). - --define(HFIELD(), ?TVFIELD(<<"hidden">>, <<"FORM_TYPE">>, ?NS_ADMIN)). + #xdata_field{type = Type, var = Var, values = vvaluel(Val)}). vvaluel(Val) -> case Val of <<>> -> []; - _ -> [?VVALUE(Val)] + _ -> [Val] end. generate_adhoc_form(Lang, Node, ServerHost) -> @@ -503,49 +471,27 @@ generate_adhoc_form(Lang, Node, ServerHost) -> true -> {<<>>, <<>>} end, - #xmlel{ - name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = [ - ?HFIELD(), - #xmlel{name = <<"title">>, children = [{xmlcdata, get_title(Lang, Node)}]} - ] - ++ - if (LNode == ?NS_ADMINL("delete-motd")) - or (LNode == ?NS_ADMINL("delete-motd-allhosts")) -> - [#xmlel{ - name = <<"field">>, - attrs = [ - {<<"var">>, <<"confirm">>}, - {<<"type">>, <<"boolean">>}, - {<<"label">>, - translate:translate(Lang, <<"Really delete message of the day?">>)} - ], - children = [ - #xmlel{name = <<"value">>, children = [{xmlcdata, <<"true">>}]} - ] - } - ]; - true -> - [#xmlel{ - name = <<"field">>, - attrs = [ - {<<"var">>, <<"subject">>}, - {<<"type">>, <<"text-single">>}, - {<<"label">>, translate:translate(Lang, <<"Subject">>)}], - children = vvaluel(OldSubject) - }, - #xmlel{ - name = <<"field">>, - attrs = [ - {<<"var">>, <<"body">>}, - {<<"type">>, <<"text-multi">>}, - {<<"label">>, translate:translate(Lang, <<"Message body">>)}], - children = vvaluel(OldBody) - } - ] - - end}. + Fs = if (LNode == ?NS_ADMINL("delete-motd")) + or (LNode == ?NS_ADMINL("delete-motd-allhosts")) -> + [#xdata_field{type = boolean, + var = <<"confirm">>, + label = translate:translate( + Lang, <<"Really delete message of the day?">>), + values = [<<"true">>]}]; + true -> + [#xdata_field{type = 'text-single', + var = <<"subject">>, + label = translate:translate(Lang, <<"Subject">>), + values = vvaluel(OldSubject)}, + #xdata_field{type = 'text-multi', + var = <<"body">>, + label = translate:translate(Lang, <<"Message body">>), + values = vvaluel(OldBody)}] + end, + #xdata{type = form, + title = get_title(Lang, Node), + fields = [#xdata_field{type = hidden, var = <<"FORM_TYPE">>, + values = [?NS_ADMIN]}|Fs]}. join_lines([]) -> <<>>; @@ -558,103 +504,73 @@ join_lines([], Acc) -> iolist_to_binary(lists:reverse(tl(Acc))). handle_adhoc_form(From, #jid{lserver = LServer} = To, - #adhoc_request{lang = Lang, - node = Node, - sessionid = SessionID}, - Fields) -> - Confirm = case lists:keysearch(<<"confirm">>, 1, Fields) of - {value, {<<"confirm">>, [<<"true">>]}} -> - true; - {value, {<<"confirm">>, [<<"1">>]}} -> - true; - _ -> - false + #adhoc_command{lang = Lang, node = Node, + sid = SessionID, xdata = XData}) -> + Confirm = case xmpp_util:get_xdata_values(<<"confirm">>, XData) of + [<<"true">>] -> true; + [<<"1">>] -> true; + _ -> false end, - Subject = case lists:keysearch(<<"subject">>, 1, Fields) of - {value, {<<"subject">>, SubjectLines}} -> - %% There really shouldn't be more than one - %% subject line, but can we stop them? - join_lines(SubjectLines); - _ -> - <<>> - end, - Body = case lists:keysearch(<<"body">>, 1, Fields) of - {value, {<<"body">>, BodyLines}} -> - join_lines(BodyLines); - _ -> - <<>> - end, - Response = #adhoc_response{lang = Lang, - node = Node, - sessionid = SessionID, - status = completed}, - Packet = #xmlel{ - name = <<"message">>, - attrs = [{<<"type">>, <<"headline">>}], - children = if Subject /= <<>> -> - [#xmlel{name = <<"subject">>, children = [{xmlcdata, Subject}]}]; - true -> - [] - end - ++ - if Body /= <<>> -> - [#xmlel{name = <<"body">>, children = [{xmlcdata, Body}]}]; - true -> - [] - end - }, + Subject = join_lines(xmpp_util:get_xdata_values(<<"subject">>, XData)), + Body = join_lines(xmpp_util:get_xdata_values(<<"body">>, XData)), + Response = #adhoc_command{lang = Lang, node = Node, sid = SessionID, + status = completed}, + Packet = #message{type = headline, + body = xmpp:mk_text(Body), + subject = xmpp:mk_text(Subject)}, Proc = gen_mod:get_module_proc(LServer, ?PROCNAME), case {Node, Body} of {?NS_ADMIN_DELETE_MOTD, _} -> if Confirm -> Proc ! {announce_motd_delete, From, To, Packet}, - adhoc:produce_response(Response); + Response; true -> - adhoc:produce_response(Response) + Response end; {?NS_ADMIN_DELETE_MOTD_ALLHOSTS, _} -> if Confirm -> Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, - adhoc:produce_response(Response); + Response; true -> - adhoc:produce_response(Response) + Response end; {_, <<>>} -> %% An announce message with no body is definitely an operator error. %% Throw an error and give him/her a chance to send message again. - {error, ?ERRT_NOT_ACCEPTABLE(Lang, - <<"No body provided for announce message">>)}; + {error, xmpp:err_not_acceptable( + <<"No body provided for announce message">>, Lang)}; %% Now send the packet to ?PROCNAME. %% We don't use direct announce_* functions because it %% leads to large delay in response and queries processing {?NS_ADMIN_ANNOUNCE, _} -> Proc ! {announce_online, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_ANNOUNCE_ALLHOSTS, _} -> Proc ! {announce_all_hosts_online, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_ANNOUNCE_ALL, _} -> Proc ! {announce_all, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS, _} -> Proc ! {announce_all_hosts_all, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_SET_MOTD, _} -> Proc ! {announce_motd, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_SET_MOTD_ALLHOSTS, _} -> Proc ! {announce_all_hosts_motd, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_EDIT_MOTD, _} -> Proc ! {announce_motd_update, From, To, Packet}, - adhoc:produce_response(Response); + Response; {?NS_ADMIN_EDIT_MOTD_ALLHOSTS, _} -> Proc ! {announce_all_hosts_motd_update, From, To, Packet}, - adhoc:produce_response(Response); - _ -> + Response; + Junk -> %% This can't happen, as we haven't registered any other %% command nodes. - {error, ?ERR_INTERNAL_SERVER_ERROR} + ?ERROR_MSG("got unexpected node/body = ~p", [Junk]), + {error, xmpp:err_internal_server_error()} end. get_title(Lang, <<"announce">>) -> @@ -687,15 +603,15 @@ announce_all(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> - Local = jid:make(<<>>, To#jid.server, <<>>), + Local = jid:make(To#jid.server), lists:foreach( fun({User, Server}) -> - Dest = jid:make(User, Server, <<>>), + Dest = jid:make(User, Server), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:get_vh_registered_users(Host)) end. @@ -704,15 +620,15 @@ announce_all_hosts_all(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> - Local = jid:make(<<>>, To#jid.server, <<>>), + Local = jid:make(To#jid.server), lists:foreach( fun({User, Server}) -> - Dest = jid:make(User, Server, <<>>), + Dest = jid:make(User, Server), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:dirty_get_registered_users()) end. @@ -722,9 +638,9 @@ announce_online(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:get_vh_session_list(Host), @@ -736,9 +652,9 @@ announce_all_hosts_online(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:dirty_get_sessions_list(), @@ -747,7 +663,7 @@ announce_all_hosts_online(From, To, Packet) -> end. announce_online1(Sessions, Server, Packet) -> - Local = jid:make(<<>>, Server, <<>>), + Local = jid:make(Server), lists:foreach( fun({U, S, R}) -> Dest = jid:make(U, S, R), @@ -759,9 +675,9 @@ announce_motd(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> announce_motd(Host, Packet) @@ -771,9 +687,9 @@ announce_all_hosts_motd(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, @@ -793,9 +709,9 @@ announce_motd_update(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> announce_motd_update(Host, Packet) @@ -805,9 +721,9 @@ announce_all_hosts_motd_update(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, @@ -817,16 +733,16 @@ announce_all_hosts_motd_update(From, To, Packet) -> announce_motd_update(LServer, Packet) -> announce_motd_delete(LServer), Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:set_motd(LServer, Packet). + Mod:set_motd(LServer, xmpp:encode(Packet)). announce_motd_delete(From, To, Packet) -> Host = To#jid.lserver, Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> announce_motd_delete(Host) @@ -836,9 +752,9 @@ announce_all_hosts_motd_delete(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), + Lang = xmpp:get_lang(Packet), Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)), + Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, @@ -853,13 +769,19 @@ send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:get_motd(LServer) of {ok, Packet} -> - case Mod:is_motd_user(LUser, LServer) of - false -> - Local = jid:make(<<>>, LServer, <<>>), - ejabberd_router:route(Local, JID, Packet), - Mod:set_motd_user(LUser, LServer); - true -> - ok + try xmpp:decode(Packet, [ignore_els]) of + Msg -> + case Mod:is_motd_user(LUser, LServer) of + false -> + Local = jid:make(LServer), + ejabberd_router:route(Local, JID, Msg), + Mod:set_motd_user(LUser, LServer); + true -> + ok + end + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode motd packet ~p: ~s", + [Packet, xmpp:format_error(Why)]) end; error -> ok @@ -871,31 +793,24 @@ get_stored_motd(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:get_motd(LServer) of {ok, Packet} -> - {fxml:get_subtag_cdata(Packet, <<"subject">>), - fxml:get_subtag_cdata(Packet, <<"body">>)}; + try xmpp:decode(Packet, [ignore_els]) of + #message{body = Body, subject = Subject} -> + {xmpp:get_text(Subject), xmpp:get_text(Body)} + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode motd packet ~p: ~s", + [Packet, xmpp:format_error(Why)]) + end; error -> {<<>>, <<>>} end. %% This function is similar to others, but doesn't perform any ACL verification send_announcement_to_all(Host, SubjectS, BodyS) -> - SubjectEls = if SubjectS /= <<>> -> - [#xmlel{name = <<"subject">>, children = [{xmlcdata, SubjectS}]}]; - true -> - [] - end, - BodyEls = if BodyS /= <<>> -> - [#xmlel{name = <<"body">>, children = [{xmlcdata, BodyS}]}]; - true -> - [] - end, - Packet = #xmlel{ - name = <<"message">>, - attrs = [{<<"type">>, <<"headline">>}], - children = SubjectEls ++ BodyEls - }, + Packet = #message{type = headline, + body = xmpp:mk_text(BodyS), + subject = xmpp:mk_text(SubjectS)}, Sessions = ejabberd_sm:dirty_get_sessions_list(), - Local = jid:make(<<>>, Host, <<>>), + Local = jid:make(Host), lists:foreach( fun({U, S, R}) -> Dest = jid:make(U, S, R), diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index c59c347f9..c8a4f002f 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,30 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"command">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"note">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"actions">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"complete">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"next">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"prev">>, + <<"http://jabber.org/protocol/commands">>} -> + decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> @@ -1254,6 +1278,24 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"command">>, + <<"http://jabber.org/protocol/commands">>} -> + true; + {<<"note">>, + <<"http://jabber.org/protocol/commands">>} -> + true; + {<<"actions">>, + <<"http://jabber.org/protocol/commands">>} -> + true; + {<<"complete">>, + <<"http://jabber.org/protocol/commands">>} -> + true; + {<<"next">>, + <<"http://jabber.org/protocol/commands">>} -> + true; + {<<"prev">>, + <<"http://jabber.org/protocol/commands">>} -> + true; {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> true; {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> true; {<<"addresses">>, @@ -2483,7 +2525,20 @@ encode({stanza_id, _, _} = Stanza_id) -> [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]); encode({client_id, _} = Client_id) -> encode_client_id(Client_id, - [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]). + [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]); +encode({adhoc_actions, _, _, _, _} = Actions) -> + encode_adhoc_command_actions(Actions, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/commands">>}]); +encode({adhoc_note, _, _} = Note) -> + encode_adhoc_command_notes(Note, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/commands">>}]); +encode({adhoc_command, _, _, _, _, _, _, _, _} = + Command) -> + encode_adhoc_command(Command, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/commands">>}]). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2661,7 +2716,11 @@ get_name({nick, _}) -> <<"nick">>; get_name({address, _, _, _, _, _}) -> <<"address">>; get_name({addresses, _}) -> <<"addresses">>; get_name({stanza_id, _, _}) -> <<"stanza-id">>; -get_name({client_id, _}) -> <<"client-id">>. +get_name({client_id, _}) -> <<"client-id">>; +get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>; +get_name({adhoc_note, _, _}) -> <<"note">>; +get_name({adhoc_command, _, _, _, _, _, _, _, _}) -> + <<"command">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -2909,7 +2968,13 @@ get_ns({address, _, _, _, _, _}) -> get_ns({addresses, _}) -> <<"http://jabber.org/protocol/address">>; get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; -get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>. +get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>; +get_ns({adhoc_actions, _, _, _, _}) -> + <<"http://jabber.org/protocol/commands">>; +get_ns({adhoc_note, _, _}) -> + <<"http://jabber.org/protocol/commands">>; +get_ns({adhoc_command, _, _, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/commands">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3140,6 +3205,11 @@ pp(address, 5) -> [type, jid, desc, node, delivered]; pp(addresses, 1) -> [list]; pp(stanza_id, 2) -> [by, id]; pp(client_id, 1) -> [id]; +pp(adhoc_actions, 4) -> [execute, prev, next, complete]; +pp(adhoc_note, 2) -> [type, data]; +pp(adhoc_command, 8) -> + [node, action, sid, status, lang, actions, notes, + xdata]; pp(_, _) -> no. join([], _Sep) -> <<>>; @@ -3186,6 +3256,474 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_adhoc_command(__TopXMLNS, __IgnoreEls, + {xmlel, <<"command">>, _attrs, _els}) -> + {Xdata, Notes, Actions} = + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + undefined, [], undefined), + {Node, Lang, Sid, Status, Action} = + decode_adhoc_command_attrs(__TopXMLNS, _attrs, + undefined, undefined, undefined, undefined, + undefined), + {adhoc_command, Node, Action, Sid, Status, Lang, + Actions, Notes, Xdata}. + +decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, [], + Xdata, Notes, Actions) -> + {Xdata, lists:reverse(Notes), Actions}; +decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"actions">>, _attrs, _} = _el | _els], + Xdata, Notes, Actions) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, + decode_adhoc_command_actions(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, + decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, + __IgnoreEls, + _el)); + _ -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, Actions) + end; +decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, + Notes, Actions) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el), + Notes, Actions); + _ -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, Actions) + end; +decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"note">>, _attrs, _} = _el | _els], Xdata, + Notes, Actions) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + [decode_adhoc_command_notes(__TopXMLNS, + __IgnoreEls, _el) + | Notes], + Actions); + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, + [decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, + __IgnoreEls, _el) + | Notes], + Actions); + _ -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, Actions) + end; +decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Xdata, Notes, Actions) -> + decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, + Xdata, Notes, Actions). + +decode_adhoc_command_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node, Lang, Sid, + Status, Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, _val, + Lang, Sid, Status, Action); +decode_adhoc_command_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], Node, _Lang, Sid, + Status, Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, + _val, Sid, Status, Action); +decode_adhoc_command_attrs(__TopXMLNS, + [{<<"sessionid">>, _val} | _attrs], Node, Lang, _Sid, + Status, Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, + Lang, _val, Status, Action); +decode_adhoc_command_attrs(__TopXMLNS, + [{<<"status">>, _val} | _attrs], Node, Lang, Sid, + _Status, Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, + Lang, Sid, _val, Action); +decode_adhoc_command_attrs(__TopXMLNS, + [{<<"action">>, _val} | _attrs], Node, Lang, Sid, + Status, _Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, + Lang, Sid, Status, _val); +decode_adhoc_command_attrs(__TopXMLNS, [_ | _attrs], + Node, Lang, Sid, Status, Action) -> + decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, + Lang, Sid, Status, Action); +decode_adhoc_command_attrs(__TopXMLNS, [], Node, Lang, + Sid, Status, Action) -> + {decode_adhoc_command_attr_node(__TopXMLNS, Node), + 'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, Lang), + decode_adhoc_command_attr_sessionid(__TopXMLNS, Sid), + decode_adhoc_command_attr_status(__TopXMLNS, Status), + decode_adhoc_command_attr_action(__TopXMLNS, Action)}. + +encode_adhoc_command({adhoc_command, Node, Action, Sid, + Status, Lang, Actions, Notes, Xdata}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_adhoc_command_$xdata'(Xdata, + 'encode_adhoc_command_$notes'(Notes, + 'encode_adhoc_command_$actions'(Actions, + [])))), + _attrs = encode_adhoc_command_attr_action(Action, + encode_adhoc_command_attr_status(Status, + encode_adhoc_command_attr_sessionid(Sid, + 'encode_adhoc_command_attr_xml:lang'(Lang, + encode_adhoc_command_attr_node(Node, + _xmlns_attrs))))), + {xmlel, <<"command">>, _attrs, _els}. + +'encode_adhoc_command_$xdata'(undefined, _acc) -> _acc; +'encode_adhoc_command_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +'encode_adhoc_command_$notes'([], _acc) -> _acc; +'encode_adhoc_command_$notes'([Notes | _els], _acc) -> + 'encode_adhoc_command_$notes'(_els, + [encode_adhoc_command_notes(Notes, []) + | _acc]). + +'encode_adhoc_command_$actions'(undefined, _acc) -> + _acc; +'encode_adhoc_command_$actions'(Actions, _acc) -> + [encode_adhoc_command_actions(Actions, []) | _acc]. + +decode_adhoc_command_attr_node(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"command">>, __TopXMLNS}}); +decode_adhoc_command_attr_node(__TopXMLNS, _val) -> + _val. + +encode_adhoc_command_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, + undefined) -> + undefined; +'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, + _val) -> + _val. + +'encode_adhoc_command_attr_xml:lang'(undefined, _acc) -> + _acc; +'encode_adhoc_command_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_adhoc_command_attr_sessionid(__TopXMLNS, + undefined) -> + undefined; +decode_adhoc_command_attr_sessionid(__TopXMLNS, _val) -> + _val. + +encode_adhoc_command_attr_sessionid(undefined, _acc) -> + _acc; +encode_adhoc_command_attr_sessionid(_val, _acc) -> + [{<<"sessionid">>, _val} | _acc]. + +decode_adhoc_command_attr_status(__TopXMLNS, + undefined) -> + undefined; +decode_adhoc_command_attr_status(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [canceled, completed, executing]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"status">>, <<"command">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_adhoc_command_attr_status(undefined, _acc) -> + _acc; +encode_adhoc_command_attr_status(_val, _acc) -> + [{<<"status">>, enc_enum(_val)} | _acc]. + +decode_adhoc_command_attr_action(__TopXMLNS, + undefined) -> + execute; +decode_adhoc_command_attr_action(__TopXMLNS, _val) -> + case catch dec_enum(_val, + [cancel, complete, execute, next, prev]) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"action">>, <<"command">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_adhoc_command_attr_action(execute, _acc) -> _acc; +encode_adhoc_command_attr_action(_val, _acc) -> + [{<<"action">>, enc_enum(_val)} | _acc]. + +decode_adhoc_command_notes(__TopXMLNS, __IgnoreEls, + {xmlel, <<"note">>, _attrs, _els}) -> + Data = decode_adhoc_command_notes_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Type = decode_adhoc_command_notes_attrs(__TopXMLNS, + _attrs, undefined), + {adhoc_note, Type, Data}. + +decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, + [], Data) -> + decode_adhoc_command_notes_cdata(__TopXMLNS, Data); +decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, + _els, Data). + +decode_adhoc_command_notes_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], _Type) -> + decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs, + _val); +decode_adhoc_command_notes_attrs(__TopXMLNS, + [_ | _attrs], Type) -> + decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs, + Type); +decode_adhoc_command_notes_attrs(__TopXMLNS, [], + Type) -> + decode_adhoc_command_notes_attr_type(__TopXMLNS, Type). + +encode_adhoc_command_notes({adhoc_note, Type, Data}, + _xmlns_attrs) -> + _els = encode_adhoc_command_notes_cdata(Data, []), + _attrs = encode_adhoc_command_notes_attr_type(Type, + _xmlns_attrs), + {xmlel, <<"note">>, _attrs, _els}. + +decode_adhoc_command_notes_attr_type(__TopXMLNS, + undefined) -> + info; +decode_adhoc_command_notes_attr_type(__TopXMLNS, + _val) -> + case catch dec_enum(_val, [info, warn, error]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"note">>, __TopXMLNS}}); + _res -> _res + end. + +encode_adhoc_command_notes_attr_type(info, _acc) -> + _acc; +encode_adhoc_command_notes_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_adhoc_command_notes_cdata(__TopXMLNS, <<>>) -> + <<>>; +decode_adhoc_command_notes_cdata(__TopXMLNS, _val) -> + _val. + +encode_adhoc_command_notes_cdata(<<>>, _acc) -> _acc; +encode_adhoc_command_notes_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_adhoc_command_actions(__TopXMLNS, __IgnoreEls, + {xmlel, <<"actions">>, _attrs, _els}) -> + {Next, Complete, Prev} = + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, false, false, + false), + Execute = decode_adhoc_command_actions_attrs(__TopXMLNS, + _attrs, undefined), + {adhoc_actions, Execute, Prev, Next, Complete}. + +decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, [], Next, Complete, Prev) -> + {Next, Complete, Prev}; +decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"prev">>, _attrs, _} = _el | _els], + Next, Complete, Prev) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, + decode_adhoc_command_prev(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, + decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, + __IgnoreEls, + _el)); + _ -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, + Prev) + end; +decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"next">>, _attrs, _} = _el | _els], + Next, Complete, Prev) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, + decode_adhoc_command_next(__TopXMLNS, + __IgnoreEls, + _el), + Complete, Prev); + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, + decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, + __IgnoreEls, + _el), + Complete, Prev); + _ -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, + Prev) + end; +decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"complete">>, _attrs, _} = _el + | _els], + Next, Complete, Prev) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, + decode_adhoc_command_complete(__TopXMLNS, + __IgnoreEls, + _el), + Prev); + <<"http://jabber.org/protocol/commands">> -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, + decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, + __IgnoreEls, + _el), + Prev); + _ -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, + Prev) + end; +decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Next, Complete, + Prev) -> + decode_adhoc_command_actions_els(__TopXMLNS, + __IgnoreEls, _els, Next, Complete, Prev). + +decode_adhoc_command_actions_attrs(__TopXMLNS, + [{<<"execute">>, _val} | _attrs], + _Execute) -> + decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs, + _val); +decode_adhoc_command_actions_attrs(__TopXMLNS, + [_ | _attrs], Execute) -> + decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs, + Execute); +decode_adhoc_command_actions_attrs(__TopXMLNS, [], + Execute) -> + decode_adhoc_command_actions_attr_execute(__TopXMLNS, + Execute). + +encode_adhoc_command_actions({adhoc_actions, Execute, + Prev, Next, Complete}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_adhoc_command_actions_$next'(Next, + 'encode_adhoc_command_actions_$complete'(Complete, + 'encode_adhoc_command_actions_$prev'(Prev, + [])))), + _attrs = + encode_adhoc_command_actions_attr_execute(Execute, + _xmlns_attrs), + {xmlel, <<"actions">>, _attrs, _els}. + +'encode_adhoc_command_actions_$next'(false, _acc) -> + _acc; +'encode_adhoc_command_actions_$next'(Next, _acc) -> + [encode_adhoc_command_next(Next, []) | _acc]. + +'encode_adhoc_command_actions_$complete'(false, _acc) -> + _acc; +'encode_adhoc_command_actions_$complete'(Complete, + _acc) -> + [encode_adhoc_command_complete(Complete, []) | _acc]. + +'encode_adhoc_command_actions_$prev'(false, _acc) -> + _acc; +'encode_adhoc_command_actions_$prev'(Prev, _acc) -> + [encode_adhoc_command_prev(Prev, []) | _acc]. + +decode_adhoc_command_actions_attr_execute(__TopXMLNS, + undefined) -> + undefined; +decode_adhoc_command_actions_attr_execute(__TopXMLNS, + _val) -> + case catch dec_enum(_val, [complete, next, prev]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"execute">>, <<"actions">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_adhoc_command_actions_attr_execute(undefined, + _acc) -> + _acc; +encode_adhoc_command_actions_attr_execute(_val, _acc) -> + [{<<"execute">>, enc_enum(_val)} | _acc]. + +decode_adhoc_command_complete(__TopXMLNS, __IgnoreEls, + {xmlel, <<"complete">>, _attrs, _els}) -> + true. + +encode_adhoc_command_complete(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"complete">>, _attrs, _els}. + +decode_adhoc_command_next(__TopXMLNS, __IgnoreEls, + {xmlel, <<"next">>, _attrs, _els}) -> + true. + +encode_adhoc_command_next(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"next">>, _attrs, _els}. + +decode_adhoc_command_prev(__TopXMLNS, __IgnoreEls, + {xmlel, <<"prev">>, _attrs, _els}) -> + true. + +encode_adhoc_command_prev(true, _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"prev">>, _attrs, _els}. + decode_client_id(__TopXMLNS, __IgnoreEls, {xmlel, <<"client-id">>, _attrs, _els}) -> Id = decode_client_id_attrs(__TopXMLNS, _attrs, diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 83f1f4adc..a4f37c926 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -11,7 +11,7 @@ %% API -export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, is_standalone_chat_state/1, get_xdata_values/2, - has_xdata_var/2]). + has_xdata_var/2, make_adhoc_response/1, make_adhoc_response/2]). -include("xmpp.hrl"). @@ -88,6 +88,18 @@ get_xdata_values(Var, #xdata{fields = Fields}) -> has_xdata_var(Var, #xdata{fields = Fields}) -> lists:keymember(Var, #xdata_field.var, Fields). +-spec make_adhoc_response(adhoc_command(), adhoc_command()) -> adhoc_command(). +make_adhoc_response(#adhoc_command{lang = Lang, node = Node, sid = SID}, + Command) -> + Command#adhoc_command{lang = Lang, node = Node, sid = SID}. + +-spec make_adhoc_response(adhoc_command()) -> adhoc_command(). +make_adhoc_response(#adhoc_command{sid = undefined} = Command) -> + SID = jlib:now_to_utc_string(p1_time_compat:timestamp()), + Command#adhoc_command{sid = SID}; +make_adhoc_response(Command) -> + Command. + %%%=================================================================== %%% Internal functions %%%=================================================================== -- cgit v1.2.3 From c26d38a8937d46837fbdcf047abbf249f6d95a56 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 26 Jul 2016 10:01:59 +0300 Subject: Remove jlib dependency from acl.erl --- src/acl.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/acl.erl b/src/acl.erl index 31a7547dd..7519e12e2 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -39,7 +39,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("jid.hrl"). -record(acl, {aclname, aclspec}). -record(access, {name :: aclname(), @@ -531,7 +531,7 @@ parse_ip_netmask(S) -> _ -> error end; [IPStr, MaskStr] -> - case catch jlib:binary_to_integer(MaskStr) of + case catch binary_to_integer(MaskStr) of Mask when is_integer(Mask), Mask >= 0 -> case inet_parse:address(binary_to_list(IPStr)) of {ok, {_, _, _, _} = IP} when Mask =< 32 -> -- cgit v1.2.3 From 23858469b7804739fa280aeb77fc7f41c1d0538e Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 26 Jul 2016 11:29:17 +0300 Subject: Get rid of "jlib.hrl" dependency in some files --- src/cyrsasl.erl | 24 ------------------------ src/cyrsasl_scram.erl | 2 -- src/ejabberd_auth_anonymous.erl | 3 +-- src/ejabberd_oauth.erl | 2 +- src/ejabberd_sm.erl | 1 - src/ejabberd_sm_mnesia.erl | 1 - src/ejabberd_sm_redis.erl | 1 - src/ejabberd_sm_sql.erl | 1 - src/ejabberd_socket.erl | 3 +-- src/jid.erl | 1 + src/mod_announce_mnesia.erl | 2 +- src/mod_announce_riak.erl | 2 +- src/mod_announce_sql.erl | 2 +- src/mod_blocking_mnesia.erl | 1 - src/mod_blocking_riak.erl | 1 - src/mod_blocking_sql.erl | 1 - src/mod_muc_sql.erl | 2 +- src/mod_offline_mnesia.erl | 2 +- src/mod_offline_riak.erl | 2 +- src/mod_offline_sql.erl | 2 +- src/mod_privacy_mnesia.erl | 2 +- src/mod_privacy_riak.erl | 2 +- src/mod_privacy_sql.erl | 2 +- src/mod_private_mnesia.erl | 2 +- src/mod_private_riak.erl | 2 +- src/mod_private_sql.erl | 2 +- src/mod_roster_mnesia.erl | 1 - src/mod_roster_riak.erl | 1 - src/mod_roster_sql.erl | 1 - src/mod_vcard_mnesia.erl | 2 +- src/mod_vcard_riak.erl | 2 +- src/mod_vcard_sql.erl | 2 +- src/prosody2ejabberd.erl | 2 +- 33 files changed, 21 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl index 46b23384e..4b0f5a26b 100644 --- a/src/cyrsasl.erl +++ b/src/cyrsasl.erl @@ -102,30 +102,6 @@ register_mechanism(Mechanism, Module, PasswordType) -> true end. -%%% TODO: use callbacks -%%-include("ejabberd.hrl"). -%%-include("jlib.hrl"). -%%check_authzid(_State, Props) -> -%% AuthzId = fxml:get_attr_s(authzid, Props), -%% case jid:from_string(AuthzId) of -%% error -> -%% {error, "invalid-authzid"}; -%% JID -> -%% LUser = jid:nodeprep(fxml:get_attr_s(username, Props)), -%% {U, S, R} = jid:tolower(JID), -%% case R of -%% "" -> -%% {error, "invalid-authzid"}; -%% _ -> -%% case {LUser, ?MYNAME} of -%% {U, S} -> -%% ok; -%% _ -> -%% {error, "invalid-authzid"} -%% end -%% end -%% end. - check_credentials(_State, Props) -> User = proplists:get_value(authzid, Props, <<>>), case jid:nodeprep(User) of diff --git a/src/cyrsasl_scram.erl b/src/cyrsasl_scram.erl index 8643a8924..fdc40cd86 100644 --- a/src/cyrsasl_scram.erl +++ b/src/cyrsasl_scram.erl @@ -34,8 +34,6 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). - -behaviour(cyrsasl). -record(state, diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index 5a5b395bf..c0ad1fb21 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -50,8 +50,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). +-include("jid.hrl"). %% Create the anonymous table if at least one virtual host has anonymous features enabled %% Register to login / logout events diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl index 57c1baab2..4e9dc8d08 100644 --- a/src/ejabberd_oauth.erl +++ b/src/ejabberd_oauth.erl @@ -50,7 +50,7 @@ -export([oauth_issue_token/1, oauth_list_tokens/0, oauth_revoke_token/1, oauth_list_scopes/0]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd.hrl"). -include("logger.hrl"). diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index ec9ef43c6..bc550ef44 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -78,7 +78,6 @@ -include("ejabberd.hrl"). -include("logger.hrl"). -%%-include("jlib.hrl"). -include("xmpp.hrl"). -include("ejabberd_commands.hrl"). diff --git a/src/ejabberd_sm_mnesia.erl b/src/ejabberd_sm_mnesia.erl index b900da315..491872aee 100644 --- a/src/ejabberd_sm_mnesia.erl +++ b/src/ejabberd_sm_mnesia.erl @@ -26,7 +26,6 @@ -include("ejabberd.hrl"). -include("ejabberd_sm.hrl"). --include("jlib.hrl"). -include_lib("stdlib/include/ms_transform.hrl"). -record(state, {}). diff --git a/src/ejabberd_sm_redis.erl b/src/ejabberd_sm_redis.erl index d25f777e3..9c78acaf7 100644 --- a/src/ejabberd_sm_redis.erl +++ b/src/ejabberd_sm_redis.erl @@ -19,7 +19,6 @@ -include("ejabberd.hrl"). -include("ejabberd_sm.hrl"). -include("logger.hrl"). --include("jlib.hrl"). %%%=================================================================== %%% API diff --git a/src/ejabberd_sm_sql.erl b/src/ejabberd_sm_sql.erl index 8871bbca4..28796aca0 100644 --- a/src/ejabberd_sm_sql.erl +++ b/src/ejabberd_sm_sql.erl @@ -24,7 +24,6 @@ -include("ejabberd.hrl"). -include("ejabberd_sm.hrl"). -include("logger.hrl"). --include("jlib.hrl"). -include("ejabberd_sql_pt.hrl"). %%%=================================================================== diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index aa916867a..7160025e7 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -49,7 +49,6 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). -type sockmod() :: ejabberd_http_bind | ejabberd_http_ws | @@ -189,7 +188,7 @@ send(SocketData, Data) -> %% Can only be called when in c2s StateData#state.xml_socket is true %% This function is used for HTTP bind %% sockmod=ejabberd_http_ws|ejabberd_http_bind or any custom module --spec send_xml(socket_state(), xmlel()) -> any(). +-spec send_xml(socket_state(), fxml:xmlel()) -> any(). send_xml(SocketData, Data) -> catch diff --git a/src/jid.erl b/src/jid.erl index d81cbcefd..9e8ea9d23 100644 --- a/src/jid.erl +++ b/src/jid.erl @@ -44,6 +44,7 @@ -include("jid.hrl"). -export_type([jid/0]). +-export_type([ljid/0]). %%%=================================================================== %%% API diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl index c43eb853b..b5a1f590e 100644 --- a/src/mod_announce_mnesia.erl +++ b/src/mod_announce_mnesia.erl @@ -13,7 +13,7 @@ -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, get_motd/1, is_motd_user/2, set_motd_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_announce.hrl"). -include("logger.hrl"). diff --git a/src/mod_announce_riak.erl b/src/mod_announce_riak.erl index 7ced0b3ce..879eb196d 100644 --- a/src/mod_announce_riak.erl +++ b/src/mod_announce_riak.erl @@ -13,7 +13,7 @@ -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, get_motd/1, is_motd_user/2, set_motd_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_announce.hrl"). %%%=================================================================== diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl index 762c97ad6..37b4412d3 100644 --- a/src/mod_announce_sql.erl +++ b/src/mod_announce_sql.erl @@ -16,7 +16,7 @@ get_motd/1, is_motd_user/2, set_motd_user/2, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_announce.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/mod_blocking_mnesia.erl b/src/mod_blocking_mnesia.erl index 5a4bde64c..b64202717 100644 --- a/src/mod_blocking_mnesia.erl +++ b/src/mod_blocking_mnesia.erl @@ -14,7 +14,6 @@ -export([process_blocklist_block/3, unblock_by_filter/3, process_blocklist_get/2]). --include("jlib.hrl"). -include("mod_privacy.hrl"). %%%=================================================================== diff --git a/src/mod_blocking_riak.erl b/src/mod_blocking_riak.erl index 5dd5cfa92..1f15591ef 100644 --- a/src/mod_blocking_riak.erl +++ b/src/mod_blocking_riak.erl @@ -14,7 +14,6 @@ -export([process_blocklist_block/3, unblock_by_filter/3, process_blocklist_get/2]). --include("jlib.hrl"). -include("mod_privacy.hrl"). %%%=================================================================== diff --git a/src/mod_blocking_sql.erl b/src/mod_blocking_sql.erl index bffe5bd25..402d6de19 100644 --- a/src/mod_blocking_sql.erl +++ b/src/mod_blocking_sql.erl @@ -14,7 +14,6 @@ -export([process_blocklist_block/3, unblock_by_filter/3, process_blocklist_get/2]). --include("jlib.hrl"). -include("mod_privacy.hrl"). %%%=================================================================== diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl index ff7ec1ebb..3139b5316 100644 --- a/src/mod_muc_sql.erl +++ b/src/mod_muc_sql.erl @@ -17,7 +17,7 @@ can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("jid.hrl"). -include("mod_muc.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index 6a1d9e309..e8db08ddf 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -15,7 +15,7 @@ read_message/3, remove_message/3, read_all_messages/2, remove_all_messages/2, count_messages/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_offline.hrl"). -include("logger.hrl"). diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl index 217e8f828..647f71dfd 100644 --- a/src/mod_offline_riak.erl +++ b/src/mod_offline_riak.erl @@ -15,7 +15,7 @@ read_message/3, remove_message/3, read_all_messages/2, remove_all_messages/2, count_messages/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_offline.hrl"). %%%=================================================================== diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index feefd3dd0..b5033c710 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -18,7 +18,7 @@ remove_all_messages/2, count_messages/2, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_offline.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl index 1a9172b5a..4642ba58e 100644 --- a/src/mod_privacy_mnesia.erl +++ b/src/mod_privacy_mnesia.erl @@ -17,7 +17,7 @@ set_privacy_list/4, get_user_list/2, get_user_lists/2, remove_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). -include("logger.hrl"). diff --git a/src/mod_privacy_riak.erl b/src/mod_privacy_riak.erl index 40e92005c..509ff5ebb 100644 --- a/src/mod_privacy_riak.erl +++ b/src/mod_privacy_riak.erl @@ -19,7 +19,7 @@ -export([privacy_schema/0]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). %%%=================================================================== diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index 66926f236..a1f743657 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -28,7 +28,7 @@ sql_get_privacy_list_id_t/2, sql_set_default_privacy_list/2, sql_set_privacy_list/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_privacy.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index 7a852c4f8..d1bf20c85 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -13,7 +13,7 @@ -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_private.hrl"). -include("logger.hrl"). diff --git a/src/mod_private_riak.erl b/src/mod_private_riak.erl index 11cfa4770..b05e7d725 100644 --- a/src/mod_private_riak.erl +++ b/src/mod_private_riak.erl @@ -14,7 +14,7 @@ -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_private.hrl"). %%%=================================================================== diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl index 0e9d1b61e..eb113d923 100644 --- a/src/mod_private_sql.erl +++ b/src/mod_private_sql.erl @@ -14,7 +14,7 @@ -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_private.hrl"). %%%=================================================================== diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index ddfa34d68..398f105d5 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -17,7 +17,6 @@ remove_user/2, update_roster/4, del_roster/3, transaction/2, read_subscription_and_groups/3, import/2]). --include("jlib.hrl"). -include("mod_roster.hrl"). -include("logger.hrl"). diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl index 38e873827..9ed5e7927 100644 --- a/src/mod_roster_riak.erl +++ b/src/mod_roster_riak.erl @@ -18,7 +18,6 @@ remove_user/2, update_roster/4, del_roster/3, transaction/2, read_subscription_and_groups/3, get_only_items/2, import/2]). --include("jlib.hrl"). -include("mod_roster.hrl"). %%%=================================================================== diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl index 61f59a990..4d97aead0 100644 --- a/src/mod_roster_sql.erl +++ b/src/mod_roster_sql.erl @@ -20,7 +20,6 @@ read_subscription_and_groups/3, get_only_items/2, import/1, import/2, export/1]). --include("jlib.hrl"). -include("mod_roster.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index 781a135c8..67abed09b 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -14,7 +14,7 @@ -export([init/2, import/2, get_vcard/2, set_vcard/4, search/4, remove_user/2]). -include("ejabberd.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_vcard.hrl"). -include("logger.hrl"). diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl index 386347387..397008a79 100644 --- a/src/mod_vcard_riak.erl +++ b/src/mod_vcard_riak.erl @@ -14,7 +14,7 @@ -export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, import/2]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_vcard.hrl"). %%%=================================================================== diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index b8234bf9c..f448d0776 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -16,7 +16,7 @@ -export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_vcard.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). diff --git a/src/prosody2ejabberd.erl b/src/prosody2ejabberd.erl index 204cfec2f..d5eca5ecb 100644 --- a/src/prosody2ejabberd.erl +++ b/src/prosody2ejabberd.erl @@ -12,7 +12,7 @@ -export([from_dir/1]). -include("ejabberd.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("logger.hrl"). -include("mod_roster.hrl"). -include("mod_offline.hrl"). -- cgit v1.2.3 From c409ed2f2c09ae79a22745e2a253023787017893 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 27 Jul 2016 10:45:08 +0300 Subject: Rewrite S2S and ejabberd_service code to use XML generator --- src/ejabberd_c2s.erl | 191 +++++----- src/ejabberd_http_bind.erl | 2 - src/ejabberd_router.erl | 21 +- src/ejabberd_s2s.erl | 46 +-- src/ejabberd_s2s_in.erl | 653 +++++++++++++++----------------- src/ejabberd_s2s_out.erl | 924 ++++++++++++++++++--------------------------- src/ejabberd_service.erl | 379 ++++++++----------- src/xmpp.erl | 13 +- src/xmpp_codec.erl | 531 +++++++++++++++++++++++++- 9 files changed, 1499 insertions(+), 1261 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 8d217a354..1ae9a7c29 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -320,42 +320,46 @@ get_subscribed(FsmRef) -> (?GEN_FSM):sync_send_all_state_event(FsmRef, get_subscribed, 1000). -wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> - DefaultLang = ?MYLANG, - case fxml:get_attr_s(<<"xmlns:stream">>, Attrs) of - ?NS_STREAM -> - Server = - case StateData#state.server of - <<"">> -> - jid:nameprep(fxml:get_attr_s(<<"to">>, Attrs)); - S -> S - end, - Lang = case fxml:get_attr_s(<<"xml:lang">>, Attrs) of - Lang1 when byte_size(Lang1) =< 35 -> - %% As stated in BCP47, 4.4.1: - %% Protocols or specifications that - %% specify limited buffer sizes for - %% language tags MUST allow for - %% language tags of at least 35 characters. - Lang1; - _ -> - %% Do not store long language tag to - %% avoid possible DoS/flood attacks - <<"">> - end, - StreamVersion = case fxml:get_attr_s(<<"version">>, Attrs) of - <<"1.0">> -> - <<"1.0">>; - _ -> - <<"">> - end, +wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> + try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of + #stream_start{xmlns = NS_CLIENT, stream_xmlns = NS_STREAM, lang = Lang} + when NS_CLIENT /= ?NS_CLIENT; NS_STREAM /= ?NS_STREAM -> + send_header(StateData, ?MYNAME, <<"">>, Lang), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData}; + #stream_start{lang = Lang} when byte_size(Lang) > 35 -> + %% As stated in BCP47, 4.4.1: + %% Protocols or specifications that specify limited buffer sizes for + %% language tags MUST allow for language tags of at least 35 characters. + %% Do not store long language tag to avoid possible DoS/flood attacks + send_header(StateData, ?MYNAME, <<"">>, ?MYLANG), + Txt = <<"Too long value of 'xml:lang' attribute">>, + send_element(StateData, + xmpp:serr_policy_violation(Txt, ?MYLANG)), + {stop, normal, StateData}; + #stream_start{to = undefined, lang = Lang} -> + Txt = <<"Missing 'to' attribute">>, + send_header(StateData, ?MYNAME, <<"">>, Lang), + send_element(StateData, + xmpp:serr_improper_addressing(Txt, Lang)), + {stop, normal, StateData}; + #stream_start{to = #jid{lserver = To}, lang = Lang, + version = Version} -> + Server = case StateData#state.server of + <<"">> -> To; + S -> S + end, + StreamVersion = case Version of + <<"1.0">> -> <<"1.0">>; + _ -> <<"">> + end, IsBlacklistedIP = is_ip_blacklisted(StateData#state.ip, Lang), case lists:member(Server, ?MYHOSTS) of true when IsBlacklistedIP == false -> change_shaper(StateData, jid:make(<<"">>, Server, <<"">>)), case StreamVersion of <<"1.0">> -> - send_header(StateData, Server, <<"1.0">>, DefaultLang), + send_header(StateData, Server, <<"1.0">>, ?MYLANG), case StateData#state.authenticated of false -> TLS = StateData#state.tls, @@ -458,7 +462,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> end end; _ -> - send_header(StateData, Server, <<"">>, DefaultLang), + send_header(StateData, Server, <<"">>, ?MYLANG), if not StateData#state.tls_enabled and StateData#state.tls_required -> send_element( @@ -477,17 +481,18 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> {true, LogReason, ReasonT} = IsBlacklistedIP, ?INFO_MSG("Connection attempt from blacklisted IP ~s: ~s", [jlib:ip_to_list(IP), LogReason]), - send_header(StateData, Server, StreamVersion, DefaultLang), + send_header(StateData, Server, StreamVersion, ?MYLANG), send_element(StateData, xmpp:serr_policy_violation(ReasonT, Lang)), {stop, normal, StateData}; _ -> - send_header(StateData, ?MYNAME, StreamVersion, DefaultLang), + send_header(StateData, ?MYNAME, StreamVersion, ?MYLANG), send_element(StateData, xmpp:serr_host_unknown()), {stop, normal, StateData} - end; - _ -> - send_header(StateData, ?MYNAME, <<"">>, DefaultLang), - send_element(StateData, xmpp:serr_invalid_namespace()), + end + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + send_header(StateData, ?MYNAME, <<"">>, ?MYLANG), + send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> @@ -854,38 +859,36 @@ resource_conflict_action(U, S, R) -> {accept_resource, Rnew} end. --spec decode_subels(stanza()) -> stanza(). -decode_subels(#iq{sub_els = [El], type = T} = IQ) when T == set; T == get -> - NewEl = case xmpp:get_ns(El) of - ?NS_BIND when T == set -> xmpp:decode(El); - ?NS_AUTH -> xmpp:decode(El); - ?NS_PRIVACY -> xmpp:decode(El); - ?NS_BLOCKING -> xmpp:decode(El); - _ -> El - end, - IQ#iq{sub_els = [NewEl]}; -decode_subels(Pkt) -> - Pkt. - --spec decode_element(xmlel(), state_name(), state()) -> fsm_next(). +-spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). decode_element(#xmlel{} = El, StateName, StateData) -> - try - Pkt0 = xmpp:decode(El, [ignore_els]), - Pkt = decode_subels(Pkt0), - ?MODULE:StateName(Pkt, StateData) + try case xmpp:decode(El, [ignore_els]) of + #iq{sub_els = [_], type = T} = Pkt when T == set; T == get -> + NewPkt = xmpp:decode_els( + Pkt, + fun(SubEl) when StateName == session_established -> + case xmpp:get_ns(SubEl) of + ?NS_PRIVACY -> true; + ?NS_BLOCKING -> true; + _ -> false + end; + (SubEl) -> + xmpp_codec:is_known_tag(SubEl) + end), + ?MODULE:StateName(NewPkt, StateData); + Pkt -> + ?MODULE:StateName(Pkt, StateData) + end catch error:{xmpp_codec, Why} -> - Type = xmpp:get_type(El), NS = xmpp:get_ns(El), case xmpp:is_stanza(El) of - true when Type /= <<"result">>, Type /= <<"error">> -> + true -> Lang = xmpp:get_lang(El), Txt = xmpp:format_error(Why), - Err = xmpp:make_error(El, xmpp:err_bad_request(Txt, Lang)), - send_element(StateData, Err); - _ when NS == ?NS_STREAM_MGMT_2; NS == ?NS_STREAM_MGMT_3 -> + send_error(StateData, El, xmpp:err_bad_request(Txt, Lang)); + false when NS == ?NS_STREAM_MGMT_2; NS == ?NS_STREAM_MGMT_3 -> Err = #sm_failed{reason = 'bad-request', xmlns = NS}, send_element(StateData, Err); - _ -> + false -> ok end, fsm_next_state(StateName, StateData) @@ -951,13 +954,7 @@ wait_for_bind(stop, StateData) -> wait_for_bind(Pkt, StateData) -> case xmpp:is_stanza(Pkt) of true -> - Type = xmpp:get_type(Pkt), - if Type /= error, Type /= result -> - Err = xmpp:make_error(Pkt, xmpp:err_not_acceptable()), - send_element(StateData, Err); - true -> - ok - end; + send_error(StateData, Pkt, xmpp:err_not_acceptable()); false -> ok end, @@ -1046,7 +1043,7 @@ session_established(closed, StateData) -> {stop, normal, StateData}; session_established(stop, StateData) -> {stop, normal, StateData}; -session_established(Pkt, StateData) -> +session_established(Pkt, StateData) when ?is_stanza(Pkt) -> FromJID = StateData#state.jid, case check_from(Pkt, FromJID) of 'invalid-from' -> @@ -1055,11 +1052,13 @@ session_established(Pkt, StateData) -> _ -> NewStateData = update_num_stanzas_in(StateData, Pkt), session_established2(Pkt, NewStateData) - end. + end; +session_established(_Pkt, StateData) -> + fsm_next_state(session_established, StateData). -spec session_established2(xmpp_element(), state()) -> fsm_next(). %% Process packets sent by user (coming from user on c2s XMPP connection) -session_established2(Pkt, StateData) when ?is_stanza(Pkt) -> +session_established2(Pkt, StateData) -> User = StateData#state.user, Server = StateData#state.server, FromJID = StateData#state.jid, @@ -1116,11 +1115,7 @@ session_established2(Pkt, StateData) when ?is_stanza(Pkt) -> end, ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, Pkt}]), - fsm_next_state(session_established, NewState); -session_established2(Pkt, StateData) -> - ejabberd_hooks:run(c2s_loop_debug, - [{xmlstreamelement, Pkt}]), - fsm_next_state(session_established, StateData). + fsm_next_state(session_established, NewState). wait_for_resume({xmlstreamelement, _El} = Event, StateData) -> Result = session_established(Event, StateData), @@ -1573,6 +1568,16 @@ send_element(StateData, #xmlel{} = El) -> send_element(StateData, Pkt) -> send_element(StateData, xmpp:encode(Pkt)). +-spec send_error(state(), xmlel() | stanza(), error()) -> ok. +send_error(StateData, Stanza, Error) -> + Type = xmpp:get_type(Stanza), + if Type == error; Type == result; + Type == <<"error">>; Type == <<"result">> -> + ok; + true -> + send_element(StateData, xmpp:make_error(Stanza, Error)) + end. + -spec send_stanza(state(), xmpp_element()) -> state(). send_stanza(StateData, Stanza) when StateData#state.csi_state == inactive -> csi_filter_stanza(StateData, Stanza); @@ -2136,28 +2141,24 @@ is_ip_blacklisted({IP, _Port}, Lang) -> %% Check from attributes %% returns invalid-from|NewElement +-spec check_from(stanza(), jid()) -> 'invalid-from' | stanza(). check_from(Pkt, FromJID) -> - case xmpp:is_stanza(Pkt) of - false -> + JID = xmpp:get_from(Pkt), + case JID of + undefined -> Pkt; - true -> - JID = xmpp:get_from(Pkt), - case JID of - undefined -> + #jid{} -> + if + (JID#jid.luser == FromJID#jid.luser) and + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == FromJID#jid.lresource) -> Pkt; - #jid{} -> - if - (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == FromJID#jid.lresource) -> - Pkt; - (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == <<"">>) -> - Pkt; - true -> - 'invalid-from' - end + (JID#jid.luser == FromJID#jid.luser) and + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == <<"">>) -> + Pkt; + true -> + 'invalid-from' end end. diff --git a/src/ejabberd_http_bind.erl b/src/ejabberd_http_bind.erl index ea8cd792f..6fa38110c 100644 --- a/src/ejabberd_http_bind.erl +++ b/src/ejabberd_http_bind.erl @@ -125,8 +125,6 @@ %% Wait 100ms before continue processing, to allow the client provide more related stanzas. -define(BOSH_VERSION, <<"1.8">>). --define(NS_CLIENT, <<"jabber:client">>). - -define(NS_BOSH, <<"urn:xmpp:xbosh">>). -define(NS_HTTP_BIND, diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 83ffd932b..d65edc6e3 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -389,7 +389,13 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> {From, To, Packet} -> LDstDomain = To#jid.lserver, case mnesia:dirty_read(route, LDstDomain) of - [] -> ejabberd_s2s:route(From, To, Packet); + [] -> + try xmpp:decode(Packet, [ignore_els]) of + Pkt -> + ejabberd_s2s:route(From, To, Pkt) + catch _:{xmpp_codec, Why} -> + log_decoding_error(From, To, Packet, Why) + end; [R] -> do_route(From, To, Packet, R); Rs -> @@ -425,15 +431,18 @@ do_route(From, To, Packet, #route{local_hint = LocalHint, Pid ! {route, From, To, Pkt} end catch error:{xmpp_codec, Why} -> - ?ERROR_MSG("failed to decode xml element ~p when " - "routing from ~s to ~s: ~s", - [Packet, jid:to_string(From), jid:to_string(To), - xmpp:format_error(Why)]), - drop + log_decoding_error(From, To, Packet, Why) end; do_route(_From, _To, _Packet, _Route) -> drop. +-spec log_decoding_error(jid(), jid(), xmlel() | xmpp_element(), term()) -> ok. +log_decoding_error(From, To, Packet, Reason) -> + ?ERROR_MSG("failed to decode xml element ~p when " + "routing from ~s to ~s: ~s", + [Packet, jid:to_string(From), jid:to_string(To), + xmpp:format_error(Reason)]). + -spec get_component_number(binary()) -> pos_integer() | undefined. get_component_number(LDomain) -> ejabberd_config:get_option( diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 19de64adb..e585257e8 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -55,7 +55,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_commands.hrl"). @@ -89,7 +89,7 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). --spec route(jid(), jid(), xmlel()) -> ok. +-spec route(jid(), jid(), xmpp_element()) -> ok. route(From, To, Packet) -> case catch do_route(From, To, Packet) of @@ -222,6 +222,7 @@ check_peer_certificate(SockMod, Sock, Peer) -> {error, <<"Cannot get peer certificate">>} end. +-spec make_key({binary(), binary()}, binary()) -> binary(). make_key({From, To}, StreamID) -> Secret = ejabberd_config:get_option(shared_key, fun(V) -> V end), p1_sha:to_hexlist( @@ -275,7 +276,7 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- - +-spec clean_table_from_bad_node(node()) -> any(). clean_table_from_bad_node(Node) -> F = fun() -> Es = mnesia:select( @@ -289,6 +290,7 @@ clean_table_from_bad_node(Node) -> end, mnesia:async_dirty(F). +-spec do_route(jid(), jid(), stanza()) -> ok | false. do_route(From, To, Packet) -> ?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket " "~P~n", @@ -296,28 +298,16 @@ do_route(From, To, Packet) -> case find_connection(From, To) of {atomic, Pid} when is_pid(Pid) -> ?DEBUG("sending to process ~p~n", [Pid]), - #xmlel{name = Name, attrs = Attrs, children = Els} = - Packet, - NewAttrs = - jlib:replace_from_to_attrs(jid:to_string(From), - jid:to_string(To), Attrs), #jid{lserver = MyServer} = From, ejabberd_hooks:run(s2s_send_packet, MyServer, [From, To, Packet]), - send_element(Pid, - #xmlel{name = Name, attrs = NewAttrs, children = Els}), + send_element(Pid, xmpp:set_from_to(Packet, From, To)), ok; {aborted, _Reason} -> - case fxml:get_tag_attr_s(<<"type">>, Packet) of - <<"error">> -> ok; - <<"result">> -> ok; - _ -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), - Txt = <<"No s2s connection found">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)), - ejabberd_router:route(To, From, Err) - end, + Lang = xmpp:get_lang(Packet), + Txt = <<"No s2s connection found">>, + Err = xmpp:err_service_unavailable(Txt, Lang), + ejabberd_router:route_error(To, From, Packet, Err), false end. @@ -367,9 +357,11 @@ find_connection(From, To) -> end end. +-spec choose_connection(jid(), [#s2s{}]) -> pid(). choose_connection(From, Connections) -> choose_pid(From, [C#s2s.pid || C <- Connections]). +-spec choose_pid(jid(), [pid()]) -> pid(). choose_pid(From, Pids) -> Pids1 = case [P || P <- Pids, node(P) == node()] of [] -> Pids; @@ -417,22 +409,21 @@ new_connection(MyServer, Server, From, FromTo, end, TRes. +-spec max_s2s_connections_number({binary(), binary()}) -> integer(). max_s2s_connections_number({From, To}) -> - case acl:match_rule(From, max_s2s_connections, - jid:make(<<"">>, To, <<"">>)) - of + case acl:match_rule(From, max_s2s_connections, jid:make(To)) of Max when is_integer(Max) -> Max; _ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER end. +-spec max_s2s_connections_number_per_node({binary(), binary()}) -> integer(). max_s2s_connections_number_per_node({From, To}) -> - case acl:match_rule(From, max_s2s_connections_per_node, - jid:make(<<"">>, To, <<"">>)) - of + case acl:match_rule(From, max_s2s_connections_per_node, jid:make(To)) of Max when is_integer(Max) -> Max; _ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE end. +-spec needed_connections_number([#s2s{}], integer(), integer()) -> integer(). needed_connections_number(Ls, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode) -> LocalLs = [L || L <- Ls, node(L#s2s.pid) == node()], @@ -444,6 +435,7 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber, %% Description: Return true if the destination must be considered as a %% service. %% -------------------------------------------------------------------- +-spec is_service(jid(), jid()) -> boolean(). is_service(From, To) -> LFromDomain = From#jid.lserver, case ejabberd_config:get_option( @@ -541,7 +533,7 @@ allow_host1(MyHost, S2SHost) -> s2s_access, fun(A) -> A end, all), - JID = jid:make(<<"">>, S2SHost, <<"">>), + JID = jid:make(S2SHost), case acl:match_rule(MyHost, Rule, JID) of deny -> false; allow -> diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index d8d0a400a..04b961b3d 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -42,7 +42,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(DICT, dict). @@ -62,40 +62,19 @@ connections = (?DICT):new() :: ?TDICT, timer = make_ref() :: reference()}). -%-define(DBGFSM, true). +-type state_name() :: wait_for_stream | wait_for_features | stream_established. +-type state() :: #state{}. +-type fsm_next() :: {next_state, state_name(), state()}. +-type fsm_stop() :: {stop, normal, state()}. +-type fsm_transition() :: fsm_stop() | fsm_next(). +%%-define(DBGFSM, true). -ifdef(DBGFSM). - -define(FSMOPTS, [{debug, [trace]}]). - -else. - -define(FSMOPTS, []). - -endif. --define(STREAM_HEADER(Version), - <<"">>). - --define(STREAM_TRAILER, <<"">>). - --define(INVALID_NAMESPACE_ERR, - fxml:element_to_binary(?SERR_INVALID_NAMESPACE)). - --define(HOST_UNKNOWN_ERR, - fxml:element_to_binary(?SERR_HOST_UNKNOWN)). - --define(INVALID_FROM_ERR, - fxml:element_to_binary(?SERR_INVALID_FROM)). - --define(INVALID_XML_ERR, - fxml:element_to_binary(?SERR_XML_NOT_WELL_FORMED)). - start(SockData, Opts) -> supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts]). @@ -185,319 +164,252 @@ init([{SockMod, Socket}, Opts]) -> %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- - -wait_for_stream({xmlstreamstart, _Name, Attrs}, - StateData) -> - case {fxml:get_attr_s(<<"xmlns">>, Attrs), - fxml:get_attr_s(<<"xmlns:db">>, Attrs), - fxml:get_attr_s(<<"to">>, Attrs), - fxml:get_attr_s(<<"version">>, Attrs) == <<"1.0">>} - of - {<<"jabber:server">>, _, Server, true} - when StateData#state.tls and - not StateData#state.authenticated -> - send_text(StateData, - ?STREAM_HEADER(<<" version='1.0'">>)), - Auth = if StateData#state.tls_enabled -> - case jid:nameprep(fxml:get_attr_s(<<"from">>, Attrs)) of - From when From /= <<"">>, From /= error -> - {Result, Message} = - ejabberd_s2s:check_peer_certificate(StateData#state.sockmod, - StateData#state.socket, - From), - {Result, From, Message}; - _ -> - {error, <<"(unknown)">>, - <<"Got no valid 'from' attribute">>} - end; - true -> - {no_verify, <<"(unknown)">>, - <<"TLS not (yet) enabled">>} - end, - StartTLS = if StateData#state.tls_enabled -> []; - not StateData#state.tls_enabled and +wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> + try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of + #stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM} + when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM -> + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData}; + #stream_start{to = #jid{lserver = Server}, + from = #jid{lserver = From}, + version = <<"1.0">>} + when StateData#state.tls and not StateData#state.authenticated -> + send_header(StateData, <<" version='1.0'">>), + Auth = if StateData#state.tls_enabled -> + {Result, Message} = + ejabberd_s2s:check_peer_certificate( + StateData#state.sockmod, + StateData#state.socket, + From), + {Result, From, Message}; + true -> + {no_verify, <<"(unknown)">>, <<"TLS not (yet) enabled">>} + end, + StartTLS = if StateData#state.tls_enabled -> []; + not StateData#state.tls_enabled and not StateData#state.tls_required -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = []}]; - not StateData#state.tls_enabled and + [#starttls{required = false}]; + not StateData#state.tls_enabled and StateData#state.tls_required -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = - [#xmlel{name = <<"required">>, - attrs = [], children = []}]}] - end, - case Auth of - {error, RemoteServer, CertError} - when StateData#state.tls_certverify -> - ?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)", - [StateData#state.server, RemoteServer, CertError]), - send_text(StateData, - <<(fxml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>, - CertError)))/binary, - (?STREAM_TRAILER)/binary>>), - {stop, normal, StateData}; - {VerifyResult, RemoteServer, Msg} -> - {SASL, NewStateData} = case VerifyResult of - ok -> - {[#xmlel{name = <<"mechanisms">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = <<"mechanism">>, - attrs = [], - children = - [{xmlcdata, - <<"EXTERNAL">>}]}]}], - StateData#state{auth_domain = RemoteServer}}; - error -> - ?DEBUG("Won't accept certificate of ~s: ~s", - [RemoteServer, Msg]), - {[], StateData}; - no_verify -> - {[], StateData} - end, - send_element(NewStateData, - #xmlel{name = <<"stream:features">>, attrs = [], - children = - SASL ++ - StartTLS ++ - ejabberd_hooks:run_fold(s2s_stream_features, - Server, [], - [Server])}), - {next_state, wait_for_feature_request, - NewStateData#state{server = Server}} - end; - {<<"jabber:server">>, _, Server, true} - when StateData#state.authenticated -> - send_text(StateData, - ?STREAM_HEADER(<<" version='1.0'">>)), - send_element(StateData, - #xmlel{name = <<"stream:features">>, attrs = [], - children = - ejabberd_hooks:run_fold(s2s_stream_features, - Server, [], - [Server])}), - {next_state, stream_established, StateData}; - {<<"jabber:server">>, <<"jabber:server:dialback">>, - _Server, _} when - (StateData#state.tls_required and StateData#state.tls_enabled) - or (not StateData#state.tls_required) -> - send_text(StateData, ?STREAM_HEADER(<<"">>)), - {next_state, stream_established, StateData}; - _ -> - send_text(StateData, ?INVALID_NAMESPACE_ERR), - {stop, normal, StateData} + [#starttls{required = true}] + end, + case Auth of + {error, RemoteServer, CertError} + when StateData#state.tls_certverify -> + ?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)", + [StateData#state.server, RemoteServer, CertError]), + send_element(StateData, + xmpp:serr_policy_violation(CertError, ?MYLANG)), + {stop, normal, StateData}; + {VerifyResult, RemoteServer, Msg} -> + {SASL, NewStateData} = + case VerifyResult of + ok -> + {[#sasl_mechanisms{list = [<<"EXTERNAL">>]}], + StateData#state{auth_domain = RemoteServer}}; + error -> + ?DEBUG("Won't accept certificate of ~s: ~s", + [RemoteServer, Msg]), + {[], StateData}; + no_verify -> + {[], StateData} + end, + send_element(NewStateData, + #stream_features{ + sub_els = SASL ++ StartTLS ++ + ejabberd_hooks:run_fold( + s2s_stream_features, Server, [], + [Server])}), + {next_state, wait_for_feature_request, + NewStateData#state{server = Server}} + end; + #stream_start{to = #jid{lserver = Server}, + version = <<"1.0">>} when StateData#state.authenticated -> + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, + #stream_features{ + sub_els = ejabberd_hooks:run_fold( + s2s_stream_features, Server, [], + [Server])}), + {next_state, stream_established, StateData}; + #stream_start{db_xmlns = ?NS_SERVER_DIALBACK} + when (StateData#state.tls_required and StateData#state.tls_enabled) + or (not StateData#state.tls_required) -> + send_header(StateData, <<"">>), + {next_state, stream_established, StateData}; + #stream_start{} -> + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, xmpp:serr_undefined_condition()), + {stop, normal, StateData} + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), + {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?STREAM_HEADER(<<"">>))/binary, - (?INVALID_XML_ERR)/binary, (?STREAM_TRAILER)/binary>>), + send_header(StateData, <<"">>), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream(timeout, StateData) -> + send_header(StateData, <<"">>), + send_element(StateData, xmpp:serr_connection_timeout()), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}. -wait_for_feature_request({xmlstreamelement, El}, - StateData) -> - #xmlel{name = Name, attrs = Attrs} = El, - TLS = StateData#state.tls, - TLSEnabled = StateData#state.tls_enabled, - SockMod = - (StateData#state.sockmod):get_sockmod(StateData#state.socket), - case {fxml:get_attr_s(<<"xmlns">>, Attrs), Name} of - {?NS_TLS, <<"starttls">>} - when TLS == true, TLSEnabled == false, - SockMod == gen_tcp -> - ?DEBUG("starttls", []), - Socket = StateData#state.socket, - TLSOpts1 = case - ejabberd_config:get_option( - {domain_certfile, StateData#state.server}, - fun iolist_to_binary/1) of - undefined -> StateData#state.tls_options; - CertFile -> - [{certfile, CertFile} | lists:keydelete(certfile, 1, - StateData#state.tls_options)] - end, - TLSOpts = case ejabberd_config:get_option( - {s2s_tls_compression, StateData#state.server}, - fun(true) -> true; - (false) -> false - end, false) of - true -> lists:delete(compression_none, TLSOpts1); - false -> [compression_none | TLSOpts1] - end, - TLSSocket = (StateData#state.sockmod):starttls(Socket, - TLSOpts, - fxml:element_to_binary(#xmlel{name - = - <<"proceed">>, - attrs - = - [{<<"xmlns">>, - ?NS_TLS}], - children - = - []})), - {next_state, wait_for_stream, - StateData#state{socket = TLSSocket, streamid = new_id(), - tls_enabled = true, tls_options = TLSOpts}}; - {?NS_SASL, <<"auth">>} when TLSEnabled -> - Mech = fxml:get_attr_s(<<"mechanism">>, Attrs), - case Mech of - <<"EXTERNAL">> when StateData#state.auth_domain /= <<"">> -> - AuthDomain = StateData#state.auth_domain, - AllowRemoteHost = ejabberd_s2s:allow_host(<<"">>, - AuthDomain), - if AllowRemoteHost -> - (StateData#state.sockmod):reset_stream(StateData#state.socket), - send_element(StateData, - #xmlel{name = <<"success">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = []}), - ?INFO_MSG("Accepted s2s EXTERNAL authentication for ~s (TLS=~p)", - [AuthDomain, StateData#state.tls_enabled]), - change_shaper(StateData, <<"">>, - jid:make(<<"">>, AuthDomain, <<"">>)), - {next_state, wait_for_stream, - StateData#state{streamid = new_id(), - authenticated = true}}; - true -> - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = []}), - send_text(StateData, ?STREAM_TRAILER), - {stop, normal, StateData} - end; - _ -> - send_element(StateData, - #xmlel{name = <<"failure">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = - [#xmlel{name = <<"invalid-mechanism">>, - attrs = [], children = []}]}), - {stop, normal, StateData} - end; - _ -> - stream_established({xmlstreamelement, El}, StateData) +wait_for_feature_request({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_feature_request, StateData); +wait_for_feature_request(#starttls{}, + #state{tls = true, tls_enabled = false} = StateData) -> + case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of + gen_tcp -> + ?DEBUG("starttls", []), + Socket = StateData#state.socket, + TLSOpts1 = case + ejabberd_config:get_option( + {domain_certfile, StateData#state.server}, + fun iolist_to_binary/1) of + undefined -> StateData#state.tls_options; + CertFile -> + lists:keystore(certfile, 1, + StateData#state.tls_options, + {certfile, CertFile}) + end, + TLSOpts = case ejabberd_config:get_option( + {s2s_tls_compression, StateData#state.server}, + fun(true) -> true; + (false) -> false + end, false) of + true -> lists:delete(compression_none, TLSOpts1); + false -> [compression_none | TLSOpts1] + end, + TLSSocket = (StateData#state.sockmod):starttls( + Socket, TLSOpts, + fxml:element_to_binary(#starttls_proceed{})), + {next_state, wait_for_stream, + StateData#state{socket = TLSSocket, streamid = new_id(), + tls_enabled = true, tls_options = TLSOpts}}; + _ -> + Txt = <<"Unsupported TLS transport">>, + send_element(StateData, xmpp:serr_policy_violation(Txt, ?MYLANG)), + {stop, normal, StateData} + end; +wait_for_feature_request(#sasl_auth{mechanism = Mech}, + #state{tls_enabled = true} = StateData) -> + case Mech of + <<"EXTERNAL">> when StateData#state.auth_domain /= <<"">> -> + AuthDomain = StateData#state.auth_domain, + AllowRemoteHost = ejabberd_s2s:allow_host(<<"">>, AuthDomain), + if AllowRemoteHost -> + (StateData#state.sockmod):reset_stream(StateData#state.socket), + send_element(StateData, #sasl_success{}), + ?INFO_MSG("Accepted s2s EXTERNAL authentication for ~s (TLS=~p)", + [AuthDomain, StateData#state.tls_enabled]), + change_shaper(StateData, <<"">>, jid:make(AuthDomain)), + {next_state, wait_for_stream, + StateData#state{streamid = new_id(), + authenticated = true}}; + true -> + send_element(StateData, #sasl_failure{}), + {stop, normal, StateData} + end; + _ -> + send_element(StateData, #sasl_failure{reason = 'invalid-mechanism'}), + {stop, normal, StateData} end; -wait_for_feature_request({xmlstreamend, _Name}, - StateData) -> - send_text(StateData, ?STREAM_TRAILER), +wait_for_feature_request({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; -wait_for_feature_request({xmlstreamerror, _}, - StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), +wait_for_feature_request({xmlstreamerror, _}, StateData) -> + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_feature_request(closed, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +wait_for_feature_request(_Pkt, #state{tls_required = TLSRequired, + tls_enabled = TLSEnabled} = StateData) + when TLSRequired and not TLSEnabled -> + Txt = <<"Use of STARTTLS required">>, + send_element(StateData, xmpp:serr_policy_violation(Txt, ?MYLANG)), + {stop, normal, StateData}; +wait_for_feature_request(El, StateData) -> + stream_established({xmlstreamelement, El}, StateData). stream_established({xmlstreamelement, El}, StateData) -> cancel_timer(StateData#state.timer), Timer = erlang:start_timer(?S2STIMEOUT, self(), []), - case is_key_packet(El) of - {key, To, From, Id, Key} -> - ?DEBUG("GET KEY: ~p", [{To, From, Id, Key}]), - LTo = jid:nameprep(To), - LFrom = jid:nameprep(From), - case {ejabberd_s2s:allow_host(LTo, LFrom), - lists:member(LTo, - ejabberd_router:dirty_get_all_domains())} - of - {true, true} -> - ejabberd_s2s_out:terminate_if_waiting_delay(LTo, LFrom), - ejabberd_s2s_out:start(LTo, LFrom, - {verify, self(), Key, - StateData#state.streamid}), - Conns = (?DICT):store({LFrom, LTo}, - wait_for_verification, - StateData#state.connections), - change_shaper(StateData, LTo, - jid:make(<<"">>, LFrom, <<"">>)), - {next_state, stream_established, - StateData#state{connections = Conns, timer = Timer}}; - {_, false} -> - send_text(StateData, ?HOST_UNKNOWN_ERR), - {stop, normal, StateData}; - {false, _} -> - send_text(StateData, ?INVALID_FROM_ERR), - {stop, normal, StateData} - end; - {verify, To, From, Id, Key} -> - ?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]), - LTo = jid:nameprep(To), - LFrom = jid:nameprep(From), - Type = case ejabberd_s2s:make_key({LTo, LFrom}, Id) of - Key -> <<"valid">>; - _ -> <<"invalid">> - end, - send_element(StateData, - #xmlel{name = <<"db:verify">>, - attrs = - [{<<"from">>, To}, {<<"to">>, From}, - {<<"id">>, Id}, {<<"type">>, Type}], - children = []}), - {next_state, stream_established, - StateData#state{timer = Timer}}; - _ -> - NewEl = jlib:remove_attr(<<"xmlns">>, El), - #xmlel{name = Name, attrs = Attrs} = NewEl, - From_s = fxml:get_attr_s(<<"from">>, Attrs), - From = jid:from_string(From_s), - To_s = fxml:get_attr_s(<<"to">>, Attrs), - To = jid:from_string(To_s), - if (To /= error) and (From /= error) -> - LFrom = From#jid.lserver, - LTo = To#jid.lserver, - if StateData#state.authenticated -> - case LFrom == StateData#state.auth_domain andalso - lists:member(LTo, - ejabberd_router:dirty_get_all_domains()) - of - true -> - if (Name == <<"iq">>) or (Name == <<"message">>) - or (Name == <<"presence">>) -> - ejabberd_hooks:run(s2s_receive_packet, LTo, - [From, To, NewEl]), - ejabberd_router:route(From, To, NewEl); - true -> error - end; - false -> error - end; - true -> - case (?DICT):find({LFrom, LTo}, - StateData#state.connections) - of - {ok, established} -> - if (Name == <<"iq">>) or (Name == <<"message">>) - or (Name == <<"presence">>) -> - ejabberd_hooks:run(s2s_receive_packet, LTo, - [From, To, NewEl]), - ejabberd_router:route(From, To, NewEl); - true -> error - end; - _ -> error - end - end; - true -> error - end, - ejabberd_hooks:run(s2s_loop_debug, - [{xmlstreamelement, El}]), - {next_state, stream_established, - StateData#state{timer = Timer}} + decode_element(El, stream_established, StateData#state{timer = Timer}); +stream_established(#db_result{to = To, from = From, key = Key}, + StateData) -> + ?DEBUG("GET KEY: ~p", [{To, From, Key}]), + LTo = To#jid.lserver, + LFrom = From#jid.lserver, + case {ejabberd_s2s:allow_host(LTo, LFrom), + lists:member(LTo, ejabberd_router:dirty_get_all_domains())} of + {true, true} -> + ejabberd_s2s_out:terminate_if_waiting_delay(LTo, LFrom), + ejabberd_s2s_out:start(LTo, LFrom, + {verify, self(), Key, + StateData#state.streamid}), + Conns = (?DICT):store({LFrom, LTo}, + wait_for_verification, + StateData#state.connections), + change_shaper(StateData, LTo, jid:make(LFrom)), + {next_state, stream_established, + StateData#state{connections = Conns}}; + {_, false} -> + send_element(StateData, xmpp:serr_host_unknown()), + {stop, normal, StateData}; + {false, _} -> + send_element(StateData, xmpp:serr_invalid_from()), + {stop, normal, StateData} end; +stream_established(#db_verify{to = To, from = From, id = Id, key = Key}, + StateData) -> + ?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]), + LTo = jid:nameprep(To), + LFrom = jid:nameprep(From), + Type = case ejabberd_s2s:make_key({LTo, LFrom}, Id) of + Key -> valid; + _ -> invalid + end, + send_element(StateData, + #db_verify{from = To, to = From, id = Id, type = Type}), + {next_state, stream_established, StateData}; +stream_established(Pkt, StateData) when ?is_stanza(Pkt) -> + From = xmpp:get_from(Pkt), + To = xmpp:get_to(Pkt), + if To /= undefined, From /= undefined -> + LFrom = From#jid.lserver, + LTo = To#jid.lserver, + if StateData#state.authenticated -> + case LFrom == StateData#state.auth_domain andalso + lists:member(LTo, ejabberd_router:dirty_get_all_domains()) of + true -> + ejabberd_hooks:run(s2s_receive_packet, LTo, + [From, To, Pkt]), + ejabberd_router:route(From, To, Pkt); + false -> + send_error(StateData, Pkt, xmpp:err_not_authorized()) + end; + true -> + case (?DICT):find({LFrom, LTo}, StateData#state.connections) of + {ok, established} -> + ejabberd_hooks:run(s2s_receive_packet, LTo, + [From, To, Pkt]), + ejabberd_router:route(From, To, Pkt); + _ -> + send_error(StateData, Pkt, xmpp:err_not_authorized()) + end + end; + true -> + send_error(StateData, Pkt, xmpp:err_jid_malformed()) + end, + ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, Pkt}]), + {next_state, stream_established, StateData}; stream_established({valid, From, To}, StateData) -> send_element(StateData, - #xmlel{name = <<"db:result">>, - attrs = - [{<<"from">>, To}, {<<"to">>, From}, - {<<"type">>, <<"valid">>}], - children = []}), + #db_result{from = To, to = From, type = valid}), ?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)", [From, StateData#state.tls_enabled]), LFrom = jid:nameprep(From), @@ -508,11 +420,7 @@ stream_established({valid, From, To}, StateData) -> {next_state, stream_established, NSD}; stream_established({invalid, From, To}, StateData) -> send_element(StateData, - #xmlel{name = <<"db:result">>, - attrs = - [{<<"from">>, To}, {<<"to">>, From}, - {<<"type">>, <<"invalid">>}], - children = []}), + #db_result{from = To, to = From, type = invalid}), LFrom = jid:nameprep(From), LTo = jid:nameprep(To), NSD = StateData#state{connections = @@ -522,14 +430,16 @@ stream_established({invalid, From, To}, StateData) -> stream_established({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; stream_established({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; stream_established(timeout, StateData) -> + send_element(StateData, xmpp:serr_connection_timeout()), {stop, normal, StateData}; stream_established(closed, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +stream_established(Pkt, StateData) -> + ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, Pkt}]), + {next_state, stream_established, StateData}. %%---------------------------------------------------------------------- %% Func: StateName/3 @@ -589,8 +499,14 @@ code_change(_OldVsn, StateName, StateData, _Extra) -> handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; -handle_info({timeout, Timer, _}, _StateName, +handle_info({timeout, Timer, _}, StateName, #state{timer = Timer} = StateData) -> + if StateName == wait_for_stream -> + send_header(StateData, <<"">>); + true -> + ok + end, + send_element(StateData, xmpp:serr_connection_timeout()), {stop, normal, StateData}; handle_info(_, StateName, StateData) -> {next_state, StateName, StateData}. @@ -603,6 +519,7 @@ terminate(Reason, _StateName, StateData) -> || Host <- get_external_hosts(StateData)]; _ -> ok end, + catch send_trailer(StateData), (StateData#state.sockmod):close(StateData#state.socket), ok. @@ -621,39 +538,69 @@ print_state(State) -> State. %%% Internal functions %%%---------------------------------------------------------------------- +-spec send_text(state(), iodata()) -> ok. send_text(StateData, Text) -> (StateData#state.sockmod):send(StateData#state.socket, Text). +-spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - send_text(StateData, fxml:element_to_binary(El)). + El1 = fix_ns(xmpp:encode(El)), + send_text(StateData, fxml:element_to_binary(El1)). + +-spec send_error(state(), xmlel() | stanza(), error()) -> ok. +send_error(StateData, Stanza, Error) -> + Type = xmpp:get_type(Stanza), + if Type == error; Type == result; + Type == <<"error">>; Type == <<"result">> -> + ok; + true -> + send_element(StateData, xmpp:make_error(Stanza, Error)) + end. + +-spec send_trailer(state()) -> ok. +send_trailer(StateData) -> + send_text(StateData, <<"">>). +-spec send_header(state(), binary()) -> ok. +send_header(StateData, Version) -> + send_text(StateData, + <<"">>). + +-spec change_shaper(state(), binary(), jid()) -> ok. change_shaper(StateData, Host, JID) -> Shaper = acl:match_rule(Host, StateData#state.shaper, JID), (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper). +-spec fix_ns(xmlel()) -> xmlel(). +fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; + Name == <<"iq">>; + Name == <<"presence">>; + Name == <<"db:verify">>, + Name == <<"db:result">> -> + Attrs = lists:filter( + fun({<<"xmlns">>, _}) -> false; + (_) -> true + end, El#xmlel.attrs), + El#xmlel{attrs = Attrs}; +fix_ns(El) -> + El. + +-spec new_id() -> binary(). new_id() -> randoms:get_string(). +-spec cancel_timer(reference()) -> ok. cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. -is_key_packet(#xmlel{name = Name, attrs = Attrs, - children = Els}) - when Name == <<"db:result">> -> - {key, fxml:get_attr_s(<<"to">>, Attrs), - fxml:get_attr_s(<<"from">>, Attrs), - fxml:get_attr_s(<<"id">>, Attrs), fxml:get_cdata(Els)}; -is_key_packet(#xmlel{name = Name, attrs = Attrs, - children = Els}) - when Name == <<"db:verify">> -> - {verify, fxml:get_attr_s(<<"to">>, Attrs), - fxml:get_attr_s(<<"from">>, Attrs), - fxml:get_attr_s(<<"id">>, Attrs), fxml:get_cdata(Els)}; -is_key_packet(_) -> false. - fsm_limit_opts(Opts) -> case lists:keysearch(max_fsm_queue, 1, Opts) of {value, {_, N}} when is_integer(N) -> [{max_queue, N}]; @@ -666,6 +613,22 @@ fsm_limit_opts(Opts) -> end end. +-spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). +decode_element(#xmlel{} = El, StateName, StateData) -> + try xmpp:decode(El) of + Pkt -> ?MODULE:StateName(Pkt, StateData) + catch error:{xmpp_codec, Why} -> + case xmpp:is_stanza(El) of + true -> + Lang = xmpp:get_lang(El), + Txt = xmpp:format_error(Why), + send_error(StateData, El, xmpp:err_bad_request(Txt, Lang)); + false -> + ok + end, + {next_state, StateName, StateData} + end. + opt_type(domain_certfile) -> fun iolist_to_binary/1; opt_type(max_fsm_queue) -> fun (I) when is_integer(I), I > 0 -> I end; diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index a30f2f438..024e51e7a 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -50,8 +50,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {socket :: ejabberd_socket:socket_state(), @@ -75,6 +74,17 @@ bridge :: {atom(), atom()}, timer = make_ref() :: reference()}). +-type state_name() :: open_socket | wait_for_stream | + wait_for_validation | wait_for_features | + wait_for_auth_result | wait_for_starttls_proceed | + relay_to_bridge | reopen_socket | wait_before_retry | + stream_established. +-type state() :: #state{}. +-type fsm_stop() :: {stop, normal, state()}. +-type fsm_next() :: {next_state, state_name(), state(), non_neg_integer()} | + {next_state, state_name(), state()}. +-type fsm_transition() :: fsm_stop() | fsm_next(). + %%-define(DBGFSM, true). -ifdef(DBGFSM). @@ -102,17 +112,6 @@ "s' xmlns='jabber:server' xmlns:db='jabber:ser" "ver:dialback' from='~s' to='~s'~s>">>). --define(STREAM_TRAILER, <<"">>). - --define(INVALID_NAMESPACE_ERR, - fxml:element_to_binary(?SERR_INVALID_NAMESPACE)). - --define(HOST_UNKNOWN_ERR, - fxml:element_to_binary(?SERR_HOST_UNKNOWN)). - --define(INVALID_XML_ERR, - fxml:element_to_binary(?SERR_XML_NOT_WELL_FORMED)). - -define(SOCKET_DEFAULT_RESULT, {error, badarg}). %%%---------------------------------------------------------------------- @@ -236,10 +235,7 @@ open_socket(init, StateData) -> NewStateData = StateData#state{socket = Socket, tls_enabled = false, streamid = new_id()}, - send_text(NewStateData, - io_lib:format(?STREAM_HEADER, - [StateData#state.myname, - StateData#state.server, Version])), + send_header(NewStateData, Version), {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; {error, _Reason} -> @@ -259,18 +255,8 @@ open_socket(init, StateData) -> _ -> wait_before_reconnect(StateData) end end; -open_socket(closed, StateData) -> - ?INFO_MSG("s2s connection: ~s -> ~s (stopped in " - "open socket)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -open_socket(timeout, StateData) -> - ?INFO_MSG("s2s connection: ~s -> ~s (timeout in " - "open socket)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -open_socket(_, StateData) -> - {next_state, open_socket, StateData}. +open_socket(Event, StateData) -> + handle_unexpected_event(Event, open_socket, StateData). open_socket1({_, _, _, _} = Addr, Port) -> open_socket2(inet, Addr, Port); @@ -309,466 +295,215 @@ open_socket2(Type, Addr, Port) -> %%---------------------------------------------------------------------- -wait_for_stream({xmlstreamstart, _Name, Attrs}, - StateData) -> - {CertCheckRes, CertCheckMsg, StateData0} = - if StateData#state.tls_certverify, StateData#state.tls_enabled -> - {Res, Msg} = - ejabberd_s2s:check_peer_certificate(ejabberd_socket, - StateData#state.socket, - StateData#state.server), - ?DEBUG("Certificate verification result for ~s: ~s", - [StateData#state.server, Msg]), - {Res, Msg, StateData#state{tls_certverify = false}}; +wait_for_stream({xmlstreamstart, Name, Attrs}, StateData0) -> + {CertCheckRes, CertCheckMsg, StateData} = + if StateData0#state.tls_certverify, StateData0#state.tls_enabled -> + {Res, Msg} = + ejabberd_s2s:check_peer_certificate(ejabberd_socket, + StateData0#state.socket, + StateData0#state.server), + ?DEBUG("Certificate verification result for ~s: ~s", + [StateData0#state.server, Msg]), + {Res, Msg, StateData0#state{tls_certverify = false}}; true -> - {no_verify, <<"Not verified">>, StateData} + {no_verify, <<"Not verified">>, StateData0} end, - RemoteStreamID = fxml:get_attr_s(<<"id">>, Attrs), - NewStateData = StateData0#state{remote_streamid = RemoteStreamID}, - case {fxml:get_attr_s(<<"xmlns">>, Attrs), - fxml:get_attr_s(<<"xmlns:db">>, Attrs), - fxml:get_attr_s(<<"version">>, Attrs) == <<"1.0">>} - of - _ when CertCheckRes == error -> - send_text(NewStateData, - <<(fxml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>, - CertCheckMsg)))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (~s)", - [NewStateData#state.myname, - NewStateData#state.server, - CertCheckMsg]), - {stop, normal, NewStateData}; - {<<"jabber:server">>, <<"jabber:server:dialback">>, - false} -> - send_db_request(NewStateData); - {<<"jabber:server">>, <<"jabber:server:dialback">>, - true} - when NewStateData#state.use_v10 -> - {next_state, wait_for_features, NewStateData, ?FSMTIMEOUT}; - %% Clause added to handle Tigase's workaround for an old ejabberd bug: - {<<"jabber:server">>, <<"jabber:server:dialback">>, - true} - when not NewStateData#state.use_v10 -> - send_db_request(NewStateData); - {<<"jabber:server">>, <<"">>, true} - when NewStateData#state.use_v10 -> - {next_state, wait_for_features, - NewStateData#state{db_enabled = false}, ?FSMTIMEOUT}; - {NSProvided, DB, _} -> - send_text(NewStateData, ?INVALID_NAMESPACE_ERR), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid " - "namespace).~nNamespace provided: ~p~nNamespac" - "e expected: \"jabber:server\"~nxmlns:db " - "provided: ~p~nAll attributes: ~p", - [NewStateData#state.myname, NewStateData#state.server, - NSProvided, DB, Attrs]), - {stop, normal, NewStateData} + try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of + _ when CertCheckRes == error -> + send_element(StateData, + xmpp:serr_policy_violation(CertCheckMsg, ?MYLANG)), + ?INFO_MSG("Closing s2s connection: ~s -> ~s (~s)", + [StateData#state.myname, StateData#state.server, + CertCheckMsg]), + {stop, normal, StateData}; + #stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM} + when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM -> + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData}; + #stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID, + version = V} when V /= <<"1.0">> -> + send_db_request(StateData#state{remote_streamid = ID}); + #stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID} + when StateData#state.use_v10 -> + {next_state, wait_for_features, + StateData#state{remote_streamid = ID}, ?FSMTIMEOUT}; + #stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID} + when not StateData#state.use_v10 -> + %% Handle Tigase's workaround for an old ejabberd bug: + send_db_request(StateData#state{remote_streamid = ID}); + #stream_start{id = ID} when StateData#state.use_v10 -> + {next_state, wait_for_features, + StateData#state{db_enabled = false, remote_streamid = ID}, + ?FSMTIMEOUT}; + #stream_start{} -> + send_header(StateData, <<"">>), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData} + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + send_header(StateData, <<" version='1.0'">>), + send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), + {stop, normal, StateData} end; -wait_for_stream({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid " - "xml)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -wait_for_stream({xmlstreamend, _Name}, StateData) -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (xmlstreamend)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -wait_for_stream(timeout, StateData) -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (timeout " - "in wait_for_stream)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -wait_for_stream(closed, StateData) -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (close " - "in wait_for_stream)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}. - -wait_for_validation({xmlstreamelement, El}, +wait_for_stream(Event, StateData) -> + handle_unexpected_event(Event, wait_for_stream, StateData). + +wait_for_validation({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_validation, StateData); +wait_for_validation(#db_result{to = To, from = From, type = Type}, StateData) -> + ?DEBUG("recv result: ~p", [{From, To, Type}]), + case {Type, StateData#state.tls_enabled, StateData#state.tls_required} of + {valid, Enabled, Required} when (Enabled == true) or (Required == false) -> + send_queue(StateData, StateData#state.queue), + ?INFO_MSG("Connection established: ~s -> ~s with " + "TLS=~p", + [StateData#state.myname, StateData#state.server, + StateData#state.tls_enabled]), + ejabberd_hooks:run(s2s_connect_hook, + [StateData#state.myname, + StateData#state.server]), + {next_state, stream_established, StateData#state{queue = queue:new()}}; + {valid, Enabled, Required} when (Enabled == false) and (Required == true) -> + ?INFO_MSG("Closing s2s connection: ~s -> ~s (TLS " + "is required but unavailable)", + [StateData#state.myname, StateData#state.server]), + {stop, normal, StateData}; + _ -> + ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid " + "dialback key result)", + [StateData#state.myname, StateData#state.server]), + {stop, normal, StateData} + end; +wait_for_validation(#db_verify{to = To, from = From, id = Id, type = Type}, StateData) -> - case is_verify_res(El) of - {result, To, From, Id, Type} -> - ?DEBUG("recv result: ~p", [{From, To, Id, Type}]), - case {Type, StateData#state.tls_enabled, - StateData#state.tls_required} - of - {<<"valid">>, Enabled, Required} - when (Enabled == true) or (Required == false) -> - send_queue(StateData, StateData#state.queue), - ?INFO_MSG("Connection established: ~s -> ~s with " - "TLS=~p", - [StateData#state.myname, StateData#state.server, - StateData#state.tls_enabled]), - ejabberd_hooks:run(s2s_connect_hook, - [StateData#state.myname, - StateData#state.server]), - {next_state, stream_established, - StateData#state{queue = queue:new()}}; - {<<"valid">>, Enabled, Required} - when (Enabled == false) and (Required == true) -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (TLS " - "is required but unavailable)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; - _ -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid " - "dialback key)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; - {verify, To, From, Id, Type} -> - ?DEBUG("recv verify: ~p", [{From, To, Id, Type}]), - case StateData#state.verify of - false -> - NextState = wait_for_validation, - {next_state, NextState, StateData, - get_timeout_interval(NextState)}; - {Pid, _Key, _SID} -> - case Type of - <<"valid">> -> - p1_fsm:send_event(Pid, - {valid, StateData#state.server, - StateData#state.myname}); - _ -> - p1_fsm:send_event(Pid, - {invalid, StateData#state.server, - StateData#state.myname}) - end, - if StateData#state.verify == false -> - {stop, normal, StateData}; - true -> - NextState = wait_for_validation, - {next_state, NextState, StateData, - get_timeout_interval(NextState)} - end - end; - _ -> - {next_state, wait_for_validation, StateData, - (?FSMTIMEOUT) * 3} + ?DEBUG("recv verify: ~p", [{From, To, Id, Type}]), + case StateData#state.verify of + false -> + NextState = wait_for_validation, + {next_state, NextState, StateData, get_timeout_interval(NextState)}; + {Pid, _Key, _SID} -> + case Type of + valid -> + p1_fsm:send_event(Pid, + {valid, StateData#state.server, + StateData#state.myname}); + _ -> + p1_fsm:send_event(Pid, + {invalid, StateData#state.server, + StateData#state.myname}) + end, + if StateData#state.verify == false -> + {stop, normal, StateData}; + true -> + NextState = wait_for_validation, + {next_state, NextState, StateData, get_timeout_interval(NextState)} + end end; -wait_for_validation({xmlstreamend, _Name}, StateData) -> - ?INFO_MSG("wait for validation: ~s -> ~s (xmlstreamend)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -wait_for_validation({xmlstreamerror, _}, StateData) -> - ?INFO_MSG("wait for validation: ~s -> ~s (xmlstreamerror)", - [StateData#state.myname, StateData#state.server]), - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - {stop, normal, StateData}; wait_for_validation(timeout, #state{verify = {VPid, VKey, SID}} = StateData) - when is_pid(VPid) and is_binary(VKey) and - is_binary(SID) -> - ?DEBUG("wait_for_validation: ~s -> ~s (timeout " - "in verify connection)", + when is_pid(VPid) and is_binary(VKey) and is_binary(SID) -> + ?DEBUG("wait_for_validation: ~s -> ~s (timeout in verify connection)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; -wait_for_validation(timeout, StateData) -> - ?INFO_MSG("wait_for_validation: ~s -> ~s (connect " - "timeout)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -wait_for_validation(closed, StateData) -> - ?INFO_MSG("wait for validation: ~s -> ~s (closed)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}. +wait_for_validation(Event, StateData) -> + handle_unexpected_event(Event, wait_for_validation, StateData). wait_for_features({xmlstreamelement, El}, StateData) -> - case El of - #xmlel{name = <<"stream:features">>, children = Els} -> - {SASLEXT, StartTLS, StartTLSRequired} = lists:foldl(fun - (#xmlel{name = - <<"mechanisms">>, - attrs = - Attrs1, - children - = - Els1} = - _El1, - {_SEXT, STLS, - STLSReq} = - Acc) -> - case - fxml:get_attr_s(<<"xmlns">>, - Attrs1) - of - ?NS_SASL -> - NewSEXT = - lists:any(fun - (#xmlel{name - = - <<"mechanism">>, - children - = - Els2}) -> - case - fxml:get_cdata(Els2) - of - <<"EXTERNAL">> -> - true; - _ -> - false - end; - (_) -> - false - end, - Els1), - {NewSEXT, - STLS, - STLSReq}; - _ -> Acc - end; - (#xmlel{name = - <<"starttls">>, - attrs = - Attrs1} = - El1, - {SEXT, _STLS, - _STLSReq} = - Acc) -> - case - fxml:get_attr_s(<<"xmlns">>, - Attrs1) - of - ?NS_TLS -> - Req = - case - fxml:get_subtag(El1, - <<"required">>) - of - #xmlel{} -> - true; - false -> - false - end, - {SEXT, - true, - Req}; - _ -> Acc - end; - (_, Acc) -> Acc - end, - {false, false, - false}, - Els), - if not SASLEXT and not StartTLS and - StateData#state.authenticated -> - send_queue(StateData, StateData#state.queue), - ?INFO_MSG("Connection established: ~s -> ~s with " - "SASL EXTERNAL and TLS=~p", - [StateData#state.myname, StateData#state.server, - StateData#state.tls_enabled]), - ejabberd_hooks:run(s2s_connect_hook, - [StateData#state.myname, - StateData#state.server]), - {next_state, stream_established, - StateData#state{queue = queue:new()}}; - SASLEXT and StateData#state.try_auth and - (StateData#state.new /= false) and - (StateData#state.tls_enabled or - not StateData#state.tls_required) -> - send_element(StateData, - #xmlel{name = <<"auth">>, - attrs = - [{<<"xmlns">>, ?NS_SASL}, - {<<"mechanism">>, <<"EXTERNAL">>}], - children = - [{xmlcdata, - jlib:encode_base64(StateData#state.myname)}]}), - {next_state, wait_for_auth_result, - StateData#state{try_auth = false}, ?FSMTIMEOUT}; - StartTLS and StateData#state.tls and - not StateData#state.tls_enabled -> - send_element(StateData, - #xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = []}), - {next_state, wait_for_starttls_proceed, StateData, - ?FSMTIMEOUT}; - StartTLSRequired and not StateData#state.tls -> - ?DEBUG("restarted: ~p", - [{StateData#state.myname, StateData#state.server}]), - ejabberd_socket:close(StateData#state.socket), - {next_state, reopen_socket, - StateData#state{socket = undefined, use_v10 = false}, - ?FSMTIMEOUT}; - StateData#state.db_enabled -> - send_db_request(StateData); - true -> - ?DEBUG("restarted: ~p", - [{StateData#state.myname, StateData#state.server}]), - ejabberd_socket:close(StateData#state.socket), - {next_state, reopen_socket, - StateData#state{socket = undefined, use_v10 = false}, - ?FSMTIMEOUT} - end; - _ -> - send_text(StateData, - <<(fxml:element_to_binary(?SERR_BAD_FORMAT))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} + decode_element(El, wait_for_features, StateData); +wait_for_features(#stream_features{sub_els = Els}, StateData) -> + {SASLEXT, StartTLS, StartTLSRequired} = + lists:foldl( + fun(#sasl_mechanisms{list = Mechs}, {_, STLS, STLSReq}) -> + {lists:member(<<"EXTERNAL">>, Mechs), STLS, STLSReq}; + (#starttls{required = Required}, {SEXT, _, _}) -> + {SEXT, true, Required}; + (_, Acc) -> + Acc + end, {false, false, false}, Els), + if not SASLEXT and not StartTLS and StateData#state.authenticated -> + send_queue(StateData, StateData#state.queue), + ?INFO_MSG("Connection established: ~s -> ~s with " + "SASL EXTERNAL and TLS=~p", + [StateData#state.myname, StateData#state.server, + StateData#state.tls_enabled]), + ejabberd_hooks:run(s2s_connect_hook, + [StateData#state.myname, + StateData#state.server]), + {next_state, stream_established, + StateData#state{queue = queue:new()}}; + SASLEXT and StateData#state.try_auth and + (StateData#state.new /= false) and + (StateData#state.tls_enabled or + not StateData#state.tls_required) -> + send_element(StateData, + #sasl_auth{mechanism = <<"EXTERNAL">>, + text = StateData#state.myname}), + {next_state, wait_for_auth_result, + StateData#state{try_auth = false}, ?FSMTIMEOUT}; + StartTLS and StateData#state.tls and + not StateData#state.tls_enabled -> + send_element(StateData, #starttls{}), + {next_state, wait_for_starttls_proceed, StateData, ?FSMTIMEOUT}; + StartTLSRequired and not StateData#state.tls -> + ?DEBUG("restarted: ~p", + [{StateData#state.myname, StateData#state.server}]), + ejabberd_socket:close(StateData#state.socket), + {next_state, reopen_socket, + StateData#state{socket = undefined, use_v10 = false}, + ?FSMTIMEOUT}; + StateData#state.db_enabled -> + send_db_request(StateData); + true -> + ?DEBUG("restarted: ~p", + [{StateData#state.myname, StateData#state.server}]), + ejabberd_socket:close(StateData#state.socket), + {next_state, reopen_socket, + StateData#state{socket = undefined, use_v10 = false}, ?FSMTIMEOUT} end; -wait_for_features({xmlstreamend, _Name}, StateData) -> - ?INFO_MSG("wait_for_features: xmlstreamend", []), - {stop, normal, StateData}; -wait_for_features({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("wait for features: xmlstreamerror", []), - {stop, normal, StateData}; -wait_for_features(timeout, StateData) -> - ?INFO_MSG("wait for features: timeout", []), - {stop, normal, StateData}; -wait_for_features(closed, StateData) -> - ?INFO_MSG("wait for features: closed", []), - {stop, normal, StateData}. - -wait_for_auth_result({xmlstreamelement, El}, - StateData) -> - case El of - #xmlel{name = <<"success">>, attrs = Attrs} -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_SASL -> - ?DEBUG("auth: ~p", - [{StateData#state.myname, StateData#state.server}]), - ejabberd_socket:reset_stream(StateData#state.socket), - send_text(StateData, - io_lib:format(?STREAM_HEADER, - [StateData#state.myname, - StateData#state.server, - <<" version='1.0'">>])), - {next_state, wait_for_stream, - StateData#state{streamid = new_id(), - authenticated = true}, - ?FSMTIMEOUT}; - _ -> - send_text(StateData, - <<(fxml:element_to_binary(?SERR_BAD_FORMAT))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; - #xmlel{name = <<"failure">>, attrs = Attrs} -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_SASL -> - ?DEBUG("restarted: ~p", - [{StateData#state.myname, StateData#state.server}]), - ejabberd_socket:close(StateData#state.socket), - {next_state, reopen_socket, - StateData#state{socket = undefined}, ?FSMTIMEOUT}; - _ -> - send_text(StateData, - <<(fxml:element_to_binary(?SERR_BAD_FORMAT))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; - _ -> - send_text(StateData, - <<(fxml:element_to_binary(?SERR_BAD_FORMAT))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; -wait_for_auth_result({xmlstreamend, _Name}, - StateData) -> - ?INFO_MSG("wait for auth result: xmlstreamend", []), - {stop, normal, StateData}; -wait_for_auth_result({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("wait for auth result: xmlstreamerror", []), - {stop, normal, StateData}; -wait_for_auth_result(timeout, StateData) -> - ?INFO_MSG("wait for auth result: timeout", []), - {stop, normal, StateData}; -wait_for_auth_result(closed, StateData) -> - ?INFO_MSG("wait for auth result: closed", []), - {stop, normal, StateData}. - -wait_for_starttls_proceed({xmlstreamelement, El}, - StateData) -> - case El of - #xmlel{name = <<"proceed">>, attrs = Attrs} -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_TLS -> - ?DEBUG("starttls: ~p", - [{StateData#state.myname, StateData#state.server}]), - Socket = StateData#state.socket, - TLSOpts = case - ejabberd_config:get_option( - {domain_certfile, StateData#state.myname}, - fun iolist_to_binary/1) - of - undefined -> StateData#state.tls_options; - CertFile -> - [{certfile, CertFile} - | lists:keydelete(certfile, 1, - StateData#state.tls_options)] - end, - TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts), - NewStateData = StateData#state{socket = TLSSocket, - streamid = new_id(), - tls_enabled = true, - tls_options = TLSOpts}, - send_text(NewStateData, - io_lib:format(?STREAM_HEADER, - [NewStateData#state.myname, - NewStateData#state.server, - <<" version='1.0'">>])), - {next_state, wait_for_stream, NewStateData, - ?FSMTIMEOUT}; - _ -> - send_text(StateData, - <<(fxml:element_to_binary(?SERR_BAD_FORMAT))/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; - _ -> - ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad " - "format)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData} - end; -wait_for_starttls_proceed({xmlstreamend, _Name}, - StateData) -> - ?INFO_MSG("wait for starttls proceed: xmlstreamend", - []), - {stop, normal, StateData}; -wait_for_starttls_proceed({xmlstreamerror, _}, - StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("wait for starttls proceed: xmlstreamerror", - []), - {stop, normal, StateData}; -wait_for_starttls_proceed(timeout, StateData) -> - ?INFO_MSG("wait for starttls proceed: timeout", []), - {stop, normal, StateData}; -wait_for_starttls_proceed(closed, StateData) -> - ?INFO_MSG("wait for starttls proceed: closed", []), - {stop, normal, StateData}. +wait_for_features(Event, StateData) -> + handle_unexpected_event(Event, wait_for_features, StateData). + +wait_for_auth_result({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_auth_result, StateData); +wait_for_auth_result(#sasl_success{}, StateData) -> + ?DEBUG("auth: ~p", [{StateData#state.myname, StateData#state.server}]), + ejabberd_socket:reset_stream(StateData#state.socket), + send_header(StateData, <<" version='1.0'">>), + {next_state, wait_for_stream, + StateData#state{streamid = new_id(), authenticated = true}, + ?FSMTIMEOUT}; +wait_for_auth_result(#sasl_failure{}, StateData) -> + ?DEBUG("restarted: ~p", [{StateData#state.myname, StateData#state.server}]), + ejabberd_socket:close(StateData#state.socket), + {next_state, reopen_socket, + StateData#state{socket = undefined}, ?FSMTIMEOUT}; +wait_for_auth_result(Event, StateData) -> + handle_unexpected_event(Event, wait_for_auth_result, StateData). + +wait_for_starttls_proceed({xmlstreamelement, El}, StateData) -> + decode_element(El, wait_for_starttls_proceed, StateData); +wait_for_starttls_proceed(#starttls_proceed{}, StateData) -> + ?DEBUG("starttls: ~p", [{StateData#state.myname, StateData#state.server}]), + Socket = StateData#state.socket, + TLSOpts = case ejabberd_config:get_option( + {domain_certfile, StateData#state.myname}, + fun iolist_to_binary/1) of + undefined -> StateData#state.tls_options; + CertFile -> + [{certfile, CertFile} + | lists:keydelete(certfile, 1, + StateData#state.tls_options)] + end, + TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts), + NewStateData = StateData#state{socket = TLSSocket, + streamid = new_id(), + tls_enabled = true, + tls_options = TLSOpts}, + send_header(NewStateData, <<" version='1.0'">>), + {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; +wait_for_starttls_proceed(Event, StateData) -> + handle_unexpected_event(Event, wait_for_starttls_proceed, StateData). reopen_socket({xmlstreamelement, _El}, StateData) -> {next_state, reopen_socket, StateData, ?FSMTIMEOUT}; @@ -797,47 +532,69 @@ relay_to_bridge(_Event, StateData) -> {next_state, relay_to_bridge, StateData}. stream_established({xmlstreamelement, El}, StateData) -> - ?DEBUG("s2S stream established", []), - case is_verify_res(El) of - {verify, VTo, VFrom, VId, VType} -> - ?DEBUG("recv verify: ~p", [{VFrom, VTo, VId, VType}]), - case StateData#state.verify of - {VPid, _VKey, _SID} -> - case VType of - <<"valid">> -> - p1_fsm:send_event(VPid, - {valid, StateData#state.server, - StateData#state.myname}); - _ -> - p1_fsm:send_event(VPid, - {invalid, StateData#state.server, - StateData#state.myname}) - end; - _ -> ok - end; - _ -> ok + decode_element(El, stream_established, StateData); +stream_established(#db_verify{to = VTo, from = VFrom, id = VId, type = VType}, + StateData) -> + ?DEBUG("recv verify: ~p", [{VFrom, VTo, VId, VType}]), + case StateData#state.verify of + {VPid, _VKey, _SID} -> + case VType of + valid -> + p1_fsm:send_event(VPid, + {valid, StateData#state.server, + StateData#state.myname}); + _ -> + p1_fsm:send_event(VPid, + {invalid, StateData#state.server, + StateData#state.myname}) + end; + _ -> ok end, {next_state, stream_established, StateData}; -stream_established({xmlstreamend, _Name}, StateData) -> - ?INFO_MSG("Connection closed in stream established: " - "~s -> ~s (xmlstreamend)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -stream_established({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - ?INFO_MSG("stream established: ~s -> ~s (xmlstreamerror)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -stream_established(timeout, StateData) -> - ?INFO_MSG("stream established: ~s -> ~s (timeout)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}; -stream_established(closed, StateData) -> - ?INFO_MSG("stream established: ~s -> ~s (closed)", - [StateData#state.myname, StateData#state.server]), - {stop, normal, StateData}. +stream_established(Event, StateData) -> + handle_unexpected_event(Event, stream_established, StateData). + +-spec handle_unexpected_event(term(), state_name(), state()) -> fsm_transition(). +handle_unexpected_event(Event, StateName, StateData) -> + case Event of + {xmlstreamerror, _} -> + send_element(StateData, xmpp:serr_not_well_formed()), + ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " + "got invalid XML from peer", + [StateData#state.myname, StateData#state.server, + StateName]), + {stop, normal, StateData}; + {xmlstreamend, _} -> + ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " + "XML stream closed by peer", + [StateData#state.myname, StateData#state.server]), + {stop, normal, StateData}; + timeout -> + send_element(StateData, xmpp:serr_connection_timeout()), + ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " + "timed out during establishing an XML stream", + [StateData#state.myname, StateData#state.server, + StateName]), + {stop, normal, StateData}; + closed -> + ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " + "connection socket closed", + [StateData#state.myname, StateData#state.server, + StateName]), + {stop, normal, StateData}; + Pkt when StateName == wait_for_stream; + StateName == wait_for_features; + StateName == wait_for_auth_result; + StateName == wait_for_starttls_proceed -> + send_element(StateData, xmpp:serr_bad_format()), + ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " + "got unexpected event ~p", + [StateData#state.myname, StateData#state.server, + StateName, Pkt]), + {stop, normal, StateData}; + _ -> + {next_state, StateName, StateData, get_timeout_interval(StateName)} + end. %%---------------------------------------------------------------------- %% Func: StateName/3 @@ -917,7 +674,7 @@ handle_info({send_element, El}, StateName, StateData) -> %% In this state we bounce all message: We are waiting before %% trying to reconnect wait_before_retry -> - bounce_element(El, ?ERR_REMOTE_SERVER_NOT_FOUND), + bounce_element(El, xmpp:err_remote_server_not_found()), {next_state, StateName, StateData}; relay_to_bridge -> {Mod, Fun} = StateData#state.bridge, @@ -926,7 +683,7 @@ handle_info({send_element, El}, StateName, StateData) -> {'EXIT', Reason} -> ?ERROR_MSG("Error while relaying to bridge: ~p", [Reason]), - bounce_element(El, ?ERR_INTERNAL_SERVER_ERROR), + bounce_element(El, xmpp:err_internal_server_error()), wait_before_reconnect(StateData); _ -> {next_state, StateName, StateData} end; @@ -966,12 +723,13 @@ terminate(Reason, StateName, StateData) -> StateData#state.server}, self()) end, - bounce_queue(StateData#state.queue, - ?ERR_REMOTE_SERVER_NOT_FOUND), - bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND), + bounce_queue(StateData#state.queue, xmpp:err_remote_server_not_found()), + bounce_messages(xmpp:err_remote_server_not_found()), case StateData#state.socket of undefined -> ok; - _Socket -> ejabberd_socket:close(StateData#state.socket) + _Socket -> + catch send_trailer(StateData), + ejabberd_socket:close(StateData#state.socket) end, ok. @@ -981,12 +739,30 @@ print_state(State) -> State. %%% Internal functions %%%---------------------------------------------------------------------- +-spec send_text(state(), iodata()) -> ok. send_text(StateData, Text) -> ejabberd_socket:send(StateData#state.socket, Text). +-spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - send_text(StateData, fxml:element_to_binary(El)). - + El1 = fix_ns(xmpp:encode(El)), + send_text(StateData, fxml:element_to_binary(El1)). + +-spec send_header(state(), binary()) -> ok. +send_header(StateData, Version) -> + Txt = io_lib:format( + "", + [StateData#state.myname, StateData#state.server, Version]), + send_text(StateData, Txt). + +-spec send_trailer(state()) -> ok. +send_trailer(StateData) -> + send_text(StateData, <<"">>). + +-spec send_queue(state(), queue:queue()) -> ok. send_queue(StateData, Q) -> case queue:out(Q) of {{value, El}, Q1} -> @@ -994,21 +770,28 @@ send_queue(StateData, Q) -> {empty, _Q1} -> ok end. +-spec fix_ns(xmlel()) -> xmlel(). +fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; + Name == <<"iq">>; + Name == <<"presence">>; + Name == <<"db:verify">>, + Name == <<"db:result">> -> + Attrs = lists:filter( + fun({<<"xmlns">>, _}) -> false; + (_) -> true + end, El#xmlel.attrs), + El#xmlel{attrs = Attrs}; +fix_ns(El) -> + El. + %% Bounce a single message (xmlelement) +-spec bounce_element(stanza(), error()) -> ok. bounce_element(El, Error) -> - #xmlel{attrs = Attrs} = El, - case fxml:get_attr_s(<<"type">>, Attrs) of - <<"error">> -> ok; - <<"result">> -> ok; - _ -> - Err = jlib:make_error_reply(El, Error), - From = jid:from_string(fxml:get_tag_attr_s(<<"from">>, - El)), - To = jid:from_string(fxml:get_tag_attr_s(<<"to">>, - El)), - ejabberd_router:route(To, From, Err) - end. + From = xmpp:get_from(El), + To = xmpp:get_to(El), + ejabberd_router:route_error(To, From, El, Error). +-spec bounce_queue(queue:queue(), error()) -> ok. bounce_queue(Q, Error) -> case queue:out(Q) of {{value, El}, Q1} -> @@ -1016,12 +799,15 @@ bounce_queue(Q, Error) -> {empty, _} -> ok end. +-spec new_id() -> binary(). new_id() -> randoms:get_string(). +-spec cancel_timer(reference()) -> ok. cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. +-spec bounce_messages(error()) -> ok. bounce_messages(Error) -> receive {send_element, El} -> @@ -1029,6 +815,7 @@ bounce_messages(Error) -> after 0 -> ok end. +-spec send_db_request(state()) -> fsm_transition(). send_db_request(StateData) -> Server = StateData#state.server, New = case StateData#state.new of @@ -1045,22 +832,18 @@ send_db_request(StateData) -> {StateData#state.myname, Server}, StateData#state.remote_streamid), send_element(StateData, - #xmlel{name = <<"db:result">>, - attrs = - [{<<"from">>, StateData#state.myname}, - {<<"to">>, Server}], - children = [{xmlcdata, Key1}]}) + #db_result{from = jid:make(StateData#state.myname), + to = jid:make(Server), + key = Key1}) end, case StateData#state.verify of false -> ok; {_Pid, Key2, SID} -> send_element(StateData, - #xmlel{name = <<"db:verify">>, - attrs = - [{<<"from">>, StateData#state.myname}, - {<<"to">>, StateData#state.server}, - {<<"id">>, SID}], - children = [{xmlcdata, Key2}]}) + #db_verify{from = jid:make(StateData#state.myname), + to = StateData#state.server, + id = SID, + key = Key2}) end, {next_state, wait_for_validation, NewStateData, (?FSMTIMEOUT) * 6} @@ -1068,20 +851,6 @@ send_db_request(StateData) -> _:_ -> {stop, normal, NewStateData} end. -is_verify_res(#xmlel{name = Name, attrs = Attrs}) - when Name == <<"db:result">> -> - {result, fxml:get_attr_s(<<"to">>, Attrs), - fxml:get_attr_s(<<"from">>, Attrs), - fxml:get_attr_s(<<"id">>, Attrs), - fxml:get_attr_s(<<"type">>, Attrs)}; -is_verify_res(#xmlel{name = Name, attrs = Attrs}) - when Name == <<"db:verify">> -> - {verify, fxml:get_attr_s(<<"to">>, Attrs), - fxml:get_attr_s(<<"from">>, Attrs), - fxml:get_attr_s(<<"id">>, Attrs), - fxml:get_attr_s(<<"type">>, Attrs)}; -is_verify_res(_) -> false. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% SRV support @@ -1190,12 +959,14 @@ get_addrs(Host, Family) -> [] end. +-spec outgoing_s2s_port() -> pos_integer(). outgoing_s2s_port() -> ejabberd_config:get_option( outgoing_s2s_port, fun(I) when is_integer(I), I > 0, I =< 65536 -> I end, 5269). +-spec outgoing_s2s_families() -> [ipv4 | ipv6]. outgoing_s2s_families() -> ejabberd_config:get_option( outgoing_s2s_families, @@ -1207,6 +978,7 @@ outgoing_s2s_families() -> Families end, [ipv4, ipv6]). +-spec outgoing_s2s_timeout() -> pos_integer(). outgoing_s2s_timeout() -> ejabberd_config:get_option( outgoing_s2s_timeout, @@ -1256,21 +1028,24 @@ log_s2s_out(_, Myname, Server, Tls) -> %% Calculate timeout depending on which state we are in: %% Can return integer > 0 | infinity +-spec get_timeout_interval(state_name()) -> pos_integer() | infinity. get_timeout_interval(StateName) -> case StateName of %% Validation implies dialback: Networking can take longer: wait_for_validation -> (?FSMTIMEOUT) * 6; %% When stream is established, we only rely on S2S Timeout timer: stream_established -> infinity; + relay_to_bridge -> infinity; + open_socket -> infinity; _ -> ?FSMTIMEOUT end. %% This function is intended to be called at the end of a state %% function that want to wait for a reconnect delay before stopping. +-spec wait_before_reconnect(state()) -> fsm_next(). wait_before_reconnect(StateData) -> - bounce_queue(StateData#state.queue, - ?ERR_REMOTE_SERVER_NOT_FOUND), - bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND), + bounce_queue(StateData#state.queue, xmpp:err_remote_server_not_found()), + bounce_messages(xmpp:err_remote_server_not_found()), cancel_timer(StateData#state.timer), Delay = case StateData#state.delay_to_retry of undefined_delay -> @@ -1282,6 +1057,7 @@ wait_before_reconnect(StateData) -> StateData#state{timer = Timer, delay_to_retry = Delay, queue = queue:new()}}. +-spec get_max_retry_delay() -> pos_integer(). get_max_retry_delay() -> case ejabberd_config:get_option( s2s_max_retry_delay, @@ -1291,6 +1067,7 @@ get_max_retry_delay() -> end. %% Terminate s2s_out connections that are in state wait_before_retry +-spec terminate_if_waiting_delay(ljid(), ljid()) -> ok. terminate_if_waiting_delay(From, To) -> FromTo = {From, To}, Pids = ejabberd_s2s:get_connections_pids(FromTo), @@ -1299,6 +1076,7 @@ terminate_if_waiting_delay(From, To) -> end, Pids). +-spec fsm_limit_opts() -> [{max_queue, pos_integer()}]. fsm_limit_opts() -> case ejabberd_config:get_option( max_fsm_queue, @@ -1307,6 +1085,24 @@ fsm_limit_opts() -> N -> [{max_queue, N}] end. +-spec decode_element(xmlel(), state_name(), state()) -> fsm_next(). +decode_element(#xmlel{} = El, StateName, StateData) -> + try xmpp:decode(El) of + Pkt -> ?MODULE:StateName(Pkt, StateData) + catch error:{xmpp_codec, Why} -> + Type = xmpp:get_type(El), + case xmpp:is_stanza(El) of + true when Type /= <<"result">>, Type /= <<"error">> -> + Lang = xmpp:get_lang(El), + Txt = xmpp:format_error(Why), + Err = xmpp:make_error(El, xmpp:err_bad_request(Txt, Lang)), + send_element(StateData, Err); + false -> + ok + end, + {next_state, StateName, StateData, get_timeout_interval(StateName)} + end. + opt_type(domain_certfile) -> fun iolist_to_binary/1; opt_type(max_fsm_queue) -> fun (I) when is_integer(I), I > 0 -> I end; diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 465fb587a..432253e09 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -46,8 +46,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {socket :: ejabberd_socket:socket_state(), @@ -58,44 +57,19 @@ access :: atom(), check_from = true :: boolean()}). -%-define(DBGFSM, true). +-type state_name() :: wait_for_stream | wait_for_handshake | stream_established. +-type state() :: #state{}. +-type fsm_next() :: {next_state, state_name(), state()}. +-type fsm_stop() :: {stop, normal, state()}. +-type fsm_transition() :: fsm_stop() | fsm_next(). +%-define(DBGFSM, true). -ifdef(DBGFSM). - -define(FSMOPTS, [{debug, [trace]}]). - -else. - -define(FSMOPTS, []). - -endif. --define(STREAM_HEADER, - <<"">>). - --define(STREAM_TRAILER, <<"">>). - --define(INVALID_HEADER_ERR, - <<"Invalid " - "Stream Header">>). - --define(INVALID_HANDSHAKE_ERR, - <<"Invalid Handshake">>). - --define(INVALID_XML_ERR, - fxml:element_to_binary(?SERR_XML_NOT_WELL_FORMED)). - --define(INVALID_NS_ERR, - fxml:element_to_binary(?SERR_INVALID_NAMESPACE)). - %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- @@ -112,14 +86,6 @@ socket_type() -> xml_stream. %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- - -%%---------------------------------------------------------------------- -%% Func: init/1 -%% Returns: {ok, StateName, StateData} | -%% {ok, StateName, StateData, Timeout} | -%% ignore | -%% {stop, StopReason} -%%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> ?INFO_MSG("(~w) External service connected", [Socket]), Access = case lists:keysearch(access, 1, Opts) of @@ -157,177 +123,127 @@ init([{SockMod, Socket}, Opts]) -> streamid = new_id(), host_opts = HostOpts, access = Access, check_from = CheckFrom}}. -%%---------------------------------------------------------------------- -%% Func: StateName/2 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- - -wait_for_stream({xmlstreamstart, _Name, Attrs}, - StateData) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - <<"jabber:component:accept">> -> - To = fxml:get_attr_s(<<"to">>, Attrs), - Host = jid:nameprep(To), - if Host == error -> - Header = io_lib:format(?STREAM_HEADER, - [<<"none">>, ?MYNAME]), - send_text(StateData, - <<(list_to_binary(Header))/binary, - (?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), - {stop, normal, StateData}; - true -> - Header = io_lib:format(?STREAM_HEADER, - [StateData#state.streamid, fxml:crypt(To)]), - send_text(StateData, Header), - HostOpts = case dict:is_key(Host, StateData#state.host_opts) of - true -> - StateData#state.host_opts; - false -> - case dict:find(global, StateData#state.host_opts) of - {ok, GlobalPass} -> - dict:from_list([{Host, GlobalPass}]); - error -> - StateData#state.host_opts - end - end, - {next_state, wait_for_handshake, - StateData#state{host = Host, host_opts = HostOpts}} - end; - _ -> - send_text(StateData, ?INVALID_HEADER_ERR), - {stop, normal, StateData} +wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> + try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of + #stream_start{xmlns = ?NS_COMPONENT, to = To} when is_record(To, jid) -> + Host = To#jid.lserver, + send_header(StateData, To), + HostOpts = case dict:is_key(Host, StateData#state.host_opts) of + true -> + StateData#state.host_opts; + false -> + case dict:find(global, StateData#state.host_opts) of + {ok, GlobalPass} -> + dict:from_list([{Host, GlobalPass}]); + error -> + StateData#state.host_opts + end + end, + {next_state, wait_for_handshake, + StateData#state{host = Host, host_opts = HostOpts}}; + #stream_start{xmlns = ?NS_COMPONENT} -> + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_improper_addressing()), + {stop, normal, StateData}; + #stream_start{} -> + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData} + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)), + {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> - Header = io_lib:format(?STREAM_HEADER, - [<<"none">>, ?MYNAME]), - send_text(StateData, - <<(list_to_binary(Header))/binary, (?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}. wait_for_handshake({xmlstreamelement, El}, StateData) -> - #xmlel{name = Name, children = Els} = El, - case {Name, fxml:get_cdata(Els)} of - {<<"handshake">>, Digest} -> - case dict:find(StateData#state.host, StateData#state.host_opts) of - {ok, Password} -> - case p1_sha:sha(<<(StateData#state.streamid)/binary, - Password/binary>>) of - Digest -> - send_text(StateData, <<"">>), - lists:foreach( - fun (H) -> - ejabberd_router:register_route(H, ?MYNAME), - ?INFO_MSG("Route registered for service ~p~n", - [H]) - end, dict:fetch_keys(StateData#state.host_opts)), - {next_state, stream_established, StateData}; - _ -> - send_text(StateData, ?INVALID_HANDSHAKE_ERR), - {stop, normal, StateData} - end; - _ -> - send_text(StateData, ?INVALID_HANDSHAKE_ERR), - {stop, normal, StateData} - end; - _ -> {next_state, wait_for_handshake, StateData} + decode_element(El, wait_for_handshake, StateData); +wait_for_handshake(#handshake{data = Digest}, StateData) -> + case dict:find(StateData#state.host, StateData#state.host_opts) of + {ok, Password} -> + case p1_sha:sha(<<(StateData#state.streamid)/binary, + Password/binary>>) of + Digest -> + send_element(StateData, #handshake{}), + lists:foreach( + fun (H) -> + ejabberd_router:register_route(H, ?MYNAME), + ?INFO_MSG("Route registered for service ~p~n", + [H]) + end, dict:fetch_keys(StateData#state.host_opts)), + {next_state, stream_established, StateData}; + _ -> + send_element(StateData, xmpp:serr_not_authorized()), + {stop, normal, StateData} + end; + _ -> + send_element(StateData, xmpp:serr_not_authorized()), + {stop, normal, StateData} end; wait_for_handshake({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; wait_for_handshake({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_handshake(closed, StateData) -> - {stop, normal, StateData}. + {stop, normal, StateData}; +wait_for_handshake(_Pkt, StateData) -> + {next_state, wait_for_handshake, StateData}. stream_established({xmlstreamelement, El}, StateData) -> - NewEl = jlib:remove_attr(<<"xmlns">>, El), - #xmlel{name = Name, attrs = Attrs} = NewEl, - From = fxml:get_attr_s(<<"from">>, Attrs), - FromJID = case StateData#state.check_from of - %% If the admin does not want to check the from field - %% when accept packets from any address. - %% In this case, the component can send packet of - %% behalf of the server users. - false -> jid:from_string(From); - %% The default is the standard behaviour in XEP-0114 - _ -> - FromJID1 = jid:from_string(From), - case FromJID1 of - #jid{lserver = Server} -> - case dict:is_key(Server, StateData#state.host_opts) of - true -> FromJID1; - false -> error - end; - _ -> error - end - end, - To = fxml:get_attr_s(<<"to">>, Attrs), - ToJID = case To of - <<"">> -> error; - _ -> jid:from_string(To) - end, - if ((Name == <<"iq">>) or (Name == <<"message">>) or - (Name == <<"presence">>)) - and (ToJID /= error) - and (FromJID /= error) -> - ejabberd_router:route(FromJID, ToJID, NewEl); + decode_element(El, stream_established, StateData); +stream_established(El, StateData) when ?is_stanza(El) -> + From = xmpp:get_from(El), + To = xmpp:get_to(El), + Lang = xmpp:get_lang(El), + if From == undefined orelse To == undefined -> + send_error(StateData, El, xmpp:err_jid_malformed()); true -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, El), - Txt = <<"Incorrect stanza name or from/to JID">>, - Err = jlib:make_error_reply(NewEl, ?ERRT_BAD_REQUEST(Lang, Txt)), - send_element(StateData, Err), - error + FromJID = case StateData#state.check_from of + false -> + %% If the admin does not want to check the from field + %% when accept packets from any address. + %% In this case, the component can send packet of + %% behalf of the server users. + From; + _ -> + %% The default is the standard behaviour in XEP-0114 + case From of + #jid{lserver = Server} -> + case dict:is_key(Server, StateData#state.host_opts) of + true -> From; + false -> error + end; + _ -> error + end + end, + if FromJID /= error -> + ejabberd_router:route(FromJID, To, El); + true -> + Txt = <<"Incorrect value of 'from' or 'to' attribute">>, + send_error(StateData, El, xmpp:err_not_allowed(Txt, Lang)) + end end, {next_state, stream_established, StateData}; stream_established({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; stream_established({xmlstreamerror, _}, StateData) -> - send_text(StateData, - <<(?INVALID_XML_ERR)/binary, - (?STREAM_TRAILER)/binary>>), + send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; stream_established(closed, StateData) -> - {stop, normal, StateData}. - -%%---------------------------------------------------------------------- -%% Func: StateName/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- -%state_name(Event, From, StateData) -> -% Reply = ok, -% {reply, Reply, state_name, StateData}. + {stop, normal, StateData}; +stream_established(_Event, StateData) -> + {next_state, stream_established, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_event/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. @@ -335,12 +251,6 @@ handle_sync_event(_Event, _From, StateName, code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; @@ -349,34 +259,20 @@ handle_info({send_element, El}, StateName, StateData) -> {next_state, StateName, StateData}; handle_info({route, From, To, Packet}, StateName, StateData) -> - case acl:match_rule(global, StateData#state.access, - From) - of + case acl:match_rule(global, StateData#state.access, From) of allow -> - #xmlel{name = Name, attrs = Attrs, children = Els} = - Packet, - Attrs2 = - jlib:replace_from_to_attrs(jid:to_string(From), - jid:to_string(To), Attrs), - Text = fxml:element_to_binary(#xmlel{name = Name, - attrs = Attrs2, children = Els}), - send_text(StateData, Text); - deny -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), - Txt = <<"Denied by ACL">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)), - ejabberd_router:route_error(To, From, Err, Packet) + Pkt = xmpp:set_from_to(Packet, From, To), + send_element(StateData, Pkt); + deny -> + Lang = xmpp:get_lang(Packet), + Err = xmpp:err_not_allowed(<<"Denied by ACL">>, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end, {next_state, StateName, StateData}; handle_info(Info, StateName, StateData) -> ?ERROR_MSG("Unexpected info: ~p", [Info]), {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: terminate/3 -%% Purpose: Shutdown the fsm -%% Returns: any -%%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> ?INFO_MSG("terminated: ~p", [Reason]), case StateName of @@ -387,6 +283,7 @@ terminate(Reason, StateName, StateData) -> dict:fetch_keys(StateData#state.host_opts)); _ -> ok end, + catch send_trailer(StateData), (StateData#state.sockmod):close(StateData#state.socket), ok. @@ -401,13 +298,69 @@ print_state(State) -> State. %%% Internal functions %%%---------------------------------------------------------------------- +-spec send_text(state(), iodata()) -> ok. send_text(StateData, Text) -> (StateData#state.sockmod):send(StateData#state.socket, Text). +-spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - send_text(StateData, fxml:element_to_binary(El)). + El1 = fix_ns(xmpp:encode(El)), + send_text(StateData, fxml:element_to_binary(El1)). + +-spec send_error(state(), xmlel() | stanza(), error()) -> ok. +send_error(StateData, Stanza, Error) -> + Type = xmpp:get_type(Stanza), + if Type == error; Type == result; + Type == <<"error">>; Type == <<"result">> -> + ok; + true -> + send_element(StateData, xmpp:make_error(Stanza, Error)) + end. + +-spec send_header(state(), binary()) -> ok. +send_header(StateData, Host) -> + send_text(StateData, + io_lib:format( + <<"">>, + [StateData#state.streamid, fxml:crypt(Host)])). + +-spec send_trailer(state()) -> ok. +send_trailer(StateData) -> + send_text(StateData, <<"">>). + +-spec fix_ns(xmlel()) -> xmlel(). +fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; + Name == <<"iq">>; + Name == <<"presence">> -> + Attrs = lists:filter( + fun({<<"xmlns">>, _}) -> false; + (_) -> true + end, El#xmlel.attrs), + El#xmlel{attrs = Attrs}; +fix_ns(El) -> + El. + +-spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). +decode_element(#xmlel{} = El, StateName, StateData) -> + try xmpp:decode(El, [ignore_els]) of + Pkt -> ?MODULE:StateName(Pkt, StateData) + catch error:{xmpp_codec, Why} -> + case xmpp:is_stanza(El) of + true -> + Lang = xmpp:get_lang(El), + Txt = xmpp:format_error(Why), + send_error(StateData, El, xmpp:err_bad_request(Txt, Lang)); + false -> + ok + end, + {next_state, StateName, StateData} + end. +-spec new_id() -> binary(). new_id() -> randoms:get_string(). transform_listen_option({hosts, Hosts, O}, Opts) -> diff --git a/src/xmpp.erl b/src/xmpp.erl index 369fb90c5..5b7e3d1cc 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -71,10 +71,6 @@ serr_unsupported_stanza_type/0, serr_unsupported_stanza_type/2, serr_unsupported_version/0, serr_unsupported_version/2]). --ifndef(NS_CLIENT). --define(NS_CLIENT, <<"jabber:client">>). --endif. - -include("xmpp.hrl"). %%%=================================================================== @@ -246,9 +242,14 @@ get_name(Pkt) -> decode(El) -> decode(El, []). --spec decode(xmlel() | xmpp_element(), [proplists:property()]) -> +-spec decode(xmlel() | xmpp_element(), + [proplists:property()] | + fun((xmlel() | xmpp_element()) -> boolean())) -> {ok, xmpp_element()} | {error, any()}. -decode(#xmlel{} = El, Opts) -> +decode(#xmlel{} = El, MatchFun) when is_function(MatchFun) -> + Pkt = xmpp_codec:decode(add_ns(El), [ignore_els]), + decode_els(Pkt, MatchFun); +decode(#xmlel{} = El, Opts) when is_list(Opts) -> xmpp_codec:decode(add_ns(El), Opts); decode(Pkt, _Opts) -> Pkt. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index c8a4f002f..7eb06b11e 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,21 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"stream:stream">>, <<"jabber:client">>} -> + decode_stream_start(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:stream">>, <<"jabber:server">>} -> + decode_stream_start(<<"jabber:server">>, IgnoreEls, + _el); + {<<"stream:stream">>, <<"jabber:component:accept">>} -> + decode_stream_start(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"handshake">>, <<"jabber:client">>} -> + decode_handshake(<<"jabber:client">>, IgnoreEls, _el); + {<<"db:verify">>, <<"jabber:client">>} -> + decode_db_verify(<<"jabber:client">>, IgnoreEls, _el); + {<<"db:result">>, <<"jabber:client">>} -> + decode_db_result(<<"jabber:client">>, IgnoreEls, _el); {<<"command">>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, @@ -1278,6 +1293,13 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"stream:stream">>, <<"jabber:client">>} -> true; + {<<"stream:stream">>, <<"jabber:server">>} -> true; + {<<"stream:stream">>, <<"jabber:component:accept">>} -> + true; + {<<"handshake">>, <<"jabber:client">>} -> true; + {<<"db:verify">>, <<"jabber:client">>} -> true; + {<<"db:result">>, <<"jabber:client">>} -> true; {<<"command">>, <<"http://jabber.org/protocol/commands">>} -> true; @@ -2538,7 +2560,19 @@ encode({adhoc_command, _, _, _, _, _, _, _, _} = Command) -> encode_adhoc_command(Command, [{<<"xmlns">>, - <<"http://jabber.org/protocol/commands">>}]). + <<"http://jabber.org/protocol/commands">>}]); +encode({db_result, _, _, _, _, _} = Db_result) -> + encode_db_result(Db_result, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({db_verify, _, _, _, _, _, _} = Db_verify) -> + encode_db_verify(Db_verify, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({handshake, _} = Handshake) -> + encode_handshake(Handshake, + [{<<"xmlns">>, <<"jabber:client">>}]); +encode({stream_start, _, _, _, _, _, _, _, _} = + Stream_stream) -> + encode_stream_start(Stream_stream, []). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2720,7 +2754,13 @@ get_name({client_id, _}) -> <<"client-id">>; get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>; get_name({adhoc_note, _, _}) -> <<"note">>; get_name({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"command">>. + <<"command">>; +get_name({db_result, _, _, _, _, _}) -> <<"db:result">>; +get_name({db_verify, _, _, _, _, _, _}) -> + <<"db:verify">>; +get_name({handshake, _}) -> <<"handshake">>; +get_name({stream_start, _, _, _, _, _, _, _, _}) -> + <<"stream:stream">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -2974,7 +3014,14 @@ get_ns({adhoc_actions, _, _, _, _}) -> get_ns({adhoc_note, _, _}) -> <<"http://jabber.org/protocol/commands">>; get_ns({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/commands">>. + <<"http://jabber.org/protocol/commands">>; +get_ns({db_result, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({db_verify, _, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({handshake, _}) -> <<"jabber:client">>; +get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> + Xmlns. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3210,6 +3257,12 @@ 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(handshake, 1) -> [data]; +pp(stream_start, 8) -> + [from, to, id, version, xmlns, stream_xmlns, db_xmlns, + lang]; pp(_, _) -> no. join([], _Sep) -> <<>>; @@ -3256,6 +3309,478 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_stream_start(__TopXMLNS, __IgnoreEls, + {xmlel, <<"stream:stream">>, _attrs, _els}) -> + {From, To, Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, + Id} = + decode_stream_start_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined), + {stream_start, From, To, Id, Version, Xmlns, + Stream_xmlns, Db_xmlns, Lang}. + +decode_stream_start_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], _From, To, Xmlns, + Stream_xmlns, Db_xmlns, Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, _val, To, + Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], From, _To, Xmlns, + Stream_xmlns, Db_xmlns, Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, + _val, Xmlns, Stream_xmlns, Db_xmlns, Lang, + Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], From, To, _Xmlns, + Stream_xmlns, Db_xmlns, Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + _val, Stream_xmlns, Db_xmlns, Lang, Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"xmlns:stream">>, _val} | _attrs], From, To, + Xmlns, _Stream_xmlns, Db_xmlns, Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, _val, Db_xmlns, Lang, Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"xmlns:db">>, _val} | _attrs], From, To, Xmlns, + Stream_xmlns, _Db_xmlns, Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, Stream_xmlns, _val, Lang, Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"xml:lang">>, _val} | _attrs], From, To, Xmlns, + Stream_xmlns, Db_xmlns, _Lang, Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, Stream_xmlns, Db_xmlns, _val, Version, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"version">>, _val} | _attrs], From, To, Xmlns, + Stream_xmlns, Db_xmlns, Lang, _Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, Stream_xmlns, Db_xmlns, Lang, _val, Id); +decode_stream_start_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], From, To, Xmlns, + Stream_xmlns, Db_xmlns, Lang, Version, _Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, + _val); +decode_stream_start_attrs(__TopXMLNS, [_ | _attrs], + From, To, Xmlns, Stream_xmlns, Db_xmlns, Lang, + Version, Id) -> + decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, + Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id); +decode_stream_start_attrs(__TopXMLNS, [], From, To, + Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id) -> + {decode_stream_start_attr_from(__TopXMLNS, From), + decode_stream_start_attr_to(__TopXMLNS, To), + decode_stream_start_attr_xmlns(__TopXMLNS, Xmlns), + 'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, + Stream_xmlns), + 'decode_stream_start_attr_xmlns:db'(__TopXMLNS, + Db_xmlns), + 'decode_stream_start_attr_xml:lang'(__TopXMLNS, Lang), + decode_stream_start_attr_version(__TopXMLNS, Version), + decode_stream_start_attr_id(__TopXMLNS, Id)}. + +encode_stream_start({stream_start, From, To, Id, + Version, Xmlns, Stream_xmlns, Db_xmlns, Lang}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_stream_start_attr_id(Id, + encode_stream_start_attr_version(Version, + 'encode_stream_start_attr_xml:lang'(Lang, + 'encode_stream_start_attr_xmlns:db'(Db_xmlns, + 'encode_stream_start_attr_xmlns:stream'(Stream_xmlns, + encode_stream_start_attr_xmlns(Xmlns, + encode_stream_start_attr_to(To, + encode_stream_start_attr_from(From, + _xmlns_attrs)))))))), + {xmlel, <<"stream:stream">>, _attrs, _els}. + +decode_stream_start_attr_from(__TopXMLNS, undefined) -> + undefined; +decode_stream_start_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"stream:stream">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_stream_start_attr_from(undefined, _acc) -> _acc; +encode_stream_start_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_stream_start_attr_to(__TopXMLNS, undefined) -> + undefined; +decode_stream_start_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"stream:stream">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_stream_start_attr_to(undefined, _acc) -> _acc; +encode_stream_start_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +decode_stream_start_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_stream_start_attr_xmlns(__TopXMLNS, _val) -> + _val. + +encode_stream_start_attr_xmlns(undefined, _acc) -> _acc; +encode_stream_start_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, + undefined) -> + <<>>; +'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, + _val) -> + _val. + +'encode_stream_start_attr_xmlns:stream'(<<>>, _acc) -> + _acc; +'encode_stream_start_attr_xmlns:stream'(_val, _acc) -> + [{<<"xmlns:stream">>, _val} | _acc]. + +'decode_stream_start_attr_xmlns:db'(__TopXMLNS, + undefined) -> + <<>>; +'decode_stream_start_attr_xmlns:db'(__TopXMLNS, _val) -> + _val. + +'encode_stream_start_attr_xmlns:db'(<<>>, _acc) -> _acc; +'encode_stream_start_attr_xmlns:db'(_val, _acc) -> + [{<<"xmlns:db">>, _val} | _acc]. + +'decode_stream_start_attr_xml:lang'(__TopXMLNS, + undefined) -> + <<>>; +'decode_stream_start_attr_xml:lang'(__TopXMLNS, _val) -> + _val. + +'encode_stream_start_attr_xml:lang'(<<>>, _acc) -> _acc; +'encode_stream_start_attr_xml:lang'(_val, _acc) -> + [{<<"xml:lang">>, _val} | _acc]. + +decode_stream_start_attr_version(__TopXMLNS, + undefined) -> + <<>>; +decode_stream_start_attr_version(__TopXMLNS, _val) -> + _val. + +encode_stream_start_attr_version(<<>>, _acc) -> _acc; +encode_stream_start_attr_version(_val, _acc) -> + [{<<"version">>, _val} | _acc]. + +decode_stream_start_attr_id(__TopXMLNS, undefined) -> + <<>>; +decode_stream_start_attr_id(__TopXMLNS, _val) -> _val. + +encode_stream_start_attr_id(<<>>, _acc) -> _acc; +encode_stream_start_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_handshake(__TopXMLNS, __IgnoreEls, + {xmlel, <<"handshake">>, _attrs, _els}) -> + Data = decode_handshake_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {handshake, Data}. + +decode_handshake_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_handshake_cdata(__TopXMLNS, Data); +decode_handshake_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_handshake_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_handshake_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_handshake_els(__TopXMLNS, __IgnoreEls, _els, + Data). + +encode_handshake({handshake, Data}, _xmlns_attrs) -> + _els = encode_handshake_cdata(Data, []), + _attrs = _xmlns_attrs, + {xmlel, <<"handshake">>, _attrs, _els}. + +decode_handshake_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_handshake_cdata(__TopXMLNS, _val) -> _val. + +encode_handshake_cdata(<<>>, _acc) -> _acc; +encode_handshake_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_db_verify(__TopXMLNS, __IgnoreEls, + {xmlel, <<"db:verify">>, _attrs, _els}) -> + {Key, Error} = decode_db_verify_els(__TopXMLNS, + __IgnoreEls, _els, <<>>, undefined), + {From, To, Id, Type} = + decode_db_verify_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {db_verify, From, To, Id, Type, Key, Error}. + +decode_db_verify_els(__TopXMLNS, __IgnoreEls, [], Key, + Error) -> + {decode_db_verify_cdata(__TopXMLNS, Key), Error}; +decode_db_verify_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Key, Error) -> + decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, + <>, Error); +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). + +decode_db_verify_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], _From, To, Id, Type) -> + decode_db_verify_attrs(__TopXMLNS, _attrs, _val, To, Id, + Type); +decode_db_verify_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], From, _To, Id, Type) -> + decode_db_verify_attrs(__TopXMLNS, _attrs, From, _val, + Id, Type); +decode_db_verify_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], From, To, _Id, Type) -> + decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, + _val, Type); +decode_db_verify_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], From, To, Id, _Type) -> + decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, Id, + _val); +decode_db_verify_attrs(__TopXMLNS, [_ | _attrs], From, + To, Id, Type) -> + decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, Id, + Type); +decode_db_verify_attrs(__TopXMLNS, [], From, To, Id, + Type) -> + {decode_db_verify_attr_from(__TopXMLNS, From), + decode_db_verify_attr_to(__TopXMLNS, To), + decode_db_verify_attr_id(__TopXMLNS, Id), + decode_db_verify_attr_type(__TopXMLNS, Type)}. + +encode_db_verify({db_verify, From, To, Id, Type, Key, + Error}, + _xmlns_attrs) -> + _els = lists:reverse(encode_db_verify_cdata(Key, + 'encode_db_verify_$error'(Error, + []))), + _attrs = encode_db_verify_attr_type(Type, + encode_db_verify_attr_id(Id, + encode_db_verify_attr_to(To, + encode_db_verify_attr_from(From, + _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">>, + __TopXMLNS}}); +decode_db_verify_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"db:verify">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_verify_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_db_verify_attr_to(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"to">>, <<"db:verify">>, __TopXMLNS}}); +decode_db_verify_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"db:verify">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_verify_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +decode_db_verify_attr_id(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"id">>, <<"db:verify">>, __TopXMLNS}}); +decode_db_verify_attr_id(__TopXMLNS, _val) -> _val. + +encode_db_verify_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_db_verify_attr_type(__TopXMLNS, undefined) -> + undefined; +decode_db_verify_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, [valid, invalid, error]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"db:verify">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_verify_attr_type(undefined, _acc) -> _acc; +encode_db_verify_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_db_verify_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_db_verify_cdata(__TopXMLNS, _val) -> _val. + +encode_db_verify_cdata(<<>>, _acc) -> _acc; +encode_db_verify_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_db_result(__TopXMLNS, __IgnoreEls, + {xmlel, <<"db:result">>, _attrs, _els}) -> + {Key, Error} = decode_db_result_els(__TopXMLNS, + __IgnoreEls, _els, <<>>, undefined), + {From, To, Type} = decode_db_result_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {db_result, From, To, Type, Key, Error}. + +decode_db_result_els(__TopXMLNS, __IgnoreEls, [], Key, + Error) -> + {decode_db_result_cdata(__TopXMLNS, Key), Error}; +decode_db_result_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Key, Error) -> + decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, + <>, Error); +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). + +decode_db_result_attrs(__TopXMLNS, + [{<<"from">>, _val} | _attrs], _From, To, Type) -> + decode_db_result_attrs(__TopXMLNS, _attrs, _val, To, + Type); +decode_db_result_attrs(__TopXMLNS, + [{<<"to">>, _val} | _attrs], From, _To, Type) -> + decode_db_result_attrs(__TopXMLNS, _attrs, From, _val, + Type); +decode_db_result_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], From, To, _Type) -> + decode_db_result_attrs(__TopXMLNS, _attrs, From, To, + _val); +decode_db_result_attrs(__TopXMLNS, [_ | _attrs], From, + To, Type) -> + decode_db_result_attrs(__TopXMLNS, _attrs, From, To, + Type); +decode_db_result_attrs(__TopXMLNS, [], From, To, + Type) -> + {decode_db_result_attr_from(__TopXMLNS, From), + decode_db_result_attr_to(__TopXMLNS, To), + decode_db_result_attr_type(__TopXMLNS, Type)}. + +encode_db_result({db_result, From, To, Type, Key, + Error}, + _xmlns_attrs) -> + _els = lists:reverse(encode_db_result_cdata(Key, + 'encode_db_result_$error'(Error, + []))), + _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">>, + __TopXMLNS}}); +decode_db_result_attr_from(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"from">>, <<"db:result">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_result_attr_from(_val, _acc) -> + [{<<"from">>, enc_jid(_val)} | _acc]. + +decode_db_result_attr_to(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"to">>, <<"db:result">>, __TopXMLNS}}); +decode_db_result_attr_to(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"to">>, <<"db:result">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_result_attr_to(_val, _acc) -> + [{<<"to">>, enc_jid(_val)} | _acc]. + +decode_db_result_attr_type(__TopXMLNS, undefined) -> + undefined; +decode_db_result_attr_type(__TopXMLNS, _val) -> + case catch dec_enum(_val, [valid, invalid, error]) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"type">>, <<"db:result">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_db_result_attr_type(undefined, _acc) -> _acc; +encode_db_result_attr_type(_val, _acc) -> + [{<<"type">>, enc_enum(_val)} | _acc]. + +decode_db_result_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_db_result_cdata(__TopXMLNS, _val) -> _val. + +encode_db_result_cdata(<<>>, _acc) -> _acc; +encode_db_result_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + decode_adhoc_command(__TopXMLNS, __IgnoreEls, {xmlel, <<"command">>, _attrs, _els}) -> {Xdata, Notes, Actions} = -- cgit v1.2.3 From 1097d31d636899d31a4062ec8d48ce58b55c0206 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 27 Jul 2016 18:05:11 +0300 Subject: Fix type spec for set_from_to/3 --- src/xmpp.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmpp.erl b/src/xmpp.erl index 5b7e3d1cc..6e8145190 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -205,9 +205,9 @@ set_to(#iq{} = IQ, J) -> IQ#iq{to = J}; set_to(#message{} = Msg, J) -> Msg#message{to = J}; set_to(#presence{} = Pres, J) -> Pres#presence{to = J}. --spec set_from_to(iq(), jid:jid(), jid:jid()) -> iq(); - (message(), jid:jid(), jid:jid()) -> message(); - (presence(), jid:jid(), jid:jid()) -> presence(). +-spec set_from_to(iq(), undefined | jid:jid(), undefined | jid:jid()) -> iq(); + (message(), undefined | jid:jid(), undefined | jid:jid()) -> message(); + (presence(), undefined | jid:jid(), undefined | jid:jid()) -> presence(). set_from_to(#iq{} = IQ, F, T) -> IQ#iq{from = F, to = T}; set_from_to(#message{} = Msg, F, T) -> Msg#message{from = F, to = T}; set_from_to(#presence{} = Pres, F, T) -> Pres#presence{from = F, to = T}. -- cgit v1.2.3 From 8275e95a1606670fc6334d9832de519c67550dcb Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 27 Jul 2016 18:06:34 +0300 Subject: Swap variables in their correct places --- src/mod_mam.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mod_mam.erl b/src/mod_mam.erl index b4ee17720..0aaf484c5 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -213,7 +213,7 @@ set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) -> catch _:{case_clause, _} -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_bad_request(Lang, ErrTxt)} + {error, xmpp:err_bad_request(ErrTxt, Lang)} end; set_room_option(Acc, _Opt, _Vals, _Lang) -> Acc. -- cgit v1.2.3 From 96e912b09acb172f6f6cc8037377384c855ae472 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 27 Jul 2016 18:06:54 +0300 Subject: Rewrite mod_register to use XML generator --- src/mod_register.erl | 531 ++++++++++++++++++++------------------------------- 1 file changed, 202 insertions(+), 329 deletions(-) (limited to 'src') diff --git a/src/mod_register.erl b/src/mod_register.erl index 45cd78fef..3f9c33123 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -35,14 +35,13 @@ -export([start/2, stop/1, stream_feature_register/2, unauthenticated_iq_register/4, try_register/5, - process_iq/3, send_registration_notifications/3, + process_iq/1, send_registration_notifications/3, transform_options/1, transform_module_options/1, mod_opt_type/1, opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). +-include("xmpp.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, @@ -79,329 +78,223 @@ stream_feature_register(Acc, Host) -> AF = gen_mod:get_module_opt(Host, ?MODULE, access_from, fun(A) -> A end, all), - case (AF /= none) and lists:keymember(<<"mechanisms">>, 2, Acc) of + case (AF /= none) and lists:keymember(sasl_mechanisms, 1, Acc) of true -> - [#xmlel{name = <<"register">>, - attrs = [{<<"xmlns">>, ?NS_FEATURE_IQREGISTER}], - children = []} - | Acc]; + [#feature_register{}|Acc]; false -> Acc end. unauthenticated_iq_register(_Acc, Server, - #iq{xmlns = ?NS_REGISTER} = IQ, IP) -> + #iq{sub_els = [#register{}]} = IQ, IP) -> Address = case IP of {A, _Port} -> A; _ -> undefined end, - ResIQ = process_iq(jid:make(<<"">>, <<"">>, - <<"">>), - jid:make(<<"">>, Server, <<"">>), IQ, Address), - Res1 = jlib:replace_from_to(jid:make(<<"">>, - Server, <<"">>), - jid:make(<<"">>, <<"">>, <<"">>), - jlib:iq_to_xml(ResIQ)), - jlib:remove_attr(<<"to">>, Res1); + ResIQ = process_iq(xmpp:set_from_to(IQ, jid:make(<<>>), jid:make(Server)), + Address), + xmpp:set_from_to(ResIQ, jid:make(Server), undefined); unauthenticated_iq_register(Acc, _Server, _IQ, _IP) -> Acc. -process_iq(From, To, IQ) -> - process_iq(From, To, IQ, jid:tolower(From)). - -process_iq(From, To, - #iq{type = Type, lang = Lang, sub_el = SubEl, id = ID} = - IQ, - Source) -> - IsCaptchaEnabled = case - gen_mod:get_module_opt(To#jid.lserver, ?MODULE, - captcha_protected, - fun(B) when is_boolean(B) -> B end, - false) - of - true -> true; - _ -> false - end, - case Type of - set -> - UTag = fxml:get_subtag(SubEl, <<"username">>), - PTag = fxml:get_subtag(SubEl, <<"password">>), - RTag = fxml:get_subtag(SubEl, <<"remove">>), - Server = To#jid.lserver, - Access = gen_mod:get_module_opt(Server, ?MODULE, access, - fun(A) -> A end, - all), - AllowRemove = allow == - acl:match_rule(Server, Access, From), - if (UTag /= false) and (RTag /= false) and - AllowRemove -> - User = fxml:get_tag_cdata(UTag), - case From of - #jid{user = User, lserver = Server} -> - ejabberd_auth:remove_user(User, Server), - IQ#iq{type = result, sub_el = []}; - _ -> - if PTag /= false -> - Password = fxml:get_tag_cdata(PTag), - case ejabberd_auth:remove_user(User, Server, - Password) - of - ok -> IQ#iq{type = result, sub_el = []}; - %% TODO FIXME: This piece of - %% code does not work since - %% the code have been changed - %% to allow several auth - %% modules. lists:foreach can - %% only return ok: - not_allowed -> - Txt = <<"Removal is not allowed">>, - IQ#iq{type = error, - sub_el = [SubEl, - ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - not_exists -> - Txt = <<"No such user">>, - IQ#iq{type = error, - sub_el = - [SubEl, - ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]}; - Err -> - ?ERROR_MSG("failed to remove user ~s@~s: ~p", - [User, Server, Err]), - IQ#iq{type = error, - sub_el = - [SubEl, - ?ERR_INTERNAL_SERVER_ERROR]} - end; - true -> - Txt = <<"No password in this query">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]} - end - end; - (UTag == false) and (RTag /= false) and AllowRemove -> - case From of - #jid{user = User, lserver = Server, - resource = Resource} -> - ResIQ = #iq{type = result, xmlns = ?NS_REGISTER, - id = ID, sub_el = []}, - ejabberd_router:route(jid:make(User, Server, - Resource), - jid:make(User, Server, - Resource), - jlib:iq_to_xml(ResIQ)), - ejabberd_auth:remove_user(User, Server), - ignore; - _ -> - Txt = <<"The query is only allowed from local users">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]} - end; - (UTag /= false) and (PTag /= false) -> - User = fxml:get_tag_cdata(UTag), - Password = fxml:get_tag_cdata(PTag), - try_register_or_set_password(User, Server, Password, - From, IQ, SubEl, Source, Lang, - not IsCaptchaEnabled); - IsCaptchaEnabled -> - case ejabberd_captcha:process_reply(SubEl) of - ok -> - case process_xdata_submit(SubEl) of - {ok, User, Password} -> - try_register_or_set_password(User, Server, - Password, From, IQ, - SubEl, Source, Lang, - true); - _ -> - Txt = <<"Incorrect data form">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]} - end; - {error, malformed} -> - Txt = <<"Incorrect CAPTCHA submit">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}; - _ -> - ErrText = <<"The CAPTCHA verification has failed">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, ErrText)]} - end; - true -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} - end; - get -> - {IsRegistered, UsernameSubels, QuerySubels} = case From - of - #jid{user = User, - lserver = - Server} -> - case - ejabberd_auth:is_user_exists(User, - Server) - of - true -> - {true, - [{xmlcdata, - User}], - [#xmlel{name - = - <<"registered">>, - attrs - = - [], - children - = - []}]}; - false -> - {false, - [{xmlcdata, - User}], - []} - end; - _ -> {false, [], []} - end, - if IsCaptchaEnabled and not IsRegistered -> - TopInstrEl = #xmlel{name = <<"instructions">>, - attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"You need a client that supports x:data " - "and CAPTCHA to register">>)}]}, - InstrEl = #xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Choose a username and password to register " - "with this server">>)}]}, - UField = #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"text-single">>}, - {<<"label">>, - translate:translate(Lang, <<"User">>)}, - {<<"var">>, <<"username">>}], - children = - [#xmlel{name = <<"required">>, attrs = [], - children = []}]}, - PField = #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"text-private">>}, - {<<"label">>, - translate:translate(Lang, - <<"Password">>)}, - {<<"var">>, <<"password">>}], - children = - [#xmlel{name = <<"required">>, attrs = [], - children = []}]}, - case ejabberd_captcha:create_captcha_x(ID, To, Lang, - Source, - [InstrEl, UField, - PField]) - of - {ok, CaptchaEls} -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_REGISTER}], - children = - [TopInstrEl | CaptchaEls]}]}; - {error, limit} -> - ErrText = <<"Too many CAPTCHA requests">>, - IQ#iq{type = error, - sub_el = - [SubEl, - ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)]}; - _Err -> - ErrText = <<"Unable to generate a CAPTCHA">>, - IQ#iq{type = error, - sub_el = - [SubEl, - ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText)]} - end; - true -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_REGISTER}], - children = - [#xmlel{name = <<"instructions">>, - attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Choose a username and password to register " - "with this server">>)}]}, - #xmlel{name = <<"username">>, - attrs = [], - children = UsernameSubels}, - #xmlel{name = <<"password">>, - attrs = [], children = []} - | QuerySubels]}]} - end +process_iq(#iq{from = From} = IQ) -> + process_iq(IQ, jid:tolower(From)). + +process_iq(#iq{from = From, to = To} = IQ, Source) -> + IsCaptchaEnabled = + case gen_mod:get_module_opt(To#jid.lserver, ?MODULE, + captcha_protected, + fun(B) when is_boolean(B) -> B end, + false) of + true -> true; + false -> false + end, + Server = To#jid.lserver, + Access = gen_mod:get_module_opt(Server, ?MODULE, access, + fun(A) -> A end, all), + AllowRemove = allow == acl:match_rule(Server, Access, From), + process_iq(IQ, Source, IsCaptchaEnabled, AllowRemove). + +process_iq(#iq{type = set, lang = Lang, + sub_els = [#register{remove = true}]} = IQ, + _Source, _IsCaptchaEnabled, _AllowRemove = false) -> + Txt = <<"Denied by ACL">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)); +process_iq(#iq{type = set, lang = Lang, to = To, from = From, + sub_els = [#register{remove = true, + username = User, + password = Password}]} = IQ, + _Source, _IsCaptchaEnabled, _AllowRemove = true) -> + Server = To#jid.lserver, + if is_binary(User) -> + case From of + #jid{user = User, lserver = Server} -> + ejabberd_auth:remove_user(User, Server), + xmpp:make_iq_result(IQ); + _ -> + if is_binary(Password) -> + ejabberd_auth:remove_user(User, Server, Password), + xmpp:make_iq_result(IQ); + true -> + Txt = <<"No 'password' found in this query">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)) + end + end; + true -> + case From of + #jid{user = User, lserver = Server, resource = Resource} -> + ResIQ = xmpp:make_iq_result(IQ), + ejabberd_router:route(jid:make(User, Server, Resource), + jid:make(User, Server, Resource), + ResIQ), + ejabberd_auth:remove_user(User, Server), + ignore; + _ -> + Txt = <<"The query is only allowed from local users">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)) + end + end; +process_iq(#iq{type = set, to = To, + sub_els = [#register{username = User, + password = Password}]} = IQ, + Source, IsCaptchaEnabled, _AllowRemove) when is_binary(User), + is_binary(Password) -> + Server = To#jid.lserver, + try_register_or_set_password( + User, Server, Password, IQ, Source, not IsCaptchaEnabled); +process_iq(#iq{type = set, to = To, + lang = Lang, sub_els = [#register{xdata = #xdata{} = X}]} = IQ, + Source, true, _AllowRemove) -> + Server = To#jid.lserver, + case ejabberd_captcha:process_reply(X) of + ok -> + case process_xdata_submit(X) of + {ok, User, Password} -> + try_register_or_set_password( + User, Server, Password, IQ, Source, true); + _ -> + Txt = <<"Incorrect data form">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)) + end; + {error, malformed} -> + Txt = <<"Incorrect CAPTCHA submit">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); + _ -> + ErrText = <<"The CAPTCHA verification has failed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(ErrText, Lang)) + end; +process_iq(#iq{type = set} = IQ, _Source, _IsCaptchaEnabled, _AllowRemove) -> + xmpp:make_error(IQ, xmpp:err_bad_request()); +process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ, + Source, IsCaptchaEnabled, _AllowRemove) -> + Server = To#jid.lserver, + {IsRegistered, Username} = + case From of + #jid{user = User, lserver = Server} -> + case ejabberd_auth:is_user_exists(User, Server) of + true -> + {true, User}; + false -> + {false, User} + end; + _ -> + {false, <<"">>} + end, + if IsCaptchaEnabled and not IsRegistered -> + TopInstr = translate:translate( + Lang, <<"You need a client that supports x:data " + "and CAPTCHA to register">>), + Instr = translate:translate( + Lang, <<"Choose a username and password to register " + "with this server">>), + UField = #xdata_field{type = 'text-single', + label = translate:translate(Lang, <<"User">>), + var = <<"username">>, + required = true}, + PField = #xdata_field{type = 'text-private', + label = translate:translate(Lang, <<"Password">>), + var = <<"password">>, + required = true}, + X = #xdata{type = form, instructions = [Instr], + fields = [UField, PField]}, + case ejabberd_captcha:create_captcha_x(ID, To, Lang, Source, X) of + {ok, Captcha} -> + xmpp:make_iq_result( + IQ, #register{instructions = TopInstr, + xdata = Captcha}); + {error, limit} -> + ErrText = <<"Too many CAPTCHA requests">>, + xmpp:make_error( + IQ, xmpp:err_resource_constraint(ErrText, Lang)); + _Err -> + ErrText = <<"Unable to generate a CAPTCHA">>, + xmpp:make_error( + IQ, xmpp:err_internal_server_error(ErrText, Lang)) + end; + true -> + Instr = <<"Choose a username and password to register with this server">>, + xmpp:make_iq_result( + IQ, + #register{instructions = translate:translate(Lang, Instr), + username = Username, + password = <<"">>, + registered = IsRegistered}) end. try_register_or_set_password(User, Server, Password, - From, IQ, SubEl, Source, Lang, CaptchaSucceed) -> + #iq{from = From, lang = Lang} = IQ, + Source, CaptchaSucceed) -> case From of - #jid{user = User, lserver = Server} -> - try_set_password(User, Server, Password, IQ, SubEl, - Lang); - _ when CaptchaSucceed -> - case check_from(From, Server) of - allow -> - case try_register(User, Server, Password, Source, Lang) - of - ok -> IQ#iq{type = result, sub_el = []}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; - deny -> - Txt = <<"Denied by ACL">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]} - end; - _ -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} + #jid{user = User, lserver = Server} -> + try_set_password(User, Server, Password, IQ); + _ when CaptchaSucceed -> + case check_from(From, Server) of + allow -> + case try_register(User, Server, Password, Source, Lang) of + ok -> + xmpp:make_iq_result(IQ); + {error, Error} -> + xmpp:make_error(IQ, Error) + end; + deny -> + Txt = <<"Denied by ACL">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)) + end; + _ -> + xmpp:make_error(IQ, xmpp:err_not_allowed()) end. %% @doc Try to change password and return IQ response -try_set_password(User, Server, Password, IQ, SubEl, - Lang) -> +try_set_password(User, Server, Password, #iq{lang = Lang} = IQ) -> case is_strong_password(Server, Password) of true -> - case ejabberd_auth:set_password(User, Server, Password) - of - ok -> IQ#iq{type = result, sub_el = []}; + case ejabberd_auth:set_password(User, Server, Password) of + ok -> + xmpp:make_iq_result(IQ); {error, empty_password} -> Txt = <<"Empty password">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}; + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); {error, not_allowed} -> Txt = <<"Changing password is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); {error, invalid_jid} -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_JID_MALFORMED]}; + xmpp:make_error(IQ, xmpp:err_jid_malformed()); Err -> ?ERROR_MSG("failed to register user ~s@~s: ~p", [User, Server, Err]), - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} + xmpp:make_error(IQ, xmpp:err_internal_server_error()) end; error_preparing_password -> ErrText = <<"The password contains unacceptable characters">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)]}; + xmpp:make_error(IQ, xmpp:err_not_acceptable(ErrText, Lang)); false -> ErrText = <<"The password is too weak">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)]} + xmpp:make_error(IQ, xmpp:err_not_acceptable(ErrText, Lang)) end. try_register(User, Server, Password, SourceRaw, Lang) -> case jid:is_nodename(User) of - false -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Malformed username">>)}; + false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)}; _ -> JID = jid:make(User, Server, <<"">>), Access = gen_mod:get_module_opt(Server, ?MODULE, access, @@ -411,8 +304,8 @@ try_register(User, Server, Password, SourceRaw, Lang) -> case {acl:match_rule(Server, Access, JID), check_ip_access(SourceRaw, IPAccess)} of - {deny, _} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)}; - {_, deny} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)}; + {deny, _} -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)}; + {_, deny} -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)}; {allow, allow} -> Source = may_remove_resource(SourceRaw), case check_timeout(Source) of @@ -432,35 +325,35 @@ try_register(User, Server, Password, SourceRaw, Lang) -> case Error of {atomic, exists} -> Txt = <<"User already exists">>, - {error, ?ERRT_CONFLICT(Lang, Txt)}; + {error, xmpp:err_conflict(Txt, Lang)}; {error, invalid_jid} -> - {error, ?ERR_JID_MALFORMED}; + {error, xmpp:err_jid_malformed()}; {error, not_allowed} -> - {error, ?ERR_NOT_ALLOWED}; + {error, xmpp:err_not_allowed()}; {error, too_many_users} -> Txt = <<"Too many users registered">>, - {error, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)}; + {error, xmpp:err_resource_constraint(Txt, Lang)}; {error, _} -> ?ERROR_MSG("failed to register user " "~s@~s: ~p", [User, Server, Error]), - {error, ?ERR_INTERNAL_SERVER_ERROR} + {error, xmpp:err_internal_server_error()} end end; error_preparing_password -> remove_timeout(Source), ErrText = <<"The password contains unacceptable characters">>, - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; + {error, xmpp:err_not_acceptable(ErrText, Lang)}; false -> remove_timeout(Source), ErrText = <<"The password is too weak">>, - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)} + {error, xmpp:err_not_acceptable(ErrText, Lang)} end; false -> ErrText = <<"Users are not allowed to register accounts " "so quickly">>, - {error, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)} + {error, xmpp:err_resource_constraint(ErrText, Lang)} end end end. @@ -479,20 +372,10 @@ send_welcome_message(JID) -> of {<<"">>, <<"">>} -> ok; {Subj, Body} -> - ejabberd_router:route(jid:make(<<"">>, Host, - <<"">>), - JID, - #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"normal">>}], - children = - [#xmlel{name = <<"subject">>, - attrs = [], - children = - [{xmlcdata, Subj}]}, - #xmlel{name = <<"body">>, - attrs = [], - children = - [{xmlcdata, Body}]}]}); + ejabberd_router:route( + jid:make(Host), JID, + #message{subject = xmpp:mk_text(Subj), + body = xmpp:mk_text(Body)}); _ -> ok end. @@ -516,13 +399,9 @@ send_registration_notifications(Mod, UJID, Source) -> lists:foreach( fun(JID) -> ejabberd_router:route( - jid:make(<<"">>, Host, <<"">>), - JID, - #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"chat">>}], - children = [#xmlel{name = <<"body">>, - attrs = [], - children = [{xmlcdata,Body}]}]}) + jid:make(Host), JID, + #message{type = chat, + body = xmpp:mk_text(Body)}) end, JIDs) end. @@ -633,17 +512,11 @@ write_time({{Y, Mo, D}, {H, Mi, S}}) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). -process_xdata_submit(El) -> - case fxml:get_subtag(El, <<"x">>) of - false -> error; - Xdata -> - Fields = jlib:parse_xdata_submit(Xdata), - case catch {proplists:get_value(<<"username">>, Fields), - proplists:get_value(<<"password">>, Fields)} - of - {[User | _], [Pass | _]} -> {ok, User, Pass}; - _ -> error - end +process_xdata_submit(X) -> + case {xmpp_util:get_xdata_values(<<"username">>, X), + xmpp_util:get_xdata_values(<<"password">>, X)} of + {[User], [Pass]} -> {ok, User, Pass}; + _ -> error end. is_strong_password(Server, Password) -> -- cgit v1.2.3 From b31ebd2ea012ba2a81ec095189f46974e1905929 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 28 Jul 2016 15:10:41 +0300 Subject: Rewrite captcha to use XML generator --- src/ejabberd_captcha.erl | 261 ++++----------- src/mod_muc_room.erl | 5 +- src/mod_register.erl | 4 +- src/mod_register_web.erl | 4 +- src/xmpp_codec.erl | 845 ++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 765 insertions(+), 354 deletions(-) (limited to 'src') diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index 157700c47..df74a68b1 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -41,31 +41,17 @@ -export([create_captcha/6, build_captcha_html/2, check_captcha/2, process_reply/1, process/2, is_feature_available/0, create_captcha_x/5, - create_captcha_x/6, opt_type/1]). - --include("jlib.hrl"). + opt_type/1]). +-include("xmpp.hrl"). -include("ejabberd.hrl"). -include("logger.hrl"). - -include("ejabberd_http.hrl"). --define(VFIELD(Type, Var, Value), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, Type}, {<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [Value]}]}). - --define(CAPTCHA_TEXT(Lang), - translate:translate(Lang, - <<"Enter the text you see">>)). - -define(CAPTCHA_LIFETIME, 120000). - -define(LIMIT_PERIOD, 60*1000*1000). --type error() :: efbig | enodata | limit | malformed_image | timeout. +-type image_error() :: efbig | enodata | limit | malformed_image | timeout. -record(state, {limits = treap:empty() :: treap:treap()}). @@ -79,188 +65,82 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). +-spec captcha_text(undefined | binary()) -> binary(). +captcha_text(Lang) -> + translate:translate(Lang, <<"Enter the text you see">>). + +-spec mk_ocr_field(binary() | undefined, binary(), binary()) -> xdata_field(). +mk_ocr_field(Lang, CID, Type) -> + URI = #media_uri{type = Type, uri = <<"cid:", CID/binary>>}, + #xdata_field{var = <<"ocr">>, + label = captcha_text(Lang), + required = true, + sub_els = [#media{uri = [URI]}]}. + +mk_field(Type, Var, Value) -> + #xdata_field{type = Type, var = Var, values = [Value]}. + -spec create_captcha(binary(), jid(), jid(), - binary(), any(), any()) -> {error, error()} | - {ok, binary(), [xmlel()]}. + binary(), any(), any()) -> {error, image_error()} | + {ok, binary(), [text()], [xmlel()]}. create_captcha(SID, From, To, Lang, Limiter, Args) -> case create_image(Limiter) of {ok, Type, Key, Image} -> Id = <<(randoms:get_string())/binary>>, - B64Image = jlib:encode_base64((Image)), JID = jid:to_string(From), - CID = <<"sha1+", (p1_sha:sha(Image))/binary, - "@bob.xmpp.org">>, - Data = #xmlel{name = <<"data">>, - attrs = - [{<<"xmlns">>, ?NS_BOB}, {<<"cid">>, CID}, - {<<"max-age">>, <<"0">>}, {<<"type">>, Type}], - children = [{xmlcdata, B64Image}]}, - Captcha = #xmlel{name = <<"captcha">>, - attrs = [{<<"xmlns">>, ?NS_CAPTCHA}], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = - [?VFIELD(<<"hidden">>, - <<"FORM_TYPE">>, - {xmlcdata, ?NS_CAPTCHA}), - ?VFIELD(<<"hidden">>, <<"from">>, - {xmlcdata, - jid:to_string(To)}), - ?VFIELD(<<"hidden">>, - <<"challenge">>, - {xmlcdata, Id}), - ?VFIELD(<<"hidden">>, <<"sid">>, - {xmlcdata, SID}), - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"ocr">>}, - {<<"label">>, - ?CAPTCHA_TEXT(Lang)}], - children = - [#xmlel{name = - <<"required">>, - attrs = [], - children = []}, - #xmlel{name = - <<"media">>, - attrs = - [{<<"xmlns">>, - ?NS_MEDIA}], - children = - [#xmlel{name - = - <<"uri">>, - attrs - = - [{<<"type">>, - Type}], - children - = - [{xmlcdata, - <<"cid:", - CID/binary>>}]}]}]}]}]}, + CID = <<"sha1+", (p1_sha:sha(Image))/binary, "@bob.xmpp.org">>, + Data = #bob_data{cid = CID, 'max-age' = 0, type = Type, + data = Image}, + Fs = [mk_field(hidden, <<"FORM_TYPE">>, ?NS_CAPTCHA), + mk_field(hidden, <<"from">>, jid:to_string(To)), + mk_field(hidden, <<"challenge">>, Id), + mk_field(hidden, <<"sid">>, SID), + mk_ocr_field(Lang, CID, Type)], + X = #xdata{type = form, fields = Fs}, + Captcha = #xcaptcha{xdata = X}, BodyString1 = translate:translate(Lang, <<"Your messages to ~s are being blocked. " "To unblock them, visit ~s">>), BodyString = iolist_to_binary(io_lib:format(BodyString1, [JID, get_url(Id)])), - Body = #xmlel{name = <<"body">>, attrs = [], - children = [{xmlcdata, BodyString}]}, - OOB = #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_OOB}], - children = - [#xmlel{name = <<"url">>, attrs = [], - children = [{xmlcdata, get_url(Id)}]}]}, + Body = xmpp:mk_text(BodyString, Lang), + OOB = #oob_x{url = get_url(Id)}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}), ets:insert(captcha, #captcha{id = Id, pid = self(), key = Key, tref = Tref, args = Args}), - {ok, Id, [Body, OOB, Captcha, Data]}; + {ok, Id, Body, [OOB, Captcha, Data]}; Err -> Err end. --spec create_captcha_x(binary(), jid(), binary(), - any(), [xmlel()]) -> {ok, [xmlel()]} | - {error, error()}. - -create_captcha_x(SID, To, Lang, Limiter, HeadEls) -> - create_captcha_x(SID, To, Lang, Limiter, HeadEls, []). +-spec create_captcha_x(binary(), jid(), binary(), any(), xdata()) -> + {ok, xdata()} | {error, image_error()}. --spec create_captcha_x(binary(), jid(), binary(), - any(), [xmlel()], [xmlel()]) -> {ok, [xmlel()]} | - {error, error()}. - -create_captcha_x(SID, To, Lang, Limiter, HeadEls, - TailEls) -> +create_captcha_x(SID, To, Lang, Limiter, #xdata{fields = Fs} = X) -> case create_image(Limiter) of {ok, Type, Key, Image} -> Id = <<(randoms:get_string())/binary>>, - B64Image = jlib:encode_base64((Image)), - CID = <<"sha1+", (p1_sha:sha(Image))/binary, - "@bob.xmpp.org">>, - Data = #xmlel{name = <<"data">>, - attrs = - [{<<"xmlns">>, ?NS_BOB}, {<<"cid">>, CID}, - {<<"max-age">>, <<"0">>}, {<<"type">>, Type}], - children = [{xmlcdata, B64Image}]}, + CID = <<"sha1+", (p1_sha:sha(Image))/binary, "@bob.xmpp.org">>, + Data = #bob_data{cid = CID, 'max-age' = 0, type = Type, data = Image}, HelpTxt = translate:translate(Lang, <<"If you don't see the CAPTCHA image here, " "visit the web page.">>), Imageurl = get_url(<>), - Captcha = #xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = - [?VFIELD(<<"hidden">>, <<"FORM_TYPE">>, - {xmlcdata, ?NS_CAPTCHA}) - | HeadEls] - ++ - [#xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"fixed">>}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, - HelpTxt}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"hidden">>}, - {<<"var">>, <<"captchahidden">>}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, - <<"workaround-for-psi">>}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, <<"text-single">>}, - {<<"label">>, - translate:translate(Lang, - <<"CAPTCHA web page">>)}, - {<<"var">>, <<"url">>}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, - Imageurl}]}]}, - ?VFIELD(<<"hidden">>, <<"from">>, - {xmlcdata, jid:to_string(To)}), - ?VFIELD(<<"hidden">>, <<"challenge">>, - {xmlcdata, Id}), - ?VFIELD(<<"hidden">>, <<"sid">>, - {xmlcdata, SID}), - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"ocr">>}, - {<<"label">>, - ?CAPTCHA_TEXT(Lang)}], - children = - [#xmlel{name = <<"required">>, - attrs = [], children = []}, - #xmlel{name = <<"media">>, - attrs = - [{<<"xmlns">>, - ?NS_MEDIA}], - children = - [#xmlel{name = - <<"uri">>, - attrs = - [{<<"type">>, - Type}], - children = - [{xmlcdata, - <<"cid:", - CID/binary>>}]}]}]}] - ++ TailEls}, + NewFs = [mk_field(hidden, <<"FORM_TYPE">>, ?NS_CAPTCHA)|Fs] ++ + [#xdata_field{type = fixed, values = [HelpTxt]}, + #xdata_field{type = hidden, var = <<"captchahidden">>, + values = [<<"workaround-for-psi">>]}, + #xdata_field{type = 'text-single', var = <<"url">>, + label = translate:translate( + Lang, <<"CAPTCHA web page">>), + values = [Imageurl]}, + mk_field(hidden, <<"from">>, jid:to_string(To)), + mk_field(hidden, <<"challenge">>, Id), + mk_field(hidden, <<"sid">>, SID), + mk_ocr_field(Lang, CID, Type)], + Captcha = X#xdata{type = form, fields = NewFs}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}), ets:insert(captcha, @@ -281,7 +161,7 @@ build_captcha_html(Id, Lang) -> attrs = [{<<"src">>, get_url(<>)}], children = []}, - TextEl = {xmlcdata, ?CAPTCHA_TEXT(Lang)}, + TextEl = {xmlcdata, captcha_text(Lang)}, IdEl = #xmlel{name = <<"input">>, attrs = [{<<"type">>, <<"hidden">>}, {<<"name">>, <<"id">>}, @@ -317,27 +197,24 @@ build_captcha_html(Id, Lang) -> _ -> captcha_not_found end. --spec process_reply(xmlel()) -> ok | {error, bad_match | not_found | malformed}. - -process_reply(#xmlel{} = El) -> - case fxml:get_subtag(El, <<"x">>) of - false -> {error, malformed}; - Xdata -> - Fields = jlib:parse_xdata_submit(Xdata), - case catch {proplists:get_value(<<"challenge">>, - Fields), - proplists:get_value(<<"ocr">>, Fields)} - of - {[Id | _], [OCR | _]} -> - case check_captcha(Id, OCR) of - captcha_valid -> ok; - captcha_non_valid -> {error, bad_match}; - captcha_not_found -> {error, not_found} - end; - _ -> {error, malformed} - end +-spec process_reply(xmpp_element()) -> ok | {error, bad_match | not_found | malformed}. + +process_reply(#xdata{} = X) -> + case {xmpp_util:get_xdata_values(<<"challenge">>, X), + xmpp_util:get_xdata_values(<<"ocr">>, X)} of + {[Id], [OCR]} -> + case check_captcha(Id, OCR) of + captcha_valid -> ok; + captcha_non_valid -> {error, bad_match}; + captcha_not_found -> {error, not_found} + end; + _ -> + {error, malformed} end; -process_reply(_) -> {error, malformed}. +process_reply(#xcaptcha{xdata = #xdata{} = X}) -> + process_reply(X); +process_reply(_) -> + {error, malformed}. process(_Handlers, #request{method = 'GET', lang = Lang, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 29b7942cf..a539ab848 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -1824,8 +1824,9 @@ add_new_user(From, Nick, Packet, StateData) -> case ejabberd_captcha:create_captcha(SID, RoomJID, To, Lang, Limiter, From) of - {ok, ID, CaptchaEls} -> - MsgPkt = #message{id = ID, sub_els = CaptchaEls}, + {ok, ID, Body, CaptchaEls} -> + MsgPkt = #message{id = ID, body = Body, + sub_els = CaptchaEls}, Robots = (?DICT):store(From, {Nick, Packet}, StateData#state.robots), ejabberd_router:route(RoomJID, From, MsgPkt), diff --git a/src/mod_register.erl b/src/mod_register.erl index 3f9c33123..1ed266d47 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -218,10 +218,10 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ, X = #xdata{type = form, instructions = [Instr], fields = [UField, PField]}, case ejabberd_captcha:create_captcha_x(ID, To, Lang, Source, X) of - {ok, Captcha} -> + {ok, CaptchaEls} -> xmpp:make_iq_result( IQ, #register{instructions = TopInstr, - xdata = Captcha}); + sub_els = CaptchaEls}); {error, limit} -> ErrText = <<"Too many CAPTCHA requests">>, xmpp:make_error( diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index 76de1677f..20b370fb9 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -60,7 +60,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). @@ -334,7 +334,7 @@ build_captcha_li_list2(Lang, IP) -> case ejabberd_captcha:create_captcha(SID, From, To, Lang, IP, Args) of - {ok, Id, _} -> + {ok, Id, _, _} -> {_, {CImg, CText, CId, CKey}} = ejabberd_captcha:build_captcha_html(Id, Lang), [?XE(<<"li">>, diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 7eb06b11e..113be860b 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,22 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"x">>, <<"jabber:x:oob">>} -> + decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"desc">>, <<"jabber:x:oob">>} -> + decode_oob_desc(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"url">>, <<"jabber:x:oob">>} -> + decode_oob_url(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"media">>, <<"urn:xmpp:media-element">>} -> + decode_media(<<"urn:xmpp:media-element">>, IgnoreEls, + _el); + {<<"uri">>, <<"urn:xmpp:media-element">>} -> + decode_media_uri(<<"urn:xmpp:media-element">>, + IgnoreEls, _el); + {<<"captcha">>, <<"urn:xmpp:captcha">>} -> + decode_captcha(<<"urn:xmpp:captcha">>, IgnoreEls, _el); + {<<"data">>, <<"urn:xmpp:bob">>} -> + decode_bob_data(<<"urn:xmpp:bob">>, IgnoreEls, _el); {<<"stream:stream">>, <<"jabber:client">>} -> decode_stream_start(<<"jabber:client">>, IgnoreEls, _el); @@ -1293,6 +1309,13 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"x">>, <<"jabber:x:oob">>} -> true; + {<<"desc">>, <<"jabber:x:oob">>} -> true; + {<<"url">>, <<"jabber:x:oob">>} -> true; + {<<"media">>, <<"urn:xmpp:media-element">>} -> true; + {<<"uri">>, <<"urn:xmpp:media-element">>} -> true; + {<<"captcha">>, <<"urn:xmpp:captcha">>} -> true; + {<<"data">>, <<"urn:xmpp:bob">>} -> true; {<<"stream:stream">>, <<"jabber:client">>} -> true; {<<"stream:stream">>, <<"jabber:server">>} -> true; {<<"stream:stream">>, <<"jabber:component:accept">>} -> @@ -2216,7 +2239,7 @@ encode({feature_register} = Register) -> [{<<"xmlns">>, <<"http://jabber.org/features/iq-register">>}]); encode({register, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _} = + _, _, _, _, _, _, _, _, _} = Query) -> encode_register(Query, [{<<"xmlns">>, <<"jabber:iq:register">>}]); @@ -2285,7 +2308,7 @@ encode({vcard_xupdate, undefined, _} = X) -> encode({xdata_option, _, _} = Option) -> encode_xdata_field_option(Option, [{<<"xmlns">>, <<"jabber:x:data">>}]); -encode({xdata_field, _, _, _, _, _, _, _} = Field) -> +encode({xdata_field, _, _, _, _, _, _, _, _} = Field) -> encode_xdata_field(Field, [{<<"xmlns">>, <<"jabber:x:data">>}]); encode({xdata, _, _, _, _, _, _} = X) -> @@ -2572,7 +2595,21 @@ encode({handshake, _} = Handshake) -> [{<<"xmlns">>, <<"jabber:client">>}]); encode({stream_start, _, _, _, _, _, _, _, _} = Stream_stream) -> - encode_stream_start(Stream_stream, []). + encode_stream_start(Stream_stream, []); +encode({bob_data, _, _, _, _} = Data) -> + encode_bob_data(Data, + [{<<"xmlns">>, <<"urn:xmpp:bob">>}]); +encode({xcaptcha, _} = Captcha) -> + encode_captcha(Captcha, + [{<<"xmlns">>, <<"urn:xmpp:captcha">>}]); +encode({media_uri, _, _} = Uri) -> + encode_media_uri(Uri, + [{<<"xmlns">>, <<"urn:xmpp:media-element">>}]); +encode({media, _, _, _} = Media) -> + encode_media(Media, + [{<<"xmlns">>, <<"urn:xmpp:media-element">>}]); +encode({oob_x, _, _, _} = X) -> + encode_oob_x(X, [{<<"xmlns">>, <<"jabber:x:oob">>}]). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2628,7 +2665,7 @@ get_name({p1_ack}) -> <<"ack">>; get_name({caps, _, _, _, _}) -> <<"c">>; get_name({feature_register}) -> <<"register">>; get_name({register, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _}) -> + _, _, _, _, _, _, _, _, _, _}) -> <<"query">>; get_name({xmpp_session, _}) -> <<"session">>; get_name({ping}) -> <<"ping">>; @@ -2659,7 +2696,7 @@ get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, <<"vCard">>; get_name({vcard_xupdate, undefined, _}) -> <<"x">>; get_name({xdata_option, _, _}) -> <<"option">>; -get_name({xdata_field, _, _, _, _, _, _, _}) -> +get_name({xdata_field, _, _, _, _, _, _, _, _}) -> <<"field">>; get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; get_name({pubsub_subscription, _, _, _, _}) -> @@ -2760,7 +2797,12 @@ get_name({db_verify, _, _, _, _, _, _}) -> <<"db:verify">>; get_name({handshake, _}) -> <<"handshake">>; get_name({stream_start, _, _, _, _, _, _, _, _}) -> - <<"stream:stream">>. + <<"stream:stream">>; +get_name({bob_data, _, _, _, _}) -> <<"data">>; +get_name({xcaptcha, _}) -> <<"captcha">>; +get_name({media_uri, _, _}) -> <<"uri">>; +get_name({media, _, _, _}) -> <<"media">>; +get_name({oob_x, _, _, _}) -> <<"x">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -2848,7 +2890,7 @@ get_ns({caps, _, _, _, _}) -> get_ns({feature_register}) -> <<"http://jabber.org/features/iq-register">>; get_ns({register, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _}) -> + _, _, _, _, _, _, _, _, _}) -> <<"jabber:iq:register">>; get_ns({xmpp_session, _}) -> <<"urn:ietf:params:xml:ns:xmpp-session">>; @@ -2881,7 +2923,7 @@ get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, get_ns({vcard_xupdate, undefined, _}) -> <<"vcard-temp:x:update">>; get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>; -get_ns({xdata_field, _, _, _, _, _, _, _}) -> +get_ns({xdata_field, _, _, _, _, _, _, _, _}) -> <<"jabber:x:data">>; get_ns({xdata, _, _, _, _, _, _}) -> <<"jabber:x:data">>; @@ -3021,7 +3063,14 @@ get_ns({db_verify, _, _, _, _, _, _}) -> <<"jabber:client">>; get_ns({handshake, _}) -> <<"jabber:client">>; get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> - Xmlns. + Xmlns; +get_ns({bob_data, _, _, _, _}) -> <<"urn:xmpp:bob">>; +get_ns({xcaptcha, _}) -> <<"urn:xmpp:captcha">>; +get_ns({media_uri, _, _}) -> + <<"urn:xmpp:media-element">>; +get_ns({media, _, _, _}) -> + <<"urn:xmpp:media-element">>; +get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3129,10 +3178,11 @@ pp(p1_rebind, 0) -> []; pp(p1_ack, 0) -> []; pp(caps, 4) -> [node, version, hash, exts]; pp(feature_register, 0) -> []; -pp(register, 21) -> +pp(register, 22) -> [registered, remove, instructions, username, nick, password, name, first, last, email, address, city, - state, zip, phone, url, date, misc, text, key, xdata]; + state, zip, phone, url, date, misc, text, key, xdata, + sub_els]; pp(xmpp_session, 1) -> [optional]; pp(ping, 0) -> []; pp(time, 2) -> [tzo, utc]; @@ -3164,8 +3214,9 @@ pp(vcard_temp, 29) -> uid, url, class, key, desc]; pp(vcard_xupdate, 2) -> [us, hash]; pp(xdata_option, 2) -> [label, value]; -pp(xdata_field, 7) -> - [label, type, var, required, desc, values, options]; +pp(xdata_field, 8) -> + [label, type, var, required, desc, values, options, + sub_els]; pp(xdata, 6) -> [type, instructions, title, reported, items, fields]; pp(pubsub_subscription, 4) -> [jid, node, subid, type]; @@ -3263,6 +3314,11 @@ pp(handshake, 1) -> [data]; pp(stream_start, 8) -> [from, to, id, version, xmlns, stream_xmlns, db_xmlns, lang]; +pp(bob_data, 4) -> [cid, 'max-age', type, data]; +pp(xcaptcha, 1) -> [xdata]; +pp(media_uri, 2) -> [type, uri]; +pp(media, 3) -> [height, width, uri]; +pp(oob_x, 3) -> [url, desc, sid]; pp(_, _) -> no. join([], _Sep) -> <<>>; @@ -3309,6 +3365,423 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_oob_x(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + {Desc, Url} = decode_oob_x_els(__TopXMLNS, __IgnoreEls, + _els, <<>>, error), + Sid = decode_oob_x_attrs(__TopXMLNS, _attrs, undefined), + {oob_x, Url, Desc, Sid}. + +decode_oob_x_els(__TopXMLNS, __IgnoreEls, [], Desc, + Url) -> + {Desc, + case Url of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"url">>, __TopXMLNS}}); + {value, Url1} -> Url1 + end}; +decode_oob_x_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"url">>, _attrs, _} = _el | _els], Desc, + Url) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:oob">> -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, + {value, + decode_oob_url(__TopXMLNS, __IgnoreEls, _el)}); + <<"jabber:x:oob">> -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, + {value, + decode_oob_url(<<"jabber:x:oob">>, __IgnoreEls, + _el)}); + _ -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, + Url) + end; +decode_oob_x_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"desc">>, _attrs, _} = _el | _els], Desc, + Url) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"jabber:x:oob">> -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, + decode_oob_desc(__TopXMLNS, __IgnoreEls, _el), Url); + <<"jabber:x:oob">> -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, + decode_oob_desc(<<"jabber:x:oob">>, __IgnoreEls, + _el), + Url); + _ -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, + Url) + end; +decode_oob_x_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Desc, Url) -> + decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, + Url). + +decode_oob_x_attrs(__TopXMLNS, + [{<<"sid">>, _val} | _attrs], _Sid) -> + decode_oob_x_attrs(__TopXMLNS, _attrs, _val); +decode_oob_x_attrs(__TopXMLNS, [_ | _attrs], Sid) -> + decode_oob_x_attrs(__TopXMLNS, _attrs, Sid); +decode_oob_x_attrs(__TopXMLNS, [], Sid) -> + decode_oob_x_attr_sid(__TopXMLNS, Sid). + +encode_oob_x({oob_x, Url, Desc, Sid}, _xmlns_attrs) -> + _els = lists:reverse('encode_oob_x_$desc'(Desc, + 'encode_oob_x_$url'(Url, []))), + _attrs = encode_oob_x_attr_sid(Sid, _xmlns_attrs), + {xmlel, <<"x">>, _attrs, _els}. + +'encode_oob_x_$desc'(<<>>, _acc) -> _acc; +'encode_oob_x_$desc'(Desc, _acc) -> + [encode_oob_desc(Desc, []) | _acc]. + +'encode_oob_x_$url'(Url, _acc) -> + [encode_oob_url(Url, []) | _acc]. + +decode_oob_x_attr_sid(__TopXMLNS, undefined) -> <<>>; +decode_oob_x_attr_sid(__TopXMLNS, _val) -> _val. + +encode_oob_x_attr_sid(<<>>, _acc) -> _acc; +encode_oob_x_attr_sid(_val, _acc) -> + [{<<"sid">>, _val} | _acc]. + +decode_oob_desc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"desc">>, _attrs, _els}) -> + Cdata = decode_oob_desc_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_oob_desc_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_oob_desc_cdata(__TopXMLNS, Cdata); +decode_oob_desc_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_oob_desc_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_oob_desc_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_oob_desc_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_oob_desc(Cdata, _xmlns_attrs) -> + _els = encode_oob_desc_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"desc">>, _attrs, _els}. + +decode_oob_desc_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_oob_desc_cdata(__TopXMLNS, _val) -> _val. + +encode_oob_desc_cdata(<<>>, _acc) -> _acc; +encode_oob_desc_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_oob_url(__TopXMLNS, __IgnoreEls, + {xmlel, <<"url">>, _attrs, _els}) -> + Cdata = decode_oob_url_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_oob_url_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_oob_url_cdata(__TopXMLNS, Cdata); +decode_oob_url_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_oob_url_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_oob_url_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_oob_url_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_oob_url(Cdata, _xmlns_attrs) -> + _els = encode_oob_url_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"url">>, _attrs, _els}. + +decode_oob_url_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"url">>, __TopXMLNS}}); +decode_oob_url_cdata(__TopXMLNS, _val) -> _val. + +encode_oob_url_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_media(__TopXMLNS, __IgnoreEls, + {xmlel, <<"media">>, _attrs, _els}) -> + Uri = decode_media_els(__TopXMLNS, __IgnoreEls, _els, + []), + {Height, Width} = decode_media_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {media, Height, Width, Uri}. + +decode_media_els(__TopXMLNS, __IgnoreEls, [], Uri) -> + lists:reverse(Uri); +decode_media_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"uri">>, _attrs, _} = _el | _els], Uri) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == <<"urn:xmpp:media-element">> -> + decode_media_els(__TopXMLNS, __IgnoreEls, _els, + [decode_media_uri(__TopXMLNS, __IgnoreEls, _el) + | Uri]); + <<"urn:xmpp:media-element">> -> + decode_media_els(__TopXMLNS, __IgnoreEls, _els, + [decode_media_uri(<<"urn:xmpp:media-element">>, + __IgnoreEls, _el) + | Uri]); + _ -> + decode_media_els(__TopXMLNS, __IgnoreEls, _els, Uri) + end; +decode_media_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Uri) -> + decode_media_els(__TopXMLNS, __IgnoreEls, _els, Uri). + +decode_media_attrs(__TopXMLNS, + [{<<"height">>, _val} | _attrs], _Height, Width) -> + decode_media_attrs(__TopXMLNS, _attrs, _val, Width); +decode_media_attrs(__TopXMLNS, + [{<<"width">>, _val} | _attrs], Height, _Width) -> + decode_media_attrs(__TopXMLNS, _attrs, Height, _val); +decode_media_attrs(__TopXMLNS, [_ | _attrs], Height, + Width) -> + decode_media_attrs(__TopXMLNS, _attrs, Height, Width); +decode_media_attrs(__TopXMLNS, [], Height, Width) -> + {decode_media_attr_height(__TopXMLNS, Height), + decode_media_attr_width(__TopXMLNS, Width)}. + +encode_media({media, Height, Width, Uri}, + _xmlns_attrs) -> + _els = lists:reverse('encode_media_$uri'(Uri, [])), + _attrs = encode_media_attr_width(Width, + encode_media_attr_height(Height, + _xmlns_attrs)), + {xmlel, <<"media">>, _attrs, _els}. + +'encode_media_$uri'([], _acc) -> _acc; +'encode_media_$uri'([Uri | _els], _acc) -> + 'encode_media_$uri'(_els, + [encode_media_uri(Uri, []) | _acc]). + +decode_media_attr_height(__TopXMLNS, undefined) -> + undefined; +decode_media_attr_height(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"height">>, <<"media">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_media_attr_height(undefined, _acc) -> _acc; +encode_media_attr_height(_val, _acc) -> + [{<<"height">>, enc_int(_val)} | _acc]. + +decode_media_attr_width(__TopXMLNS, undefined) -> + undefined; +decode_media_attr_width(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, inifinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"width">>, <<"media">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_media_attr_width(undefined, _acc) -> _acc; +encode_media_attr_width(_val, _acc) -> + [{<<"width">>, enc_int(_val)} | _acc]. + +decode_media_uri(__TopXMLNS, __IgnoreEls, + {xmlel, <<"uri">>, _attrs, _els}) -> + Uri = decode_media_uri_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Type = decode_media_uri_attrs(__TopXMLNS, _attrs, + undefined), + {media_uri, Type, Uri}. + +decode_media_uri_els(__TopXMLNS, __IgnoreEls, [], + Uri) -> + decode_media_uri_cdata(__TopXMLNS, Uri); +decode_media_uri_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Uri) -> + decode_media_uri_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_media_uri_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Uri) -> + decode_media_uri_els(__TopXMLNS, __IgnoreEls, _els, + Uri). + +decode_media_uri_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], _Type) -> + decode_media_uri_attrs(__TopXMLNS, _attrs, _val); +decode_media_uri_attrs(__TopXMLNS, [_ | _attrs], + Type) -> + decode_media_uri_attrs(__TopXMLNS, _attrs, Type); +decode_media_uri_attrs(__TopXMLNS, [], Type) -> + decode_media_uri_attr_type(__TopXMLNS, Type). + +encode_media_uri({media_uri, Type, Uri}, + _xmlns_attrs) -> + _els = encode_media_uri_cdata(Uri, []), + _attrs = encode_media_uri_attr_type(Type, _xmlns_attrs), + {xmlel, <<"uri">>, _attrs, _els}. + +decode_media_uri_attr_type(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"type">>, <<"uri">>, __TopXMLNS}}); +decode_media_uri_attr_type(__TopXMLNS, _val) -> _val. + +encode_media_uri_attr_type(_val, _acc) -> + [{<<"type">>, _val} | _acc]. + +decode_media_uri_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_media_uri_cdata(__TopXMLNS, _val) -> _val. + +encode_media_uri_cdata(<<>>, _acc) -> _acc; +encode_media_uri_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_captcha(__TopXMLNS, __IgnoreEls, + {xmlel, <<"captcha">>, _attrs, _els}) -> + Xdata = decode_captcha_els(__TopXMLNS, __IgnoreEls, + _els, error), + {xcaptcha, Xdata}. + +decode_captcha_els(__TopXMLNS, __IgnoreEls, [], + Xdata) -> + case Xdata of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"x">>, __TopXMLNS}}); + {value, Xdata1} -> Xdata1 + end; +decode_captcha_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, + {value, + decode_xdata(<<"jabber:x:data">>, __IgnoreEls, + _el)}); + _ -> + decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, Xdata) + end; +decode_captcha_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Xdata) -> + decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, + Xdata). + +encode_captcha({xcaptcha, Xdata}, _xmlns_attrs) -> + _els = lists:reverse('encode_captcha_$xdata'(Xdata, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"captcha">>, _attrs, _els}. + +'encode_captcha_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +decode_bob_data(__TopXMLNS, __IgnoreEls, + {xmlel, <<"data">>, _attrs, _els}) -> + Data = decode_bob_data_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + {Cid, Max_age, Type} = decode_bob_data_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {bob_data, Cid, Max_age, Type, Data}. + +decode_bob_data_els(__TopXMLNS, __IgnoreEls, [], + Data) -> + decode_bob_data_cdata(__TopXMLNS, Data); +decode_bob_data_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Data) -> + decode_bob_data_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_bob_data_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Data) -> + decode_bob_data_els(__TopXMLNS, __IgnoreEls, _els, + Data). + +decode_bob_data_attrs(__TopXMLNS, + [{<<"cid">>, _val} | _attrs], _Cid, Max_age, Type) -> + decode_bob_data_attrs(__TopXMLNS, _attrs, _val, Max_age, + Type); +decode_bob_data_attrs(__TopXMLNS, + [{<<"max-age">>, _val} | _attrs], Cid, _Max_age, + Type) -> + decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, _val, + Type); +decode_bob_data_attrs(__TopXMLNS, + [{<<"type">>, _val} | _attrs], Cid, Max_age, _Type) -> + decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, Max_age, + _val); +decode_bob_data_attrs(__TopXMLNS, [_ | _attrs], Cid, + Max_age, Type) -> + decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, Max_age, + Type); +decode_bob_data_attrs(__TopXMLNS, [], Cid, Max_age, + Type) -> + {decode_bob_data_attr_cid(__TopXMLNS, Cid), + 'decode_bob_data_attr_max-age'(__TopXMLNS, Max_age), + decode_bob_data_attr_type(__TopXMLNS, Type)}. + +encode_bob_data({bob_data, Cid, Max_age, Type, Data}, + _xmlns_attrs) -> + _els = encode_bob_data_cdata(Data, []), + _attrs = encode_bob_data_attr_type(Type, + 'encode_bob_data_attr_max-age'(Max_age, + encode_bob_data_attr_cid(Cid, + _xmlns_attrs))), + {xmlel, <<"data">>, _attrs, _els}. + +decode_bob_data_attr_cid(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"cid">>, <<"data">>, __TopXMLNS}}); +decode_bob_data_attr_cid(__TopXMLNS, _val) -> _val. + +encode_bob_data_attr_cid(_val, _acc) -> + [{<<"cid">>, _val} | _acc]. + +'decode_bob_data_attr_max-age'(__TopXMLNS, undefined) -> + undefined; +'decode_bob_data_attr_max-age'(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"max-age">>, <<"data">>, + __TopXMLNS}}); + _res -> _res + end. + +'encode_bob_data_attr_max-age'(undefined, _acc) -> _acc; +'encode_bob_data_attr_max-age'(_val, _acc) -> + [{<<"max-age">>, enc_int(_val)} | _acc]. + +decode_bob_data_attr_type(__TopXMLNS, undefined) -> + undefined; +decode_bob_data_attr_type(__TopXMLNS, _val) -> _val. + +encode_bob_data_attr_type(undefined, _acc) -> _acc; +encode_bob_data_attr_type(_val, _acc) -> + [{<<"type">>, _val} | _acc]. + +decode_bob_data_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_bob_data_cdata(__TopXMLNS, _val) -> + case catch base64:decode(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"data">>, __TopXMLNS}}); + _res -> _res + end. + +encode_bob_data_cdata(<<>>, _acc) -> _acc; +encode_bob_data_cdata(_val, _acc) -> + [{xmlcdata, base64:encode(_val)} | _acc]. + decode_stream_start(__TopXMLNS, __IgnoreEls, {xmlel, <<"stream:stream">>, _attrs, _els}) -> {From, To, Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, @@ -12727,60 +13200,62 @@ encode_xdata_instructions_cdata(_val, _acc) -> decode_xdata_field(__TopXMLNS, __IgnoreEls, {xmlel, <<"field">>, _attrs, _els}) -> - {Options, Values, Desc, Required} = + {Options, Values, Desc, Required, __Els} = decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - [], [], undefined, false), + [], [], undefined, false, []), {Label, Type, Var} = decode_xdata_field_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), {xdata_field, Label, Type, Var, Required, Desc, Values, - Options}. + Options, __Els}. decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [], - Options, Values, Desc, Required) -> + Options, Values, Desc, Required, __Els) -> {lists:reverse(Options), lists:reverse(Values), Desc, - Required}; + Required, lists:reverse(__Els)}; decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"required">>, _attrs, _} = _el | _els], - Options, Values, Desc, Required) -> + Options, Values, Desc, Required, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, Desc, decode_xdata_field_required(__TopXMLNS, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, Desc, decode_xdata_field_required(<<"jabber:x:data">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required) + Options, Values, Desc, Required, __Els) end; decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"desc">>, _attrs, _} = _el | _els], Options, - Values, Desc, Required) -> + Values, Desc, Required, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, decode_xdata_field_desc(__TopXMLNS, __IgnoreEls, _el), - Required); + Required, __Els); <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, decode_xdata_field_desc(<<"jabber:x:data">>, __IgnoreEls, _el), - Required); + Required, __Els); _ -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required) + Options, Values, Desc, Required, __Els) end; decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"value">>, _attrs, _} = _el | _els], Options, - Values, Desc, Required) -> + Values, Desc, Required, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, @@ -12791,7 +13266,7 @@ decode_xdata_field_els(__TopXMLNS, __IgnoreEls, undefined -> Values; _new_el -> [_new_el | Values] end, - Desc, Required); + Desc, Required, __Els); <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, @@ -12802,35 +13277,53 @@ decode_xdata_field_els(__TopXMLNS, __IgnoreEls, undefined -> Values; _new_el -> [_new_el | Values] end, - Desc, Required); + Desc, Required, __Els); _ -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required) + Options, Values, Desc, Required, __Els) end; decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"option">>, _attrs, _} = _el | _els], - Options, Values, Desc, Required) -> + Options, Values, Desc, Required, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, [decode_xdata_field_option(__TopXMLNS, __IgnoreEls, _el) | Options], - Values, Desc, Required); + Values, Desc, Required, __Els); <<"jabber:x:data">> -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, [decode_xdata_field_option(<<"jabber:x:data">>, __IgnoreEls, _el) | Options], - Values, Desc, Required); + Values, Desc, Required, __Els); _ -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required) + Options, Values, Desc, Required, __Els) end; decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Options, Values, Desc, Required) -> + [{xmlel, _, _, _} = _el | _els], Options, Values, Desc, + Required, __Els) -> + if __IgnoreEls -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required, + [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required, + [decode(_el) | __Els]); + false -> + decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, + Options, Values, Desc, Required, __Els) + end + end; +decode_xdata_field_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Options, Values, Desc, Required, __Els) -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required). + Options, Values, Desc, Required, __Els). decode_xdata_field_attrs(__TopXMLNS, [{<<"label">>, _val} | _attrs], _Label, Type, Var) -> @@ -12855,14 +13348,14 @@ decode_xdata_field_attrs(__TopXMLNS, [], Label, Type, decode_xdata_field_attr_var(__TopXMLNS, Var)}. encode_xdata_field({xdata_field, Label, Type, Var, - Required, Desc, Values, Options}, + Required, Desc, Values, Options, __Els}, _xmlns_attrs) -> - _els = - lists:reverse('encode_xdata_field_$options'(Options, - 'encode_xdata_field_$values'(Values, - 'encode_xdata_field_$desc'(Desc, - 'encode_xdata_field_$required'(Required, - []))))), + _els = [encode(_el) || _el <- __Els] ++ + lists:reverse('encode_xdata_field_$options'(Options, + 'encode_xdata_field_$values'(Values, + 'encode_xdata_field_$desc'(Desc, + 'encode_xdata_field_$required'(Required, + []))))), _attrs = encode_xdata_field_attr_var(Var, encode_xdata_field_attr_type(Type, encode_xdata_field_attr_label(Label, @@ -18909,29 +19402,31 @@ decode_register(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> {Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email} = + Username, Remove, Key, City, Nick, Url, Email, __Els} = decode_register_els(__TopXMLNS, __IgnoreEls, _els, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, false, undefined, undefined, undefined, undefined, undefined, false, undefined, undefined, - undefined, undefined, undefined), + undefined, undefined, undefined, []), {register, Registered, Remove, Instructions, Username, Nick, Password, Name, First, Last, Email, Address, City, - State, Zip, Phone, Url, Date, Misc, Text, Key, Xdata}. + State, Zip, Phone, Url, Date, Misc, Text, Key, Xdata, + __Els}. decode_register_els(__TopXMLNS, __IgnoreEls, [], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> {Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email}; + Username, Remove, Key, City, Nick, Url, Email, + lists:reverse(__Els)}; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"x">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"jabber:x:data">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -18939,19 +19434,20 @@ decode_register_els(__TopXMLNS, __IgnoreEls, _el), Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"registered">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -18960,7 +19456,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_registered(__TopXMLNS, __IgnoreEls, _el), Date, Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email); + City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -18968,19 +19464,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_registered(<<"jabber:iq:register">>, __IgnoreEls, _el), Date, Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email); + City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"remove">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -18989,7 +19485,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, decode_register_remove(__TopXMLNS, __IgnoreEls, _el), - Key, City, Nick, Url, Email); + Key, City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -18997,19 +19493,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, decode_register_remove(<<"jabber:iq:register">>, __IgnoreEls, _el), - Key, City, Nick, Url, Email); + Key, City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19018,7 +19514,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email); + Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, @@ -19026,19 +19522,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email); + Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"username">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19047,7 +19543,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, decode_register_username(__TopXMLNS, __IgnoreEls, _el), - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19055,19 +19551,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, decode_register_username(<<"jabber:iq:register">>, __IgnoreEls, _el), - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19076,7 +19572,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, City, decode_register_nick(__TopXMLNS, __IgnoreEls, _el), - Url, Email); + Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19084,19 +19580,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, City, decode_register_nick(<<"jabber:iq:register">>, __IgnoreEls, _el), - Url, Email); + Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"password">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19105,7 +19601,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_password(__TopXMLNS, __IgnoreEls, _el), Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19113,19 +19609,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_password(<<"jabber:iq:register">>, __IgnoreEls, _el), Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"name">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19133,26 +19629,28 @@ decode_register_els(__TopXMLNS, __IgnoreEls, First, Password, Registered, Date, Phone, State, decode_register_name(__TopXMLNS, __IgnoreEls, _el), - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, decode_register_name(<<"jabber:iq:register">>, __IgnoreEls, _el), - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"first">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19160,26 +19658,28 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_first(__TopXMLNS, __IgnoreEls, _el), Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, decode_register_first(<<"jabber:iq:register">>, __IgnoreEls, _el), Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"last">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19188,7 +19688,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, _el), First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, @@ -19196,19 +19696,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"email">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19216,26 +19716,28 @@ decode_register_els(__TopXMLNS, __IgnoreEls, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, decode_register_email(__TopXMLNS, __IgnoreEls, - _el)); + _el), + __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, decode_register_email(<<"jabber:iq:register">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"address">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19244,7 +19746,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, _el), Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, @@ -19252,19 +19754,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email); + Remove, Key, City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"city">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19273,7 +19775,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, decode_register_city(__TopXMLNS, __IgnoreEls, _el), - Nick, Url, Email); + Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19281,19 +19783,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, decode_register_city(<<"jabber:iq:register">>, __IgnoreEls, _el), - Nick, Url, Email); + Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"state">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19302,7 +19804,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_state(__TopXMLNS, __IgnoreEls, _el), Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19310,19 +19812,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_state(<<"jabber:iq:register">>, __IgnoreEls, _el), Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"zip">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, @@ -19330,7 +19832,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, decode_register_zip(<<"jabber:iq:register">>, @@ -19338,19 +19840,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email); + Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"phone">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19359,7 +19861,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_phone(__TopXMLNS, __IgnoreEls, _el), State, Name, Username, Remove, Key, City, Nick, - Url, Email); + Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19367,19 +19869,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_phone(<<"jabber:iq:register">>, __IgnoreEls, _el), State, Name, Username, Remove, Key, City, Nick, - Url, Email); + Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"url">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19387,7 +19889,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, decode_register_url(__TopXMLNS, __IgnoreEls, _el), - Email); + Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19395,19 +19897,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, City, Nick, decode_register_url(<<"jabber:iq:register">>, __IgnoreEls, _el), - Email); + Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"date">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19416,7 +19918,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_date(__TopXMLNS, __IgnoreEls, _el), Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email); + Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19424,19 +19926,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, decode_register_date(<<"jabber:iq:register">>, __IgnoreEls, _el), Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email); + Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"misc">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19445,7 +19947,8 @@ decode_register_els(__TopXMLNS, __IgnoreEls, _el), Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, @@ -19453,19 +19956,20 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email); + Username, Remove, Key, City, Nick, Url, Email, + __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"text">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19474,7 +19978,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, _el), Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, - Url, Email); + Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, @@ -19482,19 +19986,19 @@ decode_register_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el), Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, - Url, Email); + Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) end; decode_register_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"key">>, _attrs, _} = _el | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, @@ -19502,7 +20006,7 @@ decode_register_els(__TopXMLNS, __IgnoreEls, First, Password, Registered, Date, Phone, State, Name, Username, Remove, decode_register_key(__TopXMLNS, __IgnoreEls, _el), - City, Nick, Url, Email); + City, Nick, Url, Email, __Els); <<"jabber:iq:register">> -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, @@ -19510,50 +20014,79 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, decode_register_key(<<"jabber:iq:register">>, __IgnoreEls, _el), - City, Nick, Url, Email); + City, Nick, Url, Email, __Els); _ -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, - Email) + Email, __Els) + end; +decode_register_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], Zip, Xdata, Misc, + Address, Instructions, Text, Last, First, Password, + Registered, Date, Phone, State, Name, Username, Remove, + Key, City, Nick, Url, Email, __Els) -> + if __IgnoreEls -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, Last, + First, Password, Registered, Date, Phone, State, + Name, Username, Remove, Key, City, Nick, Url, + Email, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, + Last, First, Password, Registered, Date, + Phone, State, Name, Username, Remove, Key, + City, Nick, Url, Email, + [decode(_el) | __Els]); + false -> + decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, + Xdata, Misc, Address, Instructions, Text, + Last, First, Password, Registered, Date, + Phone, State, Name, Username, Remove, Key, + City, Nick, Url, Email, __Els) + end end; decode_register_els(__TopXMLNS, __IgnoreEls, [_ | _els], Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email) -> + Username, Remove, Key, City, Nick, Url, Email, __Els) -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email). + Username, Remove, Key, City, Nick, Url, Email, __Els). encode_register({register, Registered, Remove, Instructions, Username, Nick, Password, Name, First, Last, Email, Address, City, State, Zip, Phone, Url, - Date, Misc, Text, Key, Xdata}, + Date, Misc, Text, Key, Xdata, __Els}, _xmlns_attrs) -> - _els = lists:reverse('encode_register_$zip'(Zip, - 'encode_register_$xdata'(Xdata, - 'encode_register_$misc'(Misc, - 'encode_register_$address'(Address, - 'encode_register_$instructions'(Instructions, - 'encode_register_$text'(Text, - 'encode_register_$last'(Last, - 'encode_register_$first'(First, - 'encode_register_$password'(Password, - 'encode_register_$registered'(Registered, - 'encode_register_$date'(Date, - 'encode_register_$phone'(Phone, - 'encode_register_$state'(State, - 'encode_register_$name'(Name, - 'encode_register_$username'(Username, - 'encode_register_$remove'(Remove, - 'encode_register_$key'(Key, - 'encode_register_$city'(City, - 'encode_register_$nick'(Nick, - 'encode_register_$url'(Url, - 'encode_register_$email'(Email, - [])))))))))))))))))))))), + _els = [encode(_el) || _el <- __Els] ++ + lists:reverse('encode_register_$zip'(Zip, + 'encode_register_$xdata'(Xdata, + 'encode_register_$misc'(Misc, + 'encode_register_$address'(Address, + 'encode_register_$instructions'(Instructions, + 'encode_register_$text'(Text, + 'encode_register_$last'(Last, + 'encode_register_$first'(First, + 'encode_register_$password'(Password, + 'encode_register_$registered'(Registered, + 'encode_register_$date'(Date, + 'encode_register_$phone'(Phone, + 'encode_register_$state'(State, + 'encode_register_$name'(Name, + 'encode_register_$username'(Username, + 'encode_register_$remove'(Remove, + 'encode_register_$key'(Key, + 'encode_register_$city'(City, + 'encode_register_$nick'(Nick, + 'encode_register_$url'(Url, + 'encode_register_$email'(Email, + [])))))))))))))))))))))), _attrs = _xmlns_attrs, {xmlel, <<"query">>, _attrs, _els}. -- cgit v1.2.3 From f91f2bc3d28f7f23ba4084827046bd183f06cf08 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 29 Jul 2016 13:21:00 +0300 Subject: Rewrite several modules to use XML generator --- src/ejabberd_xmlrpc.erl | 2 +- src/mod_admin_extra.erl | 196 +++++++++---------------- src/mod_http_api.erl | 2 +- src/mod_http_fileserver.erl | 3 - src/mod_metrics.erl | 2 +- src/mod_pres_counter.erl | 41 +++--- src/mod_private.erl | 2 +- src/mod_proxy65_service.erl | 351 +++++++++++++++++++------------------------- src/mod_proxy65_sm.erl | 4 +- src/mod_service_log.erl | 21 +-- src/mod_vcard.erl | 4 +- 11 files changed, 254 insertions(+), 374 deletions(-) (limited to 'src') diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index 6680451e4..6259b4efd 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -42,7 +42,7 @@ -include("ejabberd_http.hrl"). -include("mod_roster.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(state, {access_commands = [] :: list(), diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 8f6724281..a147a5881 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -54,7 +54,7 @@ -include("ejabberd_commands.hrl"). -include("mod_roster.hrl"). -include("ejabberd_sm.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). %%% %%% gen_mod @@ -879,20 +879,22 @@ set_presence(User, Host, Resource, Type, Show, Status, Priority) when is_integer(Priority) -> BPriority = integer_to_binary(Priority), set_presence(User, Host, Resource, Type, Show, Status, BPriority); -set_presence(User, Host, Resource, Type, Show, Status, Priority) -> +set_presence(User, Host, Resource, Type, Show, Status, Priority0) -> + Priority = if is_integer(Priority0) -> Priority0; + true -> binary_to_integer(Priority0) + end, case ejabberd_sm:get_session_pid(User, Host, Resource) of none -> error; Pid -> - USR = jid:to_string(jid:make(User, Host, Resource)), - US = jid:to_string(jid:make(User, Host, <<>>)), - Message = {route_xmlstreamelement, - {xmlel, <<"presence">>, - [{<<"from">>, USR}, {<<"to">>, US}, {<<"type">>, Type}], - [{xmlel, <<"show">>, [], [{xmlcdata, Show}]}, - {xmlel, <<"status">>, [], [{xmlcdata, Status}]}, - {xmlel, <<"priority">>, [], [{xmlcdata, Priority}]}]}}, - Pid ! Message, + From = jid:make(User, Host, Resource), + To = jid:make(User, Host), + Presence = #presence{from = From, to = To, + type = jlib:binary_to_atom(Type), + show = jlib:binary_to_atom(Show), + status = xmpp:mk_text(Status), + priority = Priority}, + Pid ! {route, From, To, Presence}, ok end. @@ -930,20 +932,12 @@ user_sessions_info(User, Host) -> %%% set_nickname(User, Host, Nickname) -> - R = mod_vcard:process_sm_iq( - {jid, User, Host, <<>>, User, Host, <<>>}, - {jid, User, Host, <<>>, User, Host, <<>>}, - {iq, <<>>, set, <<>>, <<"en">>, - {xmlel, <<"vCard">>, [ - {<<"xmlns">>, <<"vcard-temp">>}], [ - {xmlel, <<"NICKNAME">>, [], [{xmlcdata, Nickname}]} - ] - }}), - case R of - {iq, <<>>, result, <<>>, _L, []} -> - ok; - _ -> - error + VCard = xmpp:encode(#vcard_temp{nickname = Nickname}), + case mod_vcard:set_vcard(User, jid:nameprep(Host), VCard) of + {error, badarg} -> + error; + ok -> + ok end. get_vcard(User, Host, Name) -> @@ -967,26 +961,17 @@ set_vcard(User, Host, Name, Subname, SomeContent) -> %% %% Internal vcard -get_module_resource(Server) -> - case gen_mod:get_module_opt(Server, ?MODULE, module_resource, fun(A) -> A end, none) of - none -> list_to_binary(atom_to_list(?MODULE)); - R when is_binary(R) -> R - end. - get_vcard_content(User, Server, Data) -> - [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}), - JID = jid:make(User, Server, get_module_resource(Server)), - IQ = #iq{type = get, xmlns = ?NS_VCARD}, - IQr = Module:Function(JID, JID, IQ), - [A1] = IQr#iq.sub_el, - case A1#xmlel.children of - [_|_] -> - case get_vcard(Data, A1) of + case mod_vcard:get_vcard(jid:nodeprep(User), jid:nameprep(Server)) of + [_|_] = Els -> + case get_vcard(Data, Els) of [false] -> throw(error_no_value_found_in_vcard); ElemList -> ?DEBUG("ELS ~p", [ElemList]), [fxml:get_tag_cdata(Elem) || Elem <- ElemList] end; [] -> - throw(error_no_vcard_found) + throw(error_no_vcard_found); + error -> + throw(database_failure) end. get_vcard([<<"TEL">>, TelType], {_, _, _, OldEls}) -> @@ -1011,25 +996,19 @@ set_vcard_content(User, Server, Data, SomeContent) -> [Bin | _] when is_binary(Bin) -> SomeContent; Bin when is_binary(Bin) -> [SomeContent] end, - [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}), - JID = jid:make(User, Server, get_module_resource(Server)), - IQ = #iq{type = get, xmlns = ?NS_VCARD}, - IQr = Module:Function(JID, JID, IQ), - %% Get old vcard - A4 = case IQr#iq.sub_el of + A4 = case mod_vcard:get_vcard(jid:nodeprep(User), jid:nameprep(Server)) of [A1] -> {_, _, _, A2} = A1, update_vcard_els(Data, ContentList, A2); [] -> - update_vcard_els(Data, ContentList, []) + update_vcard_els(Data, ContentList, []); + error -> + throw(database_failure) end, - %% Build new vcard SubEl = {xmlel, <<"vCard">>, [{<<"xmlns">>,<<"vcard-temp">>}], A4}, - IQ2 = #iq{type=set, sub_el = SubEl}, - - Module:Function(JID, JID, IQ2), + mod_vcard:set_vcard(User, jid:nameprep(Server), SubEl), ok. take_vcard_tel(TelType, [{xmlel, <<"TEL">>, _, SubEls}=OldEl | OldEls], NewEls, Taken) -> @@ -1090,11 +1069,7 @@ add_rosteritem(LU, LS, User, Server, Nick, Group, Subscription, Xattrs) -> subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) -> ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}), - mod_roster:set_items( - LU, LS, - {xmlel, <<"query">>, - [{<<"xmlns">>, ?NS_ROSTER}], - [ItemEl]}). + mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]}). delete_rosteritem(LocalUser, LocalServer, User, Server) -> case unsubscribe(LocalUser, LocalServer, User, Server) of @@ -1107,11 +1082,7 @@ delete_rosteritem(LocalUser, LocalServer, User, Server) -> unsubscribe(LU, LS, User, Server) -> ItemEl = build_roster_item(User, Server, remove), - mod_roster:set_items( - LU, LS, - {xmlel, <<"query">>, - [{<<"xmlns">>, ?NS_ROSTER}], - [ItemEl]}). + mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]}). %% ----------------------------- %% Get Roster @@ -1201,28 +1172,16 @@ push_roster_item(LU, LS, R, U, S, Action) -> ejabberd_router:route(jid:remove_resource(LJID), LJID, ResIQ). build_roster_item(U, S, {add, Nick, Subs, Group}) -> - {xmlel, <<"item">>, - [{<<"jid">>, jid:to_string(jid:make(U, S, <<>>))}, - {<<"name">>, Nick}, - {<<"subscription">>, Subs}], - [{xmlel, <<"group">>, [], [{xmlcdata, Group}]}] - }; + #roster_item{jid = jid:make(U, S), + name = Nick, + subscription = jlib:binary_to_atom(Subs), + groups = [Group]}; build_roster_item(U, S, remove) -> - {xmlel, <<"item">>, - [{<<"jid">>, jid:to_string(jid:make(U, S, <<>>))}, - {<<"subscription">>, <<"remove">>}], - [] - }. + #roster_item{jid = jid:make(U, S), subscription = remove}. build_iq_roster_push(Item) -> - {xmlel, <<"iq">>, - [{<<"type">>, <<"set">>}, {<<"id">>, <<"push">>}], - [{xmlel, <<"query">>, - [{<<"xmlns">>, ?NS_ROSTER}], - [Item] - } - ] - }. + #iq{type = set, id = <<"push">>, + sub_els = [#roster_query{items = [Item]}]}. build_broadcast(U, S, {add, _Nick, Subs, _Group}) -> build_broadcast(U, S, list_to_atom(binary_to_list(Subs))); @@ -1268,17 +1227,9 @@ get_last(User, Server) -> %% Cluth private_get(Username, Host, Element, Ns) -> - From = jid:make(Username, Host, <<>>), - To = jid:make(Username, Host, <<>>), - IQ = {iq, <<>>, get, ?NS_PRIVATE, <<>>, - {xmlel, <<"query">>, - [{<<"xmlns">>,?NS_PRIVATE}], - [{xmlel, Element, [{<<"xmlns">>, Ns}], []}]}}, - ResIq = mod_private:process_sm_iq(From, To, IQ), - [{xmlel, <<"query">>, - [{<<"xmlns">>, ?NS_PRIVATE}], - [SubEl]}] = ResIq#iq.sub_el, - binary_to_list(fxml:element_to_binary(SubEl)). + Els = mod_private:get_data(jid:nodeprep(Username), jid:nameprep(Host), + [Ns, Element]), + binary_to_list(fxml:element_to_binary(xmpp:encode(#private{xml_els = Els}))). private_set(Username, Host, ElementString) -> case fxml_stream:parse_element(ElementString) of @@ -1291,13 +1242,9 @@ private_set(Username, Host, ElementString) -> end. private_set2(Username, Host, Xml) -> - From = jid:make(Username, Host, <<>>), - To = jid:make(Username, Host, <<>>), - IQ = {iq, <<>>, set, ?NS_PRIVATE, <<>>, - {xmlel, <<"query">>, - [{<<"xmlns">>, ?NS_PRIVATE}], - [Xml]}}, - mod_private:process_sm_iq(From, To, IQ), + NS = fxml:get_tag_attr_s(<<"xmlns">>, Xml), + mod_private:set_data(jid:nodeprep(Username), jid:nameprep(Host), + [{NS, Xml}]), ok. %%% @@ -1395,23 +1342,25 @@ send_packet_all_resources(FromJID, ToU, ToS, ToR, Packet) -> ejabberd_router:route(FromJID, ToJID, Packet). build_packet(Type, Subject, Body) -> - Tail = if Subject == <<"">>; Type == <<"chat">> -> []; - true -> [{xmlel, <<"subject">>, [], [{xmlcdata, Subject}]}] - end, - {xmlel, <<"message">>, - [{<<"type">>, Type}, {<<"id">>, randoms:get_string()}], - [{xmlel, <<"body">>, [], [{xmlcdata, Body}]} | Tail] - }. + #message{type = jlib:binary_to_atom(Type), + body = xmpp:mk_text(Body), + subject = xmpp:mk_text(Subject)}. send_stanza(FromString, ToString, Stanza) -> - case fxml_stream:parse_element(Stanza) of - {error, Error} -> - {error, Error}; - XmlEl -> - #xmlel{attrs = Attrs} = XmlEl, - From = jid:from_string(proplists:get_value(<<"from">>, Attrs, FromString)), - To = jid:from_string(proplists:get_value(<<"to">>, Attrs, ToString)), - ejabberd_router:route(From, To, XmlEl) + try + #xmlel{} = El = fxml_stream:parse_element(Stanza), + #jid{} = From = jid:from_string(FromString), + #jid{} = To = jid:to_string(ToString), + Pkt = xmpp:decode(El, [ignore_els]), + ejabberd_router:route(From, To, Pkt) + catch _:{xmpp_codec, Why} -> + io:format("incorrect stanza: ~s~n", [xmpp:format_error(Why)]), + {error, Why}; + _:{badmatch, {error, Why}} -> + io:format("invalid xml: ~p~n", [Why]), + {error, Why}; + _:{badmatch, error} -> + {error, "JID malformed"} end. send_stanza_c2s(Username, Host, Resource, Stanza) -> @@ -1427,17 +1376,15 @@ send_stanza_c2s(Username, Host, Resource, Stanza) -> end. privacy_set(Username, Host, QueryS) -> - From = jid:make(Username, Host, <<"">>), - To = jid:make(<<"">>, Host, <<"">>), + From = jid:make(Username, Host), + To = jid:make(Host), QueryEl = fxml_stream:parse_element(QueryS), - StanzaEl = {xmlel, <<"iq">>, [{<<"type">>, <<"set">>}], [QueryEl]}, - IQ = jlib:iq_query_info(StanzaEl), - ejabberd_hooks:run_fold( - privacy_iq_set, - Host, - {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, - [From, To, IQ] - ), + SubEl = xmpp:decode(QueryEl), + IQ = #iq{type = set, id = <<"push">>, sub_els = [SubEl]}, + ejabberd_hooks:run_fold(privacy_iq_set, + Host, + {error, xmpp:err_feature_not_implemented()}, + [From, To, IQ]), ok. %%% @@ -1618,5 +1565,4 @@ is_glob_match(String, <<"!", Glob/binary>>) -> is_glob_match(String, Glob) -> is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)). -mod_opt_type(module_resource) -> fun (A) -> A end; -mod_opt_type(_) -> [module_resource]. +mod_opt_type(_) -> []. diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 815ed3ab6..f3a69aa80 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -77,7 +77,7 @@ -export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("logger.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index 37e02edd8..728a2d137 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -51,9 +51,6 @@ -include("ejabberd.hrl"). -include("logger.hrl"). -include("ejabberd_http.hrl"). - --include("jlib.hrl"). - -include_lib("kernel/include/file.hrl"). -record(state, diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl index f1d487e0e..cb7946a28 100644 --- a/src/mod_metrics.erl +++ b/src/mod_metrics.erl @@ -31,7 +31,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("jid.hrl"). -define(HOOKS, [offline_message_hook, sm_register_connection_hook, sm_remove_connection_hook, diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl index e6f2cfbab..786ba97f2 100644 --- a/src/mod_pres_counter.erl +++ b/src/mod_pres_counter.erl @@ -33,7 +33,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -record(pres_counter, {dir, start, count, logged = false}). @@ -52,27 +52,24 @@ depends(_Host, _Opts) -> []. check_packet(_, _User, Server, _PrivacyList, - {From, To, #xmlel{name = Name, attrs = Attrs}}, Dir) -> - case Name of - <<"presence">> -> - IsSubscription = case fxml:get_attr_s(<<"type">>, Attrs) - of - <<"subscribe">> -> true; - <<"subscribed">> -> true; - <<"unsubscribe">> -> true; - <<"unsubscribed">> -> true; - _ -> false - end, - if IsSubscription -> - JID = case Dir of - in -> To; - out -> From - end, - update(Server, JID, Dir); - true -> allow - end; - _ -> allow - end. + {From, To, #presence{type = Type}}, Dir) -> + IsSubscription = case Type of + subscribe -> true; + subscribed -> true; + unsubscribe -> true; + unsubscribed -> true; + _ -> false + end, + if IsSubscription -> + JID = case Dir of + in -> To; + out -> From + end, + update(Server, JID, Dir); + true -> allow + end; +check_packet(_, _User, _Server, _PrivacyList, _Pkt, _Dir) -> + allow. update(Server, JID, Dir) -> StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, diff --git a/src/mod_private.erl b/src/mod_private.erl index e6d0fd7cd..6236b1012 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -32,7 +32,7 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_sm_iq/1, import/3, - remove_user/2, get_data/2, export/1, import/1, + remove_user/2, get_data/2, get_data/3, export/1, import/1, mod_opt_type/1, set_data/3, depends/2]). -include("ejabberd.hrl"). diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index 7db6f9da2..e90ff21bd 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -33,24 +33,17 @@ -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3]). --export([start_link/2, add_listener/2, +-export([start_link/2, add_listener/2, process_disco_info/1, + process_disco_items/1, process_vcard/1, process_bytestreams/1, transform_module_options/1, delete_listener/1]). -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PROCNAME, ejabberd_mod_proxy65_service). --record(state, - {myhost = <<"">> :: binary(), - serverhost = <<"">> :: binary(), - name = <<"">> :: binary(), - stream_addr = [] :: [attr()], - port = 0 :: inet:port_number(), - ip = {127,0,0,1} :: inet:ip_address(), - acl = none :: atom()}). +-record(state, {myhost = <<"">> :: binary()}). %%%------------------------ %%% gen_server callbacks @@ -62,34 +55,32 @@ start_link(Host, Opts) -> [Host, Opts], []). init([Host, Opts]) -> - State = parse_options(Host, Opts), - ejabberd_router:register_route(State#state.myhost, Host), - {ok, State}. + IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, + one_queue), + MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, + ?MODULE, process_disco_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS, + ?MODULE, process_disco_items, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD, + ?MODULE, process_vcard, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS, + ?MODULE, process_bytestreams, IQDisc), + ejabberd_router:register_route(MyHost, Host), + {ok, #state{myhost = MyHost}}. terminate(_Reason, #state{myhost = MyHost}) -> - ejabberd_router:unregister_route(MyHost), ok. - -handle_info({route, From, To, - #xmlel{name = <<"iq">>} = Packet}, - State) -> - IQ = jlib:iq_query_info(Packet), - case catch process_iq(From, IQ, State) of - Result when is_record(Result, iq) -> - ejabberd_router:route(To, From, jlib:iq_to_xml(Result)); - {'EXIT', Reason} -> - ?ERROR_MSG("Error when processing IQ stanza: ~p", - [Reason]), - Err = jlib:make_error_reply(Packet, - ?ERR_INTERNAL_SERVER_ERROR), - ejabberd_router:route(To, From, Err); - _ -> ok - end, + ejabberd_router:unregister_route(MyHost), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD), + gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_BYTESTREAMS). + +handle_info({route, From, To, #iq{} = Packet}, State) -> + ejabberd_router:process_iq(From, To, Packet), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -handle_call(get_port_ip, _From, State) -> - {reply, {port_ip, State#state.port, State#state.ip}, - State}; handle_call(_Request, _From, State) -> {reply, ok, State}. @@ -102,185 +93,122 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%------------------------ add_listener(Host, Opts) -> - State = parse_options(Host, Opts), NewOpts = [Host | Opts], - ejabberd_listener:add_listener({State#state.port, - State#state.ip}, + ejabberd_listener:add_listener(get_port_ip(Host), mod_proxy65_stream, NewOpts). delete_listener(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - {port_ip, Port, IP} = gen_server:call(Proc, - get_port_ip), - catch ejabberd_listener:delete_listener({Port, IP}, + catch ejabberd_listener:delete_listener(get_port_ip(Host), mod_proxy65_stream). %%%------------------------ %%% IQ Processing %%%------------------------ - -%% disco#info request -process_iq(_, - #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = - IQ, - #state{name = Name, serverhost = ServerHost}) -> - Info = ejabberd_hooks:run_fold(disco_info, ServerHost, - [], [ServerHost, ?MODULE, <<"">>, <<"">>]), - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}], - children = iq_disco_info(Lang, Name) ++ Info}]}; -%% disco#items request -process_iq(_, - #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}], - children = []}]}; -%% vCard request -process_iq(_, - #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ, - _) -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = iq_vcard(Lang)}]}; -%% bytestreams info request -process_iq(JID, - #iq{type = get, sub_el = SubEl, lang = Lang, - xmlns = ?NS_BYTESTREAMS} = - IQ, - #state{acl = ACL, stream_addr = StreamAddr, - serverhost = ServerHost}) -> +-spec process_disco_info(iq()) -> iq(). +process_disco_info(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) -> + Host = ejabberd_router:host_of_route(To#jid.lserver), + Name = gen_mod:get_module_opt(Host, mod_proxy65, name, + fun iolist_to_binary/1, + <<"SOCKS5 Bytestreams">>), + Info = ejabberd_hooks:run_fold(disco_info, Host, + [], [Host, ?MODULE, <<"">>, <<"">>]), + xmpp:make_iq_result( + IQ, #disco_info{xdata = Info, + identities = [#identity{category = <<"proxy">>, + type = <<"bytestreams">>, + name = translate:translate(Lang, Name)}], + features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, + ?NS_VCARD, ?NS_BYTESTREAMS]}). + +-spec process_disco_items(iq()) -> iq(). +process_disco_items(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_disco_items(#iq{type = get} = IQ) -> + xmpp:make_iq_result(IQ, #disco_items{}). + +-spec process_vcard(iq()) -> iq(). +process_vcard(#iq{type = set, lang = Lang} = IQ) -> + Txt = <<"Value 'set' of 'type' attribute is not allowed">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_vcard(#iq{type = get, lang = Lang} = IQ) -> + Desc = translate:translate(Lang, <<"ejabberd SOCKS5 Bytestreams module">>), + Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, + xmpp:make_iq_result( + IQ, #vcard_temp{fn = <<"ejabberd/mod_proxy65">>, + url = ?EJABBERD_URI, + desc = <>}). + +-spec process_bytestreams(iq()) -> iq(). +process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) -> + Host = To#jid.lserver, + ServerHost = ejabberd_router:host_of_route(Host), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, + fun acl:access_rules_validator/1, + all), case acl:match_rule(ServerHost, ACL, JID) of - allow -> - StreamHostEl = [#xmlel{name = <<"streamhost">>, - attrs = StreamAddr, children = []}], - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_BYTESTREAMS}], - children = StreamHostEl}]}; - deny -> - Txt = <<"Denied by ACL">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]} + allow -> + StreamHost = get_streamhost(Host, ServerHost), + xmpp:make_iq_result(IQ, #bytestreams{hosts = [StreamHost]}); + deny -> + xmpp:make_error(IQ, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)) end; -%% bytestream activation request -process_iq(InitiatorJID, - #iq{type = set, sub_el = SubEl, lang = Lang, - xmlns = ?NS_BYTESTREAMS} = - IQ, - #state{acl = ACL, serverhost = ServerHost}) -> +process_bytestreams(#iq{type = set, lang = Lang, + sub_els = [#bytestreams{sid = undefined}]} = IQ) -> + Why = {missing_attr, <<"sid">>, <<"query">>, ?NS_BYTESTREAMS}, + Txt = xmpp:format_error(Why), + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); +process_bytestreams(#iq{type = set, lang = Lang, + sub_els = [#bytestreams{sid = SID}]} = IQ) + when SID == <<"">> orelse length(SID) > 128 -> + Why = {bad_attr_value, <<"sid">>, <<"query">>, ?NS_BYTESTREAMS}, + Txt = xmpp:format_error(Why), + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); +process_bytestreams(#iq{type = set, lang = Lang, + sub_els = [#bytestreams{activate = undefined}]} = IQ) -> + Why = {missing_cdata, <<"">>, <<"activate">>, ?NS_BYTESTREAMS}, + Txt = xmpp:format_error(Why), + xmpp:make_error(IQ, xmpp:err_jid_malformed(Txt, Lang)); +process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To, + sub_els = [#bytestreams{activate = TargetJID, + sid = SID}]} = IQ) -> + ServerHost = ejabberd_router:host_of_route(To#jid.lserver), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, + fun acl:access_rules_validator/1, + all), case acl:match_rule(ServerHost, ACL, InitiatorJID) of - allow -> - ActivateEl = fxml:get_path_s(SubEl, - [{elem, <<"activate">>}]), - SID = fxml:get_tag_attr_s(<<"sid">>, SubEl), - case catch - jid:from_string(fxml:get_tag_cdata(ActivateEl)) - of - TargetJID - when is_record(TargetJID, jid), SID /= <<"">>, - byte_size(SID) =< 128, TargetJID /= InitiatorJID -> - Target = - jid:to_string(jid:tolower(TargetJID)), - Initiator = - jid:to_string(jid:tolower(InitiatorJID)), - SHA1 = p1_sha:sha(<>), - case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID, - TargetJID, ServerHost) - of - ok -> IQ#iq{type = result, sub_el = []}; - false -> - Txt = <<"Failed to activate bytestream">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]}; - limit -> - Txt = <<"Too many active bytestreams">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)]}; - conflict -> - Txt = <<"Bytestream already activated">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_CONFLICT(Lang, Txt)]}; - _ -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} - end; - _ -> - Txt = <<"Malformed JID">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]} - end; - deny -> - Txt = <<"Denied by ACL">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]} - end; -%% Unknown "set" or "get" request -process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _) - when Type == get; Type == set -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; -%% IQ "result" or "error". -process_iq(_, _, _) -> ok. - + allow -> + Target = jid:to_string(jid:tolower(TargetJID)), + Initiator = jid:to_string(jid:tolower(InitiatorJID)), + SHA1 = p1_sha:sha(<>), + case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID, + TargetJID, ServerHost) of + ok -> + xmpp:make_iq_result(IQ); + false -> + Txt = <<"Failed to activate bytestream">>, + xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)); + limit -> + Txt = <<"Too many active bytestreams">>, + xmpp:make_error(IQ, xmpp:err_resource_constraint(Txt, Lang)); + conflict -> + Txt = <<"Bytestream already activated">>, + xmpp:make_error(IQ, xmpp:err_conflict(Txt, Lang)); + Err -> + ?ERROR_MSG("failed to activate bytestream from ~s to ~s: ~p", + [Initiator, Target, Err]), + xmpp:make_error(IQ, xmpp:err_internal_server_error()) + end; + deny -> + Txt = <<"Denied by ACL">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)) + end. %%%------------------------- %%% Auxiliary functions. %%%------------------------- --define(FEATURE(Feat), - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, Feat}], children = []}). - -iq_disco_info(Lang, Name) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"proxy">>}, - {<<"type">>, <<"bytestreams">>}, - {<<"name">>, translate:translate(Lang, Name)}], - children = []}, - ?FEATURE((?NS_DISCO_INFO)), ?FEATURE((?NS_VCARD)), - ?FEATURE((?NS_BYTESTREAMS))]. - -iq_vcard(Lang) -> - [#xmlel{name = <<"FN">>, attrs = [], - children = [{xmlcdata, <<"ejabberd/mod_proxy65">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"ejabberd SOCKS5 Bytestreams module">>))/binary, - "\nCopyright (c) 2003-2016 ProcessOne">>}]}]. - -parse_options(ServerHost, Opts) -> - MyHost = gen_mod:get_opt_host(ServerHost, Opts, - <<"proxy.@HOST@">>), - Port = gen_mod:get_opt(port, Opts, - fun(P) when is_integer(P), P>0, P<65536 -> P end, - 7777), - ACL = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1, - all), - Name = gen_mod:get_opt(name, Opts, fun iolist_to_binary/1, - <<"SOCKS5 Bytestreams">>), - IP = gen_mod:get_opt(ip, Opts, - fun(S) -> - {ok, Addr} = inet_parse:address( - binary_to_list( - iolist_to_binary(S))), - Addr - end, get_my_ip()), - HostName = gen_mod:get_opt(hostname, Opts, - fun iolist_to_binary/1, - jlib:ip_to_list(IP)), - StreamAddr = [{<<"jid">>, MyHost}, - {<<"host">>, HostName}, - {<<"port">>, jlib:integer_to_binary(Port)}], - #state{myhost = MyHost, serverhost = ServerHost, - name = Name, port = Port, ip = IP, - stream_addr = StreamAddr, acl = ACL}. - transform_module_options(Opts) -> lists:map( fun({ip, IP}) when is_tuple(IP) -> @@ -291,6 +219,33 @@ transform_module_options(Opts) -> Opt end, Opts). +-spec get_streamhost(binary(), binary()) -> streamhost(). +get_streamhost(Host, ServerHost) -> + {Port, IP} = get_port_ip(ServerHost), + HostName = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname, + fun iolist_to_binary/1, + jlib:ip_to_list(IP)), + #streamhost{jid = jid:make(Host), + host = HostName, + port = Port}. + +-spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}. +get_port_ip(Host) -> + Port = gen_mod:get_module_opt(Host, mod_proxy65, port, + fun(P) when is_integer(P), P>0, P<65536 -> + P + end, + 7777), + IP = gen_mod:get_module_opt(Host, mod_proxy65, ip, + fun(S) -> + {ok, Addr} = inet_parse:address( + binary_to_list( + iolist_to_binary(S))), + Addr + end, get_my_ip()), + {Port, IP}. + +-spec get_my_ip() -> inet:ip_address(). get_my_ip() -> {ok, MyHostName} = inet:gethostname(), case inet:getaddr(MyHostName, inet) of diff --git a/src/mod_proxy65_sm.erl b/src/mod_proxy65_sm.erl index d86b06c4b..7ef4d390e 100644 --- a/src/mod_proxy65_sm.erl +++ b/src/mod_proxy65_sm.erl @@ -38,14 +38,12 @@ -record(state, {max_connections = infinity :: non_neg_integer() | infinity}). --include("jlib.hrl"). - -record(bytestream, {sha1 = <<"">> :: binary() | '$1', target :: pid() | '_', initiator :: pid() | '_', active = false :: boolean() | '_', - jid_i = {<<"">>, <<"">>, <<"">>} :: ljid() | '_'}). + jid_i = {<<"">>, <<"">>, <<"">>} :: jid:ljid() | '_'}). -define(PROCNAME, ejabberd_mod_proxy65_sm). diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl index ae264bbc9..8f11b0ead 100644 --- a/src/mod_service_log.erl +++ b/src/mod_service_log.erl @@ -62,9 +62,7 @@ log_user_receive(Packet, _C2SState, _JID, From, To) -> log_packet(From, To, Packet, To#jid.lserver), Packet. -log_packet(From, To, - #xmlel{name = Name, attrs = Attrs, children = Els}, - Host) -> +log_packet(From, To, Packet, Host) -> Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, fun(L) -> lists:map( @@ -76,22 +74,11 @@ log_packet(From, To, end end, L) end, []), - ServerJID = #jid{user = <<"">>, server = Host, - resource = <<"">>, luser = <<"">>, lserver = Host, - lresource = <<"">>}, - NewAttrs = - jlib:replace_from_to_attrs(jid:to_string(From), - jid:to_string(To), Attrs), - FixedPacket = #xmlel{name = Name, attrs = NewAttrs, - children = Els}, + ServerJID = jid:make(Host), + FixedPacket = xmpp:set_from_to(Packet, From, To), lists:foreach(fun (Logger) -> ejabberd_router:route(ServerJID, - #jid{user = <<"">>, - server = Logger, - resource = <<"">>, - luser = <<"">>, - lserver = Logger, - lresource = <<"">>}, + jid:make(Logger), #xmlel{name = <<"route">>, attrs = [], children = diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index f738648d6..b75b6575b 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -35,7 +35,7 @@ -export([start/2, init/3, stop/1, get_sm_features/5, process_local_iq/1, process_sm_iq/1, string2lower/1, remove_user/2, export/1, import/1, import/3, depends/2, - process_search/1, process_vcard/1, + process_search/1, process_vcard/1, get_vcard/2, disco_items/5, disco_features/5, disco_identity/5, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). @@ -336,7 +336,7 @@ make_vcard_search(User, LUser, LServer, VCARD) -> orgunit = OrgUnit, lorgunit = LOrgUnit}. --spec set_vcard(binary(), binary(), xmlel()) -> any(). +-spec set_vcard(binary(), binary(), xmlel()) -> {error, badarg} | ok. set_vcard(User, LServer, VCARD) -> case jid:nodeprep(User) of error -> -- cgit v1.2.3 From 9bf1bac7df54f5be9cdca9a5d7a36160c40e25dd Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 29 Jul 2016 17:39:13 +0300 Subject: Rewrite mod_vcard_ldap to use XML generator --- src/ejabberd_config.erl | 1 + src/gen_mod.erl | 24 +- src/mod_vcard.erl | 80 ++--- src/mod_vcard_ldap.erl | 738 ++++++++++++----------------------------------- src/mod_vcard_mnesia.erl | 55 +++- src/mod_vcard_riak.erl | 11 +- src/mod_vcard_sql.erl | 52 +++- 7 files changed, 336 insertions(+), 625 deletions(-) (limited to 'src') diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 87a918704..5a39df043 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -1010,6 +1010,7 @@ replace_module(mod_private_odbc) -> {mod_private, sql}; replace_module(mod_roster_odbc) -> {mod_roster, sql}; replace_module(mod_shared_roster_odbc) -> {mod_shared_roster, sql}; replace_module(mod_vcard_odbc) -> {mod_vcard, sql}; +replace_module(mod_vcard_ldap) -> {mod_vcard, ldap}; replace_module(mod_vcard_xupdate_odbc) -> {mod_vcard_xupdate, sql}; replace_module(mod_pubsub_odbc) -> {mod_pubsub, sql}; replace_module(Module) -> diff --git a/src/gen_mod.erl b/src/gen_mod.erl index c4306577c..e5b504897 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -48,7 +48,7 @@ opts = [] :: opts() | '_' | '$2'}). -type opts() :: [{atom(), any()}]. --type db_type() :: sql | mnesia | riak. +-type db_type() :: sql | mnesia | riak | ldap. -callback start(binary(), opts()) -> any(). -callback stop(binary()) -> any(). @@ -147,7 +147,7 @@ start_module(Host, Module) -> -spec start_module(binary(), atom(), opts()) -> any(). start_module(Host, Module, Opts0) -> - Opts = validate_opts(Module, Opts0), + Opts = validate_opts(Host, Module, Opts0), ets:insert(ejabberd_modules, #ejabberd_module{module_host = {Module, Host}, opts = Opts}), @@ -308,10 +308,10 @@ get_opt_host(Host, Opts, Default) -> Val = get_opt(host, Opts, fun iolist_to_binary/1, Default), ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host). -validate_opts(Module, Opts) -> +validate_opts(Host, Module, Opts) -> lists:filtermap( fun({Opt, Val}) -> - case catch Module:mod_opt_type(Opt) of + case catch validate_opt(Host, Module, Opt, Opts) of VFun when is_function(VFun) -> try VFun(Val) of _ -> @@ -346,6 +346,22 @@ validate_opts(Module, Opts) -> false end, Opts). +validate_opt(Host, Module, Opt, Opts) -> + case Module:mod_opt_type(Opt) of + VFun1 when is_function(VFun1) -> + VFun1; + L1 when is_list(L1) -> + DBModule = db_mod(Host, Opts, Module), + try DBModule:mod_opt_type(Opt) of + VFun2 when is_function(VFun2) -> + VFun2; + L2 when is_list(L2) -> + lists:usort(L1 ++ L2) + catch _:undef -> + L1 + end + end. + -spec db_type(binary() | global, module()) -> db_type(); (opts(), module()) -> db_type(). diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index b75b6575b..231c42dc0 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -49,12 +49,15 @@ -define(PROCNAME, ejabberd_mod_vcard). -callback init(binary(), gen_mod:opts()) -> any(). +-callback stop(binary()) -> any(). -callback import(binary(), #vcard{} | #vcard_search{}) -> ok | pass. -callback get_vcard(binary(), binary()) -> [xmlel()] | error. -callback set_vcard(binary(), binary(), xmlel(), #vcard_search{}) -> {atomic, any()}. +-callback search_fields(binary()) -> [{binary(), binary()}]. +-callback search_reported(binary()) -> [{binary(), binary()}]. -callback search(binary(), [{binary(), [binary()]}], boolean(), - infinity | pos_integer()) -> [binary()]. + infinity | pos_integer()) -> [{binary(), binary()}]. -callback remove_user(binary(), binary()) -> {atomic, any()}. start(Host, Opts) -> @@ -134,6 +137,8 @@ stop(Host) -> ?NS_VCARD), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), + Mod = gen_mod:db_type(Host, ?MODULE), + Mod:stop(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, {wait, Proc}. @@ -214,7 +219,8 @@ process_vcard(#iq{type = get, lang = Lang} = IQ) -> -spec process_search(iq()) -> iq(). process_search(#iq{type = get, to = To, lang = Lang} = IQ) -> - xmpp:make_iq_result(IQ, mk_search_form(To, Lang)); + ServerHost = ejabberd_router:host_of_route(To#jid.lserver), + xmpp:make_iq_result(IQ, mk_search_form(To, ServerHost, Lang)); process_search(#iq{type = set, to = To, lang = Lang, sub_els = [#search{xdata = #xdata{type = submit, fields = Fs}}]} = IQ) -> @@ -366,22 +372,13 @@ mk_tfield(Label, Var, Lang) -> mk_field(Var, Val) -> #xdata_field{var = Var, values = [Val]}. --spec mk_search_form(jid(), undefined | binary()) -> search(). -mk_search_form(JID, Lang) -> +-spec mk_search_form(jid(), binary(), undefined | binary()) -> search(). +mk_search_form(JID, ServerHost, Lang) -> Title = <<(translate:translate(Lang, <<"Search users in ">>))/binary, (jid:to_string(JID))/binary>>, - Fs = [mk_tfield(<<"User">>, <<"user">>, Lang), - mk_tfield(<<"Full Name">>, <<"fn">>, Lang), - mk_tfield(<<"Name">>, <<"first">>, Lang), - mk_tfield(<<"Middle Name">>, <<"middle">>, Lang), - mk_tfield(<<"Family Name">>, <<"last">>, Lang), - mk_tfield(<<"Nickname">>, <<"nick">>, Lang), - mk_tfield(<<"Birthday">>, <<"bday">>, Lang), - mk_tfield(<<"Country">>, <<"ctry">>, Lang), - mk_tfield(<<"City">>, <<"locality">>, Lang), - mk_tfield(<<"Email">>, <<"email">>, Lang), - mk_tfield(<<"Organization Name">>, <<"orgname">>, Lang), - mk_tfield(<<"Organization Unit">>, <<"orgunit">>, Lang)], + Mod = gen_mod:db_mod(ServerHost, ?MODULE), + SearchFields = Mod:search_fields(ServerHost), + Fs = [mk_tfield(Label, Var, Lang) || {Label, Var} <- SearchFields], X = #xdata{type = form, title = Title, instructions = @@ -398,55 +395,20 @@ mk_search_form(JID, Lang) -> -spec search_result(undefined | binary(), jid(), binary(), [xdata_field()]) -> xdata(). search_result(Lang, JID, ServerHost, XFields) -> + Mod = gen_mod:db_mod(ServerHost, ?MODULE), + Reported = [mk_tfield(Label, Var, Lang) || + {Label, Var} <- Mod:search_reported(ServerHost)], #xdata{type = result, title = <<(translate:translate(Lang, <<"Search Results for ">>))/binary, (jid:to_string(JID))/binary>>, - reported = [mk_tfield(<<"Jabber ID">>, <<"jid">>, Lang), - mk_tfield(<<"Full Name">>, <<"fn">>, Lang), - mk_tfield(<<"Name">>, <<"first">>, Lang), - mk_tfield(<<"Middle Name">>, <<"middle">>, Lang), - mk_tfield(<<"Family Name">>, <<"last">>, Lang), - mk_tfield(<<"Nickname">>, <<"nick">>, Lang), - mk_tfield(<<"Birthday">>, <<"bday">>, Lang), - mk_tfield(<<"Country">>, <<"ctry">>, Lang), - mk_tfield(<<"City">>, <<"locality">>, Lang), - mk_tfield(<<"Email">>, <<"email">>, Lang), - mk_tfield(<<"Organization Name">>, <<"orgname">>, Lang), - mk_tfield(<<"Organization Unit">>, <<"orgunit">>, Lang)], - items = lists:map(fun (R) -> record_to_item(ServerHost, R) end, + reported = Reported, + items = lists:map(fun (Item) -> item_to_field(Item) end, search(ServerHost, XFields))}. --spec record_to_item(binary(), [binary()] | #vcard_search{}) -> [xdata_field()]. -record_to_item(LServer, - [Username, FN, Family, Given, Middle, Nickname, BDay, - CTRY, Locality, EMail, OrgName, OrgUnit]) -> - [mk_field(<<"jid">>, <>), - mk_field(<<"fn">>, FN), - mk_field(<<"last">>, Family), - mk_field(<<"first">>, Given), - mk_field(<<"middle">>, Middle), - mk_field(<<"nick">>, Nickname), - mk_field(<<"bday">>, BDay), - mk_field(<<"ctry">>, CTRY), - mk_field(<<"locality">>, Locality), - mk_field(<<"email">>, EMail), - mk_field(<<"orgname">>, OrgName), - mk_field(<<"orgunit">>, OrgUnit)]; -record_to_item(_LServer, #vcard_search{} = R) -> - {User, Server} = R#vcard_search.user, - [mk_field(<<"jid">>, <>), - mk_field(<<"fn">>, (R#vcard_search.fn)), - mk_field(<<"last">>, (R#vcard_search.family)), - mk_field(<<"first">>, (R#vcard_search.given)), - mk_field(<<"middle">>, (R#vcard_search.middle)), - mk_field(<<"nick">>, (R#vcard_search.nickname)), - mk_field(<<"bday">>, (R#vcard_search.bday)), - mk_field(<<"ctry">>, (R#vcard_search.ctry)), - mk_field(<<"locality">>, (R#vcard_search.locality)), - mk_field(<<"email">>, (R#vcard_search.email)), - mk_field(<<"orgname">>, (R#vcard_search.orgname)), - mk_field(<<"orgunit">>, (R#vcard_search.orgunit))]. +-spec item_to_field([{binary(), binary()}]) -> [xdata_field()]. +item_to_field(Items) -> + [mk_field(Var, Value) || {Var, Value} <- Items]. -spec search(binary(), [xdata_field()]) -> [binary()]. search(LServer, XFields) -> diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index a0ad305a9..74b20d2ff 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -1,53 +1,30 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_vcard_ldap.erl -%%% Author : Alexey Shchepin -%%% Purpose : Support for VCards from LDAP storage. -%%% Created : 2 Jan 2003 by Alexey Shchepin +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc %%% -%%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%---------------------u------------------------------------------------- - +%%% @end +%%% Created : 29 Jul 2016 by Evgeny Khramtsov +%%%------------------------------------------------------------------- -module(mod_vcard_ldap). --behaviour(ejabberd_config). - --author('alexey@process-one.net'). - -behaviour(gen_server). +-behaviour(mod_vcard). --behaviour(gen_mod). - -%% gen_server callbacks. --export([init/1, handle_info/2, handle_call/3, - handle_cast/2, terminate/2, code_change/3]). +%% API +-export([start_link/2]). +-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, + remove_user/2, import/2, search_fields/1, search_reported/1, + mod_opt_type/1, opt_type/1]). --export([start/2, start_link/2, stop/1, - get_sm_features/5, process_local_iq/3, process_sm_iq/3, - remove_user/1, route/4, transform_module_options/1, - mod_opt_type/1, opt_type/1, depends/2]). +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("logger.hrl"). - -include("eldap.hrl"). - --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PROCNAME, ejabberd_mod_vcard_ldap). @@ -74,59 +51,14 @@ deref_aliases = never :: never | searching | finding | always, matches = 0 :: non_neg_integer()}). --define(VCARD_MAP, - [{<<"NICKNAME">>, <<"%u">>, []}, - {<<"FN">>, <<"%s">>, [<<"displayName">>]}, - {<<"FAMILY">>, <<"%s">>, [<<"sn">>]}, - {<<"GIVEN">>, <<"%s">>, [<<"givenName">>]}, - {<<"MIDDLE">>, <<"%s">>, [<<"initials">>]}, - {<<"ORGNAME">>, <<"%s">>, [<<"o">>]}, - {<<"ORGUNIT">>, <<"%s">>, [<<"ou">>]}, - {<<"CTRY">>, <<"%s">>, [<<"c">>]}, - {<<"LOCALITY">>, <<"%s">>, [<<"l">>]}, - {<<"STREET">>, <<"%s">>, [<<"street">>]}, - {<<"REGION">>, <<"%s">>, [<<"st">>]}, - {<<"PCODE">>, <<"%s">>, [<<"postalCode">>]}, - {<<"TITLE">>, <<"%s">>, [<<"title">>]}, - {<<"URL">>, <<"%s">>, [<<"labeleduri">>]}, - {<<"DESC">>, <<"%s">>, [<<"description">>]}, - {<<"TEL">>, <<"%s">>, [<<"telephoneNumber">>]}, - {<<"EMAIL">>, <<"%s">>, [<<"mail">>]}, - {<<"BDAY">>, <<"%s">>, [<<"birthDay">>]}, - {<<"ROLE">>, <<"%s">>, [<<"employeeType">>]}, - {<<"PHOTO">>, <<"%s">>, [<<"jpegPhoto">>]}]). - --define(SEARCH_FIELDS, - [{<<"User">>, <<"%u">>}, - {<<"Full Name">>, <<"displayName">>}, - {<<"Given Name">>, <<"givenName">>}, - {<<"Middle Name">>, <<"initials">>}, - {<<"Family Name">>, <<"sn">>}, - {<<"Nickname">>, <<"%u">>}, - {<<"Birthday">>, <<"birthDay">>}, - {<<"Country">>, <<"c">>}, {<<"City">>, <<"l">>}, - {<<"Email">>, <<"mail">>}, - {<<"Organization Name">>, <<"o">>}, - {<<"Organization Unit">>, <<"ou">>}]). - --define(SEARCH_REPORTED, - [{<<"Full Name">>, <<"FN">>}, - {<<"Given Name">>, <<"FIRST">>}, - {<<"Middle Name">>, <<"MIDDLE">>}, - {<<"Family Name">>, <<"LAST">>}, - {<<"Nickname">>, <<"NICK">>}, - {<<"Birthday">>, <<"BDAY">>}, - {<<"Country">>, <<"CTRY">>}, - {<<"City">>, <<"LOCALITY">>}, - {<<"Email">>, <<"EMAIL">>}, - {<<"Organization Name">>, <<"ORGNAME">>}, - {<<"Organization Unit">>, <<"ORGUNIT">>}]). - -handle_cast(_Request, State) -> {noreply, State}. - -code_change(_OldVsn, State, _Extra) -> {ok, State}. - -start(Host, Opts) -> +%%%=================================================================== +%%% API +%%%=================================================================== +start_link(Host, Opts) -> + Proc = gen_mod:get_module_proc(Host, ?PROCNAME), + gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). + +init(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, 1000, worker, [?MODULE]}, @@ -138,141 +70,127 @@ stop(Host) -> supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). -depends(_Host, _Opts) -> - []. - -terminate(_Reason, State) -> - Host = State#state.serverhost, - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, - ?NS_VCARD), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, - ?NS_VCARD), - ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, - get_sm_features, 50), - case State#state.search of - true -> - ejabberd_router:unregister_route(State#state.myhost); - _ -> ok +get_vcard(LUser, LServer) -> + {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME), + VCardMap = State#state.vcard_map, + case find_ldap_user(LUser, State) of + #eldap_entry{attributes = Attributes} -> + ldap_attributes_to_vcard(Attributes, VCardMap, + {LUser, LServer}); + _ -> + [] end. -start_link(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:start_link({local, Proc}, ?MODULE, - [Host, Opts], []). +set_vcard(_LUser, _LServer, _VCard, _VCardSearch) -> + {atomic, not_implemented}. + +search_fields(LServer) -> + {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME), + State#state.search_fields. + +search_reported(LServer) -> + {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME), + State#state.search_reported. + +search(LServer, Data, _AllowReturnAll, MaxMatch) -> + {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME), + Base = State#state.base, + SearchFilter = State#state.search_filter, + Eldap_ID = State#state.eldap_id, + UIDs = State#state.uids, + ReportedAttrs = State#state.search_reported_attrs, + Filter = eldap:'and'([SearchFilter, + eldap_utils:make_filter(Data, UIDs)]), + case eldap_pool:search(Eldap_ID, + [{base, Base}, {filter, Filter}, {limit, MaxMatch}, + {deref_aliases, State#state.deref_aliases}, + {attributes, ReportedAttrs}]) + of + #eldap_search_result{entries = E} -> + search_items(E, State); + _ -> + [] + end. +search_items(Entries, State) -> + LServer = State#state.serverhost, + SearchReported = State#state.search_reported, + VCardMap = State#state.vcard_map, + UIDs = State#state.uids, + Attributes = lists:map(fun (E) -> + #eldap_entry{attributes = Attrs} = E, Attrs + end, + Entries), + lists:flatmap( + fun(Attrs) -> + case eldap_utils:find_ldap_attrs(UIDs, Attrs) of + {U, UIDAttrFormat} -> + case eldap_utils:get_user_part(U, UIDAttrFormat) of + {ok, Username} -> + case ejabberd_auth:is_user_exists(Username, + LServer) of + true -> + RFields = lists:map( + fun({_, VCardName}) -> + {VCardName, + map_vcard_attr(VCardName, + Attrs, + VCardMap, + {Username, + ?MYNAME})} + end, + SearchReported), + J = <>, + [{<<"jid">>, J} | RFields]; + _ -> + [] + end; + _ -> + [] + end; + <<"">> -> + [] + end + end, Attributes). + +remove_user(_User, _Server) -> + {atomic, not_implemented}. + +import(_, _) -> + pass. + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== init([Host, Opts]) -> State = parse_options(Host, Opts), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), - ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, - get_sm_features, 50), eldap_pool:start_link(State#state.eldap_id, State#state.servers, State#state.backups, State#state.port, State#state.dn, State#state.password, State#state.tls_options), - case State#state.search of - true -> - ejabberd_router:register_route(State#state.myhost, Host); - _ -> ok - end, {ok, State}. -handle_info({route, From, To, Packet}, State) -> - case catch do_route(State, From, To, Packet) of - Pid when is_pid(Pid) -> ok; - _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_INTERNAL_SERVER_ERROR), - ejabberd_router:route(To, From, Err) - end, - {noreply, State}; -handle_info(_Info, State) -> {noreply, State}. - -get_sm_features({error, _Error} = Acc, _From, _To, - _Node, _Lang) -> - Acc; -get_sm_features(Acc, _From, _To, Node, _Lang) -> - case Node of - <<"">> -> - case Acc of - {result, Features} -> {result, [?NS_VCARD | Features]}; - empty -> {result, [?NS_VCARD]} - end; - _ -> Acc - end. +handle_call(get_state, _From, State) -> + {reply, {ok, State}, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. -process_local_iq(_From, _To, - #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = - [#xmlel{name = <<"FN">>, attrs = [], - children = - [{xmlcdata, <<"ejabberd">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Erlang Jabber Server">>))/binary, - "\nCopyright (c) 2002-2016 ProcessOne">>}]}, - #xmlel{name = <<"BDAY">>, attrs = [], - children = - [{xmlcdata, <<"2002-11-16">>}]}]}]} - end. +handle_cast(_Msg, State) -> + {noreply, State}. -process_sm_iq(_From, #jid{lserver = LServer} = To, - #iq{sub_el = SubEl} = IQ) -> - case catch process_vcard_ldap(To, IQ, LServer) of - {'EXIT', _} -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; - Other -> Other - end. +handle_info(_Info, State) -> + {noreply, State}. -process_vcard_ldap(To, IQ, Server) -> - {ok, State} = eldap_utils:get_state(Server, ?PROCNAME), - #iq{type = Type, sub_el = SubEl, lang = Lang} = IQ, - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - #jid{luser = LUser} = To, - LServer = State#state.serverhost, - case ejabberd_auth:is_user_exists(LUser, LServer) of - true -> - VCardMap = State#state.vcard_map, - case find_ldap_user(LUser, State) of - #eldap_entry{attributes = Attributes} -> - Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, - {LUser, LServer}), - IQ#iq{type = result, sub_el = Vcard}; - _ -> IQ#iq{type = result, sub_el = []} - end; - _ -> IQ#iq{type = result, sub_el = []} - end - end. +terminate(_Reason, _State) -> + ok. -handle_call(get_state, _From, State) -> - {reply, {ok, State}, State}; -handle_call(stop, _From, State) -> - {stop, normal, ok, State}; -handle_call(_Request, _From, State) -> - {reply, bad_request, State}. +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +%%%=================================================================== +%%% Internal functions +%%%=================================================================== find_ldap_user(User, State) -> Base = State#state.base, RFC2254_Filter = State#state.user_filter, @@ -403,309 +321,6 @@ ldap_attribute_to_vcard(vCardA, {<<"pcode">>, Value}) -> children = [{xmlcdata, Value}]}; ldap_attribute_to_vcard(_, _) -> none. --define(TLFIELD(Type, Label, Var), - #xmlel{name = <<"field">>, - attrs = - [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = []}). - --define(FORM(JID, SearchFields), - [#xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"You need an x:data capable client to " - "search">>)}]}, - #xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}], - children = - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Search users in ">>))/binary, - (jid:to_string(JID))/binary>>}]}, - #xmlel{name = <<"instructions">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Fill in fields to search for any matching " - "Jabber User">>)}]}] - ++ - lists:map(fun ({X, Y}) -> - ?TLFIELD(<<"text-single">>, X, Y) - end, - SearchFields)}]). - -do_route(State, From, To, Packet) -> - spawn(?MODULE, route, [State, From, To, Packet]). - -route(State, From, To, Packet) -> - #jid{user = User, resource = Resource} = To, - ServerHost = State#state.serverhost, - if (User /= <<"">>) or (Resource /= <<"">>) -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err); - true -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, - sub_el = SubEl} -> - case Type of - set -> - XDataEl = find_xdata_el(SubEl), - case XDataEl of - false -> - Txt = <<"Data form not found">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_BAD_REQUEST(Lang, Txt)), - ejabberd_router:route(To, From, Err); - _ -> - XData = jlib:parse_xdata_submit(XDataEl), - case XData of - invalid -> - Txt = <<"Incorrect data form">>, - Err = jlib:make_error_reply( - Packet, ?ERRT_BAD_REQUEST(Lang, Txt)), - ejabberd_router:route(To, From, Err); - _ -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_SEARCH}], - children = - [#xmlel{name = - <<"x">>, - attrs = - [{<<"xmlns">>, - ?NS_XDATA}, - {<<"type">>, - <<"result">>}], - children - = - search_result(Lang, - To, - State, - XData)}]}]}, - ejabberd_router:route(To, From, - jlib:iq_to_xml(ResIQ)) - end - end; - get -> - SearchFields = State#state.search_fields, - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_SEARCH}], - children = - ?FORM(To, SearchFields)}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)), - ejabberd_router:route(To, From, Err); - get -> - Info = ejabberd_hooks:run_fold(disco_info, ServerHost, - [], - [ServerHost, ?MODULE, - <<"">>, <<"">>]), - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_DISCO_INFO}], - children = - [#xmlel{name = - <<"identity">>, - attrs = - [{<<"category">>, - <<"directory">>}, - {<<"type">>, - <<"user">>}, - {<<"name">>, - translate:translate(Lang, - <<"vCard User Search">>)}], - children = []}, - #xmlel{name = - <<"feature">>, - attrs = - [{<<"var">>, - ?NS_SEARCH}], - children = []}, - #xmlel{name = - <<"feature">>, - attrs = - [{<<"var">>, - ?NS_VCARD}], - children = []}] - ++ Info}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, lang = Lang, xmlns = ?NS_DISCO_ITEMS} -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)), - ejabberd_router:route(To, From, Err); - get -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = - [{<<"xmlns">>, - ?NS_DISCO_ITEMS}], - children = []}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) - end; - #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> - ResIQ = IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = iq_get_vcard(Lang)}]}, - ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); - _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err) - end - end. - -iq_get_vcard(Lang) -> - [#xmlel{name = <<"FN">>, attrs = [], - children = [{xmlcdata, <<"ejabberd/mod_vcard">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"ejabberd vCard module">>))/binary, - "\nCopyright (c) 2003-2016 ProcessOne">>}]}]. - --define(LFIELD(Label, Var), - #xmlel{name = <<"field">>, - attrs = - [{<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = []}). - -search_result(Lang, JID, State, Data) -> - SearchReported = State#state.search_reported, - Header = [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"Search Results for ">>))/binary, - (jid:to_string(JID))/binary>>}]}, - #xmlel{name = <<"reported">>, attrs = [], - children = - [?TLFIELD(<<"text-single">>, <<"Jabber ID">>, - <<"jid">>)] - ++ - lists:map(fun ({Name, Value}) -> - ?TLFIELD(<<"text-single">>, Name, - Value) - end, - SearchReported)}], - case search(State, Data) of - error -> Header; - Result -> Header ++ Result - end. - --define(FIELD(Var, Val), - #xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). - -search(State, Data) -> - Base = State#state.base, - SearchFilter = State#state.search_filter, - Eldap_ID = State#state.eldap_id, - UIDs = State#state.uids, - Limit = State#state.matches, - ReportedAttrs = State#state.search_reported_attrs, - Filter = eldap:'and'([SearchFilter, - eldap_utils:make_filter(Data, UIDs)]), - case eldap_pool:search(Eldap_ID, - [{base, Base}, {filter, Filter}, {limit, Limit}, - {deref_aliases, State#state.deref_aliases}, - {attributes, ReportedAttrs}]) - of - #eldap_search_result{entries = E} -> - search_items(E, State); - _ -> error - end. - -search_items(Entries, State) -> - LServer = State#state.serverhost, - SearchReported = State#state.search_reported, - VCardMap = State#state.vcard_map, - UIDs = State#state.uids, - Attributes = lists:map(fun (E) -> - #eldap_entry{attributes = Attrs} = E, Attrs - end, - Entries), - lists:flatmap(fun (Attrs) -> - case eldap_utils:find_ldap_attrs(UIDs, Attrs) of - {U, UIDAttrFormat} -> - case eldap_utils:get_user_part(U, UIDAttrFormat) - of - {ok, Username} -> - case - ejabberd_auth:is_user_exists(Username, - LServer) - of - true -> - RFields = lists:map(fun ({_, - VCardName}) -> - {VCardName, - map_vcard_attr(VCardName, - Attrs, - VCardMap, - {Username, - ?MYNAME})} - end, - SearchReported), - Result = [?FIELD(<<"jid">>, - <>)] - ++ - [?FIELD(Name, Value) - || {Name, Value} - <- RFields], - [#xmlel{name = <<"item">>, - attrs = [], - children = Result}]; - _ -> [] - end; - _ -> [] - end; - <<"">> -> [] - end - end, - Attributes). - -remove_user(_User) -> true. - -%%%----------------------- -%%% Auxiliary functions. -%%%----------------------- - map_vcard_attr(VCardName, Attributes, Pattern, UD) -> Res = lists:filter(fun ({Name, _, _}) -> eldap_utils:case_insensitive_match(Name, @@ -725,19 +340,54 @@ process_pattern(Str, {User, Domain}, AttrValues) -> [{<<"%u">>, User}, {<<"%d">>, Domain}] ++ [{<<"%s">>, V, 1} || V <- AttrValues]). -find_xdata_el(#xmlel{children = SubEls}) -> - find_xdata_el1(SubEls). - -find_xdata_el1([]) -> false; -find_xdata_el1([#xmlel{name = Name, attrs = Attrs, - children = SubEls} - | Els]) -> - case fxml:get_attr_s(<<"xmlns">>, Attrs) of - ?NS_XDATA -> - #xmlel{name = Name, attrs = Attrs, children = SubEls}; - _ -> find_xdata_el1(Els) - end; -find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). +default_vcard_map() -> + [{<<"NICKNAME">>, <<"%u">>, []}, + {<<"FN">>, <<"%s">>, [<<"displayName">>]}, + {<<"FAMILY">>, <<"%s">>, [<<"sn">>]}, + {<<"GIVEN">>, <<"%s">>, [<<"givenName">>]}, + {<<"MIDDLE">>, <<"%s">>, [<<"initials">>]}, + {<<"ORGNAME">>, <<"%s">>, [<<"o">>]}, + {<<"ORGUNIT">>, <<"%s">>, [<<"ou">>]}, + {<<"CTRY">>, <<"%s">>, [<<"c">>]}, + {<<"LOCALITY">>, <<"%s">>, [<<"l">>]}, + {<<"STREET">>, <<"%s">>, [<<"street">>]}, + {<<"REGION">>, <<"%s">>, [<<"st">>]}, + {<<"PCODE">>, <<"%s">>, [<<"postalCode">>]}, + {<<"TITLE">>, <<"%s">>, [<<"title">>]}, + {<<"URL">>, <<"%s">>, [<<"labeleduri">>]}, + {<<"DESC">>, <<"%s">>, [<<"description">>]}, + {<<"TEL">>, <<"%s">>, [<<"telephoneNumber">>]}, + {<<"EMAIL">>, <<"%s">>, [<<"mail">>]}, + {<<"BDAY">>, <<"%s">>, [<<"birthDay">>]}, + {<<"ROLE">>, <<"%s">>, [<<"employeeType">>]}, + {<<"PHOTO">>, <<"%s">>, [<<"jpegPhoto">>]}]. + +default_search_fields() -> + [{<<"User">>, <<"%u">>}, + {<<"Full Name">>, <<"displayName">>}, + {<<"Given Name">>, <<"givenName">>}, + {<<"Middle Name">>, <<"initials">>}, + {<<"Family Name">>, <<"sn">>}, + {<<"Nickname">>, <<"%u">>}, + {<<"Birthday">>, <<"birthDay">>}, + {<<"Country">>, <<"c">>}, + {<<"City">>, <<"l">>}, + {<<"Email">>, <<"mail">>}, + {<<"Organization Name">>, <<"o">>}, + {<<"Organization Unit">>, <<"ou">>}]. + +default_search_reported() -> + [{<<"Full Name">>, <<"FN">>}, + {<<"Given Name">>, <<"FIRST">>}, + {<<"Middle Name">>, <<"MIDDLE">>}, + {<<"Family Name">>, <<"LAST">>}, + {<<"Nickname">>, <<"NICK">>}, + {<<"Birthday">>, <<"BDAY">>}, + {<<"Country">>, <<"CTRY">>}, + {<<"City">>, <<"LOCALITY">>}, + {<<"Email">>, <<"EMAIL">>}, + {<<"Organization Name">>, <<"ORGNAME">>}, + {<<"Organization Unit">>, <<"ORGUNIT">>}]. parse_options(Host, Opts) -> MyHost = gen_mod:get_opt_host(Host, Opts, @@ -784,19 +434,19 @@ parse_options(Host, Opts) -> [iolist_to_binary(E) || E <- L]} end, Ls) - end, ?VCARD_MAP), + end, default_vcard_map()), SearchFields = gen_mod:get_opt(ldap_search_fields, Opts, fun(Ls) -> [{iolist_to_binary(S), iolist_to_binary(P)} || {S, P} <- Ls] - end, ?SEARCH_FIELDS), + end, default_search_fields()), SearchReported = gen_mod:get_opt(ldap_search_reported, Opts, fun(Ls) -> [{iolist_to_binary(S), iolist_to_binary(P)} || {S, P} <- Ls] - end, ?SEARCH_REPORTED), + end, default_search_reported()), UIDAttrs = [UAttr || {UAttr, _} <- UIDs], VCardMapAttrs = lists:usort(lists:append([A || {_, _, A} <- VCardMap]) @@ -834,27 +484,11 @@ parse_options(Host, Opts) -> search_reported_attrs = SearchReportedAttrs, matches = Matches}. -transform_module_options(Opts) -> - lists:map( - fun({ldap_vcard_map, Map}) -> - NewMap = lists:map( - fun({Field, Pattern, Attrs}) -> - {Field, [{Pattern, Attrs}]}; - (Opt) -> - Opt - end, Map), - {ldap_vcard_map, NewMap}; - (Opt) -> - Opt - end, Opts). - check_filter(F) -> NewF = iolist_to_binary(F), {ok, _} = eldap_filter:parse(NewF), NewF. -mod_opt_type(host) -> fun iolist_to_binary/1; -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(ldap_filter) -> fun check_filter/1; mod_opt_type(ldap_search_fields) -> fun (Ls) -> @@ -882,12 +516,6 @@ mod_opt_type(ldap_vcard_map) -> end, Ls) end; -mod_opt_type(matches) -> - fun (infinity) -> 0; - (I) when is_integer(I), I > 0 -> I - end; -mod_opt_type(search) -> - fun (B) when is_boolean(B) -> B end; mod_opt_type(deref_aliases) -> fun (never) -> never; (searching) -> searching; @@ -926,9 +554,9 @@ mod_opt_type(ldap_tls_verify) -> (false) -> false end; mod_opt_type(_) -> - [host, iqdisc, ldap_filter, ldap_search_fields, + [ldap_filter, ldap_search_fields, ldap_search_reported, ldap_uids, ldap_vcard_map, - matches, search, deref_aliases, ldap_backups, ldap_base, + deref_aliases, ldap_backups, ldap_base, ldap_deref_aliases, ldap_encrypt, ldap_password, ldap_port, ldap_rootdn, ldap_servers, ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index 67abed09b..3b64c29ef 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -11,7 +11,8 @@ -behaviour(mod_vcard). %% API --export([init/2, import/2, get_vcard/2, set_vcard/4, search/4, remove_user/2]). +-export([init/2, stop/1, import/2, get_vcard/2, set_vcard/4, search/4, + search_fields/1, search_reported/1, remove_user/2]). -include("ejabberd.hrl"). -include("xmpp.hrl"). @@ -43,6 +44,9 @@ init(_Host, _Opts) -> mnesia:add_table_index(vcard_search, lorgname), mnesia:add_table_index(vcard_search, lorgunit). +stop(_Host) -> + ok. + get_vcard(LUser, LServer) -> US = {LUser, LServer}, F = fun () -> mnesia:read({vcard, US}) end, @@ -71,15 +75,44 @@ search(LServer, Data, AllowReturnAll, MaxMatch) -> {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), []; Rs -> + Fields = lists:map(fun record_to_item/1, Rs), case MaxMatch of infinity -> - Rs; + Fields; Val -> - lists:sublist(Rs, Val) + lists:sublist(Fields, Val) end end end. +search_fields(_LServer) -> + [{<<"User">>, <<"user">>}, + {<<"Full Name">>, <<"fn">>}, + {<<"Name">>, <<"first">>}, + {<<"Middle Name">>, <<"middle">>}, + {<<"Family Name">>, <<"last">>}, + {<<"Nickname">>, <<"nick">>}, + {<<"Birthday">>, <<"bday">>}, + {<<"Country">>, <<"ctry">>}, + {<<"City">>, <<"locality">>}, + {<<"Email">>, <<"email">>}, + {<<"Organization Name">>, <<"orgname">>}, + {<<"Organization Unit">>, <<"orgunit">>}]. + +search_reported(_LServer) -> + [{<<"Jabber ID">>, <<"jid">>}, + {<<"Full Name">>, <<"fn">>}, + {<<"Name">>, <<"first">>}, + {<<"Middle Name">>, <<"middle">>}, + {<<"Family Name">>, <<"last">>}, + {<<"Nickname">>, <<"nick">>}, + {<<"Birthday">>, <<"bday">>}, + {<<"Country">>, <<"ctry">>}, + {<<"City">>, <<"locality">>}, + {<<"Email">>, <<"email">>}, + {<<"Organization Name">>, <<"orgname">>}, + {<<"Organization Unit">>, <<"orgunit">>}]. + remove_user(LUser, LServer) -> US = {LUser, LServer}, F = fun () -> @@ -211,3 +244,19 @@ parts_to_string(Parts) -> str:strip(list_to_binary( lists:map(fun (S) -> <> end, Parts)), right, $.). + +-spec record_to_item(#vcard_search{}) -> [{binary(), binary()}]. +record_to_item(R) -> + {User, Server} = R#vcard_search.user, + [{<<"jid">>, <>}, + {<<"fn">>, (R#vcard_search.fn)}, + {<<"last">>, (R#vcard_search.family)}, + {<<"first">>, (R#vcard_search.given)}, + {<<"middle">>, (R#vcard_search.middle)}, + {<<"nick">>, (R#vcard_search.nickname)}, + {<<"bday">>, (R#vcard_search.bday)}, + {<<"ctry">>, (R#vcard_search.ctry)}, + {<<"locality">>, (R#vcard_search.locality)}, + {<<"email">>, (R#vcard_search.email)}, + {<<"orgname">>, (R#vcard_search.orgname)}, + {<<"orgunit">>, (R#vcard_search.orgunit)}]. diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl index 397008a79..23f05f17d 100644 --- a/src/mod_vcard_riak.erl +++ b/src/mod_vcard_riak.erl @@ -12,7 +12,7 @@ %% API -export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, - import/2]). + search_fields/1, search_reported/1, import/2, stop/1]). -include("xmpp.hrl"). -include("mod_vcard.hrl"). @@ -23,6 +23,9 @@ init(_Host, _Opts) -> ok. +stop(_Host) -> + ok. + get_vcard(LUser, LServer) -> case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of {ok, R} -> @@ -89,6 +92,12 @@ set_vcard(LUser, LServer, VCARD, search(_LServer, _Data, _AllowReturnAll, _MaxMatch) -> []. +search_fields(_LServer) -> + []. + +search_reported(_LServer) -> + []. + remove_user(LUser, LServer) -> {atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}. diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index f448d0776..f8ac6be97 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -13,8 +13,8 @@ -behaviour(mod_vcard). %% API --export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, - import/1, import/2, export/1]). +-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2, + search_fields/1, search_reported/1, import/1, import/2, export/1]). -include("xmpp.hrl"). -include("mod_vcard.hrl"). @@ -27,6 +27,9 @@ init(_Host, _Opts) -> ok. +stop(_Host) -> + ok. + get_vcard(LUser, LServer) -> case catch sql_queries:get_vcard(LServer, LUser) of {selected, [{SVCARD}]} -> @@ -93,12 +96,40 @@ search(LServer, Data, AllowReturnAll, MaxMatch) -> <<"middle">>, <<"nickname">>, <<"bday">>, <<"ctry">>, <<"locality">>, <<"email">>, <<"orgname">>, <<"orgunit">>], Rs} when is_list(Rs) -> - Rs; + [row_to_item(LServer, R) || R <- Rs]; Error -> ?ERROR_MSG("~p", [Error]), [] end end. +search_fields(_LServer) -> + [{<<"User">>, <<"user">>}, + {<<"Full Name">>, <<"fn">>}, + {<<"Name">>, <<"first">>}, + {<<"Middle Name">>, <<"middle">>}, + {<<"Family Name">>, <<"last">>}, + {<<"Nickname">>, <<"nick">>}, + {<<"Birthday">>, <<"bday">>}, + {<<"Country">>, <<"ctry">>}, + {<<"City">>, <<"locality">>}, + {<<"Email">>, <<"email">>}, + {<<"Organization Name">>, <<"orgname">>}, + {<<"Organization Unit">>, <<"orgunit">>}]. + +search_reported(_LServer) -> + [{<<"Jabber ID">>, <<"jid">>}, + {<<"Full Name">>, <<"fn">>}, + {<<"Name">>, <<"first">>}, + {<<"Middle Name">>, <<"middle">>}, + {<<"Family Name">>, <<"last">>}, + {<<"Nickname">>, <<"nick">>}, + {<<"Birthday">>, <<"bday">>}, + {<<"Country">>, <<"ctry">>}, + {<<"City">>, <<"locality">>}, + {<<"Email">>, <<"email">>}, + {<<"Organization Name">>, <<"orgname">>}, + {<<"Organization Unit">>, <<"orgunit">>}]. + remove_user(LUser, LServer) -> ejabberd_sql:sql_transaction( LServer, @@ -240,3 +271,18 @@ make_val(Match, Field, Val) -> <<"">> -> Condition; _ -> [Match, <<" and ">>, Condition] end. + +row_to_item(LServer, [Username, FN, Family, Given, Middle, Nickname, BDay, + CTRY, Locality, EMail, OrgName, OrgUnit]) -> + [{<<"jid">>, <>}, + {<<"fn">>, FN}, + {<<"last">>, Family}, + {<<"first">>, Given}, + {<<"middle">>, Middle}, + {<<"nick">>, Nickname}, + {<<"bday">>, BDay}, + {<<"ctry">>, CTRY}, + {<<"locality">>, Locality}, + {<<"email">>, EMail}, + {<<"orgname">>, OrgName}, + {<<"orgunit">>, OrgUnit}]. -- cgit v1.2.3 From a093e9d441b95401a99fd36c1ce506148cf6f631 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 30 Jul 2016 08:37:34 +0300 Subject: Rewrite mod_shared_roster to use XML generator --- src/mod_shared_roster.erl | 130 +++++++++++------------------------------ src/mod_shared_roster_ldap.erl | 2 +- 2 files changed, 36 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index b472e1aab..079a2f44c 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -29,7 +29,7 @@ -behaviour(gen_mod). --export([start/2, stop/1, item_to_xml/1, export/1, +-export([start/2, stop/1, export/1, import/1, webadmin_menu/3, webadmin_page/3, get_user_roster/2, get_subscription_lists/3, get_jid_info/4, import/3, process_item/2, @@ -44,7 +44,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_roster.hrl"). @@ -172,53 +172,33 @@ get_user_roster(Items, US) -> end end, SRUsers, Items), - ModVcard = get_vcard_module(S), SRItems = [#roster{usj = {U, S, {U1, S1, <<"">>}}, us = US, jid = {U1, S1, <<"">>}, - name = get_rosteritem_name(ModVcard, U1, S1), + name = get_rosteritem_name(U1, S1), subscription = both, ask = none, groups = GroupNames} || {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. -get_vcard_module(Server) -> - Modules = gen_mod:loaded_modules(Server), - [M - || M <- Modules, - (M == mod_vcard) or (M == mod_vcard_ldap)]. - -get_rosteritem_name([], _, _) -> <<"">>; -get_rosteritem_name([ModVcard], U, S) -> - From = jid:make(<<"">>, S, jlib:atom_to_binary(?MODULE)), - To = jid:make(U, S, <<"">>), - case lists:member(To#jid.lserver, ?MYHOSTS) of +get_rosteritem_name(U, S) -> + case gen_mod:is_loaded(S, mod_vcard) of true -> - IQ = {iq, <<"">>, get, <<"vcard-temp">>, <<"">>, - #xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, <<"vcard-temp">>}], - children = []}}, - IQ_Vcard = ModVcard:process_sm_iq(From, To, IQ), - case catch get_rosteritem_name_vcard(IQ_Vcard#iq.sub_el) of - {'EXIT', Err} -> - ?ERROR_MSG("Error found when trying to get the " - "vCard of ~s@~s in ~p:~n ~p", - [U, S, ModVcard, Err]), - <<"">>; - NickName -> - NickName - end; + SubEls = mod_vcard:get_vcard(U, S), + get_rosteritem_name_vcard(SubEls); false -> <<"">> end. -get_rosteritem_name_vcard([]) -> <<"">>; -get_rosteritem_name_vcard([Vcard]) -> +-spec get_rosteritem_name_vcard([xmlel()]) -> binary(). +get_rosteritem_name_vcard([Vcard|_]) -> case fxml:get_path_s(Vcard, [{elem, <<"NICKNAME">>}, cdata]) of <<"">> -> fxml:get_path_s(Vcard, [{elem, <<"FN">>}, cdata]); Nickname -> Nickname - end. + end; +get_rosteritem_name_vcard(_) -> + <<"">>. %% This function rewrites the roster entries when moving or renaming %% them in the user contact list. @@ -305,16 +285,12 @@ set_new_rosteritems(UserFrom, ServerFrom, UserTo, RIFrom. set_item(User, Server, Resource, Item) -> - ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, - id = <<"push", (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER}], - children = [mod_roster:item_to_xml(Item)]}]}, - ejabberd_router:route(jid:make(User, Server, - Resource), - jid:make(<<"">>, Server, <<"">>), - jlib:iq_to_xml(ResIQ)). + ResIQ = #iq{type = set, id = <<"push", (randoms:get_string())/binary>>, + sub_els = [#roster_query{ + items = [mod_roster:encode_item(Item)]}]}, + ejabberd_router:route(jid:make(User, Server, Resource), + jid:make(Server), + ResIQ). get_subscription_lists({F, T}, User, Server) -> LUser = jid:nodeprep(User), @@ -574,13 +550,13 @@ add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), MoreGroupOpts = case LUser of <<"@all@">> -> [{all_users, true}]; <<"@online@">> -> [{online_users, true}]; _ -> [] end, - (?MODULE):set_group_opts(Host, Group, + mod_shared_roster:set_group_opts(Host, Group, GroupOpts ++ MoreGroupOpts); nomatch -> DisplayedToGroups = displayed_to_groups(Group, Host), @@ -612,7 +588,7 @@ remove_user_from_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), NewGroupOpts = case LUser of <<"@all@">> -> lists:filter(fun (X) -> X /= {all_users, true} @@ -623,7 +599,7 @@ remove_user_from_group(Host, US, Group) -> end, GroupOpts) end, - (?MODULE):set_group_opts(Host, Group, NewGroupOpts); + mod_shared_roster:set_group_opts(Host, Group, NewGroupOpts); nomatch -> Mod = gen_mod:db_mod(Host, ?MODULE), Result = Mod:remove_user_from_group(Host, US, Group), @@ -730,13 +706,9 @@ displayed_to_groups(GroupName, LServer) -> [Name || {Name, _} <- Gs]. push_item(User, Server, Item) -> - Stanza = jlib:iq_to_xml(#iq{type = set, - xmlns = ?NS_ROSTER, - id = <<"push", (randoms:get_string())/binary>>, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_ROSTER}], - children = [item_to_xml(Item)]}]}), + Stanza = #iq{type = set, id = <<"push", (randoms:get_string())/binary>>, + sub_els = [#roster_query{ + items = [mod_roster:encode_item(Item)]}]}, lists:foreach(fun (Resource) -> JID = jid:make(User, Server, Resource), ejabberd_router:route(jid:remove_resource(JID), JID, Stanza) @@ -752,38 +724,6 @@ push_roster_item(User, Server, ContactU, ContactS, groups = [GroupName]}, push_item(User, Server, Item). -item_to_xml(Item) -> - Attrs1 = [{<<"jid">>, - jid:to_string(Item#roster.jid)}], - Attrs2 = case Item#roster.name of - <<"">> -> Attrs1; - Name -> [{<<"name">>, Name} | Attrs1] - end, - Attrs3 = case Item#roster.subscription of - none -> [{<<"subscription">>, <<"none">>} | Attrs2]; - from -> [{<<"subscription">>, <<"from">>} | Attrs2]; - to -> [{<<"subscription">>, <<"to">>} | Attrs2]; - both -> [{<<"subscription">>, <<"both">>} | Attrs2]; - remove -> [{<<"subscription">>, <<"remove">>} | Attrs2] - end, - Attrs4 = case ask_to_pending(Item#roster.ask) of - out -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - both -> [{<<"ask">>, <<"subscribe">>} | Attrs3]; - _ -> Attrs3 - end, - SubEls1 = lists:map(fun (G) -> - #xmlel{name = <<"group">>, attrs = [], - children = [{xmlcdata, G}]} - end, - Item#roster.groups), - SubEls = SubEls1 ++ Item#roster.xs, - #xmlel{name = <<"item">>, attrs = Attrs4, - children = SubEls}. - -ask_to_pending(subscribe) -> out; -ask_to_pending(unsubscribe) -> none; -ask_to_pending(Ask) -> Ask. - user_available(New) -> LUser = New#jid.luser, LServer = New#jid.lserver, @@ -850,7 +790,7 @@ webadmin_page(Acc, _, _) -> Acc. list_shared_roster_groups(Host, Query, Lang) -> Res = list_sr_groups_parse_query(Host, Query), - SRGroups = (?MODULE):list_groups(Host), + SRGroups = mod_shared_roster:list_groups(Host), FGroups = (?XAE(<<"table">>, [], [?XE(<<"tbody">>, (lists:map(fun (Group) -> @@ -901,15 +841,15 @@ list_sr_groups_parse_query(Host, Query) -> list_sr_groups_parse_addnew(Host, Query) -> case lists:keysearch(<<"namenew">>, 1, Query) of {value, {_, Group}} when Group /= <<"">> -> - (?MODULE):create_group(Host, Group), ok; + mod_shared_roster:create_group(Host, Group), ok; _ -> error end. list_sr_groups_parse_delete(Host, Query) -> - SRGroups = (?MODULE):list_groups(Host), + SRGroups = mod_shared_roster:list_groups(Host), lists:foreach(fun (Group) -> case lists:member({<<"selected">>, Group}, Query) of - true -> (?MODULE):delete_group(Host, Group); + true -> mod_shared_roster:delete_group(Host, Group); _ -> ok end end, @@ -919,14 +859,14 @@ list_sr_groups_parse_delete(Host, Query) -> shared_roster_group(Host, Group, Query, Lang) -> Res = shared_roster_group_parse_query(Host, Group, Query), - GroupOpts = (?MODULE):get_group_opts(Host, Group), + GroupOpts = mod_shared_roster:get_group_opts(Host, Group), Name = get_opt(GroupOpts, name, <<"">>), Description = get_opt(GroupOpts, description, <<"">>), AllUsers = get_opt(GroupOpts, all_users, false), OnlineUsers = get_opt(GroupOpts, online_users, false), DisplayedGroups = get_opt(GroupOpts, displayed_groups, []), - Members = (?MODULE):get_group_explicit_users(Host, + Members = mod_shared_roster:get_group_explicit_users(Host, Group), FMembers = iolist_to_binary( [if AllUsers -> <<"@all@\n">>; @@ -1003,7 +943,7 @@ shared_roster_group_parse_query(Host, Group, Query) -> DispGroupsOpt = if DispGroups == [] -> []; true -> [{displayed_groups, DispGroups}] end, - OldMembers = (?MODULE):get_group_explicit_users(Host, + OldMembers = mod_shared_roster:get_group_explicit_users(Host, Group), SJIDs = str:tokens(SMembers, <<", \r\n">>), NewMembers = lists:foldl(fun (_SJID, error) -> error; @@ -1040,7 +980,7 @@ shared_roster_group_parse_query(Host, Group, Query) -> RemovedDisplayedGroups = CurrentDisplayedGroups -- DispGroups, displayed_groups_update(OldMembers, RemovedDisplayedGroups, remove), displayed_groups_update(OldMembers, AddedDisplayedGroups, both), - (?MODULE):set_group_opts(Host, Group, + mod_shared_roster:set_group_opts(Host, Group, NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ @@ -1050,13 +990,13 @@ shared_roster_group_parse_query(Host, Group, Query) -> AddedMembers = NewMembers -- OldMembers, RemovedMembers = OldMembers -- NewMembers, lists:foreach(fun (US) -> - (?MODULE):remove_user_from_group(Host, + mod_shared_roster:remove_user_from_group(Host, US, Group) end, RemovedMembers), lists:foreach(fun (US) -> - (?MODULE):add_user_to_group(Host, US, + mod_shared_roster:add_user_to_group(Host, US, Group) end, AddedMembers), diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 22f50d302..06dd0e3a9 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -45,7 +45,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_roster.hrl"). -include("eldap.hrl"). -- cgit v1.2.3 From f19d2fdcffb3474aeea1050746ac30a778607954 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 30 Jul 2016 08:39:30 +0300 Subject: Rewrite mod_shared_roster backends module to use XML generator --- src/mod_shared_roster_mnesia.erl | 1 - src/mod_shared_roster_riak.erl | 1 - src/mod_shared_roster_sql.erl | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl index ca2e55e2f..eb7c3c37d 100644 --- a/src/mod_shared_roster_mnesia.erl +++ b/src/mod_shared_roster_mnesia.erl @@ -17,7 +17,6 @@ get_user_displayed_groups/3, is_user_in_group/3, add_user_to_group/3, remove_user_from_group/3, import/2]). --include("jlib.hrl"). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). -include("logger.hrl"). diff --git a/src/mod_shared_roster_riak.erl b/src/mod_shared_roster_riak.erl index 0df35e37d..49d6edfcd 100644 --- a/src/mod_shared_roster_riak.erl +++ b/src/mod_shared_roster_riak.erl @@ -17,7 +17,6 @@ get_user_displayed_groups/3, is_user_in_group/3, add_user_to_group/3, remove_user_from_group/3, import/2]). --include("jlib.hrl"). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl index 2b186fd0b..5cffffeb3 100644 --- a/src/mod_shared_roster_sql.erl +++ b/src/mod_shared_roster_sql.erl @@ -20,7 +20,7 @@ add_user_to_group/3, remove_user_from_group/3, import/1, import/2, export/1]). --include("jlib.hrl"). +-include("jid.hrl"). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). -include("ejabberd_sql_pt.hrl"). -- cgit v1.2.3 From d2d3b961eb5738c03216ef436a8575da80a5a2e4 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 30 Jul 2016 13:30:29 +0300 Subject: Rewrite mod_sic to use XML generator --- src/mod_sic.erl | 83 +++++++++++------------- src/xmpp_codec.erl | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 219 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/mod_sic.erl b/src/mod_sic.erl index 49b65a0ee..4bb4eb9eb 100644 --- a/src/mod_sic.erl +++ b/src/mod_sic.erl @@ -31,73 +31,66 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, - process_sm_iq/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, process_local_iq/1, + process_sm_iq/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). - --include("jlib.hrl"). - --define(NS_SIC, <<"urn:xmpp:sic:0">>). +-include("xmpp.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_SIC, ?MODULE, process_local_iq, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_SIC, ?MODULE, process_sm_iq, IQDisc). + gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0, + ?MODULE, process_local_iq, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0, + ?MODULE, process_sm_iq, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_1, + ?MODULE, process_local_iq, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_1, + ?MODULE, process_sm_iq, IQDisc). stop(Host) -> - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, - ?NS_SIC), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, - ?NS_SIC). + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SIC_0), + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_0), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SIC_1), + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1). depends(_Host, _Opts) -> []. -process_local_iq(#jid{user = User, server = Server, - resource = Resource}, - _To, #iq{type = get, sub_el = _SubEl} = IQ) -> +process_local_iq(#iq{from = #jid{user = User, server = Server, + resource = Resource}, + type = get} = IQ) -> get_ip({User, Server, Resource}, IQ); -process_local_iq(_From, _To, - #iq{type = set, sub_el = SubEl, lang = Lang} = IQ) -> +process_local_iq(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}. + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). -process_sm_iq(#jid{user = User, server = Server, - resource = Resource}, - #jid{user = User, server = Server}, - #iq{type = get, sub_el = _SubEl} = IQ) -> +process_sm_iq(#iq{from = #jid{user = User, server = Server, + resource = Resource}, + to = #jid{user = User, server = Server}, + type = get} = IQ) -> get_ip({User, Server, Resource}, IQ); -process_sm_iq(_From, _To, - #iq{type = get, sub_el = SubEl, lang = Lang} = IQ) -> +process_sm_iq(#iq{type = get, lang = Lang} = IQ) -> Txt = <<"Query to another users is forbidden">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}; -process_sm_iq(_From, _To, - #iq{type = set, sub_el = SubEl, lang = Lang} = IQ) -> + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)); +process_sm_iq(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}. + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). get_ip({User, Server, Resource}, - #iq{lang = Lang, - sub_el = - #xmlel{name = Name, attrs = Attrs} = SubEl} = - IQ) -> + #iq{lang = Lang, sub_els = [#sic{xmlns = NS}]} = IQ) -> case ejabberd_sm:get_user_ip(User, Server, Resource) of - {IP, _} when is_tuple(IP) -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = Name, attrs = Attrs, - children = - [{xmlcdata, - iolist_to_binary(jlib:ip_to_list(IP))}]}]}; - _ -> - Txt = <<"User session not found">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]} + {IP, Port} when is_tuple(IP) -> + Result = case NS of + ?NS_SIC_0 -> #sic{ip = IP, xmlns = NS}; + ?NS_SIC_1 -> #sic{ip = IP, port = Port, xmlns = NS} + end, + xmpp:make_iq_result(IQ, Result); + _ -> + Txt = <<"User session not found">>, + xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)) end. mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 113be860b..11bd741f4 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,16 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"address">>, <<"urn:xmpp:sic:0">>} -> + decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); + {<<"address">>, <<"urn:xmpp:sic:1">>} -> + decode_sic(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); + {<<"port">>, <<"urn:xmpp:sic:1">>} -> + decode_sip_port(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); + {<<"ip">>, <<"urn:xmpp:sic:0">>} -> + decode_sic_ip(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); + {<<"ip">>, <<"urn:xmpp:sic:1">>} -> + decode_sic_ip(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); {<<"x">>, <<"jabber:x:oob">>} -> decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); {<<"desc">>, <<"jabber:x:oob">>} -> @@ -1309,6 +1319,11 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"address">>, <<"urn:xmpp:sic:0">>} -> true; + {<<"address">>, <<"urn:xmpp:sic:1">>} -> true; + {<<"port">>, <<"urn:xmpp:sic:1">>} -> true; + {<<"ip">>, <<"urn:xmpp:sic:0">>} -> true; + {<<"ip">>, <<"urn:xmpp:sic:1">>} -> true; {<<"x">>, <<"jabber:x:oob">>} -> true; {<<"desc">>, <<"jabber:x:oob">>} -> true; {<<"url">>, <<"jabber:x:oob">>} -> true; @@ -2609,7 +2624,9 @@ encode({media, _, _, _} = Media) -> encode_media(Media, [{<<"xmlns">>, <<"urn:xmpp:media-element">>}]); encode({oob_x, _, _, _} = X) -> - encode_oob_x(X, [{<<"xmlns">>, <<"jabber:x:oob">>}]). + encode_oob_x(X, [{<<"xmlns">>, <<"jabber:x:oob">>}]); +encode({sic, _, _, _} = Address) -> + encode_sic(Address, []). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2802,7 +2819,8 @@ get_name({bob_data, _, _, _, _}) -> <<"data">>; get_name({xcaptcha, _}) -> <<"captcha">>; get_name({media_uri, _, _}) -> <<"uri">>; get_name({media, _, _, _}) -> <<"media">>; -get_name({oob_x, _, _, _}) -> <<"x">>. +get_name({oob_x, _, _, _}) -> <<"x">>; +get_name({sic, _, _, _}) -> <<"address">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -3070,7 +3088,8 @@ get_ns({media_uri, _, _}) -> <<"urn:xmpp:media-element">>; get_ns({media, _, _, _}) -> <<"urn:xmpp:media-element">>; -get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>. +get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>; +get_ns({sic, _, _, Xmlns}) -> Xmlns. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3319,8 +3338,18 @@ pp(xcaptcha, 1) -> [xdata]; pp(media_uri, 2) -> [type, uri]; pp(media, 3) -> [height, width, uri]; pp(oob_x, 3) -> [url, desc, sid]; +pp(sic, 3) -> [ip, port, xmlns]; pp(_, _) -> no. +enc_ip({0, 0, 0, 0, 0, 65535, A, B}) -> + enc_ip({(A bsr 8) band 255, A band 255, + (B bsr 8) band 255, B band 255}); +enc_ip(Addr) -> list_to_binary(inet_parse:ntoa(Addr)). + +dec_ip(S) -> + {ok, Addr} = inet_parse:address(binary_to_list(S)), + Addr. + join([], _Sep) -> <<>>; join([H | T], Sep) -> <> || X <- T >>/binary>>. @@ -3365,6 +3394,155 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_sic(__TopXMLNS, __IgnoreEls, + {xmlel, <<"address">>, _attrs, _els}) -> + {Ip, Port} = decode_sic_els(__TopXMLNS, __IgnoreEls, + _els, undefined, undefined), + Xmlns = decode_sic_attrs(__TopXMLNS, _attrs, undefined), + {sic, Ip, Port, Xmlns}. + +decode_sic_els(__TopXMLNS, __IgnoreEls, [], Ip, Port) -> + {Ip, Port}; +decode_sic_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"ip">>, _attrs, _} = _el | _els], Ip, + Port) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == <<"urn:xmpp:sic:1">>; + __TopXMLNS == <<"urn:xmpp:sic:0">> -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, + decode_sic_ip(__TopXMLNS, __IgnoreEls, _el), Port); + <<"urn:xmpp:sic:0">> -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, + decode_sic_ip(<<"urn:xmpp:sic:0">>, __IgnoreEls, _el), + Port); + <<"urn:xmpp:sic:1">> -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, + decode_sic_ip(<<"urn:xmpp:sic:1">>, __IgnoreEls, _el), + Port); + _ -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port) + end; +decode_sic_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"port">>, _attrs, _} = _el | _els], Ip, + Port) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> when __TopXMLNS == <<"urn:xmpp:sic:1">> -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, + decode_sip_port(__TopXMLNS, __IgnoreEls, _el)); + <<"urn:xmpp:sic:1">> -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, + decode_sip_port(<<"urn:xmpp:sic:1">>, __IgnoreEls, + _el)); + _ -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port) + end; +decode_sic_els(__TopXMLNS, __IgnoreEls, [_ | _els], Ip, + Port) -> + decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port). + +decode_sic_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_sic_attrs(__TopXMLNS, _attrs, _val); +decode_sic_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> + decode_sic_attrs(__TopXMLNS, _attrs, Xmlns); +decode_sic_attrs(__TopXMLNS, [], Xmlns) -> + decode_sic_attr_xmlns(__TopXMLNS, Xmlns). + +encode_sic({sic, Ip, Port, Xmlns}, _xmlns_attrs) -> + _els = lists:reverse('encode_sic_$ip'(Ip, + 'encode_sic_$port'(Port, []))), + _attrs = encode_sic_attr_xmlns(Xmlns, _xmlns_attrs), + {xmlel, <<"address">>, _attrs, _els}. + +'encode_sic_$ip'(undefined, _acc) -> _acc; +'encode_sic_$ip'(Ip, _acc) -> + [encode_sic_ip(Ip, []) | _acc]. + +'encode_sic_$port'(undefined, _acc) -> _acc; +'encode_sic_$port'(Port, _acc) -> + [encode_sip_port(Port, []) | _acc]. + +decode_sic_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_sic_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_sic_attr_xmlns(undefined, _acc) -> _acc; +encode_sic_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_sip_port(__TopXMLNS, __IgnoreEls, + {xmlel, <<"port">>, _attrs, _els}) -> + Cdata = decode_sip_port_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_sip_port_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_sip_port_cdata(__TopXMLNS, Cdata); +decode_sip_port_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_sip_port_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sip_port_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_sip_port_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_sip_port(Cdata, _xmlns_attrs) -> + _els = encode_sip_port_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"port">>, _attrs, _els}. + +decode_sip_port_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"port">>, __TopXMLNS}}); +decode_sip_port_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, 65535) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"port">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sip_port_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_sic_ip(__TopXMLNS, __IgnoreEls, + {xmlel, <<"ip">>, _attrs, _els}) -> + Cdata = decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, + <<>>), + Cdata. + +decode_sic_ip_els(__TopXMLNS, __IgnoreEls, [], Cdata) -> + decode_sic_ip_cdata(__TopXMLNS, Cdata); +decode_sic_ip_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_sic_ip_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, Cdata). + +encode_sic_ip(Cdata, _xmlns_attrs) -> + _els = encode_sic_ip_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"ip">>, _attrs, _els}. + +decode_sic_ip_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"ip">>, __TopXMLNS}}); +decode_sic_ip_cdata(__TopXMLNS, _val) -> + case catch dec_ip(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"ip">>, __TopXMLNS}}); + _res -> _res + end. + +encode_sic_ip_cdata(_val, _acc) -> + [{xmlcdata, enc_ip(_val)} | _acc]. + decode_oob_x(__TopXMLNS, __IgnoreEls, {xmlel, <<"x">>, _attrs, _els}) -> {Desc, Url} = decode_oob_x_els(__TopXMLNS, __IgnoreEls, -- cgit v1.2.3 From 792e6a7c1c5f5fa0c1a9f7bb2cb25a1c21bae3a6 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 30 Jul 2016 17:48:52 +0300 Subject: Rewrite mod_http_upload to use XML generator --- src/mod_http_upload.erl | 197 +++++-------- src/mod_http_upload_quota.erl | 2 +- src/xmpp_codec.erl | 629 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 691 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index b166f2b66..63dc2dfe2 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -92,7 +92,7 @@ -include("ejabberd.hrl"). -include("ejabberd_http.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("logger.hrl"). -record(state, @@ -360,9 +360,8 @@ handle_cast(Request, State) -> -spec handle_info(timeout | _, state()) -> {noreply, state()}. -handle_info({route, From, To, #xmlel{name = <<"iq">>} = Stanza}, State) -> - Request = jlib:iq_query_info(Stanza), - {Reply, NewState} = case process_iq(From, Request, State) of +handle_info({route, From, To, #iq{} = IQ}, State) -> + {Reply, NewState} = case process_iq(From, IQ, State) of R when is_record(R, iq) -> {R, State}; {R, S} -> @@ -371,7 +370,7 @@ handle_info({route, From, To, #xmlel{name = <<"iq">>} = Stanza}, State) -> {none, State} end, if Reply /= none -> - ejabberd_router:route(To, From, jlib:iq_to_xml(Reply)); + ejabberd_router:route(To, From, Reply); true -> ok end, @@ -531,89 +530,48 @@ expand_host(Subject, Host) -> %% XMPP request handling. --spec process_iq(jid(), iq_request() | reply | invalid, state()) - -> {iq_reply(), state()} | iq_reply() | not_request. +-spec process_iq(jid(), iq(), state()) -> {iq(), state()} | iq() | not_request. process_iq(_From, - #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ, + #iq{type = get, lang = Lang, sub_els = [#disco_info{}]} = IQ, #state{server_host = ServerHost, name = Name}) -> AddInfo = ejabberd_hooks:run_fold(disco_info, ServerHost, [], [ServerHost, ?MODULE, <<"">>, <<"">>]), - IQ#iq{type = result, - sub_el = [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}], - children = iq_disco_info(ServerHost, Lang, Name) - ++ AddInfo}]}; -process_iq(From, - #iq{type = get, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ, - #state{server_host = ServerHost, access = Access} = State) - when XMLNS == ?NS_HTTP_UPLOAD; - XMLNS == ?NS_HTTP_UPLOAD_OLD -> + xmpp:make_iq_result(IQ, iq_disco_info(ServerHost, Lang, Name, AddInfo)); +process_iq(From, #iq{type = get, lang = Lang, + sub_els = [#upload_request{filename = File, + size = Size, + 'content-type' = CType, + xmlns = XMLNS}]} = IQ, + #state{server_host = ServerHost, access = Access} = State) -> case acl:match_rule(ServerHost, Access, From) of allow -> - case parse_request(SubEl, Lang) of - {ok, File, Size, ContentType} -> - case create_slot(State, From, File, Size, ContentType, - Lang) of - {ok, Slot} -> - {ok, Timer} = timer:send_after(?SLOT_TIMEOUT, - {slot_timed_out, - Slot}), - NewState = add_slot(Slot, Size, Timer, State), - SlotEl = slot_el(Slot, State, XMLNS), - {IQ#iq{type = result, sub_el = [SlotEl]}, NewState}; - {ok, PutURL, GetURL} -> - SlotEl = slot_el(PutURL, GetURL, XMLNS), - IQ#iq{type = result, sub_el = [SlotEl]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; + ContentType = yield_content_type(CType), + case create_slot(State, From, File, Size, ContentType, Lang) of + {ok, Slot} -> + {ok, Timer} = timer:send_after(?SLOT_TIMEOUT, + {slot_timed_out, + Slot}), + NewState = add_slot(Slot, Size, Timer, State), + Slot = mk_slot(Slot, State, XMLNS), + {xmpp:make_iq_result(IQ, Slot), NewState}; + {ok, PutURL, GetURL} -> + Slot = mk_slot(PutURL, GetURL, XMLNS), + xmpp:make_iq_result(IQ, Slot); {error, Error} -> - ?DEBUG("Cannot parse request from ~s", - [jid:to_string(From)]), - IQ#iq{type = error, sub_el = [SubEl, Error]} + xmpp:make_error(IQ, Error) end; deny -> ?DEBUG("Denying HTTP upload slot request from ~s", [jid:to_string(From)]), Txt = <<"Denied by ACL">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]} + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)) end; -process_iq(_From, #iq{sub_el = SubEl} = IQ, _State) -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; -process_iq(_From, reply, _State) -> - not_request; -process_iq(_From, invalid, _State) -> +process_iq(_From, #iq{type = T} = IQ, _State) when T == get; T == set -> + xmpp:make_error(IQ, xmpp:err_not_allowed()); +process_iq(_From, #iq{}, _State) -> not_request. --spec parse_request(xmlel(), binary()) - -> {ok, binary(), pos_integer(), binary()} | {error, xmlel()}. - -parse_request(#xmlel{name = <<"request">>, attrs = Attrs} = Request, Lang) -> - case fxml:get_attr(<<"xmlns">>, Attrs) of - {value, XMLNS} when XMLNS == ?NS_HTTP_UPLOAD; - XMLNS == ?NS_HTTP_UPLOAD_OLD -> - case {fxml:get_subtag_cdata(Request, <<"filename">>), - fxml:get_subtag_cdata(Request, <<"size">>), - fxml:get_subtag_cdata(Request, <<"content-type">>)} of - {File, SizeStr, ContentType} when byte_size(File) > 0 -> - case catch jlib:binary_to_integer(SizeStr) of - Size when is_integer(Size), Size > 0 -> - {ok, File, Size, yield_content_type(ContentType)}; - _ -> - Text = <<"Please specify file size.">>, - {error, ?ERRT_BAD_REQUEST(Lang, Text)} - end; - _ -> - Text = <<"Please specify file name.">>, - {error, ?ERRT_BAD_REQUEST(Lang, Text)} - end; - _ -> - Text = <<"No or invalid XML namespace">>, - {error, ?ERRT_BAD_REQUEST(Lang, Text)} - end; -parse_request(_El, _Lang) -> {error, ?ERR_BAD_REQUEST}. - -spec create_slot(state(), jid(), binary(), pos_integer(), binary(), binary()) -> {ok, slot()} | {ok, binary(), binary()} | {error, xmlel()}. @@ -624,7 +582,7 @@ create_slot(#state{service_url = undefined, max_size = MaxSize}, " Bytes.">>, ?INFO_MSG("Rejecting file ~s from ~s (too large: ~B bytes)", [File, jid:to_string(JID), Size]), - {error, ?ERRT_NOT_ACCEPTABLE(Lang, Text)}; + {error, xmpp:err_not_acceptable(Text, Lang)}; create_slot(#state{service_url = undefined, jid_in_url = JIDinURL, secret_length = SecretLength, @@ -642,8 +600,8 @@ create_slot(#state{service_url = undefined, [jid:to_string(JID), File]), {ok, [UserStr, RandStr, FileStr]}; deny -> - {error, ?ERR_SERVICE_UNAVAILABLE}; - #xmlel{} = Error -> + {error, xmpp:err_service_unavailable()}; + #error{} = Error -> {error, Error} end; create_slot(#state{service_url = ServiceURL}, @@ -669,28 +627,28 @@ create_slot(#state{service_url = ServiceURL}, ?ERROR_MSG("Can't parse data received for ~s from <~s>: ~p", [jid:to_string(JID), ServiceURL, Lines]), Txt = <<"Failed to parse HTTP response">>, - {error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)} + {error, xmpp:err_service_unavailable(Txt, Lang)} end; {ok, {402, _Body}} -> ?INFO_MSG("Got status code 402 for ~s from <~s>", [jid:to_string(JID), ServiceURL]), - {error, ?ERR_RESOURCE_CONSTRAINT}; + {error, xmpp:err_resource_constraint()}; {ok, {403, _Body}} -> ?INFO_MSG("Got status code 403 for ~s from <~s>", [jid:to_string(JID), ServiceURL]), - {error, ?ERR_NOT_ALLOWED}; + {error, xmpp:err_not_allowed()}; {ok, {413, _Body}} -> ?INFO_MSG("Got status code 413 for ~s from <~s>", [jid:to_string(JID), ServiceURL]), - {error, ?ERR_NOT_ACCEPTABLE}; + {error, xmpp:err_not_acceptable()}; {ok, {Code, _Body}} -> ?ERROR_MSG("Got unexpected status code for ~s from <~s>: ~B", [jid:to_string(JID), ServiceURL, Code]), - {error, ?ERR_SERVICE_UNAVAILABLE}; + {error, xmpp:err_service_unavailable()}; {error, Reason} -> ?ERROR_MSG("Error requesting upload slot for ~s from <~s>: ~p", [jid:to_string(JID), ServiceURL, Reason]), - {error, ?ERR_SERVICE_UNAVAILABLE} + {error, xmpp:err_service_unavailable()} end. -spec add_slot(slot(), pos_integer(), timer:tref(), state()) -> state(). @@ -710,19 +668,12 @@ del_slot(Slot, #state{slots = Slots} = State) -> NewSlots = maps:remove(Slot, Slots), State#state{slots = NewSlots}. --spec slot_el(slot() | binary(), state() | binary(), binary()) -> xmlel(). +-spec mk_slot(slot() | binary(), state() | binary(), binary()) -> xmlel(). -slot_el(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) -> +mk_slot(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) -> PutURL = str:join([PutPrefix | Slot], <<$/>>), GetURL = str:join([GetPrefix | Slot], <<$/>>), - slot_el(PutURL, GetURL, XMLNS); -slot_el(PutURL, GetURL, XMLNS) -> - #xmlel{name = <<"slot">>, - attrs = [{<<"xmlns">>, XMLNS}], - children = [#xmlel{name = <<"put">>, - children = [{xmlcdata, PutURL}]}, - #xmlel{name = <<"get">>, - children = [{xmlcdata, GetURL}]}]}. + #upload_slot{get = GetURL, put = PutURL, xmlns = XMLNS}. -spec make_user_string(jid(), sha1 | node) -> binary(). @@ -762,44 +713,30 @@ map_int_to_char(N) when N =< 61 -> N + 61. % Lower-case character. yield_content_type(<<"">>) -> ?DEFAULT_CONTENT_TYPE; yield_content_type(Type) -> Type. --spec iq_disco_info(binary(), binary(), binary()) -> [xmlel()]. +-spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> [xmlel()]. -iq_disco_info(Host, Lang, Name) -> +iq_disco_info(Host, Lang, Name, AddInfo) -> Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size, fun(I) when is_integer(I), I > 0 -> I; (infinity) -> infinity end, 104857600) of infinity -> - []; + AddInfo; MaxSize -> MaxSizeStr = jlib:integer_to_binary(MaxSize), - Fields = [#xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"hidden">>}, - {<<"var">>, <<"FORM_TYPE">>}], - children = [#xmlel{name = <<"value">>, - children = - [{xmlcdata, - ?NS_HTTP_UPLOAD}]}]}, - #xmlel{name = <<"field">>, - attrs = [{<<"var">>, <<"max-file-size">>}], - children = [#xmlel{name = <<"value">>, - children = - [{xmlcdata, - MaxSizeStr}]}]}], - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"result">>}], - children = Fields}] + Fields = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [?NS_HTTP_UPLOAD]}, + #xdata_field{var = <<"max-file-size">>, + values = [MaxSizeStr]}], + [#xdata{type = result, fields = Fields}|AddInfo] end, - [#xmlel{name = <<"identity">>, - attrs = [{<<"category">>, <<"store">>}, - {<<"type">>, <<"file">>}, - {<<"name">>, translate:translate(Lang, Name)}]}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_HTTP_UPLOAD}]}, - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, ?NS_HTTP_UPLOAD_OLD}]} | Form]. + #disco_info{identities = [#identity{category = <<"store">>, + type = <<"file">>, + name = translate:translate(Lang, Name)}], + features = [?NS_HTTP_UPLOAD, ?NS_HTTP_UPLOAD_OLD], + xdata = Form}. %% HTTP request handling. @@ -984,20 +921,14 @@ convert(Path, #media_info{type = T, width = W, height = H}) -> thumb_el(Path, URI) -> ContentType = guess_content_type(Path), - case identify(Path) of - {ok, #media_info{height = H, width = W}} -> - #xmlel{name = <<"thumbnail">>, - attrs = [{<<"xmlns">>, ?NS_THUMBS_1}, - {<<"media-type">>, ContentType}, - {<<"uri">>, URI}, - {<<"height">>, jlib:integer_to_binary(H)}, - {<<"width">>, jlib:integer_to_binary(W)}]}; - pass -> - #xmlel{name = <<"thumbnail">>, - attrs = [{<<"xmlns">>, ?NS_THUMBS_1}, - {<<"uri">>, URI}, - {<<"media-type">>, ContentType}]} - end. + xmpp:encode( + case identify(Path) of + {ok, #media_info{height = H, width = W}} -> + #thumbnail{'media-type' = ContentType, uri = URI, + height = H, width = W}; + pass -> + #thumbnail{uri = URI, 'media-type' = ContentType} + end). %%-------------------------------------------------------------------- %% Remove user. diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl index 35e266ddf..056edbedb 100644 --- a/src/mod_http_upload_quota.erl +++ b/src/mod_http_upload_quota.erl @@ -53,7 +53,7 @@ %% ejabberd_hooks callback. -export([handle_slot_request/5]). --include("jlib.hrl"). +-include("jid.hrl"). -include("logger.hrl"). -include_lib("kernel/include/file.hrl"). diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 11bd741f4..8d87712df 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -15,6 +15,56 @@ decode(_el) -> decode(_el, []). decode({xmlel, _name, _attrs, _} = _el, Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>} -> + decode_thumbnail(<<"urn:xmpp:thumbs:1">>, IgnoreEls, + _el); + {<<"slot">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_slot(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"slot">>, + <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_slot(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"put">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_put(<<"urn:xmpp:http:upload">>, IgnoreEls, + _el); + {<<"put">>, <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_put(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"get">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_get(<<"urn:xmpp:http:upload">>, IgnoreEls, + _el); + {<<"get">>, <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_get(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"request">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_request(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"request">>, + <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_request(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"content-type">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_content_type(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"content-type">>, + <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"size">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_size(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"size">>, + <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_size(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"filename">>, <<"urn:xmpp:http:upload">>} -> + decode_upload_filename(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"filename">>, + <<"eu:siacs:conversations:http:upload">>} -> + decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); {<<"address">>, <<"urn:xmpp:sic:0">>} -> decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); {<<"address">>, <<"urn:xmpp:sic:1">>} -> @@ -1319,6 +1369,34 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> is_known_tag({xmlel, _name, _attrs, _} = _el) -> case {_name, get_attr(<<"xmlns">>, _attrs)} of + {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>} -> true; + {<<"slot">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"slot">>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"put">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"put">>, <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"get">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"get">>, <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"request">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"request">>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"content-type">>, <<"urn:xmpp:http:upload">>} -> + true; + {<<"content-type">>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"size">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"size">>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"filename">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"filename">>, + <<"eu:siacs:conversations:http:upload">>} -> + true; {<<"address">>, <<"urn:xmpp:sic:0">>} -> true; {<<"address">>, <<"urn:xmpp:sic:1">>} -> true; {<<"port">>, <<"urn:xmpp:sic:1">>} -> true; @@ -2626,7 +2704,14 @@ encode({media, _, _, _} = Media) -> encode({oob_x, _, _, _} = X) -> encode_oob_x(X, [{<<"xmlns">>, <<"jabber:x:oob">>}]); encode({sic, _, _, _} = Address) -> - encode_sic(Address, []). + encode_sic(Address, []); +encode({upload_request, _, _, _, _} = Request) -> + encode_upload_request(Request, []); +encode({upload_slot, _, _, _} = Slot) -> + encode_upload_slot(Slot, []); +encode({thumbnail, _, _, _, _} = Thumbnail) -> + encode_thumbnail(Thumbnail, + [{<<"xmlns">>, <<"urn:xmpp:thumbs:1">>}]). get_name({last, _, _}) -> <<"query">>; get_name({version, _, _, _}) -> <<"query">>; @@ -2820,7 +2905,10 @@ get_name({xcaptcha, _}) -> <<"captcha">>; get_name({media_uri, _, _}) -> <<"uri">>; get_name({media, _, _, _}) -> <<"media">>; get_name({oob_x, _, _, _}) -> <<"x">>; -get_name({sic, _, _, _}) -> <<"address">>. +get_name({sic, _, _, _}) -> <<"address">>; +get_name({upload_request, _, _, _, _}) -> <<"request">>; +get_name({upload_slot, _, _, _}) -> <<"slot">>; +get_name({thumbnail, _, _, _, _}) -> <<"thumbnail">>. get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; @@ -3089,7 +3177,11 @@ get_ns({media_uri, _, _}) -> get_ns({media, _, _, _}) -> <<"urn:xmpp:media-element">>; get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>; -get_ns({sic, _, _, Xmlns}) -> Xmlns. +get_ns({sic, _, _, Xmlns}) -> Xmlns; +get_ns({upload_request, _, _, _, Xmlns}) -> Xmlns; +get_ns({upload_slot, _, _, Xmlns}) -> Xmlns; +get_ns({thumbnail, _, _, _, _}) -> + <<"urn:xmpp:thumbs:1">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3339,6 +3431,10 @@ pp(media_uri, 2) -> [type, uri]; pp(media, 3) -> [height, width, uri]; pp(oob_x, 3) -> [url, desc, sid]; pp(sic, 3) -> [ip, port, xmlns]; +pp(upload_request, 4) -> + [filename, size, 'content-type', xmlns]; +pp(upload_slot, 3) -> [get, put, xmlns]; +pp(thumbnail, 4) -> [uri, 'media-type', width, height]; pp(_, _) -> no. enc_ip({0, 0, 0, 0, 0, 65535, A, B}) -> @@ -3394,6 +3490,533 @@ dec_tzo(Val) -> M = jlib:binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. +decode_thumbnail(__TopXMLNS, __IgnoreEls, + {xmlel, <<"thumbnail">>, _attrs, _els}) -> + {Uri, Media_type, Width, Height} = + decode_thumbnail_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {thumbnail, Uri, Media_type, Width, Height}. + +decode_thumbnail_attrs(__TopXMLNS, + [{<<"uri">>, _val} | _attrs], _Uri, Media_type, Width, + Height) -> + decode_thumbnail_attrs(__TopXMLNS, _attrs, _val, + Media_type, Width, Height); +decode_thumbnail_attrs(__TopXMLNS, + [{<<"media-type">>, _val} | _attrs], Uri, _Media_type, + Width, Height) -> + decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, _val, + Width, Height); +decode_thumbnail_attrs(__TopXMLNS, + [{<<"width">>, _val} | _attrs], Uri, Media_type, _Width, + Height) -> + decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, + Media_type, _val, Height); +decode_thumbnail_attrs(__TopXMLNS, + [{<<"height">>, _val} | _attrs], Uri, Media_type, Width, + _Height) -> + decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, + Media_type, Width, _val); +decode_thumbnail_attrs(__TopXMLNS, [_ | _attrs], Uri, + Media_type, Width, Height) -> + decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, + Media_type, Width, Height); +decode_thumbnail_attrs(__TopXMLNS, [], Uri, Media_type, + Width, Height) -> + {decode_thumbnail_attr_uri(__TopXMLNS, Uri), + 'decode_thumbnail_attr_media-type'(__TopXMLNS, + Media_type), + decode_thumbnail_attr_width(__TopXMLNS, Width), + decode_thumbnail_attr_height(__TopXMLNS, Height)}. + +encode_thumbnail({thumbnail, Uri, Media_type, Width, + Height}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_thumbnail_attr_height(Height, + encode_thumbnail_attr_width(Width, + 'encode_thumbnail_attr_media-type'(Media_type, + encode_thumbnail_attr_uri(Uri, + _xmlns_attrs)))), + {xmlel, <<"thumbnail">>, _attrs, _els}. + +decode_thumbnail_attr_uri(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"uri">>, <<"thumbnail">>, + __TopXMLNS}}); +decode_thumbnail_attr_uri(__TopXMLNS, _val) -> _val. + +encode_thumbnail_attr_uri(_val, _acc) -> + [{<<"uri">>, _val} | _acc]. + +'decode_thumbnail_attr_media-type'(__TopXMLNS, + undefined) -> + <<>>; +'decode_thumbnail_attr_media-type'(__TopXMLNS, _val) -> + _val. + +'encode_thumbnail_attr_media-type'(<<>>, _acc) -> _acc; +'encode_thumbnail_attr_media-type'(_val, _acc) -> + [{<<"media-type">>, _val} | _acc]. + +decode_thumbnail_attr_width(__TopXMLNS, undefined) -> + undefined; +decode_thumbnail_attr_width(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"width">>, <<"thumbnail">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_thumbnail_attr_width(undefined, _acc) -> _acc; +encode_thumbnail_attr_width(_val, _acc) -> + [{<<"width">>, enc_int(_val)} | _acc]. + +decode_thumbnail_attr_height(__TopXMLNS, undefined) -> + undefined; +decode_thumbnail_attr_height(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"height">>, <<"thumbnail">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_thumbnail_attr_height(undefined, _acc) -> _acc; +encode_thumbnail_attr_height(_val, _acc) -> + [{<<"height">>, enc_int(_val)} | _acc]. + +decode_upload_slot(__TopXMLNS, __IgnoreEls, + {xmlel, <<"slot">>, _attrs, _els}) -> + {Put, Get} = decode_upload_slot_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined), + Xmlns = decode_upload_slot_attrs(__TopXMLNS, _attrs, + undefined), + {upload_slot, Get, Put, Xmlns}. + +decode_upload_slot_els(__TopXMLNS, __IgnoreEls, [], Put, + Get) -> + {Put, Get}; +decode_upload_slot_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"get">>, _attrs, _} = _el | _els], Put, + Get) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"eu:siacs:conversations:http:upload">>; + __TopXMLNS == <<"urn:xmpp:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, + decode_upload_get(__TopXMLNS, __IgnoreEls, + _el)); + <<"urn:xmpp:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, + decode_upload_get(<<"urn:xmpp:http:upload">>, + __IgnoreEls, _el)); + <<"eu:siacs:conversations:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, + decode_upload_get(<<"eu:siacs:conversations:http:upload">>, + __IgnoreEls, _el)); + _ -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, Get) + end; +decode_upload_slot_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"put">>, _attrs, _} = _el | _els], Put, + Get) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"eu:siacs:conversations:http:upload">>; + __TopXMLNS == <<"urn:xmpp:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_put(__TopXMLNS, __IgnoreEls, + _el), + Get); + <<"urn:xmpp:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_put(<<"urn:xmpp:http:upload">>, + __IgnoreEls, _el), + Get); + <<"eu:siacs:conversations:http:upload">> -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_put(<<"eu:siacs:conversations:http:upload">>, + __IgnoreEls, _el), + Get); + _ -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, Get) + end; +decode_upload_slot_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Put, Get) -> + decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, + Put, Get). + +decode_upload_slot_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_upload_slot_attrs(__TopXMLNS, _attrs, _val); +decode_upload_slot_attrs(__TopXMLNS, [_ | _attrs], + Xmlns) -> + decode_upload_slot_attrs(__TopXMLNS, _attrs, Xmlns); +decode_upload_slot_attrs(__TopXMLNS, [], Xmlns) -> + decode_upload_slot_attr_xmlns(__TopXMLNS, Xmlns). + +encode_upload_slot({upload_slot, Get, Put, Xmlns}, + _xmlns_attrs) -> + _els = lists:reverse('encode_upload_slot_$put'(Put, + 'encode_upload_slot_$get'(Get, + []))), + _attrs = encode_upload_slot_attr_xmlns(Xmlns, + _xmlns_attrs), + {xmlel, <<"slot">>, _attrs, _els}. + +'encode_upload_slot_$put'(undefined, _acc) -> _acc; +'encode_upload_slot_$put'(Put, _acc) -> + [encode_upload_put(Put, []) | _acc]. + +'encode_upload_slot_$get'(undefined, _acc) -> _acc; +'encode_upload_slot_$get'(Get, _acc) -> + [encode_upload_get(Get, []) | _acc]. + +decode_upload_slot_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_upload_slot_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_upload_slot_attr_xmlns(undefined, _acc) -> _acc; +encode_upload_slot_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_upload_put(__TopXMLNS, __IgnoreEls, + {xmlel, <<"put">>, _attrs, _els}) -> + Cdata = decode_upload_put_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_upload_put_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_upload_put_cdata(__TopXMLNS, Cdata); +decode_upload_put_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_upload_put_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_upload_put_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_upload_put_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_upload_put(Cdata, _xmlns_attrs) -> + _els = encode_upload_put_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"put">>, _attrs, _els}. + +decode_upload_put_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"put">>, __TopXMLNS}}); +decode_upload_put_cdata(__TopXMLNS, _val) -> _val. + +encode_upload_put_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_upload_get(__TopXMLNS, __IgnoreEls, + {xmlel, <<"get">>, _attrs, _els}) -> + Cdata = decode_upload_get_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_upload_get_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_upload_get_cdata(__TopXMLNS, Cdata); +decode_upload_get_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_upload_get_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_upload_get_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_upload_get_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_upload_get(Cdata, _xmlns_attrs) -> + _els = encode_upload_get_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"get">>, _attrs, _els}. + +decode_upload_get_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"get">>, __TopXMLNS}}); +decode_upload_get_cdata(__TopXMLNS, _val) -> _val. + +encode_upload_get_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_upload_request(__TopXMLNS, __IgnoreEls, + {xmlel, <<"request">>, _attrs, _els}) -> + {Content_type, Size, Filename} = + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + <<>>, error, error), + Xmlns = decode_upload_request_attrs(__TopXMLNS, _attrs, + undefined), + {upload_request, Filename, Size, Content_type, Xmlns}. + +decode_upload_request_els(__TopXMLNS, __IgnoreEls, [], + Content_type, Size, Filename) -> + {Content_type, + case Size of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"size">>, __TopXMLNS}}); + {value, Size1} -> Size1 + end, + case Filename of + error -> + erlang:error({xmpp_codec, + {missing_tag, <<"filename">>, __TopXMLNS}}); + {value, Filename1} -> Filename1 + end}; +decode_upload_request_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"filename">>, _attrs, _} = _el | _els], + Content_type, Size, Filename) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"eu:siacs:conversations:http:upload">>; + __TopXMLNS == <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, + {value, + decode_upload_filename(__TopXMLNS, + __IgnoreEls, _el)}); + <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, + {value, + decode_upload_filename(<<"urn:xmpp:http:upload">>, + __IgnoreEls, _el)}); + <<"eu:siacs:conversations:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, + {value, + decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, + __IgnoreEls, _el)}); + _ -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, Filename) + end; +decode_upload_request_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"size">>, _attrs, _} = _el | _els], + Content_type, Size, Filename) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"eu:siacs:conversations:http:upload">>; + __TopXMLNS == <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, + {value, + decode_upload_size(__TopXMLNS, __IgnoreEls, + _el)}, + Filename); + <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, + {value, + decode_upload_size(<<"urn:xmpp:http:upload">>, + __IgnoreEls, _el)}, + Filename); + <<"eu:siacs:conversations:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, + {value, + decode_upload_size(<<"eu:siacs:conversations:http:upload">>, + __IgnoreEls, _el)}, + Filename); + _ -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, Filename) + end; +decode_upload_request_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"content-type">>, _attrs, _} = _el | _els], + Content_type, Size, Filename) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"eu:siacs:conversations:http:upload">>; + __TopXMLNS == <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_content_type(__TopXMLNS, + __IgnoreEls, + _el), + Size, Filename); + <<"urn:xmpp:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_content_type(<<"urn:xmpp:http:upload">>, + __IgnoreEls, + _el), + Size, Filename); + <<"eu:siacs:conversations:http:upload">> -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, + __IgnoreEls, + _el), + Size, Filename); + _ -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, Filename) + end; +decode_upload_request_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Content_type, Size, Filename) -> + decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, + Content_type, Size, Filename). + +decode_upload_request_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> + decode_upload_request_attrs(__TopXMLNS, _attrs, _val); +decode_upload_request_attrs(__TopXMLNS, [_ | _attrs], + Xmlns) -> + decode_upload_request_attrs(__TopXMLNS, _attrs, Xmlns); +decode_upload_request_attrs(__TopXMLNS, [], Xmlns) -> + decode_upload_request_attr_xmlns(__TopXMLNS, Xmlns). + +encode_upload_request({upload_request, Filename, Size, + Content_type, Xmlns}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_upload_request_$content-type'(Content_type, + 'encode_upload_request_$size'(Size, + 'encode_upload_request_$filename'(Filename, + [])))), + _attrs = encode_upload_request_attr_xmlns(Xmlns, + _xmlns_attrs), + {xmlel, <<"request">>, _attrs, _els}. + +'encode_upload_request_$content-type'(<<>>, _acc) -> + _acc; +'encode_upload_request_$content-type'(Content_type, + _acc) -> + [encode_upload_content_type(Content_type, []) | _acc]. + +'encode_upload_request_$size'(Size, _acc) -> + [encode_upload_size(Size, []) | _acc]. + +'encode_upload_request_$filename'(Filename, _acc) -> + [encode_upload_filename(Filename, []) | _acc]. + +decode_upload_request_attr_xmlns(__TopXMLNS, + undefined) -> + undefined; +decode_upload_request_attr_xmlns(__TopXMLNS, _val) -> + _val. + +encode_upload_request_attr_xmlns(undefined, _acc) -> + _acc; +encode_upload_request_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_upload_content_type(__TopXMLNS, __IgnoreEls, + {xmlel, <<"content-type">>, _attrs, _els}) -> + Cdata = decode_upload_content_type_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, + [], Cdata) -> + decode_upload_content_type_cdata(__TopXMLNS, Cdata); +decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_upload_content_type(Cdata, _xmlns_attrs) -> + _els = encode_upload_content_type_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"content-type">>, _attrs, _els}. + +decode_upload_content_type_cdata(__TopXMLNS, <<>>) -> + <<>>; +decode_upload_content_type_cdata(__TopXMLNS, _val) -> + _val. + +encode_upload_content_type_cdata(<<>>, _acc) -> _acc; +encode_upload_content_type_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_upload_size(__TopXMLNS, __IgnoreEls, + {xmlel, <<"size">>, _attrs, _els}) -> + Cdata = decode_upload_size_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_upload_size_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_upload_size_cdata(__TopXMLNS, Cdata); +decode_upload_size_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_upload_size_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_upload_size_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_upload_size_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_upload_size(Cdata, _xmlns_attrs) -> + _els = encode_upload_size_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"size">>, _attrs, _els}. + +decode_upload_size_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"size">>, __TopXMLNS}}); +decode_upload_size_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"size">>, __TopXMLNS}}); + _res -> _res + end. + +encode_upload_size_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_upload_filename(__TopXMLNS, __IgnoreEls, + {xmlel, <<"filename">>, _attrs, _els}) -> + Cdata = decode_upload_filename_els(__TopXMLNS, + __IgnoreEls, _els, <<>>), + Cdata. + +decode_upload_filename_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_upload_filename_cdata(__TopXMLNS, Cdata); +decode_upload_filename_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_upload_filename_els(__TopXMLNS, __IgnoreEls, + _els, <>); +decode_upload_filename_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_upload_filename_els(__TopXMLNS, __IgnoreEls, + _els, Cdata). + +encode_upload_filename(Cdata, _xmlns_attrs) -> + _els = encode_upload_filename_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"filename">>, _attrs, _els}. + +decode_upload_filename_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"filename">>, __TopXMLNS}}); +decode_upload_filename_cdata(__TopXMLNS, _val) -> _val. + +encode_upload_filename_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + decode_sic(__TopXMLNS, __IgnoreEls, {xmlel, <<"address">>, _attrs, _els}) -> {Ip, Port} = decode_sic_els(__TopXMLNS, __IgnoreEls, -- cgit v1.2.3 From 5cd1cf5096e21988ca517fa358e8ab5ad7a5cc55 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 30 Jul 2016 18:37:57 +0300 Subject: Get rid of "jlib.hrl" dependency in some modules --- src/ejabberd_http.erl | 2 +- src/ejabberd_http_ws.erl | 2 +- src/ejabberd_web.erl | 2 +- src/ejabberd_websocket.erl | 2 +- src/gen_pubsub_nodetree.erl | 27 +++++++++++++-------------- src/mod_http_bind.erl | 2 +- src/node_buddy.erl | 1 - src/node_club.erl | 1 - src/node_hometree.erl | 1 - src/node_hometree_sql.erl | 1 - src/node_mb.erl | 1 - src/node_online.erl | 2 +- src/node_pep.erl | 1 - src/node_pep_sql.erl | 1 - src/node_private.erl | 1 - src/node_public.erl | 1 - src/nodetree_virtual.erl | 1 - 17 files changed, 19 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index 6b53f46c6..1c8de2fbf 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -39,7 +39,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl index e66cf33a5..02df19e63 100644 --- a/src/ejabberd_http_ws.erl +++ b/src/ejabberd_http_ws.erl @@ -39,7 +39,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/ejabberd_web.erl b/src/ejabberd_web.erl index 459423aa4..523feb9c7 100644 --- a/src/ejabberd_web.erl +++ b/src/ejabberd_web.erl @@ -34,7 +34,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/ejabberd_websocket.erl b/src/ejabberd_websocket.erl index 0cdd9bac5..76568aa2d 100644 --- a/src/ejabberd_websocket.erl +++ b/src/ejabberd_websocket.erl @@ -47,7 +47,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/gen_pubsub_nodetree.erl b/src/gen_pubsub_nodetree.erl index 73583af02..a18bc8d39 100644 --- a/src/gen_pubsub_nodetree.erl +++ b/src/gen_pubsub_nodetree.erl @@ -25,7 +25,6 @@ -module(gen_pubsub_nodetree). --include("jlib.hrl"). -type(host() :: mod_pubsub:host()). -type(nodeId() :: mod_pubsub:nodeId()). @@ -42,25 +41,25 @@ -callback options() -> nodeOptions(). -callback set_node(PubsubNode :: pubsubNode()) -> - ok | {result, NodeIdx::nodeIdx()} | {error, xmlel()}. + ok | {result, NodeIdx::nodeIdx()} | {error, fxml:xmlel()}. -callback get_node(Host :: host(), NodeId :: nodeId(), - From :: jid()) -> + From :: jid:jid()) -> pubsubNode() | - {error, xmlel()}. + {error, fxml:xmlel()}. -callback get_node(Host :: host(), NodeId :: nodeId()) -> pubsubNode() | - {error, xmlel()}. + {error, fxml:xmlel()}. -callback get_node(NodeIdx :: nodeIdx()) -> pubsubNode() | - {error, xmlel()}. + {error, fxml:xmlel()}. -callback get_nodes(Host :: host(), - From :: jid())-> + From :: jid:jid())-> [pubsubNode()]. -callback get_nodes(Host :: host())-> @@ -68,33 +67,33 @@ -callback get_parentnodes(Host :: host(), NodeId :: nodeId(), - From :: jid()) -> + From :: jid:jid()) -> [pubsubNode()] | - {error, xmlel()}. + {error, fxml:xmlel()}. -callback get_parentnodes_tree(Host :: host(), NodeId :: nodeId(), - From :: jid()) -> + From :: jid:jid()) -> [{0, [pubsubNode(),...]}]. -callback get_subnodes(Host :: host(), NodeId :: nodeId(), - From :: jid()) -> + From :: jid:jid()) -> [pubsubNode()]. -callback get_subnodes_tree(Host :: host(), NodeId :: nodeId(), - From :: jid()) -> + From :: jid:jid()) -> [pubsubNode()]. -callback create_node(Host :: host(), NodeId :: nodeId(), Type :: binary(), - Owner :: jid(), + Owner :: jid:jid(), Options :: nodeOptions(), Parents :: [nodeId()]) -> {ok, NodeIdx::nodeIdx()} | - {error, xmlel()} | + {error, fxml:xmlel()} | {error, {virtual, {host(), nodeId()}}}. -callback delete_node(Host :: host(), diff --git a/src/mod_http_bind.erl b/src/mod_http_bind.erl index 9a3a379f7..471b38c00 100644 --- a/src/mod_http_bind.erl +++ b/src/mod_http_bind.erl @@ -42,7 +42,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_http.hrl"). diff --git a/src/node_buddy.erl b/src/node_buddy.erl index bdaa4a89a..fb2fd1f2e 100644 --- a/src/node_buddy.erl +++ b/src/node_buddy.erl @@ -28,7 +28,6 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, diff --git a/src/node_club.erl b/src/node_club.erl index 7f6ae6520..837fa6fbb 100644 --- a/src/node_club.erl +++ b/src/node_club.erl @@ -28,7 +28,6 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, diff --git a/src/node_hometree.erl b/src/node_hometree.erl index def7b983d..67c5e9332 100644 --- a/src/node_hometree.erl +++ b/src/node_hometree.erl @@ -28,7 +28,6 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, diff --git a/src/node_hometree_sql.erl b/src/node_hometree_sql.erl index d9af49843..661a2aab4 100644 --- a/src/node_hometree_sql.erl +++ b/src/node_hometree_sql.erl @@ -28,7 +28,6 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, diff --git a/src/node_mb.erl b/src/node_mb.erl index 6c7f09780..0c3bd3722 100644 --- a/src/node_mb.erl +++ b/src/node_mb.erl @@ -28,7 +28,6 @@ -author('ecestari@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). %%% @doc The module {@module} is the pep microblog PubSub plugin. %%%

To be used, mod_pubsub must be configured:

diff --git a/src/node_online.erl b/src/node_online.erl
index 1c2ab5a03..4b01d2a2c 100644
--- a/src/node_online.erl
+++ b/src/node_online.erl
@@ -28,7 +28,7 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
+-include("jid.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
     create_node_permission/6, create_node/2, delete_node/1,
diff --git a/src/node_pep.erl b/src/node_pep.erl
index 1677ed4bd..f3b5836cf 100644
--- a/src/node_pep.erl
+++ b/src/node_pep.erl
@@ -31,7 +31,6 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
 -include("logger.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
diff --git a/src/node_pep_sql.erl b/src/node_pep_sql.erl
index ec7795475..ac42cb94f 100644
--- a/src/node_pep_sql.erl
+++ b/src/node_pep_sql.erl
@@ -31,7 +31,6 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
 -include("logger.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
diff --git a/src/node_private.erl b/src/node_private.erl
index 0cd04b9dd..1888ce33d 100644
--- a/src/node_private.erl
+++ b/src/node_private.erl
@@ -28,7 +28,6 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
     create_node_permission/6, create_node/2, delete_node/1,
diff --git a/src/node_public.erl b/src/node_public.erl
index 0786d9995..ca200e002 100644
--- a/src/node_public.erl
+++ b/src/node_public.erl
@@ -28,7 +28,6 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
     create_node_permission/6, create_node/2, delete_node/1,
diff --git a/src/nodetree_virtual.erl b/src/nodetree_virtual.erl
index 934950dd2..31802db2b 100644
--- a/src/nodetree_virtual.erl
+++ b/src/nodetree_virtual.erl
@@ -35,7 +35,6 @@
 -author('christophe.romain@process-one.net').
 
 -include("pubsub.hrl").
--include("jlib.hrl").
 
 -export([init/3, terminate/2, options/0, set_node/1,
     get_node/3, get_node/2, get_node/1, get_nodes/2,
-- 
cgit v1.2.3


From eb1d385d4e00b33bf327a3ff25f9c0f71c98a96b Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Sat, 30 Jul 2016 18:42:17 +0300
Subject: Get rid of "jlib.hrl" dependency in mod_service_log

---
 src/mod_service_log.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl
index 8f11b0ead..a88b04b58 100644
--- a/src/mod_service_log.erl
+++ b/src/mod_service_log.erl
@@ -35,7 +35,7 @@
 -include("ejabberd.hrl").
 -include("logger.hrl").
 
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 start(Host, _Opts) ->
     ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
-- 
cgit v1.2.3


From 0bcbd12776a03902f356c3ac48465cc901670393 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Sun, 31 Jul 2016 08:51:47 +0300
Subject: Rewrite mod_mix to use XML generator

---
 src/mod_mix.erl      | 116 ++++------
 src/mod_muc_room.erl |   3 +-
 src/xmpp.erl         |  20 +-
 src/xmpp_codec.erl   | 591 +++++++++++++++++++++++----------------------------
 4 files changed, 323 insertions(+), 407 deletions(-)

(limited to 'src')

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);
-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;
+			 <>, __Els);
 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,
-	      [{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, [], __Els) ->
+    lists:reverse(__Els);
 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}});
-- 
cgit v1.2.3


From e258462b6b811baa2500a2d1c843ecbecf9382a7 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Sun, 31 Jul 2016 14:17:17 +0300
Subject: Improve vCard creation from LDAP result

---
 src/mod_vcard_ldap.erl | 148 +++++++++++++++----------------------------------
 1 file changed, 44 insertions(+), 104 deletions(-)

(limited to 'src')

diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index 74b20d2ff..191676224 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -75,8 +75,9 @@ get_vcard(LUser, LServer) ->
     VCardMap = State#state.vcard_map,
     case find_ldap_user(LUser, State) of
 	#eldap_entry{attributes = Attributes} ->
-	    ldap_attributes_to_vcard(Attributes, VCardMap,
-				     {LUser, LServer});
+	    VCard = ldap_attributes_to_vcard(Attributes, VCardMap,
+					     {LUser, LServer}),
+	    [xmpp:encode(VCard)];
 	_ ->
 	    []
     end.
@@ -218,108 +219,47 @@ ldap_attributes_to_vcard(Attributes, VCardMap, UD) ->
 					      UD)}
 		      end,
 		      VCardMap),
-    Elts = [ldap_attribute_to_vcard(vCard, Attr)
-	    || Attr <- Attrs],
-    NElts = [ldap_attribute_to_vcard(vCardN, Attr)
-	     || Attr <- Attrs],
-    OElts = [ldap_attribute_to_vcard(vCardO, Attr)
-	     || Attr <- Attrs],
-    AElts = [ldap_attribute_to_vcard(vCardA, Attr)
-	     || Attr <- Attrs],
-    [#xmlel{name = <<"vCard">>,
-	    attrs = [{<<"xmlns">>, ?NS_VCARD}],
-	    children =
-		lists:append([X || X <- Elts, X /= none],
-			     [#xmlel{name = <<"N">>, attrs = [],
-				     children = [X || X <- NElts, X /= none]},
-			      #xmlel{name = <<"ORG">>, attrs = [],
-				     children = [X || X <- OElts, X /= none]},
-			      #xmlel{name = <<"ADR">>, attrs = [],
-				     children =
-					 [X || X <- AElts, X /= none]}])}].
-
-ldap_attribute_to_vcard(vCard, {<<"fn">>, Value}) ->
-    #xmlel{name = <<"FN">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard,
-			{<<"nickname">>, Value}) ->
-    #xmlel{name = <<"NICKNAME">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"title">>, Value}) ->
-    #xmlel{name = <<"TITLE">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"bday">>, Value}) ->
-    #xmlel{name = <<"BDAY">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"url">>, Value}) ->
-    #xmlel{name = <<"URL">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"desc">>, Value}) ->
-    #xmlel{name = <<"DESC">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"role">>, Value}) ->
-    #xmlel{name = <<"ROLE">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCard, {<<"tel">>, Value}) ->
-    #xmlel{name = <<"TEL">>, attrs = [],
-	   children =
-	       [#xmlel{name = <<"VOICE">>, attrs = [], children = []},
-		#xmlel{name = <<"WORK">>, attrs = [], children = []},
-		#xmlel{name = <<"NUMBER">>, attrs = [],
-		       children = [{xmlcdata, Value}]}]};
-ldap_attribute_to_vcard(vCard, {<<"email">>, Value}) ->
-    #xmlel{name = <<"EMAIL">>, attrs = [],
-	   children =
-	       [#xmlel{name = <<"INTERNET">>, attrs = [],
-		       children = []},
-		#xmlel{name = <<"PREF">>, attrs = [], children = []},
-		#xmlel{name = <<"USERID">>, attrs = [],
-		       children = [{xmlcdata, Value}]}]};
-ldap_attribute_to_vcard(vCard, {<<"photo">>, Value}) ->
-    #xmlel{name = <<"PHOTO">>, attrs = [],
-	   children =
-	       [#xmlel{name = <<"TYPE">>, attrs = [],
-		       children = [{xmlcdata, <<"image/jpeg">>}]},
-		#xmlel{name = <<"BINVAL">>, attrs = [],
-		       children = [{xmlcdata, jlib:encode_base64(Value)}]}]};
-ldap_attribute_to_vcard(vCardN,
-			{<<"family">>, Value}) ->
-    #xmlel{name = <<"FAMILY">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardN, {<<"given">>, Value}) ->
-    #xmlel{name = <<"GIVEN">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardN,
-			{<<"middle">>, Value}) ->
-    #xmlel{name = <<"MIDDLE">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardO,
-			{<<"orgname">>, Value}) ->
-    #xmlel{name = <<"ORGNAME">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardO,
-			{<<"orgunit">>, Value}) ->
-    #xmlel{name = <<"ORGUNIT">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardA,
-			{<<"locality">>, Value}) ->
-    #xmlel{name = <<"LOCALITY">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardA,
-			{<<"street">>, Value}) ->
-    #xmlel{name = <<"STREET">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardA, {<<"ctry">>, Value}) ->
-    #xmlel{name = <<"CTRY">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardA,
-			{<<"region">>, Value}) ->
-    #xmlel{name = <<"REGION">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(vCardA, {<<"pcode">>, Value}) ->
-    #xmlel{name = <<"PCODE">>, attrs = [],
-	   children = [{xmlcdata, Value}]};
-ldap_attribute_to_vcard(_, _) -> none.
+    lists:foldl(fun ldap_attribute_to_vcard/2, #vcard_temp{}, Attrs).
+
+-spec ldap_attribute_to_vcard({binary(), binary()}, vcard_temp()) -> vcard_temp().
+ldap_attribute_to_vcard({Attr, Value}, V) ->
+    Ts = V#vcard_temp.tel,
+    Es = V#vcard_temp.email,
+    N = case V#vcard_temp.n of
+	    undefined -> #vcard_name{};
+	    _ -> V#vcard_temp.n
+	end,
+    O = case V#vcard_temp.org of
+	    undefined -> #vcard_org{};
+	    _ -> V#vcard_temp.org
+	end,
+    A = case V#vcard_temp.adr of
+	    [] -> #vcard_adr{};
+	    As -> hd(As)
+	end,
+    case Attr of
+	<<"fn">> -> V#vcard_temp{fn = Value};
+	<<"nickname">> -> V#vcard_temp{nickname = Value};
+	<<"title">> -> V#vcard_temp{title = Value};
+	<<"bday">> -> V#vcard_temp{bday = Value};
+	<<"url">> -> V#vcard_temp{url = Value};
+	<<"desc">> -> V#vcard_temp{desc = Value};
+	<<"role">> -> V#vcard_temp{role = Value};
+	<<"tel">> -> V#vcard_temp{tel = [#vcard_tel{number = Value}|Ts]};
+	<<"email">> -> V#vcard_temp{email = [#vcard_email{userid = Value}|Es]};
+	<<"photo">> -> V#vcard_temp{photo = #vcard_photo{binval = Value}};
+	<<"family">> -> V#vcard_temp{n = N#vcard_name{family = V}};
+	<<"given">> -> V#vcard_temp{n = N#vcard_name{given = V}};
+	<<"middle">> -> V#vcard_temp{n = N#vcard_name{middle = V}};
+	<<"orgname">> -> V#vcard_temp{org = O#vcard_org{name = V}};
+	<<"orgunit">> -> V#vcard_temp{org = O#vcard_org{units = [Value]}};
+	<<"locality">> -> V#vcard_temp{adr = [A#vcard_adr{locality = Value}]};
+	<<"street">> -> V#vcard_temp{adr = [A#vcard_adr{street = Value}]};
+	<<"ctry">> -> V#vcard_temp{adr = [A#vcard_adr{ctry = Value}]};
+	<<"region">> -> V#vcard_temp{adr = [A#vcard_adr{region = Value}]};
+	<<"pcode">> -> V#vcard_temp{adr = [A#vcard_adr{pcode = Value}]};
+	_ -> V
+    end.
 
 map_vcard_attr(VCardName, Attributes, Pattern, UD) ->
     Res = lists:filter(fun ({Name, _, _}) ->
-- 
cgit v1.2.3


From c0272ae7669b548a3cd568229748377feba71e57 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Sun, 31 Jul 2016 14:51:16 +0300
Subject: Rewrite mod_stats to use XML generator

---
 src/mod_stats.erl  | 104 +++++++++++++++-----------------------------
 src/xmpp_codec.erl | 125 +++++++++++++++++++++++++++++++----------------------
 2 files changed, 108 insertions(+), 121 deletions(-)

(limited to 'src')

diff --git a/src/mod_stats.erl b/src/mod_stats.erl
index 99059839a..c4b8ddb15 100644
--- a/src/mod_stats.erl
+++ b/src/mod_stats.erl
@@ -31,65 +31,39 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process_local_iq/3,
-	 mod_opt_type/1, depends/2]).
+-export([start/2, stop/1, process_iq/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 start(Host, Opts) ->
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                              one_queue),
-    gen_iq_handler:add_iq_handler(ejabberd_local, Host,
-				  ?NS_STATS, ?MODULE, process_local_iq, IQDisc).
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
+				  ?MODULE, process_iq, IQDisc).
 
 stop(Host) ->
-    gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
-				     ?NS_STATS).
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
 
 depends(_Host, _Opts) ->
     [].
 
-process_local_iq(_From, To,
-		 #iq{id = _ID, type = Type, xmlns = XMLNS,
-		     sub_el = SubEl, lang = Lang} =
-		     IQ) ->
-    case Type of
-      set ->
-	  Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
-	  IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
-      get ->
-	  #xmlel{children = Els} = SubEl,
-	  Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl),
-			    <<"/">>),
-	  Names = get_names(Els, []),
-	  case get_local_stats(To#jid.server, Node, Names, Lang) of
-	    {result, Res} ->
-		IQ#iq{type = result,
-		      sub_el =
-			  [#xmlel{name = <<"query">>,
-				  attrs = [{<<"xmlns">>, XMLNS}],
-				  children = Res}]};
-	    {error, Error} ->
-		IQ#iq{type = error, sub_el = [SubEl, Error]}
-	  end
+process_iq(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_iq(#iq{type = get, to = To, lang = Lang,
+	       sub_els = [#stats{} = Stats]} = IQ) ->
+    Node = str:tokens(Stats#stats.node, <<"/">>),
+    Names = [Name || #stat{name = Name} <- Stats#stats.list],
+    case get_local_stats(To#jid.server, Node, Names, Lang) of
+	{result, List} ->
+	    xmpp:make_iq_result(IQ, Stats#stats{list = List});
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
     end.
 
-get_names([], Res) -> Res;
-get_names([#xmlel{name = <<"stat">>, attrs = Attrs}
-	   | Els],
-	  Res) ->
-    Name = fxml:get_attr_s(<<"name">>, Attrs),
-    case Name of
-      <<"">> -> get_names(Els, Res);
-      _ -> get_names(Els, [Name | Res])
-    end;
-get_names([_ | Els], Res) -> get_names(Els, Res).
-
--define(STAT(Name),
-	#xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
-	       children = []}).
+-define(STAT(Name), #stat{name = Name}).
 
 get_local_stats(_Server, [], [], _Lang) ->
     {result,
@@ -115,7 +89,7 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
     case search_running_node(ENode) of
       false ->
 	    Txt = <<"No running node found">>,
-	    {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
 	  {result,
 	   lists:map(fun (Name) -> get_node_stat(Node, Name) end,
@@ -123,27 +97,19 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
     end;
 get_local_stats(_Server, _, _, Lang) ->
     Txt = <<"No statistics found for this item">>,
-    {error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}.
+    {error, xmpp:err_feature_not_implemented(Txt, Lang)}.
 
--define(STATVAL(Val, Unit),
-	#xmlel{name = <<"stat">>,
-	       attrs =
-		   [{<<"name">>, Name}, {<<"units">>, Unit},
-		    {<<"value">>, Val}],
-	       children = []}).
+-define(STATVAL(Val, Unit), #stat{name = Name, units = Unit, value = Val}).
 
 -define(STATERR(Code, Desc),
-	#xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
-	       children =
-		   [#xmlel{name = <<"error">>,
-			   attrs = [{<<"code">>, Code}],
-			   children = [{xmlcdata, Desc}]}]}).
+	#stat{name = Name,
+	      error = #stat_error{code = Code, reason = Desc}}).
 
 get_local_stat(Server, [], Name)
     when Name == <<"users/online">> ->
     case catch ejabberd_sm:get_vh_session_list(Server) of
       {'EXIT', _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Users ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
 		   <<"users">>)
@@ -154,7 +120,7 @@ get_local_stat(Server, [], Name)
 	   ejabberd_auth:get_vh_registered_users_number(Server)
 	of
       {'EXIT', _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       NUsers ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(NUsers))),
 		   <<"users">>)
@@ -163,7 +129,7 @@ get_local_stat(_Server, [], Name)
     when Name == <<"users/all-hosts/online">> ->
     case catch mnesia:table_info(session, size) of
       {'EXIT', _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Users ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(Users))),
 		   <<"users">>)
@@ -178,7 +144,7 @@ get_local_stat(_Server, [], Name)
     ?STATVAL((iolist_to_binary(integer_to_list(NumUsers))),
 	     <<"users">>);
 get_local_stat(_Server, _, Name) ->
-    ?STATERR(<<"404">>, <<"Not Found">>).
+    ?STATERR(404, <<"Not Found">>).
 
 get_node_stat(Node, Name)
     when Name == <<"time/uptime">> ->
@@ -186,7 +152,7 @@ get_node_stat(Node, Name)
 			[wall_clock])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       CPUTime ->
 	  ?STATVAL(list_to_binary(
                      io_lib:format("~.3f",
@@ -198,7 +164,7 @@ get_node_stat(Node, Name)
     case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       RunTime ->
 	  ?STATVAL(list_to_binary(
                      io_lib:format("~.3f",
@@ -211,7 +177,7 @@ get_node_stat(Node, Name)
 			dirty_get_my_sessions_list, [])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Users ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
 		   <<"users">>)
@@ -222,7 +188,7 @@ get_node_stat(Node, Name)
 			[transaction_commits])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
 		   <<"transactions">>)
@@ -233,7 +199,7 @@ get_node_stat(Node, Name)
 			[transaction_failures])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
 		   <<"transactions">>)
@@ -244,7 +210,7 @@ get_node_stat(Node, Name)
 			[transaction_restarts])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
 		   <<"transactions">>)
@@ -255,13 +221,13 @@ get_node_stat(Node, Name)
 			[transaction_log_writes])
 	of
       {badrpc, _Reason} ->
-	  ?STATERR(<<"500">>, <<"Internal Server Error">>);
+	  ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
 	  ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
 		   <<"transactions">>)
     end;
 get_node_stat(_, Name) ->
-    ?STATERR(<<"404">>, <<"Not Found">>).
+    ?STATERR(404, <<"Not Found">>).
 
 search_running_node(SNode) ->
     search_running_node(SNode,
diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl
index 6fddf97ed..e0a5d47c9 100644
--- a/src/xmpp_codec.erl
+++ b/src/xmpp_codec.erl
@@ -2222,11 +2222,15 @@ encode({bookmark_url, _, _} = Url) ->
 encode({bookmark_storage, _, _} = Storage) ->
     encode_bookmarks_storage(Storage,
 			     [{<<"xmlns">>, <<"storage:bookmarks">>}]);
+encode({stat_error, _, _} = Error) ->
+    encode_stat_error(Error,
+		      [{<<"xmlns">>,
+			<<"http://jabber.org/protocol/stats">>}]);
 encode({stat, _, _, _, _} = Stat) ->
     encode_stat(Stat,
 		[{<<"xmlns">>,
 		  <<"http://jabber.org/protocol/stats">>}]);
-encode({stats, _} = Query) ->
+encode({stats, _, _} = Query) ->
     encode_stats(Query,
 		 [{<<"xmlns">>,
 		   <<"http://jabber.org/protocol/stats">>}]);
@@ -2734,8 +2738,9 @@ get_name({bookmark_conference, _, _, _, _, _}) ->
     <<"conference">>;
 get_name({bookmark_url, _, _}) -> <<"url">>;
 get_name({bookmark_storage, _, _}) -> <<"storage">>;
+get_name({stat_error, _, _}) -> <<"error">>;
 get_name({stat, _, _, _, _}) -> <<"stat">>;
-get_name({stats, _}) -> <<"query">>;
+get_name({stats, _, _}) -> <<"query">>;
 get_name({iq, _, _, _, _, _, _}) -> <<"iq">>;
 get_name({message, _, _, _, _, _, _, _, _, _}) ->
     <<"message">>;
@@ -2939,9 +2944,11 @@ get_ns({bookmark_conference, _, _, _, _, _}) ->
 get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>;
 get_ns({bookmark_storage, _, _}) ->
     <<"storage:bookmarks">>;
+get_ns({stat_error, _, _}) ->
+    <<"http://jabber.org/protocol/stats">>;
 get_ns({stat, _, _, _, _}) ->
     <<"http://jabber.org/protocol/stats">>;
-get_ns({stats, _}) ->
+get_ns({stats, _, _}) ->
     <<"http://jabber.org/protocol/stats">>;
 get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>;
 get_ns({message, _, _, _, _, _, _, _, _, _}) ->
@@ -3254,8 +3261,9 @@ pp(bookmark_conference, 5) ->
     [name, jid, autojoin, nick, password];
 pp(bookmark_url, 2) -> [name, url];
 pp(bookmark_storage, 2) -> [conference, url];
+pp(stat_error, 2) -> [code, reason];
 pp(stat, 4) -> [name, units, value, error];
-pp(stats, 1) -> [stat];
+pp(stats, 2) -> [list, node];
 pp(iq, 6) -> [id, type, lang, from, to, sub_els];
 pp(message, 9) ->
     [id, type, lang, from, to, subject, body, thread,
@@ -25097,53 +25105,70 @@ encode_iq_attr_to(_val, _acc) ->
 
 decode_stats(__TopXMLNS, __IgnoreEls,
 	     {xmlel, <<"query">>, _attrs, _els}) ->
-    Stat = decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
+    List = decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
 			    []),
-    {stats, Stat}.
+    Node = decode_stats_attrs(__TopXMLNS, _attrs,
+			      undefined),
+    {stats, List, Node}.
 
-decode_stats_els(__TopXMLNS, __IgnoreEls, [], Stat) ->
-    lists:reverse(Stat);
+decode_stats_els(__TopXMLNS, __IgnoreEls, [], List) ->
+    lists:reverse(List);
 decode_stats_els(__TopXMLNS, __IgnoreEls,
-		 [{xmlel, <<"stat">>, _attrs, _} = _el | _els], Stat) ->
+		 [{xmlel, <<"stat">>, _attrs, _} = _el | _els], List) ->
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">>
 	  when __TopXMLNS ==
 		 <<"http://jabber.org/protocol/stats">> ->
 	  decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
-			   [decode_stat(__TopXMLNS, __IgnoreEls, _el) | Stat]);
+			   [decode_stat(__TopXMLNS, __IgnoreEls, _el) | List]);
       <<"http://jabber.org/protocol/stats">> ->
 	  decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
 			   [decode_stat(<<"http://jabber.org/protocol/stats">>,
 					__IgnoreEls, _el)
-			    | Stat]);
+			    | List]);
       _ ->
-	  decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat)
+	  decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List)
     end;
 decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els],
-		 Stat) ->
-    decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat).
-
-encode_stats({stats, Stat}, _xmlns_attrs) ->
-    _els = lists:reverse('encode_stats_$stat'(Stat, [])),
-    _attrs = _xmlns_attrs,
+		 List) ->
+    decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List).
+
+decode_stats_attrs(__TopXMLNS,
+		   [{<<"node">>, _val} | _attrs], _Node) ->
+    decode_stats_attrs(__TopXMLNS, _attrs, _val);
+decode_stats_attrs(__TopXMLNS, [_ | _attrs], Node) ->
+    decode_stats_attrs(__TopXMLNS, _attrs, Node);
+decode_stats_attrs(__TopXMLNS, [], Node) ->
+    decode_stats_attr_node(__TopXMLNS, Node).
+
+encode_stats({stats, List, Node}, _xmlns_attrs) ->
+    _els = lists:reverse('encode_stats_$list'(List, [])),
+    _attrs = encode_stats_attr_node(Node, _xmlns_attrs),
     {xmlel, <<"query">>, _attrs, _els}.
 
-'encode_stats_$stat'([], _acc) -> _acc;
-'encode_stats_$stat'([Stat | _els], _acc) ->
-    'encode_stats_$stat'(_els,
-			 [encode_stat(Stat, []) | _acc]).
+'encode_stats_$list'([], _acc) -> _acc;
+'encode_stats_$list'([List | _els], _acc) ->
+    'encode_stats_$list'(_els,
+			 [encode_stat(List, []) | _acc]).
+
+decode_stats_attr_node(__TopXMLNS, undefined) -> <<>>;
+decode_stats_attr_node(__TopXMLNS, _val) -> _val.
+
+encode_stats_attr_node(<<>>, _acc) -> _acc;
+encode_stats_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
 decode_stat(__TopXMLNS, __IgnoreEls,
 	    {xmlel, <<"stat">>, _attrs, _els}) ->
     Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-			    []),
+			    undefined),
     {Name, Units, Value} = decode_stat_attrs(__TopXMLNS,
 					     _attrs, undefined, undefined,
 					     undefined),
     {stat, Name, Units, Value, Error}.
 
 decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) ->
-    lists:reverse(Error);
+    Error;
 decode_stat_els(__TopXMLNS, __IgnoreEls,
 		[{xmlel, <<"error">>, _attrs, _} = _el | _els],
 		Error) ->
@@ -25152,13 +25177,11 @@ decode_stat_els(__TopXMLNS, __IgnoreEls,
 	  when __TopXMLNS ==
 		 <<"http://jabber.org/protocol/stats">> ->
 	  decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-			  [decode_stat_error(__TopXMLNS, __IgnoreEls, _el)
-			   | Error]);
+			  decode_stat_error(__TopXMLNS, __IgnoreEls, _el));
       <<"http://jabber.org/protocol/stats">> ->
 	  decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-			  [decode_stat_error(<<"http://jabber.org/protocol/stats">>,
-					     __IgnoreEls, _el)
-			   | Error]);
+			  decode_stat_error(<<"http://jabber.org/protocol/stats">>,
+					    __IgnoreEls, _el));
       _ ->
 	  decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error)
     end;
@@ -25196,10 +25219,9 @@ encode_stat({stat, Name, Units, Value, Error},
 										 _xmlns_attrs))),
     {xmlel, <<"stat">>, _attrs, _els}.
 
-'encode_stat_$error'([], _acc) -> _acc;
-'encode_stat_$error'([Error | _els], _acc) ->
-    'encode_stat_$error'(_els,
-			 [encode_stat_error(Error, []) | _acc]).
+'encode_stat_$error'(undefined, _acc) -> _acc;
+'encode_stat_$error'(Error, _acc) ->
+    [encode_stat_error(Error, []) | _acc].
 
 decode_stat_attr_name(__TopXMLNS, undefined) ->
     erlang:error({xmpp_codec,
@@ -25209,41 +25231,39 @@ decode_stat_attr_name(__TopXMLNS, _val) -> _val.
 encode_stat_attr_name(_val, _acc) ->
     [{<<"name">>, _val} | _acc].
 
-decode_stat_attr_units(__TopXMLNS, undefined) ->
-    undefined;
+decode_stat_attr_units(__TopXMLNS, undefined) -> <<>>;
 decode_stat_attr_units(__TopXMLNS, _val) -> _val.
 
-encode_stat_attr_units(undefined, _acc) -> _acc;
+encode_stat_attr_units(<<>>, _acc) -> _acc;
 encode_stat_attr_units(_val, _acc) ->
     [{<<"units">>, _val} | _acc].
 
-decode_stat_attr_value(__TopXMLNS, undefined) ->
-    undefined;
+decode_stat_attr_value(__TopXMLNS, undefined) -> <<>>;
 decode_stat_attr_value(__TopXMLNS, _val) -> _val.
 
-encode_stat_attr_value(undefined, _acc) -> _acc;
+encode_stat_attr_value(<<>>, _acc) -> _acc;
 encode_stat_attr_value(_val, _acc) ->
     [{<<"value">>, _val} | _acc].
 
 decode_stat_error(__TopXMLNS, __IgnoreEls,
 		  {xmlel, <<"error">>, _attrs, _els}) ->
-    Cdata = decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-				  _els, <<>>),
+    Reason = decode_stat_error_els(__TopXMLNS, __IgnoreEls,
+				   _els, <<>>),
     Code = decode_stat_error_attrs(__TopXMLNS, _attrs,
 				   undefined),
-    {Code, Cdata}.
+    {stat_error, Code, Reason}.
 
 decode_stat_error_els(__TopXMLNS, __IgnoreEls, [],
-		      Cdata) ->
-    decode_stat_error_cdata(__TopXMLNS, Cdata);
+		      Reason) ->
+    decode_stat_error_cdata(__TopXMLNS, Reason);
 decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-		      [{xmlcdata, _data} | _els], Cdata) ->
+		      [{xmlcdata, _data} | _els], Reason) ->
     decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
-			  <>);
+			  <>);
 decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-		      [_ | _els], Cdata) ->
+		      [_ | _els], Reason) ->
     decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
-			  Cdata).
+			  Reason).
 
 decode_stat_error_attrs(__TopXMLNS,
 			[{<<"code">>, _val} | _attrs], _Code) ->
@@ -25254,8 +25274,9 @@ decode_stat_error_attrs(__TopXMLNS, [_ | _attrs],
 decode_stat_error_attrs(__TopXMLNS, [], Code) ->
     decode_stat_error_attr_code(__TopXMLNS, Code).
 
-encode_stat_error({Code, Cdata}, _xmlns_attrs) ->
-    _els = encode_stat_error_cdata(Cdata, []),
+encode_stat_error({stat_error, Code, Reason},
+		  _xmlns_attrs) ->
+    _els = encode_stat_error_cdata(Reason, []),
     _attrs = encode_stat_error_attr_code(Code,
 					 _xmlns_attrs),
     {xmlel, <<"error">>, _attrs, _els}.
@@ -25274,10 +25295,10 @@ decode_stat_error_attr_code(__TopXMLNS, _val) ->
 encode_stat_error_attr_code(_val, _acc) ->
     [{<<"code">>, enc_int(_val)} | _acc].
 
-decode_stat_error_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_stat_error_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_stat_error_cdata(__TopXMLNS, _val) -> _val.
 
-encode_stat_error_cdata(undefined, _acc) -> _acc;
+encode_stat_error_cdata(<<>>, _acc) -> _acc;
 encode_stat_error_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-- 
cgit v1.2.3


From 5d06c6acbf9dfc69085f29ce38fe0ac6bdf5d9b0 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Wed, 3 Aug 2016 10:34:54 +0300
Subject: Rewrite mod_configure to use XML generator

---
 src/mod_configure.erl | 1876 +++++++++++++++++++------------------------------
 1 file changed, 729 insertions(+), 1147 deletions(-)

(limited to 'src')

diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index 97c944842..342a15232 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -40,10 +40,8 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
-
--include("jlib.hrl").
+-include("xmpp.hrl").
 -include("ejabberd_sm.hrl").
--include("adhoc.hrl").
 
 -define(T(Lang, Text), translate:translate(Lang, Text)).
 
@@ -102,29 +100,19 @@ depends(_Host, _Opts) ->
 %%%-----------------------------------------------------------------------
 
 -define(INFO_IDENTITY(Category, Type, Name, Lang),
-	[#xmlel{name = <<"identity">>,
-		attrs =
-		    [{<<"category">>, Category}, {<<"type">>, Type},
-		     {<<"name">>, ?T(Lang, Name)}],
-		children = []}]).
+	[#identity{category = Category, type = Type, name = ?T(Lang, Name)}]).
 
 -define(INFO_COMMAND(Name, Lang),
 	?INFO_IDENTITY(<<"automation">>, <<"command-node">>,
 		       Name, Lang)).
 
 -define(NODEJID(To, Name, Node),
-	#xmlel{name = <<"item">>,
-	       attrs =
-		   [{<<"jid">>, jid:to_string(To)},
-		    {<<"name">>, ?T(Lang, Name)}, {<<"node">>, Node}],
-	       children = []}).
+	#disco_item{jid = To, name = ?T(Lang, Name), node = Node}).
 
 -define(NODE(Name, Node),
-	#xmlel{name = <<"item">>,
-	       attrs =
-		   [{<<"jid">>, Server}, {<<"name">>, ?T(Lang, Name)},
-		    {<<"node">>, Node}],
-	       children = []}).
+	#disco_item{jid = jid:make(Server),
+		    node = Node,
+		    name = ?T(Lang, Name)}).
 
 -define(NS_ADMINX(Sub),
 	<<(?NS_ADMIN)/binary, "#", Sub/binary>>).
@@ -133,6 +121,7 @@ depends(_Host, _Opts) ->
 	[<<"http:">>, <<"jabber.org">>, <<"protocol">>,
 	 <<"admin">>, Sub]).
 
+tokenize(undefined) -> [];
 tokenize(Node) -> str:tokens(Node, <<"/#">>).
 
 get_sm_identity(Acc, _From, _To, Node, Lang) ->
@@ -204,7 +193,7 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
 
 -define(INFO_RESULT(Allow, Feats, Lang),
 	case Allow of
-	  deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+	  deny -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
 	  allow -> {result, Feats}
 	end).
 
@@ -291,12 +280,8 @@ adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To,
 		    {result, Its} -> Its;
 		    empty -> []
 		  end,
-	  Nodes = [#xmlel{name = <<"item">>,
-			  attrs =
-			      [{<<"jid">>, jid:to_string(To)},
-			       {<<"name">>, ?T(Lang, <<"Configuration">>)},
-			       {<<"node">>, <<"config">>}],
-			  children = []}],
+	  Nodes = [#disco_item{jid = To, node = <<"config">>,
+			       name = ?T(Lang, <<"Configuration">>)}],
 	  {result, Items ++ Nodes};
       _ -> Acc
     end.
@@ -315,7 +300,7 @@ get_sm_items(Acc, From,
 		    empty -> []
 		  end,
 	  case {acl:match_rule(LServer, configure, From), Node} of
-	    {allow, <<"">>} ->
+	    {allow, undefined} ->
 		Nodes = [?NODEJID(To, <<"Configuration">>,
 				  <<"config">>),
 			 ?NODEJID(To, <<"User Management">>, <<"user">>)],
@@ -323,7 +308,7 @@ get_sm_items(Acc, From,
 		 Items ++ Nodes ++ get_user_resources(User, Server)};
 	    {allow, <<"config">>} -> {result, []};
 	    {_, <<"config">>} ->
-		  {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+		  {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
 	    _ -> Acc
 	  end
     end.
@@ -331,13 +316,8 @@ get_sm_items(Acc, From,
 get_user_resources(User, Server) ->
     Rs = ejabberd_sm:get_user_resources(User, Server),
     lists:map(fun (R) ->
-		      #xmlel{name = <<"item">>,
-			     attrs =
-				 [{<<"jid">>,
-				   <>},
-				  {<<"name">>, User}],
-			     children = []}
+		      #disco_item{jid = jid:make(User, Server, R),
+				  name = User}
 	      end,
 	      lists:sort(Rs)).
 
@@ -383,25 +363,19 @@ recursively_get_local_items(PermLev, LServer, Node,
 	      {result, Res} -> Res;
 	      {error, _Error} -> []
 	    end,
-    Nodes = lists:flatten(lists:map(fun (N) ->
-					    S = fxml:get_tag_attr_s(<<"jid">>,
-								   N),
-					    Nd = fxml:get_tag_attr_s(<<"node">>,
-								    N),
-					    if (S /= Server) or
-						 (Nd == <<"">>) ->
-						   [];
-					       true ->
-						   [N,
-						    recursively_get_local_items(PermLev,
-										LServer,
-										Nd,
-										Server,
-										Lang)]
-					    end
-				    end,
-				    Items)),
-    Nodes.
+    lists:flatten(
+      lists:map(
+	fun(#disco_item{jid = #jid{server = S}, node = Nd} = Item) ->
+		if (S /= Server) or
+		   (Nd == <<"">>) ->
+			[];
+		   true ->
+			[Item,
+			 recursively_get_local_items(
+			   PermLev, LServer, Nd, Server, Lang)]
+		end
+	end,
+	Items)).
 
 get_permission_level(JID) ->
     case acl:match_rule(global, configure, JID) of
@@ -425,7 +399,7 @@ get_permission_level(JID) ->
 	end).
 
 get_local_items(Acc, From, #jid{lserver = LServer} = To,
-		<<"">>, Lang) ->
+		undefined, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
       false -> Acc;
       _ ->
@@ -453,7 +427,7 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
       _ ->
 	  LNode = tokenize(Node),
 	  Allow = acl:match_rule(LServer, configure, From),
-	  Err = ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>),
+	  Err = xmpp:err_forbidden(<<"Denied by ACL">>, Lang),
 	  case LNode of
 	    [<<"config">>] ->
 		?ITEMS_RESULT(Allow, LNode, {error, Err});
@@ -570,27 +544,18 @@ get_local_items({_, Host},
 		_Lang) ->
     Users = ejabberd_auth:get_vh_registered_users(Host),
     SUsers = lists:sort([{S, U} || {U, S} <- Users]),
-    case catch begin
-		   [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
-		   N1 = jlib:binary_to_integer(S1),
-		   N2 = jlib:binary_to_integer(S2),
-		   Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
-		   lists:map(fun ({S, U}) ->
-				     #xmlel{name = <<"item">>,
-					    attrs =
-						[{<<"jid">>,
-						  <>},
-						 {<<"name">>,
-						  <>}],
-					    children = []}
-			     end,
-			     Sub)
-	       end
-    of
-	{'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
-	Res -> {result, Res}
+    try
+	[S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
+	N1 = jlib:binary_to_integer(S1),
+	N2 = jlib:binary_to_integer(S2),
+	Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
+	{result, lists:map(
+		   fun({S, U}) ->
+			   #disco_item{jid = jid:make(U, S),
+				       name = <>}
+		   end, Sub)}
+    catch _:_ ->
+	    xmpp:err_not_acceptable()
     end;
 get_local_items({_, Host}, [<<"outgoing s2s">>],
 		_Server, Lang) ->
@@ -676,24 +641,18 @@ get_local_items(_Host,
 		_Lang) ->
     {result, []};
 get_local_items(_Host, _, _Server, _Lang) ->
-    {error, ?ERR_ITEM_NOT_FOUND}.
+    {error, xmpp:err_item_not_found()}.
 
 get_online_vh_users(Host) ->
     case catch ejabberd_sm:get_vh_session_list(Host) of
       {'EXIT', _Reason} -> [];
       USRs ->
 	  SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
-	  lists:map(fun ({S, U, R}) ->
-			    #xmlel{name = <<"item">>,
-				   attrs =
-				       [{<<"jid">>,
-					 <>},
-					{<<"name">>,
-					 <>}],
-				   children = []}
-		    end,
-		    SURs)
+	  lists:map(
+	    fun({S, U, R}) ->
+		    #disco_item{jid = jid:make(U, S, R),
+				name = <>}
+		    end, SURs)
     end.
 
 get_all_vh_users(Host) ->
@@ -704,16 +663,10 @@ get_all_vh_users(Host) ->
 	  SUsers = lists:sort([{S, U} || {U, S} <- Users]),
 	  case length(SUsers) of
 	    N when N =< 100 ->
-		lists:map(fun ({S, U}) ->
-				  #xmlel{name = <<"item">>,
-					 attrs =
-					     [{<<"jid">>,
-					       <>},
-					      {<<"name">>,
-					       <>}],
-					 children = []}
-			  end,
-			  SUsers);
+		lists:map(fun({S, U}) ->
+				  #disco_item{jid = jid:make(U, S),
+					      name = <>}
+			  end, SUsers);
 	    N ->
 		NParts = trunc(math:sqrt(N * 6.17999999999999993783e-1))
 			   + 1,
@@ -730,13 +683,9 @@ get_all_vh_users(Host) ->
 					     end,
 				  Name = <>,
-				  #xmlel{name = <<"item">>,
-					 attrs =
-					     [{<<"jid">>, Host},
-					      {<<"node">>,
-					       <<"all users/", Node/binary>>},
-					      {<<"name">>, Name}],
-					 children = []}
+				  #disco_item{jid = jid:make(Host),
+					      node = <<"all users/", Node/binary>>,
+					      name = Name}
 			  end,
 			  lists:seq(1, N, M))
 	  end
@@ -750,59 +699,45 @@ get_outgoing_s2s(Host, Lang) ->
 	  TConns = [TH
 		    || {FH, TH} <- Connections,
 		       Host == FH orelse str:suffix(DotHost, FH)],
-	  lists:map(fun (T) ->
-			    #xmlel{name = <<"item">>,
-				   attrs =
-				       [{<<"jid">>, Host},
-					{<<"node">>,
-					 <<"outgoing s2s/", T/binary>>},
-					{<<"name">>,
-					 iolist_to_binary(io_lib:format(?T(Lang,
-									   <<"To ~s">>),
-									[T]))}],
-				   children = []}
-		    end,
-		    lists:usort(TConns))
+	  lists:map(
+	    fun (T) ->
+		    Name = iolist_to_binary(
+			     io_lib:format(?T(Lang, <<"To ~s">>),[T])),
+		    #disco_item{jid = jid:make(Host),
+				node = <<"outgoing s2s/", T/binary>>,
+				name = Name}
+	    end, lists:usort(TConns))
     end.
 
 get_outgoing_s2s(Host, Lang, To) ->
     case catch ejabberd_s2s:dirty_get_connections() of
       {'EXIT', _Reason} -> [];
       Connections ->
-	  lists:map(fun ({F, _T}) ->
-			    #xmlel{name = <<"item">>,
-				   attrs =
-				       [{<<"jid">>, Host},
-					{<<"node">>,
-					 <<"outgoing s2s/", To/binary, "/",
-					   F/binary>>},
-					{<<"name">>,
-					 iolist_to_binary(io_lib:format(?T(Lang,
-									   <<"From ~s">>),
-									[F]))}],
-				   children = []}
-		    end,
-		    lists:keysort(1,
-				  lists:filter(fun (E) -> element(2, E) == To
-					       end,
-					       Connections)))
+	  lists:map(
+	    fun ({F, _T}) ->
+		    Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
+		    Name = iolist_to_binary(
+			     io_lib:format(?T(Lang, <<"From ~s">>), [F])),
+		    #disco_item{jid = jid:make(Host), node = Node, name = Name}
+	    end,
+	    lists:keysort(1,
+			  lists:filter(fun (E) -> element(2, E) == To
+				       end,
+				       Connections)))
     end.
 
 get_running_nodes(Server, _Lang) ->
     case catch mnesia:system_info(running_db_nodes) of
       {'EXIT', _Reason} -> [];
       DBNodes ->
-	  lists:map(fun (N) ->
-			    S = iolist_to_binary(atom_to_list(N)),
-			    #xmlel{name = <<"item">>,
-				   attrs =
-				       [{<<"jid">>, Server},
-					{<<"node">>,
-					 <<"running nodes/", S/binary>>},
-					{<<"name">>, S}],
-				   children = []}
-		    end,
-		    lists:sort(DBNodes))
+	  lists:map(
+	    fun (N) ->
+		    S = iolist_to_binary(atom_to_list(N)),
+		    #disco_item{jid = jid:make(Server),
+				node = <<"running nodes/", S/binary>>,
+				name = S}
+	    end,
+	    lists:sort(DBNodes))
     end.
 
 get_stopped_nodes(_Lang) ->
@@ -812,17 +747,14 @@ get_stopped_nodes(_Lang) ->
 	of
       {'EXIT', _Reason} -> [];
       DBNodes ->
-	  lists:map(fun (N) ->
-			    S = iolist_to_binary(atom_to_list(N)),
-			    #xmlel{name = <<"item">>,
-				   attrs =
-				       [{<<"jid">>, ?MYNAME},
-					{<<"node">>,
-					 <<"stopped nodes/", S/binary>>},
-					{<<"name">>, S}],
-				   children = []}
-		    end,
-		    lists:sort(DBNodes))
+	  lists:map(
+	    fun (N) ->
+		    S = iolist_to_binary(atom_to_list(N)),
+		    #disco_item{jid = jid:make(?MYNAME),
+				node = <<"stopped nodes/", S/binary>>,
+				name = S}
+	    end,
+	    lists:sort(DBNodes))
     end.
 
 %%-------------------------------------------------------------------------
@@ -830,13 +762,13 @@ get_stopped_nodes(_Lang) ->
 -define(COMMANDS_RESULT(LServerOrGlobal, From, To,
 			Request, Lang),
 	case acl:match_rule(LServerOrGlobal, configure, From) of
-	  deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+	  deny -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
 	  allow -> adhoc_local_commands(From, To, Request)
 	end).
 
 adhoc_local_commands(Acc, From,
 		     #jid{lserver = LServer} = To,
-		     #adhoc_request{node = Node, lang = Lang} = Request) ->
+		     #adhoc_command{node = Node, lang = Lang} = Request) ->
     LNode = tokenize(Node),
     case LNode of
       [<<"running nodes">>, _ENode, <<"DB">>] ->
@@ -860,171 +792,107 @@ adhoc_local_commands(Acc, From,
 
 adhoc_local_commands(From,
 		     #jid{lserver = LServer} = _To,
-		     #adhoc_request{lang = Lang, node = Node,
-				    sessionid = SessionID, action = Action,
-				    xdata = XData} =
-			 Request) ->
+		     #adhoc_command{lang = Lang, node = Node,
+				    sid = SessionID, action = Action,
+				    xdata = XData} = Request) ->
     LNode = tokenize(Node),
-    ActionIsExecute = lists:member(Action,
-				   [<<"">>, <<"execute">>, <<"complete">>]),
-    if Action == <<"cancel">> ->
-	   adhoc:produce_response(Request,
-				  #adhoc_response{status = canceled});
-       XData == false, ActionIsExecute ->
+    ActionIsExecute = Action == execute orelse Action == complete,
+    if Action == cancel ->
+	    #adhoc_command{status = canceled, lang = Lang,
+			   node = Node, sid = SessionID};
+       XData == undefined, ActionIsExecute ->
 	   case get_form(LServer, LNode, Lang) of
 	     {result, Form} ->
-		 adhoc:produce_response(Request,
-					#adhoc_response{status = executing,
-							elements = Form});
+		 xmpp_util:make_adhoc_response(
+		   Request,
+		   #adhoc_command{status = executing, xdata = Form});
 	     {result, Status, Form} ->
-		 adhoc:produce_response(Request,
-					#adhoc_response{status = Status,
-							elements = Form});
+		 xmpp_util:make_adhoc_response(
+		   Request,
+		   #adhoc_command{status = Status, xdata = Form});
 	     {error, Error} -> {error, Error}
 	   end;
-       XData /= false, ActionIsExecute ->
-	   case jlib:parse_xdata_submit(XData) of
-	     invalid ->
-		 {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
-	     Fields ->
-		 case catch set_form(From, LServer, LNode, Lang, Fields)
-		     of
-		   {result, Res} ->
-		       adhoc:produce_response(#adhoc_response{lang = Lang,
-							      node = Node,
-							      sessionid =
-								  SessionID,
-							      elements = Res,
-							      status =
-								  completed});
-		   {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
-		   {error, Error} -> {error, Error}
-		 end
-	   end;
+       XData /= undefined, ActionIsExecute ->
+	    case catch set_form(From, LServer, LNode, Lang, XData) of
+		{result, Res} ->
+		    xmpp_util:make_adhoc_response(
+		      Request,
+		      #adhoc_command{xdata = Res, status = completed});
+		{'EXIT', _} -> {error, xmpp:err_bad_request()};
+		{error, Error} -> {error, Error}
+	    end;
        true ->
-	  {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect action or data form">>)}
+	  {error, xmpp:err_bad_request(<<"Unexpected action">>, Lang)}
     end.
 
 -define(TVFIELD(Type, Var, Val),
-	#xmlel{name = <<"field">>,
-	       attrs = [{<<"type">>, Type}, {<<"var">>, Var}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children = [{xmlcdata, Val}]}]}).
+	#xdata_field{type = Type, var = Var, values = [Val]}).
 
 -define(HFIELD(),
-	?TVFIELD(<<"hidden">>, <<"FORM_TYPE">>, (?NS_ADMIN))).
+	?TVFIELD(hidden, <<"FORM_TYPE">>, (?NS_ADMIN))).
 
 -define(TLFIELD(Type, Label, Var),
-	#xmlel{name = <<"field">>,
-	       attrs =
-		   [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
-		    {<<"var">>, Var}],
-	       children = []}).
+	#xdata_field{type = Type, label = ?T(Lang, Label), var = Var}).
 
 -define(XFIELD(Type, Label, Var, Val),
-	#xmlel{name = <<"field">>,
-	       attrs =
-		   [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
-		    {<<"var">>, Var}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children = [{xmlcdata, Val}]}]}).
+	#xdata_field{type = Type, label = ?T(Lang, Label),
+		     var = Var, values = [Val]}).
 
 -define(XMFIELD(Type, Label, Var, Vals),
-	#xmlel{name = <<"field">>,
-	       attrs =
-		   [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
-		    {<<"var">>, Var}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children = [{xmlcdata, Val}]}
-		    || Val <- Vals]}).
+	#xdata_field{type = Type, label = ?T(Lang, Label),
+		     var = Var, values = Vals}).
 
 -define(TABLEFIELD(Table, Val),
-	#xmlel{name = <<"field">>,
-	       attrs =
-		   [{<<"type">>, <<"list-single">>},
-		    {<<"label">>, iolist_to_binary(atom_to_list(Table))},
-		    {<<"var">>, iolist_to_binary(atom_to_list(Table))}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children =
-			       [{xmlcdata,
-				 iolist_to_binary(atom_to_list(Val))}]},
-		    #xmlel{name = <<"option">>,
-			   attrs = [{<<"label">>, ?T(Lang, <<"RAM copy">>)}],
-			   children =
-			       [#xmlel{name = <<"value">>, attrs = [],
-				       children =
-					   [{xmlcdata, <<"ram_copies">>}]}]},
-		    #xmlel{name = <<"option">>,
-			   attrs =
-			       [{<<"label">>,
-				 ?T(Lang, <<"RAM and disc copy">>)}],
-			   children =
-			       [#xmlel{name = <<"value">>, attrs = [],
-				       children =
-					   [{xmlcdata, <<"disc_copies">>}]}]},
-		    #xmlel{name = <<"option">>,
-			   attrs =
-			       [{<<"label">>, ?T(Lang, <<"Disc only copy">>)}],
-			   children =
-			       [#xmlel{name = <<"value">>, attrs = [],
-				       children =
-					   [{xmlcdata,
-					     <<"disc_only_copies">>}]}]},
-		    #xmlel{name = <<"option">>,
-			   attrs = [{<<"label">>, ?T(Lang, <<"Remote copy">>)}],
-			   children =
-			       [#xmlel{name = <<"value">>, attrs = [],
-				       children =
-					   [{xmlcdata, <<"unknown">>}]}]}]}).
+	#xdata_field{
+	   type = 'list-single',
+	   label = iolist_to_binary(atom_to_list(Table)),
+	   var = iolist_to_binary(atom_to_list(Table)),
+	   values = [iolist_to_binary(atom_to_list(Val))],
+	   options = [#xdata_option{label = ?T(Lang, <<"RAM copy">>),
+				    value = <<"ram_copies">>},
+		      #xdata_option{label = ?T(Lang, <<"RAM and disc copy">>),
+				    value = <<"disc_copies">>},
+		      #xdata_option{label = ?T(Lang, <<"Disc only copy">>),
+				    value =  <<"disc_only_copies">>},
+		      #xdata_option{label = ?T(Lang, <<"Remote copy">>),
+				    value = <<"unknown">>}]}).
 
 get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
 	 Lang) ->
     case search_running_node(ENode) of
       false ->
 	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+	  {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
 	  case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
 	    {badrpc, Reason} ->
 		?ERROR_MSG("RPC call mnesia:system_info(tables) on node "
 			   "~s failed: ~p", [Node, Reason]),
-		{error, ?ERR_INTERNAL_SERVER_ERROR};
+		{error, xmpp:err_internal_server_error()};
 	    Tables ->
 		STables = lists:sort(Tables),
-		{result,
-		 [#xmlel{name = <<"x">>,
-			 attrs = [{<<"xmlns">>, ?NS_XDATA}],
-			 children =
-			     [?HFIELD(),
-			      #xmlel{name = <<"title">>, attrs = [],
-				     children =
-					 [{xmlcdata,
-					   <<(?T(Lang,
-						 <<"Database Tables Configuration at ">>))/binary,
-					     ENode/binary>>}]},
-			      #xmlel{name = <<"instructions">>, attrs = [],
-				     children =
-					 [{xmlcdata,
-					   ?T(Lang,
-					      <<"Choose storage type of tables">>)}]}
-			      | lists:map(fun (Table) ->
-						  case ejabberd_cluster:call(Node, mnesia,
-								table_info,
-								[Table,
-								 storage_type])
-						      of
-						    {badrpc, _} ->
-							?TABLEFIELD(Table,
-								    unknown);
-						    Type ->
-							?TABLEFIELD(Table, Type)
-						  end
-					  end,
-					  STables)]}]}
+		Title = <<(?T(Lang, <<"Database Tables Configuration at ">>))/binary,
+			  ENode/binary>>,
+		Instr = ?T(Lang, <<"Choose storage type of tables">>),
+		try
+		    Fs = lists:map(
+			   fun(Table) ->
+				   case ejabberd_cluster:call(
+					  Node, mnesia, table_info,
+					  [Table, storage_type]) of
+				       Type when is_atom(Type) ->
+					   ?TABLEFIELD(Table, Type)
+				   end
+			   end, STables),
+		    {result, #xdata{title = Title,
+				    type = form,
+				    instructions = [Instr],
+				    fields = [?HFIELD()|Fs]}}
+		catch _:{case_clause, {badrpc, Reason}} ->
+			?ERROR_MSG("RPC call mnesia:table_info/2 "
+				   "on node ~s failed: ~p", [Node, Reason]),
+			{error, xmpp:err_internal_server_error()}
+		end
 	  end
     end;
 get_form(Host,
@@ -1033,37 +901,26 @@ get_form(Host,
     case search_running_node(ENode) of
       false ->
 	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+	  {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
 	  case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
 	    {badrpc, Reason} ->
 		?ERROR_MSG("RPC call gen_mod:loaded_modules(~s) on node "
 			   "~s failed: ~p", [Host, Node, Reason]),
-		{error, ?ERR_INTERNAL_SERVER_ERROR};
+		{error, xmpp:err_internal_server_error()};
 	    Modules ->
 		SModules = lists:sort(Modules),
-		{result,
-		 [#xmlel{name = <<"x">>,
-			 attrs = [{<<"xmlns">>, ?NS_XDATA}],
-			 children =
-			     [?HFIELD(),
-			      #xmlel{name = <<"title">>, attrs = [],
-				     children =
-					 [{xmlcdata,
-					   <<(?T(Lang,
-						 <<"Stop Modules at ">>))/binary,
-					     ENode/binary>>}]},
-			      #xmlel{name = <<"instructions">>, attrs = [],
-				     children =
-					 [{xmlcdata,
-					   ?T(Lang,
-					      <<"Choose modules to stop">>)}]}
-			      | lists:map(fun (M) ->
-						  S = jlib:atom_to_binary(M),
-						  ?XFIELD(<<"boolean">>, S, S,
-							  <<"0">>)
-					  end,
-					  SModules)]}]}
+		Title = <<(?T(Lang, <<"Stop Modules at ">>))/binary,
+			  ENode/binary>>,
+		Instr = ?T(Lang, <<"Choose modules to stop">>),
+		Fs = lists:map(fun(M) ->
+				       S = jlib:atom_to_binary(M),
+				       ?XFIELD(boolean, S, S, <<"0">>)
+			       end, SModules),
+		{result, #xdata{title = Title,
+				type = form,
+				instructions = [Instr],
+				fields = [?HFIELD()|Fs]}}
 	  end
     end;
 get_form(_Host,
@@ -1071,153 +928,88 @@ get_form(_Host,
 	  <<"start">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang, <<"Start Modules at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang,
-				  <<"Enter list of {Module, [Options]}">>)}]},
-		  ?XFIELD(<<"text-multi">>,
-			  <<"List of modules to start">>, <<"modules">>,
-			  <<"[].">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Start Modules at ">>))/binary, ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter list of {Module, [Options]}">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-multi',
+			      <<"List of modules to start">>, <<"modules">>,
+			      <<"[].">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"backup">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang, <<"Backup to File at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang, <<"Enter path to backup file">>)}]},
-		  ?XFIELD(<<"text-single">>, <<"Path to File">>,
-			  <<"path">>, <<"">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Backup to File at ">>))/binary, ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter path to backup file">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-single', <<"Path to File">>,
+			      <<"path">>, <<"">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"restore">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang,
-				     <<"Restore Backup from File at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang, <<"Enter path to backup file">>)}]},
-		  ?XFIELD(<<"text-single">>, <<"Path to File">>,
-			  <<"path">>, <<"">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Restore Backup from File at ">>))/binary,
+		      ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter path to backup file">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-single', <<"Path to File">>,
+			      <<"path">>, <<"">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"textfile">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang,
-				     <<"Dump Backup to Text File at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang, <<"Enter path to text file">>)}]},
-		  ?XFIELD(<<"text-single">>, <<"Path to File">>,
-			  <<"path">>, <<"">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Dump Backup to Text File at ">>))/binary,
+		      ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter path to text file">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-single', <<"Path to File">>,
+			      <<"path">>, <<"">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, ENode, <<"import">>, <<"file">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang,
-				     <<"Import User from File at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang,
-				  <<"Enter path to jabberd14 spool file">>)}]},
-		  ?XFIELD(<<"text-single">>, <<"Path to File">>,
-			  <<"path">>, <<"">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Import User from File at ">>))/binary,
+		      ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter path to jabberd14 spool file">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-single', <<"Path to File">>,
+			      <<"path">>, <<"">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang,
-				     <<"Import Users from Dir at ">>))/binary,
-				 ENode/binary>>}]},
-		  #xmlel{name = <<"instructions">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang,
-				  <<"Enter path to jabberd14 spool dir">>)}]},
-		  ?XFIELD(<<"text-single">>, <<"Path to Dir">>,
-			  <<"path">>, <<"">>)]}]};
+     #xdata{title = <<(?T(Lang, <<"Import Users from Dir at ">>))/binary,
+		      ENode/binary>>,
+	    type = form,
+	    instructions = [?T(Lang, <<"Enter path to jabberd14 spool dir">>)],
+	    fields = [?HFIELD(),
+		      ?XFIELD('text-single', <<"Path to Dir">>,
+			      <<"path">>, <<"">>)]}};
 get_form(_Host,
 	 [<<"running nodes">>, _ENode, <<"restart">>], Lang) ->
-    Make_option = fun (LabelNum, LabelUnit, Value) ->
-			  #xmlel{name = <<"option">>,
-				 attrs =
-				     [{<<"label">>,
-				       <>}],
-				 children =
-				     [#xmlel{name = <<"value">>, attrs = [],
-					     children = [{xmlcdata, Value}]}]}
-		  end,
+    Make_option =
+	fun (LabelNum, LabelUnit, Value) ->
+		#xdata_option{
+		   label = <>,
+		   value = Value}
+	end,
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"Restart Service">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"list-single">>},
-			      {<<"label">>, ?T(Lang, <<"Time delay">>)},
-			      {<<"var">>, <<"delay">>}],
-			 children =
+     #xdata{title = ?T(Lang, <<"Restart Service">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{
+			 type = 'list-single',
+			 label = ?T(Lang, <<"Time delay">>),
+			 var = <<"delay">>,
+			 required = true,
+			 options =
 			     [Make_option(<<"">>, <<"immediately">>, <<"1">>),
 			      Make_option(<<"15 ">>, <<"seconds">>, <<"15">>),
 			      Make_option(<<"30 ">>, <<"seconds">>, <<"30">>),
@@ -1229,55 +1021,35 @@ get_form(_Host,
 			      Make_option(<<"5 ">>, <<"minutes">>, <<"300">>),
 			      Make_option(<<"10 ">>, <<"minutes">>, <<"600">>),
 			      Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
-			      Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>),
-			      #xmlel{name = <<"required">>, attrs = [],
-				     children = []}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"fixed">>},
-			      {<<"label">>,
-			       ?T(Lang,
-				  <<"Send announcement to all online users "
-				    "on all hosts">>)}],
-			 children = []},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"var">>, <<"subject">>},
-			      {<<"type">>, <<"text-single">>},
-			      {<<"label">>, ?T(Lang, <<"Subject">>)}],
-			 children = []},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"var">>, <<"announcement">>},
-			      {<<"type">>, <<"text-multi">>},
-			      {<<"label">>, ?T(Lang, <<"Message body">>)}],
-			 children = []}]}]};
+			      Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
+		      #xdata_field{type = fixed,
+				   label = ?T(Lang,
+					      <<"Send announcement to all online users "
+						"on all hosts">>)},
+		      #xdata_field{var = <<"subject">>,
+				   type = 'text-single',
+				   label = ?T(Lang, <<"Subject">>)},
+		      #xdata_field{var = <<"announcement">>,
+				   type = 'text-multi',
+				   label = ?T(Lang, <<"Message body">>)}]}};
 get_form(_Host,
 	 [<<"running nodes">>, _ENode, <<"shutdown">>], Lang) ->
-    Make_option = fun (LabelNum, LabelUnit, Value) ->
-			  #xmlel{name = <<"option">>,
-				 attrs =
-				     [{<<"label">>,
-				       <>}],
-				 children =
-				     [#xmlel{name = <<"value">>, attrs = [],
-					     children = [{xmlcdata, Value}]}]}
-		  end,
+    Make_option =
+	fun (LabelNum, LabelUnit, Value) ->
+		#xdata_option{
+		   label = <>,
+		   value = Value}
+	end,
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"Shut Down Service">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"list-single">>},
-			      {<<"label">>, ?T(Lang, <<"Time delay">>)},
-			      {<<"var">>, <<"delay">>}],
-			 children =
+     #xdata{title = ?T(Lang, <<"Shut Down Service">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{
+			 type = 'list-single',
+			 label = ?T(Lang, <<"Time delay">>),
+			 var = <<"delay">>,
+			 required = true,
+			 options =
 			     [Make_option(<<"">>, <<"immediately">>, <<"1">>),
 			      Make_option(<<"15 ">>, <<"seconds">>, <<"15">>),
 			      Make_option(<<"30 ">>, <<"seconds">>, <<"30">>),
@@ -1289,323 +1061,191 @@ get_form(_Host,
 			      Make_option(<<"5 ">>, <<"minutes">>, <<"300">>),
 			      Make_option(<<"10 ">>, <<"minutes">>, <<"600">>),
 			      Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
-			      Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>),
-			      #xmlel{name = <<"required">>, attrs = [],
-				     children = []}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"fixed">>},
-			      {<<"label">>,
-			       ?T(Lang,
-				  <<"Send announcement to all online users "
-				    "on all hosts">>)}],
-			 children = []},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"var">>, <<"subject">>},
-			      {<<"type">>, <<"text-single">>},
-			      {<<"label">>, ?T(Lang, <<"Subject">>)}],
-			 children = []},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"var">>, <<"announcement">>},
-			      {<<"type">>, <<"text-multi">>},
-			      {<<"label">>, ?T(Lang, <<"Message body">>)}],
-			 children = []}]}]};
+			      Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
+		      #xdata_field{type = fixed,
+				   label = ?T(Lang,
+					      <<"Send announcement to all online users "
+						"on all hosts">>)},
+		      #xdata_field{var = <<"subject">>,
+				   type = 'text-single',
+				   label = ?T(Lang, <<"Subject">>)},
+		      #xdata_field{var = <<"announcement">>,
+				   type = 'text-multi',
+				   label = ?T(Lang, <<"Message body">>)}]}};
 get_form(Host, [<<"config">>, <<"acls">>], Lang) ->
+    ACLs = str:tokens(
+	     iolist_to_binary(
+	       io_lib:format("~p.",
+			     [ets:select(
+				acl,
+				ets:fun2ms(
+				  fun({acl, {Name, H}, Spec}) when H == Host ->
+					  {acl, Name, Spec}
+				  end))])),
+	     <<"\n">>),
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang,
-				  <<"Access Control List Configuration">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-multi">>},
-			      {<<"label">>,
-			       ?T(Lang, <<"Access control lists">>)},
-			      {<<"var">>, <<"acls">>}],
-			 children =
-			     lists:map(fun (S) ->
-					       #xmlel{name = <<"value">>,
-						      attrs = [],
-						      children =
-							  [{xmlcdata, S}]}
-				       end,
-				       str:tokens(iolist_to_binary(io_lib:format("~p.",
-										 [ets:select(acl,
-											     [{{acl,
-												{'$1',
-												 '$2'},
-												'$3'},
-											       [{'==',
-												 '$2',
-												 Host}],
-											       [{{acl,
-												  '$1',
-												  '$3'}}]}])])),
-						  <<"\n">>))}]}]};
+     #xdata{title = ?T(Lang, <<"Access Control List Configuration">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'text-multi',
+				   label = ?T(Lang, <<"Access control lists">>),
+				   var = <<"acls">>,
+				   values = ACLs}]}};
 get_form(Host, [<<"config">>, <<"access">>], Lang) ->
+    Accs = str:tokens(
+	     iolist_to_binary(
+	       io_lib:format("~p.",
+			     [ets:select(
+				access,
+				ets:fun2ms(
+				  fun({access, {Name, H}, Acc}) when H == Host ->
+					  {access, Name, Acc}
+				  end))])),
+	     <<"\n">>),
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang, <<"Access Configuration">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-multi">>},
-			      {<<"label">>, ?T(Lang, <<"Access rules">>)},
-			      {<<"var">>, <<"access">>}],
-			 children =
-			     lists:map(fun (S) ->
-					       #xmlel{name = <<"value">>,
-						      attrs = [],
-						      children =
-							  [{xmlcdata, S}]}
-				       end,
-				       str:tokens(iolist_to_binary(io_lib:format("~p.",
-										 [ets:select(access,
-											     [{{access,
-												{'$1',
-												 '$2'},
-												'$3'},
-											       [{'==',
-												 '$2',
-												 Host}],
-											       [{{access,
-												  '$1',
-												  '$3'}}]}])])),
-						  <<"\n">>))}]}]};
+     #xdata{title = ?T(Lang, <<"Access Configuration">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'text-multi',
+				   label = ?T(Lang, <<"Access rules">>),
+				   var = <<"access">>,
+				   values = Accs}]}};
 get_form(_Host, ?NS_ADMINL(<<"add-user">>), Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children = [{xmlcdata, ?T(Lang, <<"Add User">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-private">>},
-			      {<<"label">>, ?T(Lang, <<"Password">>)},
-			      {<<"var">>, <<"password">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-private">>},
-			      {<<"label">>,
-			       ?T(Lang, <<"Password Verification">>)},
-			      {<<"var">>, <<"password-verify">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Add User">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   required = true,
+				   var = <<"accountjid">>},
+		      #xdata_field{type = 'text-private',
+				   label = ?T(Lang, <<"Password">>),
+				   required = true,
+				   var = <<"password">>},
+		      #xdata_field{type = 'text-private',
+				   label = ?T(Lang, <<"Password Verification">>),
+				   required = true,
+				   var = <<"password-verify">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"delete-user">>), Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children = [{xmlcdata, ?T(Lang, <<"Delete User">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-multi">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjids">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Delete User">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-multi',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   required = true,
+				   var = <<"accountjids">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"end-user-session">>),
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"End User Session">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"End User Session">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   required = true,
+				   var = <<"accountjid">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"get-user-password">>),
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"Get User Password">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Get User Password">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   var = <<"accountjid">>,
+				   required = true}]}};
 get_form(_Host, ?NS_ADMINL(<<"change-user-password">>),
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"Get User Password">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-private">>},
-			      {<<"label">>, ?T(Lang, <<"Password">>)},
-			      {<<"var">>, <<"password">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Get User Password">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   required = true,
+				   var = <<"accountjid">>},
+		      #xdata_field{type = 'text-private',
+				   label = ?T(Lang, <<"Password">>),
+				   required = true,
+				   var = <<"password">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"get-user-lastlogin">>),
 	 Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       ?T(Lang, <<"Get User Last Login Time">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Get User Last Login Time">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   var = <<"accountjid">>,
+				   required = true}]}};
 get_form(_Host, ?NS_ADMINL(<<"user-stats">>), Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata, ?T(Lang, <<"Get User Statistics">>)}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"jid-single">>},
-			      {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
-			      {<<"var">>, <<"accountjid">>}],
-			 children =
-			     [#xmlel{name = <<"required">>, attrs = [],
-				     children = []}]}]}]};
+     #xdata{title = ?T(Lang, <<"Get User Statistics">>),
+	    type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'jid-single',
+				   label = ?T(Lang, <<"Jabber ID">>),
+				   var = <<"accountjid">>,
+				   required = true}]}};
 get_form(Host,
 	 ?NS_ADMINL(<<"get-registered-users-num">>), Lang) ->
     Num = list_to_binary(
             io_lib:format("~p",
 			  [ejabberd_auth:get_vh_registered_users_number(Host)])),
     {result, completed,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-single">>},
-			      {<<"label">>,
-			       ?T(Lang, <<"Number of registered users">>)},
-			      {<<"var">>, <<"registeredusersnum">>}],
-			 children =
-			     [#xmlel{name = <<"value">>, attrs = [],
-				     children = [{xmlcdata, Num}]}]}]}]};
+     #xdata{type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'text-single',
+				   label = ?T(Lang, <<"Number of registered users">>),
+				   var = <<"registeredusersnum">>,
+				   values = [Num]}]}};
 get_form(Host, ?NS_ADMINL(<<"get-online-users-num">>),
 	 Lang) ->
     Num = list_to_binary(
             io_lib:format("~p",
                           [length(ejabberd_sm:get_vh_session_list(Host))])),
     {result, completed,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"text-single">>},
-			      {<<"label">>,
-			       ?T(Lang, <<"Number of online users">>)},
-			      {<<"var">>, <<"onlineusersnum">>}],
-			 children =
-			     [#xmlel{name = <<"value">>, attrs = [],
-				     children = [{xmlcdata, Num}]}]}]}]};
+     #xdata{type = form,
+	    fields = [?HFIELD(),
+		      #xdata_field{type = 'text-single',
+				   label = ?T(Lang, <<"Number of online users">>),
+				   var = <<"onlineusersnum">>,
+				   values = [Num]}]}};
 get_form(_Host, _, _Lang) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+    {error, xmpp:err_service_unavailable()}.
 
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
     case search_running_node(ENode) of
       false ->
 	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+	  {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
-	  lists:foreach(fun ({SVar, SVals}) ->
-				Table = jlib:binary_to_atom(SVar),
-				Type = case SVals of
-					 [<<"unknown">>] -> unknown;
-					 [<<"ram_copies">>] -> ram_copies;
-					 [<<"disc_copies">>] -> disc_copies;
-					 [<<"disc_only_copies">>] ->
-					     disc_only_copies;
-					 _ -> false
-				       end,
-				if Type == false -> ok;
-				   Type == unknown ->
-				       mnesia:del_table_copy(Table, Node);
-				   true ->
-				       case mnesia:add_table_copy(Table, Node,
-								  Type)
-					   of
-					 {aborted, _} ->
-					     mnesia:change_table_copy_type(Table,
-									   Node,
-									   Type);
-					 _ -> ok
-				       end
-				end
-			end,
-			XData),
-	  {result, []}
+	  lists:foreach(
+	    fun(#xdata_field{var = SVar, values = SVals}) ->
+		    Table = jlib:binary_to_atom(SVar),
+		    Type = case SVals of
+			       [<<"unknown">>] -> unknown;
+			       [<<"ram_copies">>] -> ram_copies;
+			       [<<"disc_copies">>] -> disc_copies;
+			       [<<"disc_only_copies">>] -> disc_only_copies;
+			       _ -> false
+			   end,
+		    if Type == false -> ok;
+		       Type == unknown ->
+			    mnesia:del_table_copy(Table, Node);
+		       true ->
+			    case mnesia:add_table_copy(Table, Node, Type) of
+				{aborted, _} ->
+				    mnesia:change_table_copy_type(
+				      Table, Node, Type);
+				_ -> ok
+			    end
+		    end
+	    end, XData#xdata.fields),
+	    {result, undefined}
     end;
 set_form(_From, Host,
 	 [<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
@@ -1613,187 +1253,193 @@ set_form(_From, Host,
     case search_running_node(ENode) of
       false ->
 	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+	  {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
-	  lists:foreach(fun ({Var, Vals}) ->
-				case Vals of
-				  [<<"1">>] ->
-				      Module = jlib:binary_to_atom(Var),
-				      ejabberd_cluster:call(Node, gen_mod, stop_module,
-					       [Host, Module]);
-				  _ -> ok
-				end
-			end,
-			XData),
-	  {result, []}
+	  lists:foreach(
+	    fun(#xdata_field{var = Var, values = Vals}) ->
+		    case Vals of
+			[<<"1">>] ->
+			    Module = jlib:binary_to_atom(Var),
+			    ejabberd_cluster:call(Node, gen_mod, stop_module,
+						  [Host, Module]);
+			_ -> ok
+		    end
+	    end, XData#xdata.fields),
+	  {result, undefined}
     end;
 set_form(_From, Host,
 	 [<<"running nodes">>, ENode, <<"modules">>,
 	  <<"start">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"modules">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'modules' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, Strings}} ->
-		String = lists:foldl(fun (S, Res) ->
-					     <>
-				     end,
-				     <<"">>, Strings),
-		case erl_scan:string(binary_to_list(String)) of
-		  {ok, Tokens, _} ->
-		      case erl_parse:parse_term(Tokens) of
-			{ok, Modules} ->
-			    lists:foreach(fun ({Module, Args}) ->
-						  ejabberd_cluster:call(Node, gen_mod,
-							   start_module,
-							   [Host, Module, Args])
-					  end,
-					  Modules),
-			    {result, []};
-			_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
-		      end;
-		  _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
-		end
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"modules">>, XData) of
+		[] ->
+		    Txt = <<"No 'modules' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		Strings ->
+		    String = lists:foldl(fun (S, Res) ->
+						 <>
+					 end, <<"">>, Strings),
+		    case erl_scan:string(binary_to_list(String)) of
+			{ok, Tokens, _} ->
+			    case erl_parse:parse_term(Tokens) of
+				{ok, Modules} ->
+				    lists:foreach(
+				      fun ({Module, Args}) ->
+					      ejabberd_cluster:call(
+						Node, gen_mod, start_module,
+						[Host, Module, Args])
+				      end,
+				      Modules),
+				    {result, undefined};
+				_ ->
+				    Txt = <<"Parse failed">>,
+				    {error, xmpp:err_bad_request(Txt, Lang)}
+			    end;
+			_ ->
+			    Txt = <<"Scan failed">>,
+			    {error, xmpp:err_bad_request(Txt, Lang)}
+		    end
+	    end
     end;
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"backup">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"path">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'path' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, [String]}} ->
-		case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
-		  {badrpc, Reason} ->
-		      ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
-				 "failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  {error, Reason} ->
-		      ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
-				 "failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  _ -> {result, []}
-		end;
-	    _ ->
-		Txt = <<"Incorrect value of 'path' in data form">>,
-	        {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"path">>, XData) of
+		[] ->
+		    Txt = <<"No 'path' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		[String] ->
+		    case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
+			{badrpc, Reason} ->
+			    ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+				       "failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			{error, Reason} ->
+			    ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+				       "failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			_ ->
+			    {result, undefined}
+		    end;
+		_ ->
+		    Txt = <<"Incorrect value of 'path' in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"restore">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"path">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'path' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, [String]}} ->
-		case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String])
-		    of
-		  {badrpc, Reason} ->
-		      ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
-				 "~s failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  {error, Reason} ->
-		      ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
-				 "~s failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  _ -> {result, []}
-		end;
-	    _ ->
-		Txt = <<"Incorrect value of 'path' in data form">>,
-	        {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"path">>, XData) of
+		[] ->
+		    Txt = <<"No 'path' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		[String] ->
+		    case ejabberd_cluster:call(Node, ejabberd_admin,
+					       restore, [String]) of
+			{badrpc, Reason} ->
+			    ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+				       "~s failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			{error, Reason} ->
+			    ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+				       "~s failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			_ ->
+			    {result, undefined}
+		    end;
+		_ ->
+		    Txt = <<"Incorrect value of 'path' in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"backup">>,
 	  <<"textfile">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"path">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'path' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, [String]}} ->
-		case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile,
-			      [String])
-		    of
-		  {badrpc, Reason} ->
-		      ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
-				 "to node ~s failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  {error, Reason} ->
-		      ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
-				 "to node ~s failed: ~p", [String, Node, Reason]),
-		      {error, ?ERR_INTERNAL_SERVER_ERROR};
-		  _ -> {result, []}
-		end;
-	    _ ->
-		Txt = <<"Incorrect value of 'path' in data form">>,
-	        {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"path">>, XData) of
+		[] ->
+		    Txt = <<"No 'path' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		[String] ->
+		    case ejabberd_cluster:call(Node, ejabberd_admin,
+					       dump_to_textfile, [String]) of
+			{badrpc, Reason} ->
+			    ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+				       "to node ~s failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			{error, Reason} ->
+			    ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+				       "to node ~s failed: ~p", [String, Node, Reason]),
+			    {error, xmpp:err_internal_server_error()};
+			_ ->
+			    {result, undefined}
+		    end;
+		_ ->
+		    Txt = <<"Incorrect value of 'path' in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"import">>, <<"file">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"path">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'path' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, [String]}} ->
-		ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
-		{result, []};
-	    _ ->
-		Txt = <<"Incorrect value of 'path' in data form">>,
-	        {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"path">>, XData) of
+		[] ->
+		    Txt = <<"No 'path' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		[String] ->
+		    ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
+		    {result, undefined};
+		_ ->
+		    Txt = <<"Incorrect value of 'path' in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 set_form(_From, _Host,
 	 [<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
 	 Lang, XData) ->
     case search_running_node(ENode) of
-      false ->
-	  Txt = <<"No running node found">>,
-	  {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
-      Node ->
-	  case lists:keysearch(<<"path">>, 1, XData) of
-	    false ->
-		Txt = <<"No 'path' found in data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-	    {value, {_, [String]}} ->
-		ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
-		{result, []};
-	    _ ->
-		Txt = <<"Incorrect value of 'path' in data form">>,
-	        {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	false ->
+	    Txt = <<"No running node found">>,
+	    {error, xmpp:err_item_not_found(Txt, Lang)};
+	Node ->
+	    case xmpp_util:get_xdata_values(<<"path">>, XData) of
+		[] ->
+		    Txt = <<"No 'path' found in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)};
+		[String] ->
+		    ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
+		    {result, undefined};
+		_ ->
+		    Txt = <<"Incorrect value of 'path' in data form">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 set_form(From, Host,
 	 [<<"running nodes">>, ENode, <<"restart">>], _Lang,
@@ -1805,75 +1451,72 @@ set_form(From, Host,
     stop_node(From, Host, ENode, stop, XData);
 set_form(_From, Host, [<<"config">>, <<"acls">>], Lang,
 	 XData) ->
-    case lists:keysearch(<<"acls">>, 1, XData) of
-      {value, {_, Strings}} ->
-	  String = lists:foldl(fun (S, Res) ->
-				       <>
-			       end,
-			       <<"">>, Strings),
-	  case erl_scan:string(binary_to_list(String)) of
-	    {ok, Tokens, _} ->
-		case erl_parse:parse_term(Tokens) of
-		  {ok, ACLs} ->
-		      acl:add_list(Host, ACLs, true),
-                      {result, []};
-		  _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
-		end;
-	    _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
-	  end;
-      _ ->
-	  Txt = <<"No 'acls' found in data form">>,
-	  {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
+    case xmpp_util:get_xdata_values(<<"acls">>, XData) of
+	[] ->
+	    Txt = <<"No 'acls' found in data form">>,
+	    {error, xmpp:err_bad_request(Txt, Lang)};
+	Strings ->
+	    String = lists:foldl(fun (S, Res) ->
+					 <>
+				 end, <<"">>, Strings),
+	    case erl_scan:string(binary_to_list(String)) of
+		{ok, Tokens, _} ->
+		    case erl_parse:parse_term(Tokens) of
+			{ok, ACLs} ->
+			    acl:add_list(Host, ACLs, true),
+			    {result, undefined};
+			_ ->
+			    Txt = <<"Parse failed">>,
+			    {error, xmpp:err_bad_request(Txt, Lang)}
+		    end;
+		_ ->
+		    {error, xmpp:err_bad_request(<<"Scan failed">>, Lang)}
+	    end
     end;
 set_form(_From, Host, [<<"config">>, <<"access">>],
 	 Lang, XData) ->
-    SetAccess = fun (Rs) ->
-			mnesia:transaction(fun () ->
-						   Os = mnesia:select(access,
-								      [{{access,
-									 {'$1',
-									  '$2'},
-									 '$3'},
-									[{'==',
-									  '$2',
-									  Host}],
-									['$_']}]),
-						   lists:foreach(fun (O) ->
-									 mnesia:delete_object(O)
-								 end,
-								 Os),
-						   lists:foreach(fun ({access,
-								       Name,
-								       Rules}) ->
-									 mnesia:write({access,
-										       {Name,
-											Host},
-										       Rules})
-								 end,
-								 Rs)
-					   end)
-		end,
-    case lists:keysearch(<<"access">>, 1, XData) of
-      {value, {_, Strings}} ->
-	  String = lists:foldl(fun (S, Res) ->
-				       <>
-			       end,
-			       <<"">>, Strings),
-	  case erl_scan:string(binary_to_list(String)) of
-	    {ok, Tokens, _} ->
-		case erl_parse:parse_term(Tokens) of
-		  {ok, Rs} ->
-		      case SetAccess(Rs) of
-			{atomic, _} -> {result, []};
-			_ -> {error, ?ERR_BAD_REQUEST}
-		      end;
-		  _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
-		end;
-	    _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
-	  end;
-      _ ->
-	  Txt = <<"No 'access' found in data form">>,
-	  {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
+    SetAccess =
+	fun(Rs) ->
+		mnesia:transaction(
+		  fun () ->
+			  Os = mnesia:select(
+				 access,
+				 ets:fun2ms(
+				   fun({access, {_, H}, _} = O) when H == Host ->
+					   O
+				   end)),
+			  lists:foreach(fun mnesia:delete_object/1, Os),
+			  lists:foreach(
+			    fun({access, Name, Rules}) ->
+				    mnesia:write({access, {Name, Host}, Rules})
+			    end, Rs)
+		  end)
+	end,
+    case xmpp_util:get_xdata_values(<<"access">>, XData) of
+	[] ->
+	    Txt = <<"No 'access' found in data form">>,
+	    {error, xmpp:err_bad_request(Txt, Lang)};
+	Strings ->
+	    String = lists:foldl(fun (S, Res) ->
+					 <>
+				 end, <<"">>, Strings),
+	    case erl_scan:string(binary_to_list(String)) of
+		{ok, Tokens, _} ->
+		    case erl_parse:parse_term(Tokens) of
+			{ok, Rs} ->
+			    case SetAccess(Rs) of
+				{atomic, _} ->
+				    {result, undefined};
+				_ ->
+				    {error, xmpp:err_bad_request()}
+			    end;
+			_ ->
+			    Txt = <<"Parse failed">>,
+			    {error, xmpp:err_bad_request(Txt, Lang)}
+		    end;
+		_ ->
+		    {error, xmpp:err_bad_request(<<"Scan failed">>, Lang)}
+	    end
     end;
 set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
 	 XData) ->
@@ -1887,7 +1530,7 @@ set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
     true = Server == Host orelse
 	     get_permission_level(From) == global,
     ejabberd_auth:try_register(User, Server, Password),
-    {result, []};
+    {result, undefined};
 set_form(From, Host, ?NS_ADMINL(<<"delete-user">>),
 	 _Lang, XData) ->
     AccountStringList = get_values(<<"accountjids">>,
@@ -1905,7 +1548,7 @@ set_form(From, Host, ?NS_ADMINL(<<"delete-user">>),
 		     AccountStringList),
     [ejabberd_auth:remove_user(User, Server)
      || {User, Server} <- ASL2],
-    {result, []};
+    {result, undefined};
 set_form(From, Host, ?NS_ADMINL(<<"end-user-session">>),
 	 Lang, XData) ->
     AccountString = get_value(<<"accountjid">>, XData),
@@ -1914,7 +1557,7 @@ set_form(From, Host, ?NS_ADMINL(<<"end-user-session">>),
     LServer = JID#jid.lserver,
     true = LServer == Host orelse
 	     get_permission_level(From) == global,
-    Xmlelement = ?SERRT_POLICY_VIOLATION(Lang, <<"has been kicked">>),
+    Xmlelement = xmpp:serr_policy_violation(<<"has been kicked">>, Lang),
     case JID#jid.lresource of
       <<>> ->
 	  SIDs = mnesia:dirty_select(session,
@@ -1933,7 +1576,7 @@ set_form(From, Host, ?NS_ADMINL(<<"end-user-session">>),
 					     [{{'$1', '$2'}}]}]),
 	  Pid ! {kick, kicked_by_admin, Xmlelement}
     end,
-    {result, []};
+    {result, undefined};
 set_form(From, Host,
 	 ?NS_ADMINL(<<"get-user-password">>), Lang, XData) ->
     AccountString = get_value(<<"accountjid">>, XData),
@@ -1945,14 +1588,12 @@ set_form(From, Host,
     Password = ejabberd_auth:get_password(User, Server),
     true = is_binary(Password),
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
-			  <<"accountjid">>, AccountString),
-		  ?XFIELD(<<"text-single">>, <<"Password">>,
-			  <<"password">>, Password)]}]};
+     #xdata{type = form,
+	    fields = [?HFIELD(),
+		      ?XFIELD('jid-single', <<"Jabber ID">>,
+			      <<"accountjid">>, AccountString),
+		      ?XFIELD('text-single', <<"Password">>,
+			      <<"password">>, Password)]}};
 set_form(From, Host,
 	 ?NS_ADMINL(<<"change-user-password">>), _Lang, XData) ->
     AccountString = get_value(<<"accountjid">>, XData),
@@ -1964,7 +1605,7 @@ set_form(From, Host,
 	     get_permission_level(From) == global,
     true = ejabberd_auth:is_user_exists(User, Server),
     ejabberd_auth:set_password(User, Server, Password),
-    {result, []};
+    {result, undefined};
 set_form(From, Host,
 	 ?NS_ADMINL(<<"get-user-lastlogin">>), Lang, XData) ->
     AccountString = get_value(<<"accountjid">>, XData),
@@ -1991,15 +1632,12 @@ set_form(From, Host,
 	      _ -> ?T(Lang, <<"Online">>)
 	    end,
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs =
-		 [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}],
-	     children =
-		 [?HFIELD(),
-		  ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
-			  <<"accountjid">>, AccountString),
-		  ?XFIELD(<<"text-single">>, <<"Last login">>,
-			  <<"lastlogin">>, FLast)]}]};
+     #xdata{type = form,
+	    fields = [?HFIELD(),
+		      ?XFIELD('jid-single', <<"Jabber ID">>,
+			      <<"accountjid">>, AccountString),
+		      ?XFIELD('text-single', <<"Last login">>,
+			      <<"lastlogin">>, FLast)]}};
 set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang,
 	 XData) ->
     AccountString = get_value(<<"accountjid">>, XData),
@@ -2019,27 +1657,24 @@ set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang,
 				    [{User, Server}]),
     Rostersize = jlib:integer_to_binary(erlang:length(Items)),
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
-			  <<"accountjid">>, AccountString),
-		  ?XFIELD(<<"text-single">>, <<"Roster size">>,
-			  <<"rostersize">>, Rostersize),
-		  ?XMFIELD(<<"text-multi">>, <<"IP addresses">>,
-			   <<"ipaddresses">>, IPs),
-		  ?XMFIELD(<<"text-multi">>, <<"Resources">>,
-			   <<"onlineresources">>, Resources)]}]};
+     #xdata{type = form,
+	    fields = [?HFIELD(),
+		      ?XFIELD('jid-single', <<"Jabber ID">>,
+			      <<"accountjid">>, AccountString),
+		      ?XFIELD('text-single', <<"Roster size">>,
+			      <<"rostersize">>, Rostersize),
+		      ?XMFIELD('text-multi', <<"IP addresses">>,
+			       <<"ipaddresses">>, IPs),
+		      ?XMFIELD('text-multi', <<"Resources">>,
+			       <<"onlineresources">>, Resources)]}};
 set_form(_From, _Host, _, _Lang, _XData) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+    {error, xmpp:err_service_unavailable()}.
 
 get_value(Field, XData) -> hd(get_values(Field, XData)).
 
 get_values(Field, XData) ->
-    {value, {_, ValueList}} = lists:keysearch(Field, 1,
-					      XData),
-    ValueList.
+    [_|_] = Values = xmpp_util:get_xdata_values(Field, XData),
+    Values.
 
 search_running_node(SNode) ->
     search_running_node(SNode,
@@ -2053,57 +1688,34 @@ search_running_node(SNode, [Node | Nodes]) ->
     end.
 
 stop_node(From, Host, ENode, Action, XData) ->
-    Delay = jlib:binary_to_integer(get_value(<<"delay">>,
-					       XData)),
+    Delay = jlib:binary_to_integer(get_value(<<"delay">>, XData)),
     Subject = case get_value(<<"subject">>, XData) of
-		<<"">> -> [];
-		S ->
-		    [#xmlel{name = <<"field">>,
-			    attrs = [{<<"var">>, <<"subject">>}],
-			    children =
-				[#xmlel{name = <<"value">>, attrs = [],
-					children = [{xmlcdata, S}]}]}]
+		  <<"">> ->
+		      [];
+		  S ->
+		      [#xdata_field{var = <<"subject">>, values = [S]}]
 	      end,
-    Announcement = case get_values(<<"announcement">>,
-				   XData)
-		       of
-		     [] -> [];
-		     As ->
-			 [#xmlel{name = <<"field">>,
-				 attrs = [{<<"var">>, <<"body">>}],
-				 children =
-				     [#xmlel{name = <<"value">>, attrs = [],
-					     children = [{xmlcdata, Line}]}
-				      || Line <- As]}]
+    Announcement = case get_values(<<"announcement">>, XData) of
+		       [] ->
+			   [];
+		       As ->
+			   [#xdata_field{var = <<"body">>, values = As}]
 		   end,
     case Subject ++ Announcement of
-      [] -> ok;
-      SubEls ->
-	  Request = #adhoc_request{node =
-				       ?NS_ADMINX(<<"announce-allhosts">>),
-				   action = <<"complete">>,
-				   xdata =
-				       #xmlel{name = <<"x">>,
-					      attrs =
-						  [{<<"xmlns">>,
-						    ?NS_XDATA},
-						   {<<"type">>, <<"submit">>}],
-					      children = SubEls},
-				   others =
-				       [#xmlel{name = <<"x">>,
-					       attrs =
-						   [{<<"xmlns">>,
-						     ?NS_XDATA},
-						    {<<"type">>, <<"submit">>}],
-					       children = SubEls}]},
-	  To = jid:make(<<"">>, Host, <<"">>),
-	  mod_announce:announce_commands(empty, From, To, Request)
+	[] ->
+	    ok;
+	Fields ->
+	    Request = #adhoc_command{node = ?NS_ADMINX(<<"announce-allhosts">>),
+				     action = complete,
+				     xdata = #xdata{type = submit,
+						    fields = Fields}},
+	    To = jid:make(Host),
+	    mod_announce:announce_commands(empty, From, To, Request)
     end,
     Time = timer:seconds(Delay),
     Node = jlib:binary_to_atom(ENode),
-    {ok, _} = timer:apply_after(Time, rpc, call,
-				[Node, init, Action, []]),
-    {result, []}.
+    {ok, _} = timer:apply_after(Time, rpc, call, [Node, init, Action, []]),
+    {result, undefined}.
 
 get_last_info(User, Server) ->
     case gen_mod:is_loaded(Server, mod_last) of
@@ -2114,111 +1726,81 @@ get_last_info(User, Server) ->
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 adhoc_sm_commands(_Acc, From,
-		  #jid{user = User, server = Server, lserver = LServer} =
-		      _To,
-		  #adhoc_request{lang = Lang, node = <<"config">>,
-				 action = Action, xdata = XData} =
-		      Request) ->
+		  #jid{user = User, server = Server, lserver = LServer},
+		  #adhoc_command{lang = Lang, node = <<"config">>,
+				 action = Action, xdata = XData} = Request) ->
     case acl:match_rule(LServer, configure, From) of
-      deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
-      allow ->
-	  ActionIsExecute = lists:member(Action,
-					 [<<"">>, <<"execute">>,
-					  <<"complete">>]),
-	  if Action == <<"cancel">> ->
-		 adhoc:produce_response(Request,
-					#adhoc_response{status = canceled});
-	     XData == false, ActionIsExecute ->
-		 case get_sm_form(User, Server, <<"config">>, Lang) of
-		   {result, Form} ->
-		       adhoc:produce_response(Request,
-					      #adhoc_response{status =
-								  executing,
-							      elements = Form});
-		   {error, Error} -> {error, Error}
-		 end;
-	     XData /= false, ActionIsExecute ->
-		 case jlib:parse_xdata_submit(XData) of
-		   invalid ->
-		       Txt = <<"Incorrect data form">>,
-		       {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
-		   Fields ->
-		       set_sm_form(User, Server, <<"config">>, Request, Fields)
-		 end;
-	     true ->
-		Txt = <<"Incorrect action or data form">>,
-		{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
-	  end
+	deny ->
+	    {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
+	allow ->
+	    ActionIsExecute = Action == execute orelse Action == complete,
+	    if Action == cancel ->
+		    xmpp_util:make_adhoc_response(
+		      Request, #adhoc_command{status = canceled});
+	       XData == undefined, ActionIsExecute ->
+		    case get_sm_form(User, Server, <<"config">>, Lang) of
+			{result, Form} ->
+			    xmpp_util:make_adhoc_response(
+			      Request, #adhoc_command{status = executing,
+						      xdata = Form});
+			{error, Error} ->
+			    {error, Error}
+		    end;
+	       XData /= undefined, ActionIsExecute ->
+		    set_sm_form(User, Server, <<"config">>, Request);
+	       true ->
+		    Txt = <<"Unexpected action">>,
+		    {error, xmpp:err_bad_request(Txt, Lang)}
+	    end
     end;
 adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
 
 get_sm_form(User, Server, <<"config">>, Lang) ->
     {result,
-     [#xmlel{name = <<"x">>,
-	     attrs = [{<<"xmlns">>, ?NS_XDATA}],
-	     children =
-		 [?HFIELD(),
-		  #xmlel{name = <<"title">>, attrs = [],
-			 children =
-			     [{xmlcdata,
-			       <<(?T(Lang, <<"Administration of ">>))/binary,
-				 User/binary>>}]},
-		  #xmlel{name = <<"field">>,
-			 attrs =
-			     [{<<"type">>, <<"list-single">>},
-			      {<<"label">>, ?T(Lang, <<"Action on user">>)},
-			      {<<"var">>, <<"action">>}],
-			 children =
-			     [#xmlel{name = <<"value">>, attrs = [],
-				     children = [{xmlcdata, <<"edit">>}]},
-			      #xmlel{name = <<"option">>,
-				     attrs =
-					 [{<<"label">>,
-					   ?T(Lang, <<"Edit Properties">>)}],
-				     children =
-					 [#xmlel{name = <<"value">>, attrs = [],
-						 children =
-						     [{xmlcdata,
-						       <<"edit">>}]}]},
-			      #xmlel{name = <<"option">>,
-				     attrs =
-					 [{<<"label">>,
-					   ?T(Lang, <<"Remove User">>)}],
-				     children =
-					 [#xmlel{name = <<"value">>, attrs = [],
-						 children =
-						     [{xmlcdata,
-						       <<"remove">>}]}]}]},
-		  ?XFIELD(<<"text-private">>, <<"Password">>,
-			  <<"password">>,
-			  (ejabberd_auth:get_password_s(User, Server)))]}]};
+     #xdata{type = form,
+	    title = <<(?T(Lang, <<"Administration of ">>))/binary, User/binary>>,
+	    fields =
+		[?HFIELD(),
+		 #xdata_field{
+		    type = 'list-single',
+		    label = ?T(Lang, <<"Action on user">>),
+		    var = <<"action">>,
+		    values = [<<"edit">>],
+		    options = [#xdata_option{
+				  label = ?T(Lang, <<"Edit Properties">>),
+				  value = <<"edit">>},
+			       #xdata_option{
+				  label = ?T(Lang, <<"Remove User">>),
+				  value = <<"remove">>}]},
+		 ?XFIELD('text-private', <<"Password">>,
+			 <<"password">>,
+			 ejabberd_auth:get_password_s(User, Server))]}};
 get_sm_form(_User, _Server, _Node, _Lang) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+    {error, xmpp:err_service_unavailable()}.
 
 set_sm_form(User, Server, <<"config">>,
-	    #adhoc_request{lang = Lang, node = Node,
-			   sessionid = SessionID},
-	    XData) ->
-    Response = #adhoc_response{lang = Lang, node = Node,
-			       sessionid = SessionID, status = completed},
-    case lists:keysearch(<<"action">>, 1, XData) of
-      {value, {_, [<<"edit">>]}} ->
-	  case lists:keysearch(<<"password">>, 1, XData) of
-	    {value, {_, [Password]}} ->
-		ejabberd_auth:set_password(User, Server, Password),
-		adhoc:produce_response(Response);
-	    _ ->
-		Txt = <<"No 'password' found in data form">>,
-		{error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
-	  end;
-      {value, {_, [<<"remove">>]}} ->
-	  catch ejabberd_auth:remove_user(User, Server),
-	  adhoc:produce_response(Response);
-      _ ->
-	  Txt = <<"Incorrect value of 'action' in data form">>,
-	  {error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
+	    #adhoc_command{lang = Lang, node = Node,
+			   sid = SessionID, xdata = XData}) ->
+    Response = #adhoc_command{lang = Lang, node = Node,
+			      sid = SessionID, status = completed},
+    case xmpp_util:get_xdata_values(<<"action">>, XData) of
+	[<<"edit">>] ->
+	    case xmpp_util:get_xdata_values(<<"password">>, XData) of
+		[Password] ->
+		    ejabberd_auth:set_password(User, Server, Password),
+		    xmpp_util:make_adhoc_response(Response);
+		_ ->
+		    Txt = <<"No 'password' found in data form">>,
+		    {error, xmpp:err_not_acceptable(Txt, Lang)}
+	    end;
+	[<<"remove">>] ->
+	    catch ejabberd_auth:remove_user(User, Server),
+	    xmpp_util:make_adhoc_response(Response);
+	_ ->
+	    Txt = <<"Incorrect value of 'action' in data form">>,
+	    {error, xmpp:err_not_acceptable(Txt, Lang)}
     end;
-set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+set_sm_form(_User, _Server, _Node, _Request) ->
+    {error, xmpp:err_service_unavailable()}.
 
 mod_opt_type(_) -> [].
-- 
cgit v1.2.3


From a417fbf45b88bae2163397cc9e06a7bc22b20f7a Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Wed, 3 Aug 2016 20:57:05 +0300
Subject: Rewrite mod_irc to use XML generator

---
 src/mod_irc.erl            | 1227 +++++++++++++++------------------------
 src/mod_irc_connection.erl | 1368 ++++++++++++++++----------------------------
 src/mod_irc_mnesia.erl     |    2 +-
 src/mod_irc_riak.erl       |    2 +-
 src/mod_irc_sql.erl        |    2 +-
 src/xmpp.erl               |   20 +-
 6 files changed, 974 insertions(+), 1647 deletions(-)

(limited to 'src')

diff --git a/src/mod_irc.erl b/src/mod_irc.erl
index 2206028b7..91f43716f 100644
--- a/src/mod_irc.erl
+++ b/src/mod_irc.erl
@@ -34,7 +34,8 @@
 %% API
 -export([start_link/2, start/2, stop/1, export/1, import/1,
 	 import/3, closed_connection/3, get_connection_params/3,
-	 data_to_binary/2]).
+	 data_to_binary/2, process_disco_info/1, process_disco_items/1,
+	 process_register/1, process_vcard/1, process_command/1]).
 
 -export([init/1, handle_call/3, handle_cast/2,
 	 handle_info/2, terminate/2, code_change/3,
@@ -42,11 +43,7 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
-
--include("jlib.hrl").
-
--include("adhoc.hrl").
-
+-include("xmpp.hrl").
 -include("mod_irc.hrl").
 
 -define(DEFAULT_IRC_ENCODING, <<"iso8859-15">>).
@@ -125,6 +122,18 @@ init([Host, Opts]) ->
     catch ets:new(irc_connection,
 		  [named_table, public,
 		   {keypos, #irc_connection.jid_server_host}]),
+    IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
+                             one_queue),
+    gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
+				  ?MODULE, process_disco_info, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS,
+				  ?MODULE, process_disco_items, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER,
+				  ?MODULE, process_register, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD,
+				  ?MODULE, process_vcard, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_COMMANDS,
+				  ?MODULE, process_command, IQDisc),
     ejabberd_router:register_route(MyHost, Host),
     {ok,
      #state{host = MyHost, server_host = Host,
@@ -176,8 +185,13 @@ handle_info(_Info, State) -> {noreply, State}.
 %% cleaning up. When it returns, the gen_server terminates with Reason.
 %% The return value is ignored.
 %%--------------------------------------------------------------------
-terminate(_Reason, State) ->
-    ejabberd_router:unregister_route(State#state.host), ok.
+terminate(_Reason, #state{host = MyHost}) ->
+    ejabberd_router:unregister_route(MyHost),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_COMMANDS).
 
 %%--------------------------------------------------------------------
 %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
@@ -203,287 +217,222 @@ stop_supervisor(Host) ->
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
-do_route(Host, ServerHost, Access, From, To, Packet) ->
+do_route(Host, ServerHost, Access, From,
+	 #jid{luser = LUser, lresource = LResource} = To, Packet) ->
     case acl:match_rule(ServerHost, Access, From) of
-      allow -> do_route1(Host, ServerHost, From, To, Packet);
-      _ ->
-	  #xmlel{attrs = Attrs} = Packet,
-	  Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
-	  ErrText = <<"Access denied by service policy">>,
-	  Err = jlib:make_error_reply(Packet,
-				      ?ERRT_FORBIDDEN(Lang, ErrText)),
-	  ejabberd_router:route(To, From, Err)
+	allow ->
+	    case Packet of
+		#iq{} when LUser == <<"">>, LResource == <<"">> ->
+		    ejabberd_router:process_iq(From, To, Packet);
+		#iq{} when LUser == <<"">>, LResource /= <<"">> ->
+		    Err = xmpp:err_service_unavailable(),
+		    ejabberd_router:route_error(To, From, Packet, Err);
+		_ ->
+		    sm_route(Host, ServerHost, From, To, Packet)
+	    end;
+	deny ->
+	    Lang = xmpp:get_lang(Packet),
+	    Err = xmpp:err_forbidden(<<"Denied by ACL">>, Lang),
+	    ejabberd_router:route_error(To, From, Packet, Err)
+    end.
+
+process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_disco_info(#iq{type = get, lang = Lang, to = To,
+		       sub_els = [#disco_info{node = Node}]} = IQ) ->
+    ServerHost = ejabberd_router:host_of_route(To#jid.lserver),
+    Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
+				   [], [ServerHost, ?MODULE, <<"">>, <<"">>]),
+    case iq_disco(ServerHost, Node, Lang) of
+	undefined ->
+	    xmpp:make_iq_result(IQ, #disco_info{});
+	DiscoInfo ->
+	    xmpp:make_iq_result(IQ, DiscoInfo#disco_info{xdata = Info})
+    end.
+
+process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_disco_items(#iq{type = get, lang = Lang, to = To,
+			sub_els = [#disco_items{node = Node}]} = IQ) ->
+    case Node of
+	undefined ->
+	    xmpp:make_iq_result(IQ, #disco_items{});
+	<<"join">> ->
+	    xmpp:make_iq_result(IQ, #disco_items{});
+	<<"register">> ->
+	    xmpp:make_iq_result(IQ, #disco_items{});
+	?NS_COMMANDS ->
+	    Host = To#jid.lserver,
+	    ServerHost = ejabberd_router:host_of_route(Host),
+	    xmpp:make_iq_result(
+	      IQ, #disco_items{node = Node,
+			       items = command_items(ServerHost, Host, Lang)});
+	_ ->
+	    Txt = <<"Node not found">>,
+	    xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang))
+    end.
+
+process_register(#iq{type = get, to = To, from = From, lang = Lang} = IQ) ->
+    Host = To#jid.lserver,
+    ServerHost = ejabberd_router:host_of_route(Host),
+    case get_form(ServerHost, Host, From, Lang) of
+	{result, Res} ->
+	    xmpp:make_iq_result(IQ, Res);
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
+    end;
+process_register(#iq{type = set, lang = Lang, to = To, from = From,
+		     sub_els = [#register{xdata = #xdata{} = X}]} = IQ) ->
+    case X#xdata.type of
+	cancel ->
+	    xmpp:make_iq_result(IQ, #register{});
+	submit ->
+	    Host = To#jid.lserver,
+	    ServerHost = ejabberd_router:host_of_route(Host),
+	    case set_form(ServerHost, Host, From, Lang, X) of
+		{result, Res} ->
+		    xmpp:make_iq_result(IQ, Res);
+		{error, Error} ->
+		    xmpp:make_error(IQ, Error)
+	    end;
+	_ ->
+	    Txt = <<"Incorrect value of 'type' attribute">>,
+	    xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
+    end;
+process_register(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"No data form found">>,
+    xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
+
+process_vcard(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_vcard(#iq{type = get, lang = Lang} = IQ) ->
+    xmpp:make_iq_result(IQ, iq_get_vcard(Lang)).
+
+process_command(#iq{type = get, lang = Lang} = IQ) ->
+    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_command(#iq{type = set, lang = Lang, to = To, from = From,
+		    sub_els = [#adhoc_command{node = Node} = Request]} = IQ) ->
+    Host = To#jid.lserver,
+    ServerHost = ejabberd_router:host_of_route(Host),
+    case lists:keyfind(Node, 1, commands(ServerHost)) of
+	{_, _, Function} ->
+	    try Function(From, To, Request) of
+		ignore ->
+		    ignore;
+		{error, Error} ->
+		    xmpp:make_error(IQ, Error);
+		Command ->
+		    xmpp:make_iq_result(IQ, Command)
+	    catch E:R ->
+		    ?ERROR_MSG("ad-hoc handler failed: ~p",
+			       [{E, {R, erlang:get_stacktrace()}}]),
+		    xmpp:make_error(IQ, xmpp:internal_server_error())
+	    end;
+	_ ->
+	    Txt = <<"Node not found">>,
+	    xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang))
     end.
 
-do_route1(Host, ServerHost, From, To, Packet) ->
+sm_route(Host, ServerHost, From, To, Packet) ->
     #jid{user = ChanServ, resource = Resource} = To,
-    #xmlel{} = Packet,
-    case ChanServ of
-      <<"">> ->
-	  case Resource of
-	    <<"">> ->
-		case jlib:iq_query_info(Packet) of
-		  #iq{type = get, xmlns = (?NS_DISCO_INFO) = XMLNS,
-		      sub_el = SubEl, lang = Lang} =
-		      IQ ->
-		      Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
-		      Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
-						     [],
-						     [ServerHost, ?MODULE,
-						      <<"">>, <<"">>]),
-		      case iq_disco(ServerHost, Node, Lang) of
-			[] ->
-			    Res = IQ#iq{type = result,
-					sub_el =
-					    [#xmlel{name = <<"query">>,
-						    attrs =
-							[{<<"xmlns">>, XMLNS}],
-						    children = []}]},
-			    ejabberd_router:route(To, From,
-						  jlib:iq_to_xml(Res));
-			DiscoInfo ->
-			    Res = IQ#iq{type = result,
-					sub_el =
-					    [#xmlel{name = <<"query">>,
-						    attrs =
-							[{<<"xmlns">>, XMLNS}],
-						    children =
-							DiscoInfo ++ Info}]},
-			    ejabberd_router:route(To, From, jlib:iq_to_xml(Res))
-		      end;
-		  #iq{type = get, xmlns = (?NS_DISCO_ITEMS) = XMLNS,
-		      sub_el = SubEl, lang = Lang} =
-		      IQ ->
-		      Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
-		      case Node of
-			<<>> ->
-			    ResIQ = IQ#iq{type = result,
-					  sub_el =
-					      [#xmlel{name = <<"query">>,
-						      attrs =
-							  [{<<"xmlns">>,
-							    XMLNS}],
-						      children = []}]},
-			    Res = jlib:iq_to_xml(ResIQ);
-			<<"join">> ->
-			    ResIQ = IQ#iq{type = result,
-					  sub_el =
-					      [#xmlel{name = <<"query">>,
-						      attrs =
-							  [{<<"xmlns">>,
-							    XMLNS}],
-						      children = []}]},
-			    Res = jlib:iq_to_xml(ResIQ);
-			<<"register">> ->
-			    ResIQ = IQ#iq{type = result,
-					  sub_el =
-					      [#xmlel{name = <<"query">>,
-						      attrs =
-							  [{<<"xmlns">>,
-							    XMLNS}],
-						      children = []}]},
-			    Res = jlib:iq_to_xml(ResIQ);
-			?NS_COMMANDS ->
-			    ResIQ = IQ#iq{type = result,
-					  sub_el =
-					      [#xmlel{name = <<"query">>,
-						      attrs =
-							  [{<<"xmlns">>, XMLNS},
-							   {<<"node">>, Node}],
-						      children =
-							  command_items(ServerHost,
-									Host,
-									Lang)}]},
-			    Res = jlib:iq_to_xml(ResIQ);
-			_ ->
-			    Txt = <<"Node not found">>,
-			    Res = jlib:make_error_reply(
-				    Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt))
-		      end,
-		      ejabberd_router:route(To, From, Res);
-		  #iq{xmlns = ?NS_REGISTER} = IQ ->
-		      process_register(ServerHost, Host, From, To, IQ);
-		  #iq{type = get, xmlns = (?NS_VCARD) = XMLNS,
-		      lang = Lang} =
-		      IQ ->
-		      Res = IQ#iq{type = result,
-				  sub_el =
-				      [#xmlel{name = <<"vCard">>,
-					      attrs = [{<<"xmlns">>, XMLNS}],
-					      children = iq_get_vcard(Lang)}]},
-		      ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
-		  #iq{type = set, xmlns = ?NS_COMMANDS, lang = Lang,
-		      sub_el = SubEl} =
-		      IQ ->
-		      Request = adhoc:parse_request(IQ),
-		      case lists:keysearch(Request#adhoc_request.node, 1,
-					   commands(ServerHost))
-			  of
-			{value, {_, _, Function}} ->
-			    case catch Function(From, To, Request) of
-			      {'EXIT', Reason} ->
-				  ?ERROR_MSG("~p~nfor ad-hoc handler of ~p",
-					     [Reason, {From, To, IQ}]),
-				  Res = IQ#iq{type = error,
-					      sub_el =
-						  [SubEl,
-						   ?ERR_INTERNAL_SERVER_ERROR]};
-			      ignore -> Res = ignore;
-			      {error, Error} ->
-				  Res = IQ#iq{type = error,
-					      sub_el = [SubEl, Error]};
-			      Command ->
-				  Res = IQ#iq{type = result, sub_el = [Command]}
-			    end,
-			    if Res /= ignore ->
-				   ejabberd_router:route(To, From,
-							 jlib:iq_to_xml(Res));
-			       true -> ok
-			    end;
-			_ ->
-			    Txt = <<"Node not found">>,
-			    Err = jlib:make_error_reply(
-				    Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)),
-			    ejabberd_router:route(To, From, Err)
-		      end;
-		  #iq{} = _IQ ->
-		      Err = jlib:make_error_reply(Packet,
-						  ?ERR_FEATURE_NOT_IMPLEMENTED),
-		      ejabberd_router:route(To, From, Err);
-		  _ -> ok
-		end;
-	    _ ->
-		Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
-		ejabberd_router:route(To, From, Err)
-	  end;
-      _ ->
-	  case str:tokens(ChanServ, <<"%">>) of
-	    [<<_, _/binary>> = Channel, <<_, _/binary>> = Server] ->
-		case ets:lookup(irc_connection, {From, Server, Host}) of
-		  [] ->
-		      ?DEBUG("open new connection~n", []),
-		      {Username, Encoding, Port, Password} =
-			  get_connection_params(Host, ServerHost, From, Server),
-		      ConnectionUsername = case Packet of
+    case str:tokens(ChanServ, <<"%">>) of
+	[<<_, _/binary>> = Channel, <<_, _/binary>> = Server] ->
+	    case ets:lookup(irc_connection, {From, Server, Host}) of
+		[] ->
+		    ?DEBUG("open new connection~n", []),
+		    {Username, Encoding, Port, Password} =
+			get_connection_params(Host, ServerHost, From, Server),
+		    ConnectionUsername = case Packet of
 					     %% If the user tries to join a
 					     %% chatroom, the packet for sure
 					     %% contains the desired username.
-					     #xmlel{name = <<"presence">>} ->
-						 Resource;
+					     #presence{} -> Resource;
 					     %% Otherwise, there is no firm
 					     %% conclusion from the packet.
 					     %% Better to use the configured
 					     %% username (which defaults to the
 					     %% username part of the JID).
 					     _ -> Username
-					   end,
-		      Ident = extract_ident(Packet),
-		      RemoteAddr = extract_ip_address(Packet),
-		      RealName = get_realname(ServerHost),
-		      WebircPassword = get_webirc_password(ServerHost),
-		      {ok, Pid} = mod_irc_connection:start(From, Host,
-							   ServerHost, Server,
-							   ConnectionUsername,
-							   Encoding, Port,
-							   Password, Ident, RemoteAddr, RealName, WebircPassword, ?MODULE),
-		      ets:insert(irc_connection,
-				 #irc_connection{jid_server_host =
-						     {From, Server, Host},
-						 pid = Pid}),
-		      mod_irc_connection:route_chan(Pid, Channel, Resource,
-						    Packet),
-		      ok;
-		  [R] ->
-		      Pid = R#irc_connection.pid,
-		      ?DEBUG("send to process ~p~n", [Pid]),
-		      mod_irc_connection:route_chan(Pid, Channel, Resource,
-						    Packet),
-		      ok
-		end;
-	    _ ->
-		Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
-		case str:tokens(ChanServ, <<"!">>) of
-		  [<<_, _/binary>> = Nick, <<_, _/binary>> = Server] ->
-		      case ets:lookup(irc_connection, {From, Server, Host}) of
+					 end,
+		    Ident = extract_ident(Packet),
+		    RemoteAddr = extract_ip_address(Packet),
+		    RealName = get_realname(ServerHost),
+		    WebircPassword = get_webirc_password(ServerHost),
+		    {ok, Pid} = mod_irc_connection:start(
+				  From, Host, ServerHost, Server,
+				  ConnectionUsername, Encoding, Port,
+				  Password, Ident, RemoteAddr, RealName,
+				  WebircPassword, ?MODULE),
+		    ets:insert(irc_connection,
+			       #irc_connection{
+				  jid_server_host = {From, Server, Host},
+				  pid = Pid}),
+		    mod_irc_connection:route_chan(Pid, Channel, Resource, Packet);
+		[R] ->
+		    Pid = R#irc_connection.pid,
+		    ?DEBUG("send to process ~p~n", [Pid]),
+		    mod_irc_connection:route_chan(Pid, Channel, Resource, Packet)
+	    end;
+	_ ->
+	    Lang = xmpp:get_lang(Packet),
+	    case str:tokens(ChanServ, <<"!">>) of
+		[<<_, _/binary>> = Nick, <<_, _/binary>> = Server] ->
+		    case ets:lookup(irc_connection, {From, Server, Host}) of
 			[] ->
 			    Txt = <<"IRC connection not found">>,
-			    Err = jlib:make_error_reply(
-				    Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
-			    ejabberd_router:route(To, From, Err);
+			    Err = xmpp:err_service_unavailable(Txt, Lang),
+			    ejabberd_router:route_error(To, From, Packet, Err);
 			[R] ->
 			    Pid = R#irc_connection.pid,
 			    ?DEBUG("send to process ~p~n", [Pid]),
-			    mod_irc_connection:route_nick(Pid, Nick, Packet),
-			    ok
-		      end;
-		  _ ->
-		      Txt = <<"Failed to parse chanserv">>,
-		      Err = jlib:make_error_reply(
-			      Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
-		      ejabberd_router:route(To, From, Err)
-		end
-	  end
+			    mod_irc_connection:route_nick(Pid, Nick, Packet)
+		    end;
+		_ ->
+		    Txt = <<"Failed to parse chanserv">>,
+		    Err = xmpp:err_bad_request(Txt, Lang),
+		    ejabberd_router:route_error(To, From, Packet, Err)
+	    end
     end.
 
 closed_connection(Host, From, Server) ->
     ets:delete(irc_connection, {From, Server, Host}).
 
-iq_disco(_ServerHost, <<>>, Lang) ->
-    [#xmlel{name = <<"identity">>,
-	    attrs =
-		[{<<"category">>, <<"conference">>},
-		 {<<"type">>, <<"irc">>},
-		 {<<"name">>,
-		  translate:translate(Lang, <<"IRC Transport">>)}],
-	    children = []},
-     #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_DISCO_INFO}], children = []},
-     #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_MUC}], children = []},
-     #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_REGISTER}], children = []},
-     #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_VCARD}], children = []},
-     #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_COMMANDS}], children = []}];
+iq_disco(_ServerHost, undefined, Lang) ->
+    #disco_info{
+       identities = [#identity{category = <<"conference">>,
+			       type = <<"irc">>,
+			       name = translate:translate(Lang, <<"IRC Transport">>)}],
+       features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, ?NS_MUC,
+		   ?NS_REGISTER, ?NS_VCARD, ?NS_COMMANDS]};
 iq_disco(ServerHost, Node, Lang) ->
-    case lists:keysearch(Node, 1, commands(ServerHost)) of
-      {value, {_, Name, _}} ->
-	  [#xmlel{name = <<"identity">>,
-		  attrs =
-		      [{<<"category">>, <<"automation">>},
-		       {<<"type">>, <<"command-node">>},
-		       {<<"name">>, translate:translate(Lang, Name)}],
-		  children = []},
-	   #xmlel{name = <<"feature">>,
-		  attrs = [{<<"var">>, ?NS_COMMANDS}], children = []},
-	   #xmlel{name = <<"feature">>,
-		  attrs = [{<<"var">>, ?NS_XDATA}], children = []}];
-      _ -> []
+    case lists:keyfind(Node, commands(ServerHost)) of
+	{_, Name, _} ->
+	    #disco_info{
+	       identities = [#identity{category = <<"automation">>,
+				       type = <<"command-node">>,
+				       name = translate:translate(Lang, Name)}],
+	       features = [?NS_COMMANDS, ?NS_XDATA]};
+	_ ->
+	    undefined
     end.
 
 iq_get_vcard(Lang) ->
-    [#xmlel{name = <<"FN">>, attrs = [],
-	    children = [{xmlcdata, <<"ejabberd/mod_irc">>}]},
-     #xmlel{name = <<"URL">>, attrs = [],
-	    children = [{xmlcdata, ?EJABBERD_URI}]},
-     #xmlel{name = <<"DESC">>, attrs = [],
-	    children =
-		[{xmlcdata,
-		  <<(translate:translate(Lang,
-					 <<"ejabberd IRC module">>))/binary,
-		    "\nCopyright (c) 2003-2016 ProcessOne">>}]}].
+    Desc = translate:translate(Lang, <<"ejabberd IRC module">>),
+    Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>,
+    #vcard_temp{fn = <<"ejabberd/mod_irc">>,
+		url = ?EJABBERD_URI,
+		desc = <>}.
 
 command_items(ServerHost, Host, Lang) ->
-    lists:map(fun ({Node, Name, _Function}) ->
-		      #xmlel{name = <<"item">>,
-			     attrs =
-				 [{<<"jid">>, Host}, {<<"node">>, Node},
-				  {<<"name">>,
-				   translate:translate(Lang, Name)}],
-			     children = []}
-	      end,
-	      commands(ServerHost)).
+    lists:map(fun({Node, Name, _Function}) ->
+		      #disco_item{jid = jid:make(Host),
+				  node = Node,
+				  name = translate:translate(Lang, Name)}
+	      end, commands(ServerHost)).
 
 commands(ServerHost) ->
     [{<<"join">>, <<"Join channel">>, fun adhoc_join/3},
@@ -494,243 +443,120 @@ commands(ServerHost) ->
 	      adhoc_register(ServerHost, From, To, Request)
       end}].
 
-process_register(ServerHost, Host, From, To,
-		 #iq{} = IQ) ->
-    case catch process_irc_register(ServerHost, Host, From,
-				    To, IQ)
-	of
-      {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
-      ResIQ ->
-	  if ResIQ /= ignore ->
-		 ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ));
-	     true -> ok
-	  end
-    end.
-
-find_xdata_el(#xmlel{children = SubEls}) ->
-    find_xdata_el1(SubEls).
-
-find_xdata_el1([]) -> false;
-find_xdata_el1([#xmlel{name = Name, attrs = Attrs,
-		       children = SubEls}
-		| Els]) ->
-    case fxml:get_attr_s(<<"xmlns">>, Attrs) of
-      ?NS_XDATA ->
-	  #xmlel{name = Name, attrs = Attrs, children = SubEls};
-      _ -> find_xdata_el1(Els)
-    end;
-find_xdata_el1([_ | Els]) -> find_xdata_el1(Els).
-
-process_irc_register(ServerHost, Host, From, _To,
-		     #iq{type = Type, xmlns = XMLNS, lang = Lang,
-			 sub_el = SubEl} =
-			 IQ) ->
-    case Type of
-      set ->
-	  XDataEl = find_xdata_el(SubEl),
-	  case XDataEl of
-	    false ->
-		Txt1 = <<"No data form found">>,
-		IQ#iq{type = error,
-		      sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, Txt1)]};
-	    #xmlel{attrs = Attrs} ->
-		case fxml:get_attr_s(<<"type">>, Attrs) of
-		  <<"cancel">> ->
-		      IQ#iq{type = result,
-			    sub_el =
-				[#xmlel{name = <<"query">>,
-					attrs = [{<<"xmlns">>, XMLNS}],
-					children = []}]};
-		  <<"submit">> ->
-		      XData = jlib:parse_xdata_submit(XDataEl),
-		      case XData of
-			invalid ->
-			    Txt2 = <<"Incorrect data form">>,
-			    IQ#iq{type = error,
-				  sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt2)]};
-			_ ->
-			    Node = str:tokens(fxml:get_tag_attr_s(<<"node">>,
-								 SubEl),
-					      <<"/">>),
-			    case set_form(ServerHost, Host, From, Node, Lang,
-					  XData)
-				of
-			      {result, Res} ->
-				  IQ#iq{type = result,
-					sub_el =
-					    [#xmlel{name = <<"query">>,
-						    attrs =
-							[{<<"xmlns">>, XMLNS}],
-						    children = Res}]};
-			      {error, Error} ->
-				  IQ#iq{type = error, sub_el = [SubEl, Error]}
-			    end
-		      end;
-		  _ ->
-		      Txt3 = <<"Incorrect value of 'type' attribute">>,
-		      IQ#iq{type = error,
-			    sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt3)]}
-		end
-	  end;
-      get ->
-	  Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl),
-			    <<"/">>),
-	  case get_form(ServerHost, Host, From, Node, Lang) of
-	    {result, Res} ->
-		IQ#iq{type = result,
-		      sub_el =
-			  [#xmlel{name = <<"query">>,
-				  attrs = [{<<"xmlns">>, XMLNS}],
-				  children = Res}]};
-	    {error, Error} ->
-		IQ#iq{type = error, sub_el = [SubEl, Error]}
-	  end
-    end.
-
 get_data(ServerHost, Host, From) ->
     LServer = jid:nameprep(ServerHost),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:get_data(LServer, Host, From).
 
-get_form(ServerHost, Host, From, [], Lang) ->
+get_form(ServerHost, Host, From, Lang) ->
     #jid{user = User, server = Server} = From,
     DefaultEncoding = get_default_encoding(Host),
     Customs = case get_data(ServerHost, Host, From) of
-		error ->
+		  error ->
 		      Txt1 = <<"Database failure">>,
-		      {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt1)};
-		empty -> {User, []};
-		Data -> get_username_and_connection_params(Data)
+		      {error, xmpp:err_internal_server_error(Txt1, Lang)};
+		  empty -> {User, []};
+		  Data -> get_username_and_connection_params(Data)
 	      end,
     case Customs of
-      {error, _Error} -> Customs;
-      {Username, ConnectionsParams} ->
-	  {result,
-	   [#xmlel{name = <<"instructions">>, attrs = [],
-		   children =
-		       [{xmlcdata,
-			 translate:translate(Lang,
-					     <<"You need an x:data capable client to "
-					       "configure mod_irc settings">>)}]},
-	    #xmlel{name = <<"x">>,
-		   attrs = [{<<"xmlns">>, ?NS_XDATA}],
-		   children =
-		       [#xmlel{name = <<"title">>, attrs = [],
-			       children =
-				   [{xmlcdata,
-				     <<(translate:translate(Lang,
-							    <<"Registration in mod_irc for ">>))/binary,
-				       User/binary, "@", Server/binary>>}]},
-			#xmlel{name = <<"instructions">>, attrs = [],
-			       children =
-				   [{xmlcdata,
-				     translate:translate(Lang,
-							 <<"Enter username, encodings, ports and "
-							   "passwords you wish to use for connecting "
-							   "to IRC servers">>)}]},
-			#xmlel{name = <<"field">>,
-			       attrs =
-				   [{<<"type">>, <<"text-single">>},
-				    {<<"label">>,
-				     translate:translate(Lang,
-							 <<"IRC Username">>)},
-				    {<<"var">>, <<"username">>}],
-			       children =
-				   [#xmlel{name = <<"value">>, attrs = [],
-					   children = [{xmlcdata, Username}]}]},
-			#xmlel{name = <<"field">>,
-			       attrs = [{<<"type">>, <<"fixed">>}],
-			       children =
-				   [#xmlel{name = <<"value">>, attrs = [],
-					   children =
-					       [{xmlcdata,
-						 iolist_to_binary(
-                                                   io_lib:format(
-                                                     translate:translate(
-                                                       Lang,
-                                                       <<"If you want to specify"
-                                                         " different ports, "
-                                                         "passwords, encodings "
-                                                         "for IRC servers, "
-                                                         "fill this list with "
-                                                         "values in format "
-                                                         "'{\"irc server\", "
-                                                         "\"encoding\", port, "
-                                                         "\"password\"}'.  "
-                                                         "By default this "
-                                                         "service use \"~s\" "
-                                                         "encoding, port ~p, "
-                                                         "empty password.">>),
-                                                     [DefaultEncoding,
-                                                      ?DEFAULT_IRC_PORT]))}]}]},
-			#xmlel{name = <<"field">>,
-			       attrs = [{<<"type">>, <<"fixed">>}],
-			       children =
-				   [#xmlel{name = <<"value">>, attrs = [],
-					   children =
-					       [{xmlcdata,
-						 translate:translate(Lang,
-								     <<"Example: [{\"irc.lucky.net\", \"koi8-r\", "
-								       "6667, \"secret\"}, {\"vendetta.fef.net\", "
-								       "\"iso8859-1\", 7000}, {\"irc.sometestserver.n"
-								       "et\", \"utf-8\"}].">>)}]}]},
-			#xmlel{name = <<"field">>,
-			       attrs =
-				   [{<<"type">>, <<"text-multi">>},
-				    {<<"label">>,
-				     translate:translate(Lang,
-							 <<"Connections parameters">>)},
-				    {<<"var">>, <<"connections_params">>}],
-			       children =
-				   lists:map(fun (S) ->
-						     #xmlel{name = <<"value">>,
-							    attrs = [],
-							    children =
-								[{xmlcdata, S}]}
-					     end,
-					     str:tokens(list_to_binary(
-                                                          io_lib:format(
-                                                            "~p.",
-                                                            [conn_params_to_list(
-                                                               ConnectionsParams)])),
-							<<"\n">>))}]}]}
-    end;
-get_form(_ServerHost, _Host, _, _, _Lang) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+	{error, _Error} ->
+	    Customs;
+	{Username, ConnectionsParams} ->
+	    Fs = [#xdata_field{type = 'text-single',
+			       label =  translate:translate(Lang, <<"IRC Username">>),
+			       var = <<"username">>,
+			       values = [Username]},
+		  #xdata_field{type = fixed,
+			       values = [iolist_to_binary(
+					   io_lib:format(
+					     translate:translate(
+					       Lang,
+					       <<"If you want to specify"
+						 " different ports, "
+						 "passwords, encodings "
+						 "for IRC servers, "
+						 "fill this list with "
+						 "values in format "
+						 "'{\"irc server\", "
+						 "\"encoding\", port, "
+						 "\"password\"}'.  "
+						 "By default this "
+						 "service use \"~s\" "
+						 "encoding, port ~p, "
+						 "empty password.">>),
+					     [DefaultEncoding, ?DEFAULT_IRC_PORT]))]},
+		  #xdata_field{type = fixed,
+			       values = [translate:translate(
+					   Lang,
+					   <<"Example: [{\"irc.lucky.net\", \"koi8-r\", "
+					     "6667, \"secret\"}, {\"vendetta.fef.net\", "
+					     "\"iso8859-1\", 7000}, {\"irc.sometestserver.n"
+					     "et\", \"utf-8\"}].">>)]},
+		  #xdata_field{type = 'text-multi',
+			       label = translate:translate(
+					 Lang, <<"Connections parameters">>),
+			       var = <<"connections_params">>,
+			       values = str:tokens(list_to_binary(
+						     io_lib:format(
+						       "~p.",
+						       [conn_params_to_list(
+							  ConnectionsParams)])),
+						   <<"\n">>)}],
+	    X = #xdata{type = form,
+		       title = <<(translate:translate(
+				    Lang, <<"Registration in mod_irc for ">>))/binary,
+				 User/binary, "@", Server/binary>>,
+		       instructions =
+			   [translate:translate(
+			      Lang,
+			      <<"Enter username, encodings, ports and "
+				"passwords you wish to use for connecting "
+				"to IRC servers">>)],
+		       fields = Fs},
+	    {result,
+	     #register{instructions = 
+			   translate:translate(Lang,
+					       <<"You need an x:data capable client to "
+						 "configure mod_irc settings">>),
+		       xdata = X}}
+    end.
 
 set_data(ServerHost, Host, From, Data) ->
     LServer = jid:nameprep(ServerHost),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:set_data(LServer, Host, From, data_to_binary(From, Data)).
 
-set_form(ServerHost, Host, From, [], Lang, XData) ->
-    case {lists:keysearch(<<"username">>, 1, XData),
-	  lists:keysearch(<<"connections_params">>, 1, XData)}
-	of
-      {{value, {_, [Username]}}, {value, {_, Strings}}} ->
-	  EncString = lists:foldl(fun (S, Res) ->
-					  <>
-				  end,
-				  <<"">>, Strings),
-	  case erl_scan:string(binary_to_list(EncString)) of
-	    {ok, Tokens, _} ->
-		case erl_parse:parse_term(Tokens) of
-		  {ok, ConnectionsParams} ->
-		      case set_data(ServerHost, Host, From,
-				    [{username, Username},
-				     {connections_params, ConnectionsParams}])
-			  of
-			{atomic, _} -> {result, []};
-			_ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Database failure">>)}
-		      end;
-		  _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Parse error">>)}
-		end;
-	    _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Scan error">>)}
-	  end;
-      _ -> {error, ?ERR_NOT_ACCEPTABLE}
-    end;
-set_form(_ServerHost, _Host, _, _, _Lang, _XData) ->
-    {error, ?ERR_SERVICE_UNAVAILABLE}.
+set_form(ServerHost, Host, From, Lang, XData) ->
+    case {xmpp_util:get_xdata_values(<<"username">>, XData),
+	  xmpp_util:get_xdata_values(<<"connections_params">>, XData)} of
+	{[Username], [_|_] = Strings} ->
+	    EncString = lists:foldl(fun (S, Res) ->
+					    <>
+				    end, <<"">>, Strings),
+	    case erl_scan:string(binary_to_list(EncString)) of
+		{ok, Tokens, _} ->
+		    case erl_parse:parse_term(Tokens) of
+			{ok, ConnectionsParams} ->
+			    case set_data(ServerHost, Host, From,
+					  [{username, Username},
+					   {connections_params, ConnectionsParams}]) of
+				{atomic, _} ->
+				    {result, undefined};
+				_ ->
+				    Txt = <<"Database failure">>,
+				    {error, xmpp:err_internal_server_error(Txt, Lang)}
+			    end;
+			_ ->
+			    Txt = <<"Parse error">>,
+			    {error, xmpp:err_not_acceptable(Txt, Lang)}
+		    end;
+		_ ->
+		    {error, xmpp:err_not_acceptable(<<"Scan error">>, Lang)}
+	    end;
+	_ ->
+	    Txt = <<"Incorrect value in data form">>,
+	    {error, xmpp:err_not_acceptable(Txt, Lang)}
+    end.
 
 get_connection_params(Host, From, IRCServer) ->
     [_ | HostTail] = str:tokens(Host, <<".">>),
@@ -805,212 +631,118 @@ get_connection_params(Host, ServerHost, From,
 	   iolist_to_binary(NewPassword)}
     end.
 
-adhoc_join(_From, _To,
-	   #adhoc_request{action = <<"cancel">>} = Request) ->
-    adhoc:produce_response(Request,
-			   #adhoc_response{status = canceled});
-adhoc_join(From, To,
-	   #adhoc_request{lang = Lang, node = _Node,
-			  action = _Action, xdata = XData} =
-	       Request) ->
-    if XData == false ->
-	   Form = #xmlel{name = <<"x">>,
-			 attrs =
-			     [{<<"xmlns">>, ?NS_XDATA},
-			      {<<"type">>, <<"form">>}],
-			 children =
-			     [#xmlel{name = <<"title">>, attrs = [],
-				     children =
-					 [{xmlcdata,
-					   translate:translate(Lang,
-							       <<"Join IRC channel">>)}]},
-			      #xmlel{name = <<"field">>,
-				     attrs =
-					 [{<<"var">>, <<"channel">>},
-					  {<<"type">>, <<"text-single">>},
-					  {<<"label">>,
-					   translate:translate(Lang,
-							       <<"IRC channel (don't put the first #)">>)}],
-				     children =
-					 [#xmlel{name = <<"required">>,
-						 attrs = [], children = []}]},
-			      #xmlel{name = <<"field">>,
-				     attrs =
-					 [{<<"var">>, <<"server">>},
-					  {<<"type">>, <<"text-single">>},
-					  {<<"label">>,
-					   translate:translate(Lang,
-							       <<"IRC server">>)}],
-				     children =
-					 [#xmlel{name = <<"required">>,
-						 attrs = [], children = []}]}]},
-	   adhoc:produce_response(Request,
-				  #adhoc_response{status = executing,
-						  elements = [Form]});
+adhoc_join(_From, _To, #adhoc_command{action = cancel} = Request) ->
+    xmpp_util:make_adhoc_response(Request, #adhoc_command{status = canceled});
+adhoc_join(_From, _To, #adhoc_command{lang = Lang, xdata = undefined} = Request) ->
+    X = #xdata{type = form,
+	       title = translate:translate(Lang, <<"Join IRC channel">>),
+	       fields = [#xdata_field{var = <<"channel">>,
+				      type = 'text-single',
+				      label = translate:translate(
+						Lang, <<"IRC channel (don't put the first #)">>),
+				      required = true},
+			 #xdata_field{var = <<"server">>,
+				      type = 'text-single',
+				      label = translate:translate(Lang, <<"IRC server">>),
+				      required = true}]},
+    xmpp_utils:make_adhoc_response(
+      Request, #adhoc_command{status = executing, xdata = X});
+adhoc_join(From, To, #adhoc_command{lang = Lang, xdata = X} = Request) ->
+    Channel = case xmpp_util:get_xdata_values(<<"channel">>, X) of
+		  [C] -> C;
+		  _ -> false
+	      end,
+    Server = case xmpp_util:get_xdata_values(<<"server">>, X) of
+		 [S] -> S;
+		 _ -> false
+	     end,
+    if Channel /= false, Server /= false ->
+	    RoomJID = jid:make(<>,
+			       To#jid.server),
+	    Reason = translate:translate(Lang, <<"Join the IRC channel here.">>),
+	    Body = iolist_to_binary(
+		     io_lib:format(
+		       translate:translate(
+			 Lang, <<"Join the IRC channel in this Jabber ID: ~s">>),
+		       [jid:to_string(RoomJID)])),
+	    Invite = #message{
+			body = xmpp:mk_text(Body, Lang),
+			sub_els = [#muc_user{
+				      invites = [#muc_invite{from = From,
+							     reason = Reason}]},
+				   #x_conference{reason = Reason,
+						 jid = RoomJID}]},
+	    ejabberd_router:route(RoomJID, From, Invite),
+	    xmpp_util:make_adhoc_response(
+	      Request, #adhoc_command{status = completed});
        true ->
-	   case jlib:parse_xdata_submit(XData) of
-	     invalid ->
-		 Txt1 = <<"Incorrect data form">>,
-		 {error, ?ERRT_BAD_REQUEST(Lang, Txt1)};
-	     Fields ->
-		 Channel = case lists:keysearch(<<"channel">>, 1, Fields)
-			       of
-			     {value, {<<"channel">>, [C]}} -> C;
-			     _ -> false
-			   end,
-		 Server = case lists:keysearch(<<"server">>, 1, Fields)
-			      of
-			    {value, {<<"server">>, [S]}} -> S;
-			    _ -> false
-			  end,
-		 if Channel /= false, Server /= false ->
-			RoomJID = <>,
-			Invite = #xmlel{name = <<"message">>, attrs = [],
-					children =
-					    [#xmlel{name = <<"x">>,
-						    attrs =
-							[{<<"xmlns">>,
-							  ?NS_MUC_USER}],
-						    children =
-							[#xmlel{name =
-								    <<"invite">>,
-								attrs =
-								    [{<<"from">>,
-								      jid:to_string(From)}],
-								children =
-								    [#xmlel{name
-										=
-										<<"reason">>,
-									    attrs
-										=
-										[],
-									    children
-										=
-										[{xmlcdata,
-										  translate:translate(Lang,
-												      <<"Join the IRC channel here.">>)}]}]}]},
-					     #xmlel{name = <<"x">>,
-						    attrs =
-							[{<<"xmlns">>,
-							  ?NS_XCONFERENCE}],
-						    children =
-							[{xmlcdata,
-							  translate:translate(Lang,
-									      <<"Join the IRC channel here.">>)}]},
-					     #xmlel{name = <<"body">>,
-						    attrs = [],
-						    children =
-							[{xmlcdata,
-							  iolist_to_binary(
-                                                            io_lib:format(
-                                                              translate:translate(
-                                                                Lang,
-                                                                <<"Join the IRC channel in this Jabber ID: ~s">>),
-                                                              [RoomJID]))}]}]},
-			ejabberd_router:route(jid:from_string(RoomJID), From,
-					      Invite),
-			adhoc:produce_response(Request,
-					       #adhoc_response{status =
-								   completed});
-		    true -> {error, ?ERR_BAD_REQUEST}
-		 end
-	   end
+	    Txt = <<"Missing 'channel' or 'server' in the data form">>,
+	    {error, xmpp:err_bad_request(Txt, Lang)}
     end.
 
+-spec adhoc_register(binary(), jid(), jid(), adhoc_command()) ->
+			    adhoc_command() | {error, error()}.
 adhoc_register(_ServerHost, _From, _To,
-	       #adhoc_request{action = <<"cancel">>} = Request) ->
-    adhoc:produce_response(Request,
-			   #adhoc_response{status = canceled});
+	       #adhoc_command{action = cancel} = Request) ->
+    xmpp_util:make_adhoc_response(Request, #adhoc_command{status = canceled});
 adhoc_register(ServerHost, From, To,
-	       #adhoc_request{lang = Lang, node = _Node, xdata = XData,
-			      action = Action} =
-		   Request) ->
+	       #adhoc_command{lang = Lang, xdata = X,
+			      action = Action} = Request) ->
     #jid{user = User} = From,
     #jid{lserver = Host} = To,
-    if XData == false ->
-	   case get_data(ServerHost, Host, From) of
-	     error -> Username = User, ConnectionsParams = [];
-	     empty -> Username = User, ConnectionsParams = [];
-	     Data ->
-		 {Username, ConnectionsParams} =
-                       get_username_and_connection_params(Data)
-	   end,
-	   Error = false;
-       true ->
-	   case jlib:parse_xdata_submit(XData) of
-	     invalid ->
-		 Txt1 = <<"Incorrect data form">>,
-		 Error = {error, ?ERRT_BAD_REQUEST(Lang, Txt1)},
-		 Username = false,
-		 ConnectionsParams = false;
-	     Fields ->
-		 Username = case lists:keysearch(<<"username">>, 1,
-						 Fields)
-				of
-			      {value, {<<"username">>, U}} -> U;
-			      _ -> User
-			    end,
-		 ConnectionsParams = parse_connections_params(Fields),
-		 Error = false
-	   end
-    end,
-    if Error /= false -> Error;
-       Action == <<"complete">> ->
-	   case set_data(ServerHost, Host, From,
-			 [{username, Username},
-			  {connections_params, ConnectionsParams}])
-	       of
-	     {atomic, _} ->
-		 adhoc:produce_response(Request,
-					#adhoc_response{status = completed});
-	     _ ->
-		 Txt2 = <<"Database failure">>,
-		 {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt2)}
-	   end;
+    {Username, ConnectionsParams} =
+	if X == undefined ->
+		case get_data(ServerHost, Host, From) of
+		    error -> {User, []};
+		    empty -> {User, []};
+		    Data -> get_username_and_connection_params(Data)
+		end;
+	   true ->
+		{case xmpp_util:get_xdata_values(<<"username">>, X) of
+		     [U] -> U;
+		     _ -> User
+		 end, parse_connections_params(X)}
+	end,
+    if Action == complete ->
+	    case set_data(ServerHost, Host, From,
+			  [{username, Username},
+			   {connections_params, ConnectionsParams}]) of
+		{atomic, _} ->
+		    xmpp_util:make_adhoc_response(
+		      Request, #adhoc_command{status = completed});
+		_ ->
+		    Txt = <<"Database failure">>,
+		    {error, xmpp:err_internal_server_error(Txt, Lang)}
+	    end;
        true ->
-	   Form = generate_adhoc_register_form(Lang, Username,
-					       ConnectionsParams),
-	   adhoc:produce_response(Request,
-				  #adhoc_response{status = executing,
-						  elements = [Form],
-						  actions =
-						      [<<"next">>,
-						       <<"complete">>]})
+	    Form = generate_adhoc_register_form(Lang, Username,
+						ConnectionsParams),
+	    xmpp_util:make_adhoc_response(
+	      Request, #adhoc_command{
+			  status = executing,
+			  xdata = Form,
+			  actions = #adhoc_actions{next = true,
+						   complete = true}})
     end.
 
 generate_adhoc_register_form(Lang, Username,
 			     ConnectionsParams) ->
-    #xmlel{name = <<"x">>,
-	   attrs =
-	       [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}],
-	   children =
-	       [#xmlel{name = <<"title">>, attrs = [],
-		       children =
-			   [{xmlcdata,
-			     translate:translate(Lang, <<"IRC settings">>)}]},
-		#xmlel{name = <<"instructions">>, attrs = [],
-		       children =
-			   [{xmlcdata,
-			     translate:translate(Lang,
-						 <<"Enter username and encodings you wish "
-						   "to use for connecting to IRC servers. "
-						   " Press 'Next' to get more fields to "
-						   "fill in.  Press 'Complete' to save settings.">>)}]},
-		#xmlel{name = <<"field">>,
-		       attrs =
-			   [{<<"var">>, <<"username">>},
-			    {<<"type">>, <<"text-single">>},
-			    {<<"label">>,
-			     translate:translate(Lang, <<"IRC username">>)}],
-		       children =
-			   [#xmlel{name = <<"required">>, attrs = [],
-				   children = []},
-			    #xmlel{name = <<"value">>, attrs = [],
-				   children = [{xmlcdata, Username}]}]}]
-		 ++
-		 generate_connection_params_fields(Lang,
-						   ConnectionsParams, 1, [])}.
+    #xdata{type = form,
+	   title = translate:translate(Lang, <<"IRC settings">>),
+	   instructions = [translate:translate(
+			     Lang,
+			     <<"Enter username and encodings you wish "
+			       "to use for connecting to IRC servers. "
+			       " Press 'Next' to get more fields to "
+			       "fill in.  Press 'Complete' to save settings.">>)],
+	   fields = [#xdata_field{
+			var = <<"username">>,
+			type = 'text-single',
+			label = translate:translate(Lang, <<"IRC username">>),
+			required = true,
+			values = [Username]}
+		     | generate_connection_params_fields(
+			 Lang, ConnectionsParams, 1, [])]}.
 
 generate_connection_params_fields(Lang, [], Number,
 				  Acc) ->
@@ -1061,91 +793,67 @@ generate_connection_params_field(Lang, Server, Encoding,
 		   end,
     NumberString =
 	iolist_to_binary(integer_to_list(Number)),
-    [#xmlel{name = <<"field">>,
-	    attrs =
-		[{<<"var">>, <<"password", NumberString/binary>>},
-		 {<<"type">>, <<"text-single">>},
-		 {<<"label">>,
-		  iolist_to_binary(
-                    io_lib:format(
-                      translate:translate(Lang, <<"Password ~b">>),
-                      [Number]))}],
-	    children =
-		[#xmlel{name = <<"value">>, attrs = [],
-			children = [{xmlcdata, PasswordUsed}]}]},
-     #xmlel{name = <<"field">>,
-	    attrs =
-		[{<<"var">>, <<"port", NumberString/binary>>},
-		 {<<"type">>, <<"text-single">>},
-		 {<<"label">>,
-		  iolist_to_binary(
-                    io_lib:format(translate:translate(Lang, <<"Port ~b">>),
-                                  [Number]))}],
-	    children =
-		[#xmlel{name = <<"value">>, attrs = [],
-			children = [{xmlcdata, PortUsed}]}]},
-     #xmlel{name = <<"field">>,
-	    attrs =
-		[{<<"var">>, <<"encoding", NumberString/binary>>},
-		 {<<"type">>, <<"list-single">>},
-		 {<<"label">>,
-		  list_to_binary(
-                    io_lib:format(translate:translate(
-                                    Lang,
-                                    <<"Encoding for server ~b">>),
-                                  [Number]))}],
-	    children =
-		[#xmlel{name = <<"value">>, attrs = [],
-			children = [{xmlcdata, EncodingUsed}]}
-		 | lists:map(fun (E) ->
-				     #xmlel{name = <<"option">>,
-					    attrs = [{<<"label">>, E}],
-					    children =
-						[#xmlel{name = <<"value">>,
-							attrs = [],
-							children =
-							    [{xmlcdata, E}]}]}
-			     end,
-			     ?POSSIBLE_ENCODINGS)]},
-     #xmlel{name = <<"field">>,
-	    attrs =
-		[{<<"var">>, <<"server", NumberString/binary>>},
-		 {<<"type">>, <<"text-single">>},
-		 {<<"label">>,
-		  list_to_binary(
-                    io_lib:format(translate:translate(Lang, <<"Server ~b">>),
-                                  [Number]))}],
-	    children =
-		[#xmlel{name = <<"value">>, attrs = [],
-			children = [{xmlcdata, Server}]}]}].
-
-parse_connections_params(Fields) ->
+    [#xdata_field{var = <<"password", NumberString/binary>>,
+		  type = 'text-single',
+		  label =  iolist_to_binary(
+			     io_lib:format(
+			       translate:translate(Lang, <<"Password ~b">>),
+			       [Number])),
+		  values = [PasswordUsed]},
+     #xdata_field{var = <<"port", NumberString/binary>>,
+		  type = 'text-single',
+		  label = iolist_to_binary(
+			    io_lib:format(
+			      translate:translate(Lang, <<"Port ~b">>),
+			      [Number])),
+		  values = [PortUsed]},
+     #xdata_field{var = <<"encoding", NumberString/binary>>,
+		  type = 'list-single',
+		  label = list_to_binary(
+			    io_lib:format(
+			      translate:translate(Lang, <<"Encoding for server ~b">>),
+			      [Number])),
+		  values = [EncodingUsed],
+		  options = [#xdata_option{label = E, value = E}
+			     || E <- ?POSSIBLE_ENCODINGS]},
+     #xdata_field{var = <<"server", NumberString/binary>>,
+		  type = 'text-single',
+		  label = list_to_binary(
+			    io_lib:format(
+			      translate:translate(Lang, <<"Server ~b">>),
+			      [Number])),
+		  values = [Server]}].
+
+parse_connections_params(#xdata{fields = Fields}) ->
     Servers = lists:flatmap(
-                fun({<<"server", Var/binary>>, Value}) ->
-                        [{Var, Value}];
+                fun(#xdata_field{var = <<"server", Var/binary>>,
+				 values = Values}) ->
+                        [{Var, Values}];
                    (_) ->
                         []
                 end, Fields),
     Encodings = lists:flatmap(
-                  fun({<<"encoding", Var/binary>>, Value}) ->
-                          [{Var, Value}];
+                  fun(#xdata_field{var = <<"encoding", Var/binary>>,
+				   values = Values}) ->
+                          [{Var, Values}];
                      (_) ->
                           []
                   end, Fields),
     Ports = lists:flatmap(
-              fun({<<"port", Var/binary>>, Value}) ->
-                      [{Var, Value}];
+              fun(#xdata_field{var = <<"port", Var/binary>>,
+			       values = Values}) ->
+                      [{Var, Values}];
                  (_) ->
                       []
               end, Fields),
     Passwords = lists:flatmap(
-                  fun({<<"password", Var/binary>>, Value}) ->
-                          [{Var, Value}];
+                  fun(#xdata_field{var = <<"password", Var/binary>>,
+				   values = Values}) ->
+                          [{Var, Values}];
                      (_) ->
                           []
                   end, Fields),
-    parse_connections_params(Servers, Encodings, Ports,
-			     Passwords).
+    parse_connections_params(Servers, Encodings, Ports, Passwords).
 
 retrieve_connections_params(ConnectionParams,
 			    ServerN) ->
@@ -1263,28 +971,19 @@ mod_opt_type(host) -> fun iolist_to_binary/1;
 mod_opt_type(_) ->
     [access, db_type, default_encoding, host].
 
+-spec extract_ident(stanza()) -> binary().
 extract_ident(Packet) ->
-    case fxml:get_subtag(Packet, <<"headers">>) of
-	{xmlel, _Name, _Attrs, Headers} ->
-	    extract_header(<<"X-Irc-Ident">>, Headers);
-	_ ->
-	    "chatmovil"
-    end.
+    Hdrs = extract_headers(Packet),
+    proplists:get_value(<<"X-Irc-Ident">>, Hdrs, <<"chatmovil">>).
 
+-spec extract_ip_address(stanza()) -> binary().
 extract_ip_address(Packet) ->
-    case fxml:get_subtag(Packet, <<"headers">>) of
-	{xmlel, _Name, _Attrs, Headers} ->
-	    extract_header(<<"X-Forwarded-For">>, Headers);
-	_ ->
-	    "127.0.0.1"
+    Hdrs = extract_headers(Packet),
+    proplists:get_value(<<"X-Forwarded-For">>, Hdrs, <<"127.0.0.1">>).
+
+-spec extract_headers(stanza()) -> [{binary(), binary()}].
+extract_headers(Packet) ->
+    case xmpp:get_subtag(Packet, #shim{}) of
+	#shim{headers = Hs} -> Hs;
+	false -> []
     end.
-
-extract_header(HeaderName, [{xmlel, _Name, _Attrs, [{xmlcdata, Value}]} | Tail]) ->
-    case fxml:get_attr(<<"name">>, _Attrs) of
-	{value, HeaderName} ->
-	    binary_to_list(Value);
-	_ ->
-	    extract_header(HeaderName, Tail)
-    end;
-extract_header(_HeaderName, _Headers) ->
-	false.
diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl
index 098c8c286..fb301330a 100644
--- a/src/mod_irc_connection.erl
+++ b/src/mod_irc_connection.erl
@@ -41,8 +41,7 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
-
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 -define(SETS, gb_sets).
 
@@ -66,6 +65,8 @@
 	 inbuf = <<"">>        :: binary(),
          outbuf = <<"">>       :: binary()}).
 
+-type state() :: #state{}.
+
 %-define(DBGFSM, true).
 
 -ifdef(DBGFSM).
@@ -228,27 +229,13 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
                                           (iolist_to_binary(S))/binary>>}
 	end).
 
-get_password_from_presence(#xmlel{name = <<"presence">>,
-				  children = Els}) ->
-    case lists:filter(fun (El) ->
-			      case El of
-				#xmlel{name = <<"x">>, attrs = Attrs} ->
-				    case fxml:get_attr_s(<<"xmlns">>, Attrs) of
-				      ?NS_MUC -> true;
-				      _ -> false
-				    end;
-				_ -> false
-			      end
-		      end,
-		      Els)
-	of
-      [ElXMUC | _] ->
-	  case fxml:get_subtag(ElXMUC, <<"password">>) of
-	    #xmlel{name = <<"password">>} = PasswordTag ->
-		{true, fxml:get_tag_cdata(PasswordTag)};
-	    _ -> false
-	  end;
-      _ -> false
+-spec get_password_from_presence(presence()) -> {true, binary()} | false.
+get_password_from_presence(#presence{} = Pres) ->
+    case xmpp:get_subtag(Pres, #muc{}) of
+	#muc{password = Password} ->
+	    {true, Password};
+	_ ->
+	    false
     end.
 
 %%----------------------------------------------------------------------
@@ -257,284 +244,243 @@ get_password_from_presence(#xmlel{name = <<"presence">>,
 %%          {next_state, NextStateName, NextStateData, Timeout} |
 %%          {stop, Reason, NewStateData}
 %%----------------------------------------------------------------------
-handle_info({route_chan, Channel, Resource,
-	     #xmlel{name = <<"presence">>, attrs = Attrs} =
-		 Presence},
+handle_info({route_chan, _, _, #presence{type = error}}, _, StateData) ->
+    {stop, normal, StateData};
+handle_info({route_chan, Channel, _, #presence{type = unavailable}},
 	    StateName, StateData) ->
-    NewStateData = case fxml:get_attr_s(<<"type">>, Attrs) of
-		     <<"unavailable">> ->
-			 send_stanza_unavailable(Channel, StateData),
-			 S1 = (?SEND((io_lib:format("PART #~s\r\n",
-						    [Channel])))),
-			 S1#state{channels =
-				      dict:erase(Channel, S1#state.channels)};
-		     <<"subscribe">> -> StateData;
-		     <<"subscribed">> -> StateData;
-		     <<"unsubscribe">> -> StateData;
-		     <<"unsubscribed">> -> StateData;
-		     <<"error">> -> stop;
-		     _ ->
-			 Nick = case Resource of
-				  <<"">> -> StateData#state.nick;
-				  _ -> Resource
-				end,
-			 S1 = if Nick /= StateData#state.nick ->
-				     S11 = (?SEND((io_lib:format("NICK ~s\r\n",
-								 [Nick])))),
-				     S11#state{nickchannel = Channel};
-				 true -> StateData
-			      end,
-			 case dict:is_key(Channel, S1#state.channels) of
-			   true -> S1;
-			   _ ->
-			       case get_password_from_presence(Presence) of
-				 {true, Password} ->
-				     S2 =
-					 (?SEND((io_lib:format("JOIN #~s ~s\r\n",
-							       [Channel,
-								Password]))));
-				 _ ->
-				     S2 = (?SEND((io_lib:format("JOIN #~s\r\n",
-								[Channel]))))
-			       end,
-			       S2#state{channels =
-					    dict:store(Channel, (?SETS):new(),
-						       S1#state.channels)}
-			 end
-		   end,
-    if NewStateData == stop -> {stop, normal, StateData};
-       true ->
-	   case dict:fetch_keys(NewStateData#state.channels) of
-	     [] -> {stop, normal, NewStateData};
-	     _ -> {next_state, StateName, NewStateData}
-	   end
-    end;
+    send_stanza_unavailable(Channel, StateData),
+    S1 = (?SEND((io_lib:format("PART #~s\r\n", [Channel])))),
+    S2 = S1#state{channels = dict:erase(Channel, S1#state.channels)},
+    {next_state, StateName, S2};
 handle_info({route_chan, Channel, Resource,
-	     #xmlel{name = <<"message">>, attrs = Attrs} = El},
+	     #presence{type = available} = Presence},
 	    StateName, StateData) ->
-    NewStateData = case fxml:get_attr_s(<<"type">>, Attrs) of
-		     <<"groupchat">> ->
-			 case fxml:get_path_s(El, [{elem, <<"subject">>}, cdata])
-			     of
-			   <<"">> ->
-			       ejabberd_router:route(
-                                 jid:make(
-                                   iolist_to_binary([Channel,
-                                                     <<"%">>,
-                                                     StateData#state.server]),
-                                   StateData#state.host,
-                                   StateData#state.nick),
-                                 StateData#state.user, El),
-			       Body = fxml:get_path_s(El,
-						     [{elem, <<"body">>},
-						      cdata]),
-			       case Body of
-				 <<"/quote ", Rest/binary>> ->
-				     ?SEND(<>);
-				 <<"/msg ", Rest/binary>> ->
-				     ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
-				 <<"/me ", Rest/binary>> ->
-				     Strings = str:tokens(Rest, <<"\n">>),
-				     Res = iolist_to_binary(
-                                             lists:map(
-                                               fun (S) ->
-                                                       io_lib:format(
-                                                         "PRIVMSG #~s :\001ACTION ~s\001\r\n",
-                                                         [Channel, S])
-                                               end,
-                                               Strings)),
-				     ?SEND(Res);
-				 <<"/ctcp ", Rest/binary>> ->
-				     Words = str:tokens(Rest, <<" ">>),
-				     case Words of
-				       [CtcpDest | _] ->
-					   CtcpCmd = str:to_upper(
-                                                       str:substr(Rest,
-                                                                  str:str(Rest,
-                                                                          <<" ">>)
-                                                                  + 1)),
-					   Res =
-					       io_lib:format("PRIVMSG ~s :\001~s\001\r\n",
-							     [CtcpDest,
-							      CtcpCmd]),
-					   ?SEND(Res);
-				       _ -> ok
-				     end;
-				 _ ->
-				     Strings = str:tokens(Body, <<"\n">>),
-				     Res = iolist_to_binary(
-                                             lists:map(
-                                               fun (S) ->
-                                                       io_lib:format("PRIVMSG #~s :~s\r\n",
-                                                                     [Channel, S])
-                                               end,
-                                               Strings)),
-				     ?SEND(Res)
-			       end;
-			   Subject ->
-			       Strings = str:tokens(Subject, <<"\n">>),
-			       Res = iolist_to_binary(
-                                       lists:map(
-                                         fun (S) ->
-                                                 io_lib:format("TOPIC #~s :~s\r\n",
-                                                               [Channel, S])
-                                         end,
-                                         Strings)),
-			       ?SEND(Res)
-			 end;
-		     Type
-			 when Type == <<"chat">>;
-			      Type == <<"">>;
-			      Type == <<"normal">> ->
-			 Body = fxml:get_path_s(El, [{elem, <<"body">>}, cdata]),
-			 case Body of
-			   <<"/quote ", Rest/binary>> ->
-			       ?SEND(<>);
-			   <<"/msg ", Rest/binary>> ->
-			       ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
-			   <<"/me ", Rest/binary>> ->
-			       Strings = str:tokens(Rest, <<"\n">>),
-			       Res = iolist_to_binary(
-                                       lists:map(
-                                         fun (S) ->
-                                                 io_lib:format(
-                                                   "PRIVMSG ~s :\001ACTION ~s\001\r\n",
-                                                   [Resource, S])
-                                         end,
-                                         Strings)),
-			       ?SEND(Res);
-			   <<"/ctcp ", Rest/binary>> ->
-			       Words = str:tokens(Rest, <<" ">>),
-			       case Words of
-				 [CtcpDest | _] ->
-				     CtcpCmd = str:to_upper(
-                                                 str:substr(Rest,
-                                                            str:str(Rest,
-                                                                    <<" ">>)
-                                                            + 1)),
-				     Res = io_lib:format("PRIVMSG ~s :~s\r\n",
-							 [CtcpDest,
-							  <<"\001",
-							    CtcpCmd/binary,
-							    "\001">>]),
-				     ?SEND(Res);
-				 _ -> ok
-			       end;
-			   _ ->
-			       Strings = str:tokens(Body, <<"\n">>),
-			       Res = iolist_to_binary(
-                                       lists:map(
-                                         fun (S) ->
-                                                 io_lib:format(
-                                                   "PRIVMSG ~s :~s\r\n",
-                                                   [Resource, S])
-                                         end,
-                                         Strings)),
-			       ?SEND(Res)
-			 end;
-		     <<"error">> -> stop;
-		     _ -> StateData
-		   end,
-    if NewStateData == stop -> {stop, normal, StateData};
-       true -> {next_state, StateName, NewStateData}
-    end;
-handle_info({route_chan, Channel, Resource,
-	     #xmlel{name = <<"iq">>} = El},
+    Nick = case Resource of
+	       <<"">> -> StateData#state.nick;
+	       _ -> Resource
+	   end,
+    S1 = if Nick /= StateData#state.nick ->
+		 S11 = (?SEND((io_lib:format("NICK ~s\r\n", [Nick])))),
+		 S11#state{nickchannel = Channel};
+	    true -> StateData
+	 end,
+    {next_state, StateName,
+     case dict:is_key(Channel, S1#state.channels) of
+	 true -> S1;
+	 _ ->
+	     case get_password_from_presence(Presence) of
+		 {true, Password} ->
+		     S2 = ?SEND((io_lib:format("JOIN #~s ~s\r\n",
+					       [Channel, Password])));
+		 _ ->
+		     S2 = ?SEND((io_lib:format("JOIN #~s\r\n", [Channel])))
+	     end,
+	     S2#state{channels = dict:store(Channel, ?SETS:new(),
+					    S1#state.channels)}
+     end};
+handle_info({route_chan, Channel, _Resource, #message{type = groupchat} = Msg},
 	    StateName, StateData) ->
+    {next_state, StateName,
+    case xmpp:get_text(Msg#message.subject) of
+	<<"">> ->
+	    ejabberd_router:route(
+	      jid:make(
+		iolist_to_binary([Channel,
+				  <<"%">>,
+				  StateData#state.server]),
+		StateData#state.host,
+		StateData#state.nick),
+	      StateData#state.user, Msg),
+	    Body = xmpp:get_text(Msg#message.body),
+	    case Body of
+		<<"/quote ", Rest/binary>> ->
+		    ?SEND(<>);
+		<<"/msg ", Rest/binary>> ->
+		    ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
+		<<"/me ", Rest/binary>> ->
+		    Strings = str:tokens(Rest, <<"\n">>),
+		    Res = iolist_to_binary(
+			    lists:map(
+			      fun (S) ->
+				      io_lib:format(
+					"PRIVMSG #~s :\001ACTION ~s\001\r\n",
+					[Channel, S])
+			      end,
+			      Strings)),
+		    ?SEND(Res);
+		<<"/ctcp ", Rest/binary>> ->
+		    Words = str:tokens(Rest, <<" ">>),
+		    case Words of
+			[CtcpDest | _] ->
+			    CtcpCmd = str:to_upper(
+					str:substr(
+					  Rest, str:str(Rest, <<" ">>) + 1)),
+			    Res = io_lib:format("PRIVMSG ~s :\001~s\001\r\n",
+						[CtcpDest, CtcpCmd]),
+			    ?SEND(Res);
+			_ -> ok
+		    end;
+		_ ->
+		    Strings = str:tokens(Body, <<"\n">>),
+		    Res = iolist_to_binary(
+			    lists:map(
+			      fun (S) ->
+				      io_lib:format("PRIVMSG #~s :~s\r\n",
+						    [Channel, S])
+			      end, Strings)),
+		    ?SEND(Res)
+	    end;
+	Subject ->
+	    Strings = str:tokens(Subject, <<"\n">>),
+	    Res = iolist_to_binary(
+		    lists:map(
+		      fun (S) ->
+			      io_lib:format("TOPIC #~s :~s\r\n",
+					    [Channel, S])
+		      end,
+		      Strings)),
+	    ?SEND(Res)
+    end};
+handle_info({route_chan, _Channel, Resource, #message{type = Type} = Msg},
+	    StateName, StateData) when Type == chat; Type == normal ->
+    Body = xmpp:get_text(Msg#message.body),
+    {next_state, StateName,
+     case Body of
+	 <<"/quote ", Rest/binary>> ->
+	     ?SEND(<>);
+	 <<"/msg ", Rest/binary>> ->
+	     ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
+	 <<"/me ", Rest/binary>> ->
+	     Strings = str:tokens(Rest, <<"\n">>),
+	     Res = iolist_to_binary(
+		     lists:map(
+		       fun (S) ->
+			       io_lib:format(
+				 "PRIVMSG ~s :\001ACTION ~s\001\r\n",
+				 [Resource, S])
+		       end, Strings)),
+	     ?SEND(Res);
+	 <<"/ctcp ", Rest/binary>> ->
+	     Words = str:tokens(Rest, <<" ">>),
+	     case Words of
+		 [CtcpDest | _] ->
+		     CtcpCmd = str:to_upper(
+				 str:substr(
+				   Rest, str:str(Rest, <<" ">>) + 1)),
+		     Res = io_lib:format("PRIVMSG ~s :~s\r\n",
+					 [CtcpDest,
+					  <<"\001", CtcpCmd/binary, "\001">>]),
+		     ?SEND(Res);
+		 _ -> ok
+	     end;
+	 _ ->
+	     Strings = str:tokens(Body, <<"\n">>),
+	     Res = iolist_to_binary(
+		     lists:map(
+		       fun (S) ->
+			       io_lib:format("PRIVMSG ~s :~s\r\n",
+					     [Resource, S])
+		       end, Strings)),
+	     ?SEND(Res)
+     end};
+handle_info({route_chan, _, _, #message{type = error}}, _, StateData) ->
+    {stop, normal, StateData};
+handle_info({route_chan, Channel, Resource,
+	     #iq{type = T, sub_els = [_]} = Packet},
+	    StateName, StateData) when T == set; T == get ->
     From = StateData#state.user,
-    To = jid:make(iolist_to_binary([Channel, <<"%">>,
-                                         StateData#state.server]),
-		       StateData#state.host, StateData#state.nick),
-    _ = case jlib:iq_query_info(El) of
-	  #iq{xmlns = ?NS_MUC_ADMIN} = IQ ->
-	      iq_admin(StateData, Channel, From, To, IQ);
-	  #iq{xmlns = ?NS_VERSION} ->
-	      Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n",
-				  [Resource]),
-	      _ = (?SEND(Res)),
-	      Err = jlib:make_error_reply(El,
-					  ?ERR_FEATURE_NOT_IMPLEMENTED),
-	      ejabberd_router:route(To, From, Err);
-	  #iq{xmlns = ?NS_TIME} ->
-	      Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n",
-				  [Resource]),
-	      _ = (?SEND(Res)),
-	      Err = jlib:make_error_reply(El,
-					  ?ERR_FEATURE_NOT_IMPLEMENTED),
-	      ejabberd_router:route(To, From, Err);
-	  #iq{xmlns = ?NS_VCARD} ->
-	      Res = io_lib:format("WHOIS ~s \r\n", [Resource]),
-	      _ = (?SEND(Res)),
-	      Err = jlib:make_error_reply(El,
-					  ?ERR_FEATURE_NOT_IMPLEMENTED),
-	      ejabberd_router:route(To, From, Err);
-	  #iq{} ->
-	      Err = jlib:make_error_reply(El,
-					  ?ERR_FEATURE_NOT_IMPLEMENTED),
-	      ejabberd_router:route(To, From, Err);
-	  _ -> ok
-	end,
+    To = jid:make(iolist_to_binary([Channel, <<"%">>, StateData#state.server]),
+		  StateData#state.host, StateData#state.nick),
+    try xmpp:decode_els(Packet) of
+	#iq{sub_els = [SubEl]} = IQ ->
+	    case xmpp:get_ns(SubEl) of
+		?NS_MUC_ADMIN ->
+		    iq_admin(StateData, Channel, From, To, IQ);
+		?NS_VERSION ->
+		    Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n",
+					[Resource]),
+		    _ = (?SEND(Res)),
+		    Err = xmpp:err_feature_not_implemented(),
+		    ejabberd_router:route_error(To, From, Packet, Err);
+		?NS_TIME ->
+		    Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n",
+					[Resource]),
+		    _ = (?SEND(Res)),
+		    Err = xmpp:err_feature_not_implemented(),
+		    ejabberd_router:route_error(To, From, Packet, Err);
+		?NS_VCARD ->
+		    Res = io_lib:format("WHOIS ~s \r\n", [Resource]),
+		    _ = (?SEND(Res)),
+		    Err = xmpp:err_feature_not_implemented(),
+		    ejabberd_router:route_error(To, From, Packet, Err);
+		_ ->
+		    Err = xmpp:err_feature_not_implemented(),
+		    ejabberd_router:route_error(To, From, Packet, Err)
+	    end
+    catch _:{xmpp_codec, Why} ->
+	    Err = xmpp:err_bad_request(
+		    xmpp:format_error(Why), xmpp:get_lang(Packet)),
+	    ejabberd_router:route_error(To, From, Packet, Err)
+    end,
     {next_state, StateName, StateData};
-handle_info({route_chan, _Channel, _Resource, _Packet},
-	    StateName, StateData) ->
+handle_info({route_chan, Channel, _, #iq{} = IQ}, StateName, StateData) ->
+    From = StateData#state.user,
+    To = jid:make(iolist_to_binary([Channel, <<"%">>, StateData#state.server]),
+		  StateData#state.host, StateData#state.nick),
+    Err = xmpp:err_feature_not_implemented(),
+    ejabberd_router:route_error(To, From, IQ, Err),
     {next_state, StateName, StateData};
-handle_info({route_nick, Nick,
-	     #xmlel{name = <<"message">>, attrs = Attrs} = El},
+handle_info({route_nick, Nick, #message{type = chat} = Msg},
 	    StateName, StateData) ->
-    NewStateData = case fxml:get_attr_s(<<"type">>, Attrs) of
-		     <<"chat">> ->
-			 Body = fxml:get_path_s(El, [{elem, <<"body">>}, cdata]),
-			 case Body of
-			   <<"/quote ", Rest/binary>> ->
-			       ?SEND(<>);
-			   <<"/msg ", Rest/binary>> ->
-			       ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
-			   <<"/me ", Rest/binary>> ->
-			       Strings = str:tokens(Rest, <<"\n">>),
-			       Res = iolist_to_binary(
-                                       lists:map(
-                                         fun (S) ->
-                                                 io_lib:format(
-                                                   "PRIVMSG ~s :\001ACTION ~s\001\r\n",
-                                                   [Nick, S])
-                                         end,
-                                         Strings)),
-			       ?SEND(Res);
-			   <<"/ctcp ", Rest/binary>> ->
-			       Words = str:tokens(Rest, <<" ">>),
-			       case Words of
-				 [CtcpDest | _] ->
-				     CtcpCmd = str:to_upper(
-                                                 str:substr(Rest,
-                                                            str:str(Rest,
-                                                                    <<" ">>)
-                                                            + 1)),
-				     Res = io_lib:format("PRIVMSG ~s :~s\r\n",
-							 [CtcpDest,
-							  <<"\001",
-							    CtcpCmd/binary,
-							    "\001">>]),
-				     ?SEND(Res);
-				 _ -> ok
-			       end;
-			   _ ->
-			       Strings = str:tokens(Body, <<"\n">>),
-			       Res = iolist_to_binary(
-                                       lists:map(
-                                         fun (S) ->
-                                                 io_lib:format(
-                                                   "PRIVMSG ~s :~s\r\n",
-                                                   [Nick, S])
-                                         end,
-                                         Strings)),
-			       ?SEND(Res)
-			 end;
-		     <<"error">> -> stop;
-		     _ -> StateData
-		   end,
-    if NewStateData == stop -> {stop, normal, StateData};
-       true -> {next_state, StateName, NewStateData}
-    end;
+    Body = xmpp:get_text(Msg#message.body),
+    {next_state, StateName,
+     case Body of
+	 <<"/quote ", Rest/binary>> ->
+	     ?SEND(<>);
+	 <<"/msg ", Rest/binary>> ->
+	     ?SEND(<<"PRIVMSG ", Rest/binary, "\r\n">>);
+	 <<"/me ", Rest/binary>> ->
+	     Strings = str:tokens(Rest, <<"\n">>),
+	     Res = iolist_to_binary(
+		     lists:map(
+		       fun (S) ->
+			       io_lib:format(
+				 "PRIVMSG ~s :\001ACTION ~s\001\r\n",
+				 [Nick, S])
+		       end,
+		       Strings)),
+	     ?SEND(Res);
+	 <<"/ctcp ", Rest/binary>> ->
+	     Words = str:tokens(Rest, <<" ">>),
+	     case Words of
+		 [CtcpDest | _] ->
+		     CtcpCmd = str:to_upper(
+				 str:substr(Rest,
+					    str:str(Rest,
+						    <<" ">>)
+					    + 1)),
+		     Res = io_lib:format("PRIVMSG ~s :~s\r\n",
+					 [CtcpDest,
+					  <<"\001",
+					    CtcpCmd/binary,
+					    "\001">>]),
+		     ?SEND(Res);
+		 _ -> ok
+	     end;
+	 _ ->
+	     Strings = str:tokens(Body, <<"\n">>),
+	     Res = iolist_to_binary(
+		     lists:map(
+		       fun (S) ->
+			       io_lib:format(
+				 "PRIVMSG ~s :~s\r\n",
+				 [Nick, S])
+		       end,
+		       Strings)),
+	     ?SEND(Res)
+     end};
+handle_info({route_nick, _, #message{type = error}}, _, StateData) ->
+    {stop, normal, StateData};
 handle_info({route_nick, _Nick, _Packet}, StateName,
 	    StateData) ->
     {next_state, StateName, StateData};
@@ -561,13 +507,13 @@ handle_info({ircstring, <<$:, String/binary>>},
 				     {error,
 				      {error,
 				       error_unknown_num(StateData, String,
-							 <<"cancel">>),
+							 cancel),
 				       StateData}};
 				 [_, <<$5, _, _>> | _] ->
 				     {error,
 				      {error,
 				       error_unknown_num(StateData, String,
-							 <<"cancel">>),
+							 cancel),
 				       StateData}};
 				 _ ->
 				     ?DEBUG("unknown irc command '~s'~n",
@@ -702,11 +648,8 @@ terminate(_Reason, _StateName, FullStateData) ->
     {Error, StateData} = case FullStateData of
 			   {error, SError, SStateData} -> {SError, SStateData};
 			   _ ->
-			       {#xmlel{name = <<"error">>,
-				       attrs = [{<<"code">>, <<"502">>}],
-				       children =
-					   [{xmlcdata,
-					     <<"Server Connect Failed">>}]},
+			       {xmpp:err_internal_server_error(
+				  <<"Server Connect Failed">>, ?MYLANG),
 				FullStateData}
 			 end,
     (StateData#state.mod):closed_connection(StateData#state.host,
@@ -714,9 +657,7 @@ terminate(_Reason, _StateName, FullStateData) ->
                                             StateData#state.server),
     bounce_messages(<<"Server Connect Failed">>),
     lists:foreach(fun (Chan) ->
-			  Stanza = #xmlel{name = <<"presence">>,
-					  attrs = [{<<"type">>, <<"error">>}],
-					  children = [Error]},
+			  Stanza = xmpp:make_error(#presence{}, Error),
 			  send_stanza(Chan, StateData, Stanza)
 		  end,
 		  dict:fetch_keys(StateData#state.channels)),
@@ -726,34 +667,24 @@ terminate(_Reason, _StateName, FullStateData) ->
     end,
     ok.
 
+-spec send_stanza(binary(), state(), stanza()) -> ok.
 send_stanza(Chan, StateData, Stanza) ->
     ejabberd_router:route(
-      jid:make(
-        iolist_to_binary([Chan,
-                          <<"%">>,
-                          StateData#state.server]),
-        StateData#state.host,
-        StateData#state.nick),
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host,
+	       StateData#state.nick),
       StateData#state.user, Stanza).
 
+-spec send_stanza_unavailable(binary(), state()) -> ok.
 send_stanza_unavailable(Chan, StateData) ->
-    Affiliation = <<"member">>,
-    Role = <<"none">>,
-    Stanza = #xmlel{name = <<"presence">>,
-		    attrs = [{<<"type">>, <<"unavailable">>}],
-		    children =
-			[#xmlel{name = <<"x">>,
-				attrs = [{<<"xmlns">>, ?NS_MUC_USER}],
-				children =
-				    [#xmlel{name = <<"item">>,
-					    attrs =
-						[{<<"affiliation">>,
-						  Affiliation},
-						 {<<"role">>, Role}],
-					    children = []},
-				     #xmlel{name = <<"status">>,
-					    attrs = [{<<"code">>, <<"110">>}],
-					    children = []}]}]},
+    Affiliation = member,
+    Role = none,
+    Stanza = #presence{
+		type = unavailable,
+		sub_els = [#muc_user{
+			      items = [#muc_item{affiliation = Affiliation,
+						 role = Role}],
+			      status_codes = [110]}]},
     send_stanza(Chan, StateData, Stanza).
 
 %%%----------------------------------------------------------------------
@@ -776,20 +707,14 @@ send_text(#state{socket = Socket, encoding = Encoding},
 
 bounce_messages(Reason) ->
     receive
-      {send_element, El} ->
-	  #xmlel{attrs = Attrs} = El,
-	  case fxml:get_attr_s(<<"type">>, Attrs) of
-	    <<"error">> -> ok;
-	    _ ->
-		Err = jlib:make_error_reply(El, <<"502">>, Reason),
-		From = jid:from_string(fxml:get_attr_s(<<"from">>,
-							 Attrs)),
-		To = jid:from_string(fxml:get_attr_s(<<"to">>,
-						       Attrs)),
-		ejabberd_router:route(To, From, Err)
-	  end,
-	  bounce_messages(Reason)
-      after 0 -> ok
+	{send_element, El} ->
+	    From = xmpp:get_from(El),
+	    To = xmpp:get_to(El),
+	    Lang = xmpp:get_lang(El),
+	    Err = xmpp:err_internal_server_error(Reason, Lang),
+	    ejabberd_router:route_error(To, From, El, Err),
+	    bounce_messages(Reason)
+    after 0 -> ok
     end.
 
 route_chan(Pid, Channel, Resource, Packet) ->
@@ -842,51 +767,32 @@ process_channel_list_user(StateData, Chan, User) ->
 				       {U2, <<"admin">>, <<"moderator">>};
 				   _ -> {User1, <<"member">>, <<"participant">>}
 				 end,
-    ejabberd_router:route(jid:make(iolist_to_binary([Chan,
-                                                          <<"%">>,
-                                                          StateData#state.server]),
-					StateData#state.host, User2),
-			  StateData#state.user,
-			  #xmlel{name = <<"presence">>, attrs = [],
-				 children =
-				     [#xmlel{name = <<"x">>,
-					     attrs =
-						 [{<<"xmlns">>, ?NS_MUC_USER}],
-					     children =
-						 [#xmlel{name = <<"item">>,
-							 attrs =
-							     [{<<"affiliation">>,
-							       Affiliation},
-							      {<<"role">>,
-							       Role}],
-							 children = []}]}]}),
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, User2),
+      StateData#state.user,
+      #presence{
+	 sub_els = [#muc_user{items = [#muc_item{affiliation = Affiliation,
+						 role = Role}]}]}),
     case catch dict:update(Chan,
 			   fun (Ps) -> (?SETS):add_element(User2, Ps) end,
-			   StateData#state.channels)
-	of
-      {'EXIT', _} -> StateData;
-      NS -> StateData#state{channels = NS}
+			   StateData#state.channels) of
+	{'EXIT', _} -> StateData;
+	NS -> StateData#state{channels = NS}
     end.
 
 process_channel_topic(StateData, Chan, String) ->
     Msg = ejabberd_regexp:replace(String, <<".*332[^:]*:">>,
 				  <<"">>),
-    Msg1 = filter_message(Msg),
-    ejabberd_router:route(jid:make(iolist_to_binary([Chan,
-                                                          <<"%">>,
-                                                          StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"subject">>, attrs = [],
-					     children = [{xmlcdata, Msg1}]},
-				      #xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   <<"Topic for #", Chan/binary,
-						     ": ", Msg1/binary>>}]}]}).
+    Subject = filter_message(Msg),
+    Body = <<"Topic for #", Chan/binary, ": ", Subject/binary>>,
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host),
+      StateData#state.user,
+      #message{type = groupchat,
+	       subject = xmpp:mk_text(Subject),
+	       body = xmpp:mk_text(Body)}).
 
 process_channel_topic_who(StateData, Chan, String) ->
     Words = str:tokens(String, <<" ">>),
@@ -901,30 +807,17 @@ process_channel_topic_who(StateData, Chan, String) ->
 	     _ -> String
 	   end,
     Msg2 = filter_message(Msg1),
-    ejabberd_router:route(jid:make(iolist_to_binary([Chan,
-                                                          <<"%">>,
-                                                          StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, <<"">>),
+      StateData#state.user,
+      #message{type = groupchat, body = xmpp:mk_text(Msg2)}).
 
 error_nick_in_use(_StateData, String) ->
     Msg = ejabberd_regexp:replace(String,
 				  <<".*433 +[^ ]* +">>, <<"">>),
     Msg1 = filter_message(Msg),
-    #xmlel{name = <<"error">>,
-	   attrs =
-	       [{<<"code">>, <<"409">>}, {<<"type">>, <<"cancel">>}],
-	   children =
-	       [#xmlel{name = <<"conflict">>,
-		       attrs = [{<<"xmlns">>, ?NS_STANZAS}], children = []},
-		#xmlel{name = <<"text">>,
-		       attrs = [{<<"xmlns">>, ?NS_STANZAS}],
-		       children = [{xmlcdata, Msg1}]}]}.
+    xmpp:err_conflict(Msg1, ?MYLANG).
 
 process_nick_in_use(StateData, String) ->
     Error = error_nick_in_use(StateData, String),
@@ -933,121 +826,73 @@ process_nick_in_use(StateData, String) ->
 	  % Shouldn't happen with a well behaved server
 	  StateData;
       Chan ->
-	  ejabberd_router:route(jid:make(iolist_to_binary([Chan,
-                                                                <<"%">>,
-                                                                StateData#state.server]),
-					      StateData#state.host,
-					      StateData#state.nick),
-				StateData#state.user,
-				#xmlel{name = <<"presence">>,
-				       attrs = [{<<"type">>, <<"error">>}],
-				       children = [Error]}),
-	  StateData#state{nickchannel = undefined}
+	  ejabberd_router:route(
+	    jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+		     StateData#state.host,
+		     StateData#state.nick),
+	    StateData#state.user,
+	    xmpp:make_error(#presence{}, Error)),
+	    StateData#state{nickchannel = undefined}
     end.
 
 process_num_error(StateData, String) ->
-    Error = error_unknown_num(StateData, String,
-			      <<"continue">>),
-    lists:foreach(fun (Chan) ->
-			  ejabberd_router:route(
-                            jid:make(
-                              iolist_to_binary(
-                                [Chan,
-                                 <<"%">>,
-                                 StateData#state.server]),
-                              StateData#state.host,
-                              StateData#state.nick),
-                            StateData#state.user,
-                            #xmlel{name = <<"message">>,
-                                   attrs =
-                                       [{<<"type">>,
-                                         <<"error">>}],
-                                   children = [Error]})
-		  end,
-		  dict:fetch_keys(StateData#state.channels)),
+    Error = error_unknown_num(StateData, String, continue),
+    lists:foreach(
+      fun(Chan) ->
+	      ejabberd_router:route(
+		jid:make(iolist_to_binary([Chan, $%, StateData#state.server]),
+			 StateData#state.host,
+			 StateData#state.nick),
+		StateData#state.user,
+		xmpp:make_error(#message{}, Error))
+      end, dict:fetch_keys(StateData#state.channels)),
     StateData.
 
 process_endofwhois(StateData, _String, Nick) ->
-    ejabberd_router:route(jid:make(iolist_to_binary([Nick,
-                                                          <<"!">>,
-                                                          StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   <<"End of WHOIS">>}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Nick, <<"!">>, StateData#state.server]),
+	       StateData#state.host),
+      StateData#state.user,
+      #message{type = chat, body = xmpp:mk_text(<<"End of WHOIS">>)}).
 
 process_whois311(StateData, String, Nick, Ident,
 		 Irchost) ->
     Fullname = ejabberd_regexp:replace(String,
 				       <<".*311[^:]*:">>, <<"">>),
-    ejabberd_router:route(jid:make(iolist_to_binary([Nick,
-                                                          <<"!">>,
-                                                          StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   iolist_to_binary(
-                                                     [<<"WHOIS: ">>,
-                                                      Nick,
-                                                      <<" is ">>,
-                                                      Ident,
-                                                      <<"@">>,
-                                                      Irchost,
-                                                      <<" : ">>,
-                                                      Fullname])}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Nick, <<"!">>, StateData#state.server]),
+	       StateData#state.host, <<"">>),
+      StateData#state.user,
+      #message{type = chat,
+	       body = xmpp:mk_text(
+			iolist_to_binary(
+			  [<<"WHOIS: ">>, Nick, <<" is ">>, Ident,
+			   <<"@">>, Irchost, <<" : ">>, Fullname]))}).
 
 process_whois312(StateData, String, Nick, Ircserver) ->
     Ircserverdesc = ejabberd_regexp:replace(String,
 					    <<".*312[^:]*:">>, <<"">>),
-    ejabberd_router:route(jid:make(iolist_to_binary([Nick,
-                                                          <<"!">>,
-                                                          StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   iolist_to_binary(
-                                                     [<<"WHOIS: ">>,
-                                                      Nick,
-                                                      <<" use ">>,
-                                                      Ircserver,
-                                                      <<" : ">>,
-                                                      Ircserverdesc])}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Nick, <<"!">>, StateData#state.server]),
+	       StateData#state.host, <<"">>),
+      StateData#state.user,
+      #message{type = chat,
+	       body = xmpp:mk_text(
+			iolist_to_binary(
+			  [<<"WHOIS: ">>, Nick, <<" use ">>, Ircserver,
+			   <<" : ">>, Ircserverdesc]))}).
 
 process_whois319(StateData, String, Nick) ->
     Chanlist = ejabberd_regexp:replace(String,
 				       <<".*319[^:]*:">>, <<"">>),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Nick,
-                                           <<"!">>,
-                                           StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   iolist_to_binary(
-                                                     [<<"WHOIS: ">>,
-                                                      Nick,
-                                                      <<" is on ">>,
-                                                      Chanlist])}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Nick, <<"!">>, StateData#state.server]),
+	       StateData#state.host, <<"">>),
+      StateData#state.user,
+      #message{type = chat,
+	       body = xmpp:mk_text(
+			iolist_to_binary(
+			  [<<"WHOIS: ">>, Nick, <<" is on ">>, Chanlist]))}).
 
 process_chanprivmsg(StateData, Chan, From, String) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
@@ -1059,17 +904,11 @@ process_chanprivmsg(StateData, Chan, From, String) ->
 	     _ -> Msg
 	   end,
     Msg2 = filter_message(Msg1),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, FromUser),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, FromUser),
+      StateData#state.user,
+      #message{type = groupchat, body = xmpp:mk_text(Msg2)}).
 
 process_channotice(StateData, Chan, From, String) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
@@ -1081,17 +920,11 @@ process_channotice(StateData, Chan, From, String) ->
 	     _ -> <<"/me NOTICE: ", Msg/binary>>
 	   end,
     Msg2 = filter_message(Msg1),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, FromUser),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, FromUser),
+      StateData#state.user,
+      #message{type = groupchat, body = xmpp:mk_text(Msg2)}).
 
 process_privmsg(StateData, _Nick, From, String) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
@@ -1103,17 +936,11 @@ process_privmsg(StateData, _Nick, From, String) ->
 	     _ -> Msg
 	   end,
     Msg2 = filter_message(Msg1),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [FromUser,
-                                           <<"!">>,
-                                           StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([FromUser, <<"!">>, StateData#state.server]),
+	       StateData#state.host, <<"">>),
+      StateData#state.user,
+      #message{type = chat, body = xmpp:mk_text(Msg2)}).
 
 process_notice(StateData, _Nick, From, String) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
@@ -1125,17 +952,11 @@ process_notice(StateData, _Nick, From, String) ->
 	     _ -> <<"/me NOTICE: ", Msg/binary>>
 	   end,
     Msg2 = filter_message(Msg1),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [FromUser,
-                                           <<"!">>,
-                                           StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"chat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([FromUser, <<"!">>, StateData#state.server]),
+	       StateData#state.host),
+      StateData#state.user,
+      #message{type = chat, body = xmpp:mk_text(Msg2)}).
 
 process_version(StateData, _Nick, From) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
@@ -1160,54 +981,30 @@ process_topic(StateData, Chan, From, String) ->
     Msg = ejabberd_regexp:replace(String,
 				  <<".*TOPIC[^:]*:">>, <<"">>),
     Msg1 = filter_message(Msg),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, FromUser),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"subject">>, attrs = [],
-					     children = [{xmlcdata, Msg1}]},
-				      #xmlel{name = <<"body">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-						   <<"/me has changed the subject to: ",
-						     Msg1/binary>>}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, FromUser),
+      StateData#state.user,
+      #message{type = groupchat,
+	       subject = xmpp:mk_text(Msg1),
+	       body = xmpp:mk_text(<<"/me has changed the subject to: ",
+				     Msg1/binary>>)}).
 
 process_part(StateData, Chan, From, String) ->
     [FromUser | FromIdent] = str:tokens(From, <<"!">>),
     Msg = ejabberd_regexp:replace(String,
 				  <<".*PART[^:]*:">>, <<"">>),
     Msg1 = filter_message(Msg),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, FromUser),
-			  StateData#state.user,
-			  #xmlel{name = <<"presence">>,
-				 attrs = [{<<"type">>, <<"unavailable">>}],
-				 children =
-				     [#xmlel{name = <<"x">>,
-					     attrs =
-						 [{<<"xmlns">>, ?NS_MUC_USER}],
-					     children =
-						 [#xmlel{name = <<"item">>,
-							 attrs =
-							     [{<<"affiliation">>,
-							       <<"member">>},
-							      {<<"role">>,
-							       <<"none">>}],
-							 children = []}]},
-				      #xmlel{name = <<"status">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-                                                   list_to_binary(
-                                                     [Msg1, " (",
-                                                      FromIdent, ")"])}]}]}),
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, FromUser),
+      StateData#state.user,
+      #presence{type = unavailable,
+		sub_els = [#muc_user{
+			      items = [#muc_item{affiliation = member,
+						 role = none}]}],
+		status = xmpp:mk_text(
+			   list_to_binary([Msg1, " (", FromIdent, ")"]))}),
     case catch dict:update(Chan,
 			   fun (Ps) -> remove_element(FromUser, Ps) end,
 			   StateData#state.channels)
@@ -1221,81 +1018,40 @@ process_quit(StateData, From, String) ->
     Msg = ejabberd_regexp:replace(String,
 				  <<".*QUIT[^:]*:">>, <<"">>),
     Msg1 = filter_message(Msg),
-    dict:map(fun (Chan, Ps) ->
-		     case (?SETS):is_member(FromUser, Ps) of
-		       true ->
-			   ejabberd_router:route(jid:make(iolist_to_binary(
-                                                                 [Chan,
-                                                                  <<"%">>,
-                                                                  StateData#state.server]),
-							       StateData#state.host,
-							       FromUser),
-						 StateData#state.user,
-						 #xmlel{name = <<"presence">>,
-							attrs =
-							    [{<<"type">>,
-							      <<"unavailable">>}],
-							children =
-							    [#xmlel{name =
-									<<"x">>,
-								    attrs =
-									[{<<"xmlns">>,
-									  ?NS_MUC_USER}],
-								    children =
-									[#xmlel{name
-										    =
-										    <<"item">>,
-										attrs
-										    =
-										    [{<<"affiliation">>,
-										      <<"member">>},
-										     {<<"role">>,
-										      <<"none">>}],
-										children
-										    =
-										    []}]},
-							     #xmlel{name =
-									<<"status">>,
-								    attrs = [],
-								    children =
-									[{xmlcdata,
-                                                                          list_to_binary(
-                                                                            [Msg1, " (",
-                                                                             FromIdent,
-                                                                             ")"])}]}]}),
-			   remove_element(FromUser, Ps);
-		       _ -> Ps
-		     end
-	     end,
-	     StateData#state.channels),
+    dict:map(
+      fun(Chan, Ps) ->
+	      case (?SETS):is_member(FromUser, Ps) of
+		  true ->
+		      ejabberd_router:route(
+			jid:make(iolist_to_binary([Chan, $%, StateData#state.server]),
+				 StateData#state.host,
+				 FromUser),
+			StateData#state.user,
+			#presence{type = unavailable,
+				  sub_els = [#muc_user{
+						items = [#muc_item{
+							    affiliation = member,
+							    role = none}]}],
+				  status = xmpp:mk_text(
+					     list_to_binary([Msg1, " (", FromIdent, ")"]))}),
+		      remove_element(FromUser, Ps);
+		  _ ->
+		      Ps
+	      end
+      end, StateData#state.channels),
     StateData.
 
 process_join(StateData, Channel, From, _String) ->
     [FromUser | FromIdent] = str:tokens(From, <<"!">>),
     [Chan | _] = binary:split(Channel, <<":#">>),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, FromUser),
-			  StateData#state.user,
-			  #xmlel{name = <<"presence">>, attrs = [],
-				 children =
-				     [#xmlel{name = <<"x">>,
-					     attrs =
-						 [{<<"xmlns">>, ?NS_MUC_USER}],
-					     children =
-						 [#xmlel{name = <<"item">>,
-							 attrs =
-							     [{<<"affiliation">>,
-							       <<"member">>},
-							      {<<"role">>,
-							       <<"participant">>}],
-							 children = []}]},
-				      #xmlel{name = <<"status">>, attrs = [],
-					     children =
-						 [{xmlcdata,
-                                                   list_to_binary(FromIdent)}]}]}),
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, FromUser),
+      StateData#state.user,
+      #presence{
+	 sub_els = [#muc_user{items = [#muc_item{affiliation = member,
+						 role = participant}]}],
+	 status = xmpp:mk_text(list_to_binary(FromIdent))}),
     case catch dict:update(Chan,
 			   fun (Ps) -> (?SETS):add_element(FromUser, Ps) end,
 			   StateData#state.channels)
@@ -1306,160 +1062,67 @@ process_join(StateData, Channel, From, _String) ->
 
 process_mode_o(StateData, Chan, _From, Nick,
 	       Affiliation, Role) ->
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, Nick),
-			  StateData#state.user,
-			  #xmlel{name = <<"presence">>, attrs = [],
-				 children =
-				     [#xmlel{name = <<"x">>,
-					     attrs =
-						 [{<<"xmlns">>, ?NS_MUC_USER}],
-					     children =
-						 [#xmlel{name = <<"item">>,
-							 attrs =
-							     [{<<"affiliation">>,
-							       Affiliation},
-							      {<<"role">>,
-							       Role}],
-							 children = []}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, Nick),
+      StateData#state.user,
+      #presence{
+	 sub_els = [#muc_user{items = [#muc_item{affiliation = Affiliation,
+						 role = Role}]}]}).
 
 process_kick(StateData, Chan, From, Nick, String) ->
     Msg = lists:last(str:tokens(String, <<":">>)),
     Msg2 = <>,
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, <<"">>),
-			  StateData#state.user,
-			  #xmlel{name = <<"message">>,
-				 attrs = [{<<"type">>, <<"groupchat">>}],
-				 children =
-				     [#xmlel{name = <<"body">>, attrs = [],
-					     children = [{xmlcdata, Msg2}]}]}),
-    ejabberd_router:route(jid:make(iolist_to_binary(
-                                          [Chan,
-                                           <<"%">>,
-                                           StateData#state.server]),
-					StateData#state.host, Nick),
-			  StateData#state.user,
-			  #xmlel{name = <<"presence">>,
-				 attrs = [{<<"type">>, <<"unavailable">>}],
-				 children =
-				     [#xmlel{name = <<"x">>,
-					     attrs =
-						 [{<<"xmlns">>, ?NS_MUC_USER}],
-					     children =
-						 [#xmlel{name = <<"item">>,
-							 attrs =
-							     [{<<"affiliation">>,
-							       <<"none">>},
-							      {<<"role">>,
-							       <<"none">>}],
-							 children = []},
-						  #xmlel{name = <<"status">>,
-							 attrs =
-							     [{<<"code">>,
-							       <<"307">>}],
-							 children = []}]}]}).
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host),
+      StateData#state.user,
+      #message{type = groupchat, body = xmpp:mk_text(Msg2)}),
+    ejabberd_router:route(
+      jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
+	       StateData#state.host, Nick),
+      StateData#state.user,
+      #presence{type = unavailable,
+		sub_els = [#muc_user{items = [#muc_item{
+						 affiliation = none,
+						 role = none}],
+				     status_codes = [307]}]}).
 
 process_nick(StateData, From, NewNick) ->
     [FromUser | _] = str:tokens(From, <<"!">>),
     [Nick | _] = binary:split(NewNick, <<":">>),
-    NewChans = dict:map(fun (Chan, Ps) ->
-				case (?SETS):is_member(FromUser, Ps) of
-				  true ->
-				      ejabberd_router:route(jid:make(
-                                                              iolist_to_binary(
-                                                                [Chan,
-                                                                 <<"%">>,
-                                                                 StateData#state.server]),
-                                                              StateData#state.host,
-                                                              FromUser),
-							    StateData#state.user,
-							    #xmlel{name =
-								       <<"presence">>,
-								   attrs =
-								       [{<<"type">>,
-									 <<"unavailable">>}],
-								   children =
-								       [#xmlel{name
-										   =
-										   <<"x">>,
-									       attrs
-										   =
-										   [{<<"xmlns">>,
-										     ?NS_MUC_USER}],
-									       children
-										   =
-										   [#xmlel{name
-											       =
-											       <<"item">>,
-											   attrs
-											       =
-											       [{<<"affiliation">>,
-												 <<"member">>},
-												{<<"role">>,
-												 <<"participant">>},
-												{<<"nick">>,
-												 Nick}],
-											   children
-											       =
-											       []},
-										    #xmlel{name
-											       =
-											       <<"status">>,
-											   attrs
-											       =
-											       [{<<"code">>,
-												 <<"303">>}],
-											   children
-											       =
-											       []}]}]}),
-				      ejabberd_router:route(jid:make(
-                                                              iolist_to_binary(
-                                                                [Chan,
-                                                                 <<"%">>,
-                                                                 StateData#state.server]),
-                                                              StateData#state.host,
-                                                              Nick),
-							    StateData#state.user,
-							    #xmlel{name =
-								       <<"presence">>,
-								   attrs = [],
-								   children =
-								       [#xmlel{name
-										   =
-										   <<"x">>,
-									       attrs
-										   =
-										   [{<<"xmlns">>,
-										     ?NS_MUC_USER}],
-									       children
-										   =
-										   [#xmlel{name
-											       =
-											       <<"item">>,
-											   attrs
-											       =
-											       [{<<"affiliation">>,
-												 <<"member">>},
-												{<<"role">>,
-												 <<"participant">>}],
-											   children
-											       =
-											       []}]}]}),
-				      (?SETS):add_element(Nick,
-							  remove_element(FromUser,
-									 Ps));
-				  _ -> Ps
-				end
-			end,
-			StateData#state.channels),
+    NewChans =
+	dict:map(
+	  fun(Chan, Ps) ->
+		  case (?SETS):is_member(FromUser, Ps) of
+		      true ->
+			  ejabberd_router:route(
+			    jid:make(iolist_to_binary([Chan, $%, StateData#state.server]),
+				     StateData#state.host,
+				     FromUser),
+			    StateData#state.user,
+			    #presence{
+			       type = unavailable,
+			       sub_els = [#muc_user{
+					     items = [#muc_item{
+							 affiliation = member,
+							 role = participant,
+							 nick = Nick}],
+					     status_codes = [303]}]}),
+			  ejabberd_router:route(
+			    jid:make(iolist_to_binary([Chan, $%, StateData#state.server]),
+				     StateData#state.host, Nick),
+			    StateData#state.user,
+			    #presence{
+			       sub_els = [#muc_user{
+					     items = [#muc_item{
+							 affiliation = member,
+							 role = participant}]}]}),
+			  (?SETS):add_element(Nick, remove_element(FromUser, Ps));
+		      _ -> Ps
+		  end
+	  end, StateData#state.channels),
     if FromUser == StateData#state.nick ->
 	   StateData#state{nick = Nick, nickchannel = undefined,
 			   channels = NewChans};
@@ -1467,43 +1130,23 @@ process_nick(StateData, From, NewNick) ->
     end.
 
 process_error(StateData, String) ->
-    lists:foreach(fun (Chan) ->
-			  ejabberd_router:route(jid:make(
-                                                  iolist_to_binary(
-                                                    [Chan,
-                                                     <<"%">>,
-                                                     StateData#state.server]),
-                                                  StateData#state.host,
-                                                  StateData#state.nick),
-						StateData#state.user,
-						#xmlel{name = <<"presence">>,
-						       attrs =
-							   [{<<"type">>,
-							     <<"error">>}],
-						       children =
-							   [#xmlel{name =
-								       <<"error">>,
-								   attrs =
-								       [{<<"code">>,
-									 <<"502">>}],
-								   children =
-								       [{xmlcdata,
-									 String}]}]})
-		  end,
-		  dict:fetch_keys(StateData#state.channels)).
+    lists:foreach(
+      fun(Chan) ->
+	      ejabberd_router:route(
+		jid:make(iolist_to_binary([Chan, $%, StateData#state.server]),
+			 StateData#state.host,
+			 StateData#state.nick),
+		StateData#state.user,
+		xmpp:make_error(
+		  #presence{},
+		  xmpp:err_internal_server_error(String, ?MYLANG)))
+      end, dict:fetch_keys(StateData#state.channels)).
 
 error_unknown_num(_StateData, String, Type) ->
     Msg = ejabberd_regexp:replace(String,
 				  <<".*[45][0-9][0-9] +[^ ]* +">>, <<"">>),
     Msg1 = filter_message(Msg),
-    #xmlel{name = <<"error">>,
-	   attrs = [{<<"code">>, <<"500">>}, {<<"type">>, Type}],
-	   children =
-	       [#xmlel{name = <<"undefined-condition">>,
-		       attrs = [{<<"xmlns">>, ?NS_STANZAS}], children = []},
-		#xmlel{name = <<"text">>,
-		       attrs = [{<<"xmlns">>, ?NS_STANZAS}],
-		       children = [{xmlcdata, Msg1}]}]}.
+    xmpp:err_undefined_condition(Type, Msg1, ?MYLANG).
 
 remove_element(E, Set) ->
     case (?SETS):is_element(E, Set) of
@@ -1512,49 +1155,33 @@ remove_element(E, Set) ->
     end.
 
 iq_admin(StateData, Channel, From, To,
-	 #iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) ->
-    case catch process_iq_admin(StateData, Channel, Type,
-				SubEl)
-	of
-      {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
-      Res ->
-	  if Res /= ignore ->
-		 ResIQ = case Res of
-			   {result, ResEls} ->
-			       IQ#iq{type = result,
-				     sub_el =
-					 [#xmlel{name = <<"query">>,
-						 attrs = [{<<"xmlns">>, XMLNS}],
-						 children = ResEls}]};
-			   {error, Error} ->
-			       IQ#iq{type = error, sub_el = [SubEl, Error]}
-			 end,
-		 ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ));
-	     true -> ok
-	  end
+	 #iq{type = Type, sub_els = [SubEl]} = IQ) ->
+    try process_iq_admin(StateData, Channel, Type, SubEl) of
+	ignore ->
+	    ignore;
+	{result, Result} ->
+	    ejabberd_router:route(To, From, xmpp:make_iq_result(IQ, Result));
+	{error, Error} ->
+	    ejabberd_router:route_error(To, From, IQ, Error)
+    catch E:R ->
+	    ?ERROR_MSG("failed to process admin query from ~s: ~p",
+		       [jid:to_string(From), {E, {R, erlang:get_stacktrace()}}]),
+	    ejabberd_router:route_error(
+	      To, From, IQ, xmpp:internal_server_error())
     end.
 
-process_iq_admin(StateData, Channel, set, SubEl) ->
-    case fxml:get_subtag(SubEl, <<"item">>) of
-      false -> {error, ?ERR_BAD_REQUEST};
-      ItemEl ->
-	  Nick = fxml:get_tag_attr_s(<<"nick">>, ItemEl),
-	  Affiliation = fxml:get_tag_attr_s(<<"affiliation">>,
-					   ItemEl),
-	  Role = fxml:get_tag_attr_s(<<"role">>, ItemEl),
-	  Reason = fxml:get_path_s(ItemEl,
-				  [{elem, <<"reason">>}, cdata]),
-	  process_admin(StateData, Channel, Nick, Affiliation,
-			Role, Reason)
-    end;
-process_iq_admin(_StateData, _Channel, get, _SubEl) ->
-    {error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
-
-process_admin(_StateData, _Channel, <<"">>,
-	      _Affiliation, _Role, _Reason) ->
-    {error, ?ERR_FEATURE_NOT_IMPLEMENTED};
-process_admin(StateData, Channel, Nick, _Affiliation,
-	      <<"none">>, Reason) ->
+process_iq_admin(_StateData, _Channel, set, #muc_admin{items = []}) ->
+    {error, xmpp:err_bad_request()};
+process_iq_admin(StateData, Channel, set, #muc_admin{items = [Item|_]}) ->
+    process_admin(StateData, Channel, Item);
+process_iq_admin(_StateData, _Channel, _, _SubEl) ->
+    {error, xmpp:err_feature_not_implemented()}.
+
+process_admin(_StateData, _Channel, #muc_item{nick = <<"">>}) ->
+    {error, xmpp:err_feature_not_implemented()};
+process_admin(StateData, Channel, #muc_item{nick = Nick,
+					    reason = Reason,
+					    role = none}) ->
     case Reason of
       <<"">> ->
 	  send_text(StateData,
@@ -1564,10 +1191,9 @@ process_admin(StateData, Channel, Nick, _Affiliation,
 		    io_lib:format("KICK #~s ~s :~s\r\n",
 				  [Channel, Nick, Reason]))
     end,
-    {result, []};
-process_admin(_StateData, _Channel, _Nick, _Affiliation,
-	      _Role, _Reason) ->
-    {error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
+    {result, undefined};
+process_admin(_StateData, _Channel, _Item) ->
+    {error, xmpp:err_feature_not_implemented()}.
 
 filter_message(Msg) ->
     list_to_binary(
diff --git a/src/mod_irc_mnesia.erl b/src/mod_irc_mnesia.erl
index 9f8117ad3..95cceb54c 100644
--- a/src/mod_irc_mnesia.erl
+++ b/src/mod_irc_mnesia.erl
@@ -13,7 +13,7 @@
 %% API
 -export([init/2, get_data/3, set_data/4, import/2]).
 
--include("jlib.hrl").
+-include("jid.hrl").
 -include("mod_irc.hrl").
 -include("logger.hrl").
 
diff --git a/src/mod_irc_riak.erl b/src/mod_irc_riak.erl
index 6ac7befdf..a71859c5c 100644
--- a/src/mod_irc_riak.erl
+++ b/src/mod_irc_riak.erl
@@ -13,7 +13,7 @@
 %% API
 -export([init/2, get_data/3, set_data/4, import/2]).
 
--include("jlib.hrl").
+-include("jid.hrl").
 -include("mod_irc.hrl").
 
 %%%===================================================================
diff --git a/src/mod_irc_sql.erl b/src/mod_irc_sql.erl
index 8aa428e54..7905db91f 100644
--- a/src/mod_irc_sql.erl
+++ b/src/mod_irc_sql.erl
@@ -15,7 +15,7 @@
 %% API
 -export([init/2, get_data/3, set_data/4, import/1, import/2, export/1]).
 
--include("jlib.hrl").
+-include("jid.hrl").
 -include("mod_irc.hrl").
 -include("ejabberd_sql_pt.hrl").
 
diff --git a/src/xmpp.erl b/src/xmpp.erl
index a927a6a9a..b43243157 100644
--- a/src/xmpp.erl
+++ b/src/xmpp.erl
@@ -41,7 +41,7 @@
          err_resource_constraint/0, err_resource_constraint/2,
          err_service_unavailable/0, err_service_unavailable/2,
          err_subscription_required/0, err_subscription_required/2,
-         err_undefined_condition/0, err_undefined_condition/2,
+         err_undefined_condition/1, err_undefined_condition/3,
          err_unexpected_request/0, err_unexpected_request/2]).
 
 %% XMPP stream errors
@@ -567,14 +567,16 @@ err_subscription_required(Text, Lang) ->
     err(auth, 'subscription-required', 407, Text, Lang).
 
 %% No error type is defined for .
-%% We choose "modify" as it's used in RFC 6120 example.
--spec err_undefined_condition() -> error().
-err_undefined_condition() ->
-    err(modify, 'undefined-condition', 500).
-
--spec err_undefined_condition(binary(), binary() | undefined) -> error().
-err_undefined_condition(Text, Lang) ->
-    err(modify, 'undefined-condition', 500, Text, Lang).
+%% Let user provide the type.
+-spec err_undefined_condition('auth' | 'cancel' | 'continue' |
+			      'modify' | 'wait') -> error().
+err_undefined_condition(Type) ->
+    err(Type, 'undefined-condition', 500).
+
+-spec err_undefined_condition('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
+			      binary(), binary() | undefined) -> error().
+err_undefined_condition(Type, Text, Lang) ->
+    err(Type, 'undefined-condition', 500, Text, Lang).
 
 %% RFC 6120 says error type SHOULD be "wait" or "modify".
 %% RFC 3920 and XEP-0082 says it SHOULD be "wait".
-- 
cgit v1.2.3


From abb4446b51d3f516e89106a694660676df75edde Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Wed, 3 Aug 2016 21:00:22 +0300
Subject: Fix calls to undefined functions

---
 src/mod_irc.erl            | 6 +++---
 src/mod_irc_connection.erl | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'src')

diff --git a/src/mod_irc.erl b/src/mod_irc.erl
index 91f43716f..1960c988d 100644
--- a/src/mod_irc.erl
+++ b/src/mod_irc.erl
@@ -330,7 +330,7 @@ process_command(#iq{type = set, lang = Lang, to = To, from = From,
 	    catch E:R ->
 		    ?ERROR_MSG("ad-hoc handler failed: ~p",
 			       [{E, {R, erlang:get_stacktrace()}}]),
-		    xmpp:make_error(IQ, xmpp:internal_server_error())
+		    xmpp:make_error(IQ, xmpp:err_internal_server_error())
 	    end;
 	_ ->
 	    Txt = <<"Node not found">>,
@@ -409,7 +409,7 @@ iq_disco(_ServerHost, undefined, Lang) ->
        features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, ?NS_MUC,
 		   ?NS_REGISTER, ?NS_VCARD, ?NS_COMMANDS]};
 iq_disco(ServerHost, Node, Lang) ->
-    case lists:keyfind(Node, commands(ServerHost)) of
+    case lists:keyfind(Node, 1, commands(ServerHost)) of
 	{_, Name, _} ->
 	    #disco_info{
 	       identities = [#identity{category = <<"automation">>,
@@ -645,7 +645,7 @@ adhoc_join(_From, _To, #adhoc_command{lang = Lang, xdata = undefined} = Request)
 				      type = 'text-single',
 				      label = translate:translate(Lang, <<"IRC server">>),
 				      required = true}]},
-    xmpp_utils:make_adhoc_response(
+    xmpp_util:make_adhoc_response(
       Request, #adhoc_command{status = executing, xdata = X});
 adhoc_join(From, To, #adhoc_command{lang = Lang, xdata = X} = Request) ->
     Channel = case xmpp_util:get_xdata_values(<<"channel">>, X) of
diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl
index fb301330a..694accf45 100644
--- a/src/mod_irc_connection.erl
+++ b/src/mod_irc_connection.erl
@@ -1167,7 +1167,7 @@ iq_admin(StateData, Channel, From, To,
 	    ?ERROR_MSG("failed to process admin query from ~s: ~p",
 		       [jid:to_string(From), {E, {R, erlang:get_stacktrace()}}]),
 	    ejabberd_router:route_error(
-	      To, From, IQ, xmpp:internal_server_error())
+	      To, From, IQ, xmpp:err_internal_server_error())
     end.
 
 process_iq_admin(_StateData, _Channel, set, #muc_admin{items = []}) ->
-- 
cgit v1.2.3


From bc33a3873dbb0828714eef69094213575fc979b6 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Thu, 4 Aug 2016 11:49:17 +0300
Subject: Rewrite multicast code to use XML generator

---
 src/ejabberd_router_multicast.erl |  12 +-
 src/mod_multicast.erl             | 500 +++++++++++++++-----------------------
 2 files changed, 205 insertions(+), 307 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl
index fa32c8ed7..967699007 100644
--- a/src/ejabberd_router_multicast.erl
+++ b/src/ejabberd_router_multicast.erl
@@ -43,9 +43,10 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
 
--record(route_multicast, {domain, pid}).
+-record(route_multicast, {domain = <<"">> :: binary(),
+			  pid = self() :: pid()}).
 -record(state, {}).
 
 %%====================================================================
@@ -58,7 +59,7 @@
 start_link() ->
     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
 
-
+-spec route_multicast(jid(), binary(), [jid()], stanza()) -> ok.
 route_multicast(From, Domain, Destinations, Packet) ->
     case catch do_route(From, Domain, Destinations, Packet) of
 	{'EXIT', Reason} ->
@@ -68,6 +69,7 @@ route_multicast(From, Domain, Destinations, Packet) ->
 	    ok
     end.
 
+-spec register_route(binary()) -> any().
 register_route(Domain) ->
     case jid:nameprep(Domain) of
 	error ->
@@ -81,6 +83,7 @@ register_route(Domain) ->
 	    mnesia:transaction(F)
     end.
 
+-spec unregister_route(binary()) -> any().
 unregister_route(Domain) ->
     case jid:nameprep(Domain) of
 	error ->
@@ -206,6 +209,7 @@ code_change(_OldVsn, State, _Extra) ->
 %%--------------------------------------------------------------------
 %% From = #jid
 %% Destinations = [#jid]
+-spec do_route(jid(), binary(), [jid()], stanza()) -> any().
 do_route(From, Domain, Destinations, Packet) ->
 
     ?DEBUG("route_multicast~n\tfrom ~s~n\tdomain ~s~n\tdestinations ~p~n\tpacket ~p~n",
@@ -226,6 +230,7 @@ do_route(From, Domain, Destinations, Packet) ->
 	    Pid ! {route_trusted, From, Destinations, Packet}
     end.
 
+-spec pick_multicast_pid([#route_multicast{}]) -> pid().
 pick_multicast_pid(Rs) ->
     List = case [R || R <- Rs, node(R#route_multicast.pid) == node()] of
 	[] -> Rs;
@@ -233,5 +238,6 @@ pick_multicast_pid(Rs) ->
     end,
     (hd(List))#route_multicast.pid.
 
+-spec do_route_normal(jid(), [jid()], stanza()) -> any().
 do_route_normal(From, Destinations, Packet) ->
     [ejabberd_router:route(From, To, Packet) || To <- Destinations].
diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl
index df385c28c..f1c090ae4 100644
--- a/src/mod_multicast.erl
+++ b/src/mod_multicast.erl
@@ -45,16 +45,20 @@
 -include("ejabberd.hrl").
 -include("logger.hrl").
 
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 -record(state,
 	{lserver, lservice, access, service_limits}).
+-type state() :: #state{}.
 
 -record(multicastc, {rserver, response, ts}).
 
 %% ts: timestamp (in seconds) when the cache item was last updated
 
--record(dest, {jid_string, jid_jid, type, full_xml}).
+-record(dest, {jid_string = none :: binary(),
+	       jid_jid :: jid(),
+	       type :: atom(),
+	       full_xml :: address()}).
 
 %% jid_string = string()
 %% jid_jid = jid()
@@ -168,10 +172,8 @@ handle_cast(_Msg, State) -> {noreply, State}.
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
 
-handle_info({route, From, To,
-	     #xmlel{name = <<"iq">>, attrs = Attrs} = Packet},
-	    State) ->
-    case catch handle_iq(From, To, #xmlel{attrs = Attrs} = Packet, State) of
+handle_info({route, From, To, #iq{} = Packet}, State) ->
+    case catch handle_iq(From, To, Packet, State) of
         {'EXIT', Reason} ->
             ?ERROR_MSG("Error when processing IQ stanza: ~p",
                        [Reason]);
@@ -179,13 +181,10 @@ handle_info({route, From, To,
     end,
     {noreply, State};
 %% XEP33 allows only 'message' and 'presence' stanza type
-handle_info({route, From, To,
-	     #xmlel{name = Stanza_type} = Packet},
+handle_info({route, From, To, Packet},
 	    #state{lservice = LServiceS, lserver = LServerS,
 		   access = Access, service_limits = SLimits} =
-		State)
-    when (Stanza_type == <<"message">>) or
-	   (Stanza_type == <<"presence">>) ->
+		State) when ?is_stanza(Packet) ->
     route_untrusted(LServiceS, LServerS, Access, SLimits,
 		    From, To, Packet),
     {noreply, State};
@@ -220,91 +219,59 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
 %%% IQ Request Processing
 %%%------------------------
 
-handle_iq(From, To, #xmlel{attrs = Attrs} = Packet, State) ->
-    IQ = jlib:iq_query_info(Packet),
-    case catch process_iq(From, IQ, State) of
-        Result when is_record(Result, iq) ->
-            ejabberd_router:route(To, From, jlib:iq_to_xml(Result));
-        {'EXIT', Reason} ->
-            ?ERROR_MSG("Error when processing IQ stanza: ~p",
-                       [Reason]),
-            Err = jlib:make_error_reply(Packet,
-                                        ?ERR_INTERNAL_SERVER_ERROR),
-            ejabberd_router:route(To, From, Err);
-        reply ->
-            LServiceS = jts(To),
-            case fxml:get_attr_s(<<"type">>, Attrs) of
-                <<"result">> ->
-                    process_iqreply_result(From, LServiceS, Packet, State);
-                <<"error">> ->
-                    process_iqreply_error(From, LServiceS, Packet)
-            end;
-        ok -> ok
+handle_iq(From, To, Packet, State) ->
+    try
+	IQ = xmpp:decode_els(Packet),
+	case process_iq(From, IQ, State) of
+	    {result, SubEl} ->
+		ejabberd_router:route(To, From, xmpp:make_iq_result(Packet, SubEl));
+	    {error, Error} ->
+		ejabberd_router:route_error(To, From, Packet, Error);
+	    reply ->
+		LServiceS = jid:to_string(To),
+		case Packet#iq.type of
+		    result ->
+			process_iqreply_result(From, LServiceS, IQ);
+		    error ->
+			process_iqreply_error(From, LServiceS, IQ)
+		end
+	end
+    catch _:{xmpp_codec, Why} ->
+	    Lang = xmpp:get_lang(Packet),
+	    Err = xmpp:err_bad_request(xmpp:format_error(Why), Lang),
+	    ejabberd_router:route_error(To, From, Packet, Err)
     end.
 
-process_iq(From,
-	   #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} =
-	       IQ,
-	   State) ->
-    IQ#iq{type = result,
-	  sub_el =
-	      [#xmlel{name = <<"query">>,
-		      attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}],
-		      children = iq_disco_info(From, Lang, State)}]};
-%% disco#items request
-process_iq(_,
-	   #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) ->
-    IQ#iq{type = result,
-	  sub_el =
-	      [#xmlel{name = <<"query">>,
-		      attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}],
-		      children = []}]};
-%% vCard request
-process_iq(_,
-	   #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ,
-	   _) ->
-    IQ#iq{type = result,
-	  sub_el =
-	      [#xmlel{name = <<"vCard">>,
-		      attrs = [{<<"xmlns">>, ?NS_VCARD}],
-		      children = iq_vcard(Lang)}]};
-%% Unknown "set" or "get" request
-process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _)
-    when Type == get; Type == set ->
-    IQ#iq{type = error,
-	  sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
-%% IQ "result" or "error".
-process_iq(_, reply, _) -> reply;
-%% IQ "result" or "error".
-process_iq(_, _, _) -> ok.
-
--define(FEATURE(Feat),
-	#xmlel{name = <<"feature">>,
-	       attrs = [{<<"var">>, Feat}], children = []}).
+-spec process_iq(jid(), iq(), state()) -> {result, xmpp_element()} |
+					  {error, error()} | reply.
+process_iq(From, #iq{type = get, lang = Lang,
+		     sub_els = [#disco_info{}]}, State) ->
+    {result, iq_disco_info(From, Lang, State)};
+process_iq(_, #iq{type = get, sub_els = [#disco_items{}]}, _) ->
+    {result, #disco_items{}};
+process_iq(_, #iq{type = get, lang = Lang, sub_els = [#vcard_temp{}]}, _) ->
+    {result, iq_vcard(Lang)};
+process_iq(_, #iq{type = T}, _) when T == set; T == get ->
+    {error, xmpp:err_service_unavailable()};
+process_iq(_, _, _) ->
+    reply.
+
+-define(FEATURE(Feat), Feat).
 
 iq_disco_info(From, Lang, State) ->
-    [#xmlel{name = <<"identity">>,
-	    attrs =
-		[{<<"category">>, <<"service">>},
-		 {<<"type">>, <<"multicast">>},
-		 {<<"name">>,
-		  translate:translate(Lang, <<"Multicast">>)}],
-	    children = []},
-     ?FEATURE((?NS_DISCO_INFO)), ?FEATURE((?NS_DISCO_ITEMS)),
-     ?FEATURE((?NS_VCARD)), ?FEATURE((?NS_ADDRESS))]
-      ++ iq_disco_info_extras(From, State).
+    #disco_info{
+       identities = [#identity{category = <<"service">>,
+			       type = <<"multicast">>,
+			       name = translate:translate(Lang, <<"Multicast">>)}],
+       features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, ?NS_VCARD, ?NS_ADDRESS],
+       xdata = iq_disco_info_extras(From, State)}.
 
 iq_vcard(Lang) ->
-    [#xmlel{name = <<"FN">>, attrs = [],
-	    children = [{xmlcdata, <<"ejabberd/mod_multicast">>}]},
-     #xmlel{name = <<"URL">>, attrs = [],
-	    children = [{xmlcdata, ?EJABBERD_URI}]},
-     #xmlel{name = <<"DESC">>, attrs = [],
-	    children =
-		[{xmlcdata,
-                  <<(translate:translate(Lang,
-                                      <<"ejabberd Multicast service">>))/binary,
-                                        "\nCopyright (c) 2002-2016 ProcessOne">>}]}].
+    Desc = translate:translate(Lang, <<"ejabberd Multicast service">>),
+    Copyright = <<"Copyright (c) 2002-2016 ProcessOne">>,
+    #vcard_temp{fn = <<"ejabberd/mod_multicast">>,
+		url = ?EJABBERD_URI,
+		desc = <>}.
 
 %%%-------------------------
 %%% Route
@@ -313,19 +280,14 @@ iq_vcard(Lang) ->
 route_trusted(LServiceS, LServerS, FromJID,
 	      Destinations, Packet) ->
     Packet_stripped = Packet,
-    AAttrs = [{<<"xmlns">>, ?NS_ADDRESS}],
+    AAttrs = [],
     Delivereds = [],
-    Dests2 = lists:map(fun (D) ->
-			       DS = jts(D),
-			       XML = #xmlel{name = <<"address">>,
-					    attrs =
-						[{<<"type">>, <<"bcc">>},
-						 {<<"jid">>, DS}],
-					    children = []},
-			       #dest{jid_string = DS, jid_jid = D,
-				     type = <<"bcc">>, full_xml = XML}
-		       end,
-		       Destinations),
+    Dests2 = lists:map(
+	       fun(D) ->
+		       #dest{jid_string = jid:to_string(D),
+			     jid_jid = D, type = bcc,
+			     full_xml = #address{type = bcc, jid = D}}
+	       end, Destinations),
     Groups = group_dests(Dests2),
     route_common(LServerS, LServiceS, FromJID, Groups,
 		 Delivereds, Packet_stripped, AAttrs).
@@ -363,20 +325,19 @@ route_untrusted(LServiceS, LServerS, Access, SLimits,
 route_untrusted2(LServiceS, LServerS, Access, SLimits,
 		 FromJID, Packet) ->
     ok = check_access(LServerS, Access, FromJID),
-    {ok, Packet_stripped, AAttrs, Addresses} =
-	strip_addresses_element(Packet),
-    {To_deliver, Delivereds} =
-	split_addresses_todeliver(Addresses),
+    {ok, Packet_stripped, Addresses} = strip_addresses_element(Packet),
+    {To_deliver, Delivereds} = split_addresses_todeliver(Addresses),
     Dests = convert_dest_record(To_deliver),
     {Dests2, Not_jids} = split_dests_jid(Dests),
     report_not_jid(FromJID, Packet, Not_jids),
-    ok = check_limit_dests(SLimits, FromJID, Packet,
-			   Dests2),
+    ok = check_limit_dests(SLimits, FromJID, Packet, Dests2),
     Groups = group_dests(Dests2),
     ok = check_relay(FromJID#jid.server, LServerS, Groups),
     route_common(LServerS, LServiceS, FromJID, Groups,
-		 Delivereds, Packet_stripped, AAttrs).
+		 Delivereds, Packet_stripped, []).
 
+-spec route_common(binary(), binary(), jid(), [#group{}],
+		   [address()], stanza(), list()) -> any().
 route_common(LServerS, LServiceS, FromJID, Groups,
 	     Delivereds, Packet_stripped, AAttrs) ->
     Groups2 = look_cached_servers(LServerS, Groups),
@@ -435,52 +396,39 @@ check_access(LServerS, Access, From) ->
 %%% Strip 'addresses' XML element
 %%%-------------------------
 
+-spec strip_addresses_element(stanza()) -> {ok, stanza(), [address()]}.
 strip_addresses_element(Packet) ->
-    case fxml:get_subtag(Packet, <<"addresses">>) of
-      #xmlel{name = <<"addresses">>, attrs = AAttrs,
-	     children = Addresses} ->
-	  case fxml:get_attr_s(<<"xmlns">>, AAttrs) of
-	    ?NS_ADDRESS ->
-		#xmlel{name = Name, attrs = Attrs, children = Els} =
-		    Packet,
-		Els_stripped = lists:keydelete(<<"addresses">>, 2, Els),
-		Packet_stripped = #xmlel{name = Name, attrs = Attrs,
-					 children = Els_stripped},
-		{ok, Packet_stripped, AAttrs, fxml:remove_cdata(Addresses)};
-	    _ -> throw(ewxmlns)
-	  end;
-      _ -> throw(eadsele)
+    case xmpp:get_subtag(Packet, #addresses{}) of
+	#addresses{list = Addrs} ->
+	    PacketStripped = xmpp:remove_subtag(Packet, #addresses{}),
+	    {ok, PacketStripped, Addrs};
+	undefined ->
+	    throw(eadsele)
     end.
 
 %%%-------------------------
 %%% Split Addresses
 %%%-------------------------
 
+-spec split_addresses_todeliver([address()]) -> {[address()], [address()]}.
 split_addresses_todeliver(Addresses) ->
-    lists:partition(fun (XML) ->
-			    case XML of
-			      #xmlel{name = <<"address">>, attrs = Attrs} ->
-				  case fxml:get_attr_s(<<"delivered">>, Attrs) of
-				    <<"true">> -> false;
-				    _ ->
-					Type = fxml:get_attr_s(<<"type">>,
-							      Attrs),
-					case Type of
-					  <<"to">> -> true;
-					  <<"cc">> -> true;
-					  <<"bcc">> -> true;
-					  _ -> false
-					end
-				  end;
-			      _ -> false
-			    end
-		    end,
-		    Addresses).
+    lists:partition(
+      fun(#address{delivered = true}) ->
+	      false;
+	 (#address{type = Type}) ->
+	      case Type of
+		  to -> true;
+		  cc -> true;
+		  bcc -> true;
+		  _ -> false
+	      end
+      end, Addresses).
 
 %%%-------------------------
 %%% Check does not exceed limit of destinations
 %%%-------------------------
 
+-spec check_limit_dests(_, jid(), stanza(), [address()]) -> ok.
 check_limit_dests(SLimits, FromJID, Packet,
 		  Addresses) ->
     SenderT = sender_type(FromJID),
@@ -497,24 +445,22 @@ check_limit_dests(SLimits, FromJID, Packet,
 %%% Convert Destination XML to record
 %%%-------------------------
 
-convert_dest_record(XMLs) ->
-    lists:map(fun (XML) ->
-		      case fxml:get_tag_attr_s(<<"jid">>, XML) of
-			<<"">> -> #dest{jid_string = none, full_xml = XML};
-			JIDS ->
-			    Type = fxml:get_tag_attr_s(<<"type">>, XML),
-			    JIDJ = stj(JIDS),
-			    #dest{jid_string = JIDS, jid_jid = JIDJ,
-				  type = Type, full_xml = XML}
-		      end
-	      end,
-	      XMLs).
+-spec convert_dest_record([address()]) -> [#dest{}].
+convert_dest_record(Addrs) ->
+    lists:map(
+      fun(#address{jid = undefined} = Addr) ->
+	      #dest{jid_string = none, full_xml = Addr};
+	 (#address{jid = JID, type = Type} = Addr) ->
+	      #dest{jid_string = jid:to_string(JID), jid_jid = JID,
+		    type = Type, full_xml = Addr}
+      end, Addrs).
 
 %%%-------------------------
 %%% Split destinations by existence of JID
 %%% and send error messages for other dests
 %%%-------------------------
 
+-spec split_dests_jid([#dest{}]) -> {[#dest{}], [#dest{}]}.
 split_dests_jid(Dests) ->
     lists:partition(fun (Dest) ->
 			    case Dest#dest.jid_string of
@@ -524,8 +470,9 @@ split_dests_jid(Dests) ->
 		    end,
 		    Dests).
 
+-spec report_not_jid(jid(), stanza(), #dest{}) -> any().
 report_not_jid(From, Packet, Dests) ->
-    Dests2 = [fxml:element_to_binary(Dest#dest.full_xml)
+    Dests2 = [fxml:element_to_binary(xmpp:encode(Dest#dest.full_xml))
 	      || Dest <- Dests],
     [route_error(From, From, Packet, jid_malformed,
 		 <<"This service can not process the address: ",
@@ -536,6 +483,7 @@ report_not_jid(From, Packet, Dests) ->
 %%% Group destinations by their servers
 %%%-------------------------
 
+-spec group_dests([#dest{}]) -> [#group{}].
 group_dests(Dests) ->
     D = lists:foldl(fun (Dest, Dict) ->
 			    ServerS = (Dest#dest.jid_jid)#jid.server,
@@ -575,18 +523,17 @@ build_other_xml(Dests) ->
     lists:foldl(fun (Dest, R) ->
 			XML = Dest#dest.full_xml,
 			case Dest#dest.type of
-			  <<"to">> -> [add_delivered(XML) | R];
-			  <<"cc">> -> [add_delivered(XML) | R];
-			  <<"bcc">> -> R;
+			  to -> [add_delivered(XML) | R];
+			  cc -> [add_delivered(XML) | R];
+			  bcc -> R;
 			  _ -> [XML | R]
 			end
 		end,
 		[], Dests).
 
-add_delivered(#xmlel{name = Name, attrs = Attrs,
-		     children = Els}) ->
-    Attrs2 = [{<<"delivered">>, <<"true">>} | Attrs],
-    #xmlel{name = Name, attrs = Attrs2, children = Els}.
+-spec add_delivered(address()) -> address().
+add_delivered(Addr) ->
+    Addr#address{delivered = true}.
 
 %%%-------------------------
 %%% Add preliminary packets
@@ -636,7 +583,7 @@ decide_action_group(Group) ->
 
 route_packet(From, ToDest, Packet, AAttrs, Others, Addresses) ->
     Dests = case ToDest#dest.type of
-	      <<"bcc">> -> [];
+	      bcc -> [];
 	      _ -> [ToDest]
 	    end,
     route_packet2(From, ToDest#dest.jid_string, Dests,
@@ -652,20 +599,20 @@ route_packet_multicast(From, ToS, Packet, AAttrs, Dests,
 		   Addresses)
      || DFragment <- Fragmented_dests].
 
-route_packet2(From, ToS, Dests, Packet, AAttrs,
+-spec route_packet2(jid(), binary(), [#dest{}], stanza(), list(), [address()]) -> ok.
+route_packet2(From, ToS, Dests, Packet, _AAttrs,
 	      Addresses) ->
-    #xmlel{name = T, attrs = A, children = C} = Packet,
-    C2 = case append_dests(Dests, Addresses) of
-	   [] -> C;
-	   ACs ->
-	       [#xmlel{name = <<"addresses">>, attrs = AAttrs,
-		       children = ACs}
-		| C]
-	 end,
-    Packet2 = #xmlel{name = T, attrs = A, children = C2},
+    Els = case append_dests(Dests, Addresses) of
+	      [] ->
+		  xmpp:get_els(Packet);
+	      ACs ->
+		  [#addresses{list = ACs}|xmpp:get_els(Packet)]
+	  end,
+    Packet2 = xmpp:set_els(Packet, Els),
     ToJID = stj(ToS),
     ejabberd_router:route(From, ToJID, Packet2).
 
+-spec append_dests([#dest{}], {[address()], [address()]} | [address()]) -> [address()].
 append_dests(_Dests, {Others, Addresses}) ->
     Addresses++Others;
 append_dests([], Addresses) -> Addresses;
@@ -676,12 +623,14 @@ append_dests([Dest | Dests], Addresses) ->
 %%% Check relay
 %%%-------------------------
 
+-spec check_relay(binary(), binary(), [#group{}]) -> ok.
 check_relay(RS, LS, Gs) ->
     case check_relay_required(RS, LS, Gs) of
       false -> ok;
       true -> throw(edrelay)
     end.
 
+-spec check_relay_required(binary(), binary(), [#group{}]) -> boolean().
 check_relay_required(RServer, LServerS, Groups) ->
     case lists:suffix(str:tokens(LServerS, <<".">>),
                       str:tokens(RServer, <<".">>)) of
@@ -689,6 +638,7 @@ check_relay_required(RServer, LServerS, Groups) ->
       false -> check_relay_required(LServerS, Groups)
     end.
 
+-spec check_relay_required(binary(), [#group{}]) -> boolean().
 check_relay_required(LServerS, Groups) ->
     lists:any(fun (Group) -> Group#group.server /= LServerS
 	      end,
@@ -701,19 +651,16 @@ check_relay_required(LServerS, Groups) ->
 send_query_info(RServerS, LServiceS) ->
     case str:str(RServerS, <<"echo.">>) of
       1 -> false;
-      _ -> send_query(RServerS, LServiceS, ?NS_DISCO_INFO)
+      _ -> send_query(RServerS, LServiceS, #disco_info{})
     end.
 
 send_query_items(RServerS, LServiceS) ->
-    send_query(RServerS, LServiceS, ?NS_DISCO_ITEMS).
-
-send_query(RServerS, LServiceS, XMLNS) ->
-    Packet = #xmlel{name = <<"iq">>,
-		    attrs = [{<<"to">>, RServerS}, {<<"type">>, <<"get">>}],
-		    children =
-			[#xmlel{name = <<"query">>,
-				attrs = [{<<"xmlns">>, XMLNS}],
-				children = []}]},
+    send_query(RServerS, LServiceS, #disco_items{}).
+
+-spec send_query(binary(), binary(), [disco_info()|disco_items()]) -> ok.
+send_query(RServerS, LServiceS, SubEl) ->
+    Packet = #iq{id = randoms:get_string(),
+		 type = get, sub_els = [SubEl]},
     ejabberd_router:route(stj(LServiceS), stj(RServerS),
 			  Packet).
 
@@ -733,49 +680,40 @@ process_iqreply_error(From, LServiceS, _Packet) ->
 %%% Check protocol support: Receive response: Disco
 %%%-------------------------
 
-process_iqreply_result(From, LServiceS, Packet, State) ->
-    #xmlel{name = <<"query">>, attrs = Attrs2,
-	   children = Els2} =
-	fxml:get_subtag(Packet, <<"query">>),
-    case fxml:get_attr_s(<<"xmlns">>, Attrs2) of
-      ?NS_DISCO_INFO ->
-	  process_discoinfo_result(From, LServiceS, Els2, State);
-      ?NS_DISCO_ITEMS ->
-	  process_discoitems_result(From, LServiceS, Els2)
+-spec process_iqreply_result(jid(), binary(), iq()) -> any().
+process_iqreply_result(From, LServiceS, #iq{sub_els = [SubEl]}) ->
+    case SubEl of
+	#disco_info{} ->
+	    process_discoinfo_result(From, LServiceS, SubEl);
+	#disco_items{} ->
+	    process_discoitems_result(From, LServiceS, SubEl);
+	_ ->
+	    ok
     end.
 
 %%%-------------------------
 %%% Check protocol support: Receive response: Disco Info
 %%%-------------------------
 
-process_discoinfo_result(From, LServiceS, Els,
-			 _State) ->
+process_discoinfo_result(From, LServiceS, DiscoInfo) ->
     FromS = jts(From),
     case search_waiter(FromS, LServiceS, info) of
       {found_waiter, Waiter} ->
-	  process_discoinfo_result2(From, FromS, LServiceS, Els,
+	  process_discoinfo_result2(From, FromS, LServiceS, DiscoInfo,
 				    Waiter);
       _ -> ok
     end.
 
-process_discoinfo_result2(From, FromS, LServiceS, Els,
+process_discoinfo_result2(From, FromS, LServiceS,
+			  #disco_info{features = Feats} = DiscoInfo,
 			  Waiter) ->
-    Multicast_support =
-	lists:any(
-	    fun(XML) ->
-		    case XML of
-			#xmlel{name = <<"feature">>, attrs = Attrs} ->
-			    (?NS_ADDRESS) == fxml:get_attr_s(<<"var">>, Attrs);
-			_ -> false
-		    end
-	    end,
-	    Els),
+    Multicast_support = lists:member(?NS_ADDRESS, Feats),
     Group = Waiter#waiter.group,
     RServer = Group#group.server,
     case Multicast_support of
 	true ->
 	    SenderT = sender_type(From),
-	    RLimits = get_limits_xml(Els, SenderT),
+	    RLimits = get_limits_xml(DiscoInfo, SenderT),
 	    add_response(RServer, {multicast_supported, FromS, RLimits}),
 	    FromM = Waiter#waiter.sender,
 	    DestsM = Group#group.dests,
@@ -799,90 +737,58 @@ process_discoinfo_result2(From, FromS, LServiceS, Els,
 	  end
     end.
 
-get_limits_xml(Els, SenderT) ->
-    LimitOpts = get_limits_els(Els),
+get_limits_xml(DiscoInfo, SenderT) ->
+    LimitOpts = get_limits_els(DiscoInfo),
     build_remote_limit_record(LimitOpts, SenderT).
 
-get_limits_els(Els) ->
-    lists:foldl(fun (XML, R) ->
-			case XML of
-			  #xmlel{name = <<"x">>, attrs = Attrs,
-				 children = SubEls} ->
-			      case ((?NS_XDATA) ==
-				      fxml:get_attr_s(<<"xmlns">>, Attrs))
-				     and
-				     (<<"result">> ==
-					fxml:get_attr_s(<<"type">>, Attrs))
-				  of
-				true -> get_limits_fields(SubEls) ++ R;
-				false -> R
-			      end;
-			  _ -> R
-			end
-		end,
-		[], Els).
-
-get_limits_fields(Fields) ->
-    {Head, Tail} = lists:partition(fun (Field) ->
-					   case Field of
-					     #xmlel{name = <<"field">>,
-						    attrs = Attrs} ->
-						 (<<"FORM_TYPE">> ==
-						    fxml:get_attr_s(<<"var">>,
-								   Attrs))
-						   and
-						   (<<"hidden">> ==
-						      fxml:get_attr_s(<<"type">>,
-								     Attrs));
-					     _ -> false
-					   end
-				   end,
-				   Fields),
+-spec get_limits_els(disco_info()) -> [{atom(), integer()}].
+get_limits_els(DiscoInfo) ->
+    lists:flatmap(
+      fun(#xdata{type = result} = X) ->
+	      get_limits_fields(X);
+	 (_) ->
+	      []
+      end, DiscoInfo#disco_info.xdata).
+
+-spec get_limits_fields(xdata()) -> [{atom(), integer()}].
+get_limits_fields(X) ->
+    {Head, Tail} = lists:partition(
+		     fun(#xdata_field{var = Var, type = Type}) ->
+			     Var == <<"FORM_TYPE">> andalso Type == hidden
+		     end, X#xdata.fields),
     case Head of
       [] -> [];
       _ -> get_limits_values(Tail)
     end.
 
-get_limits_values(Values) ->
-    lists:foldl(fun (Value, R) ->
-			case Value of
-			  #xmlel{name = <<"field">>, attrs = Attrs,
-				 children = SubEls} ->
-			      [#xmlel{name = <<"value">>, children = SubElsV}] =
-				  SubEls,
-			      Number = fxml:get_cdata(SubElsV),
-			      Name = fxml:get_attr_s(<<"var">>, Attrs),
-			      [{jlib:binary_to_atom(Name),
-				jlib:binary_to_integer(Number)}
-			       | R];
-			  _ -> R
-			end
-		end,
-		[], Values).
+-spec get_limits_values([xdata_field()]) -> [{atom(), integer()}].
+get_limits_values(Fields) ->
+    lists:flatmap(
+      fun(#xdata_field{var = Name, values = [Number]}) ->
+	      try
+		  [{binary_to_atom(Name, utf8), binary_to_integer(Number)}]
+	      catch _:badarg ->
+		      []
+	      end;
+	 (_) ->
+	      []
+      end, Fields).
 
 %%%-------------------------
 %%% Check protocol support: Receive response: Disco Items
 %%%-------------------------
 
-process_discoitems_result(From, LServiceS, Els) ->
+process_discoitems_result(From, LServiceS, #disco_items{items = Items}) ->
     FromS = jts(From),
     case search_waiter(FromS, LServiceS, items) of
         {found_waiter, Waiter} ->
-            List = lists:foldl(
-                     fun(XML, Res) ->
-                             case XML of
-                                 #xmlel{name = <<"item">>, attrs = Attrs} ->
-                                     SJID = fxml:get_attr_s(<<"jid">>, Attrs),
-                                     case jid:from_string(SJID) of
-                                         #jid{luser = <<"">>,
-                                              lresource = <<"">>} ->
-                                             [SJID | Res];
-                                         _ -> Res
-                                     end;
-                                 _ -> Res
-                             end
-                     end,
-                     [], Els),
+            List = lists:flatmap(
+		     fun(#disco_item{jid = #jid{luser = <<"">>,
+						lresource = <<"">>} = J}) ->
+			     [J];
+			(_) ->
+			     []
+		     end, Items),
             case List of
                 [] ->
                     received_awaiter(FromS, Waiter, LServiceS);
@@ -1109,9 +1015,7 @@ get_limit_value(Name, Default, LimitOpts) ->
       false -> {default, Default}
     end.
 
-type_of_stanza(#xmlel{name = <<"message">>}) -> message;
-type_of_stanza(#xmlel{name = <<"presence">>}) ->
-    presence.
+type_of_stanza(Stanza) -> element(1, Stanza).
 
 get_limit_number(message, Limits) ->
     Limits#limits.message;
@@ -1144,17 +1048,10 @@ fragment_dests(Dests, Limit_number) ->
 %% Some parts of code are borrowed from mod_muc_room.erl
 
 -define(RFIELDT(Type, Var, Val),
-	#xmlel{name = <<"field">>,
-	       attrs = [{<<"var">>, Var}, {<<"type">>, Type}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children = [{xmlcdata, Val}]}]}).
+	#xdata_field{type = Type, var = Var, values = [Val]}).
 
 -define(RFIELDV(Var, Val),
-	#xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}],
-	       children =
-		   [#xmlel{name = <<"value">>, attrs = [],
-			   children = [{xmlcdata, Val}]}]}).
+	#xdata_field{var = Var, values = [Val]}).
 
 iq_disco_info_extras(From, State) ->
     SenderT = sender_type(From),
@@ -1162,12 +1059,9 @@ iq_disco_info_extras(From, State) ->
     case iq_disco_info_extras2(SenderT, Service_limits) of
       [] -> [];
       List_limits_xmpp ->
-	  [#xmlel{name = <<"x">>,
-		  attrs =
-		      [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}],
-		  children =
-		      [?RFIELDT(<<"hidden">>, <<"FORM_TYPE">>, (?NS_ADDRESS))]
-			++ List_limits_xmpp}]
+	    #xdata{type = result,
+		   fields = [?RFIELDT(hidden, <<"FORM_TYPE">>, ?NS_ADDRESS)
+			     | List_limits_xmpp]}
     end.
 
 sender_type(From) ->
@@ -1198,22 +1092,20 @@ to_binary(A) -> list_to_binary(hd(io_lib:format("~p", [A]))).
 %%%-------------------------
 
 route_error(From, To, Packet, ErrType, ErrText) ->
-    #xmlel{attrs = Attrs} = Packet,
-    Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
-    Reply = make_reply(ErrType, Lang, ErrText),
-    Err = jlib:make_error_reply(Packet, Reply),
-    ejabberd_router:route(From, To, Err).
+    Lang = xmpp:get_lang(Packet),
+    Err = make_reply(ErrType, Lang, ErrText),
+    ejabberd_router:route_error(From, To, Packet, Err).
 
 make_reply(bad_request, Lang, ErrText) ->
-    ?ERRT_BAD_REQUEST(Lang, ErrText);
+    xmpp:err_bad_request(ErrText, Lang);
 make_reply(jid_malformed, Lang, ErrText) ->
-    ?ERRT_JID_MALFORMED(Lang, ErrText);
+    xmpp:err_jid_malformed(ErrText, Lang);
 make_reply(not_acceptable, Lang, ErrText) ->
-    ?ERRT_NOT_ACCEPTABLE(Lang, ErrText);
+    xmpp:err_not_acceptable(ErrText, Lang);
 make_reply(internal_server_error, Lang, ErrText) ->
-    ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText);
+    xmpp:err_internal_server_error(ErrText, Lang);
 make_reply(forbidden, Lang, ErrText) ->
-    ?ERRT_FORBIDDEN(Lang, ErrText).
+    xmpp:err_forbidden(ErrText, Lang).
 
 stj(String) -> jid:from_string(String).
 
-- 
cgit v1.2.3


From cbdc106427d6d1e6e9371796645fa2f64b64c9a5 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Thu, 4 Aug 2016 12:34:12 +0300
Subject: Rewrite jd2ejd to use XML generator

---
 src/jd2ejd.erl | 66 +++++++++++++++++++++++++++-------------------------------
 1 file changed, 31 insertions(+), 35 deletions(-)

(limited to 'src')

diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
index 099387c9a..8afd9c80a 100644
--- a/src/jd2ejd.erl
+++ b/src/jd2ejd.erl
@@ -32,8 +32,7 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
-
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 %%%----------------------------------------------------------------------
 %%% API
@@ -112,7 +111,9 @@ process_xdb(User, Server,
 
 xdb_data(_User, _Server, {xmlcdata, _CData}) -> ok;
 xdb_data(User, Server, #xmlel{attrs = Attrs} = El) ->
-    From = jid:make(User, Server, <<"">>),
+    From = jid:make(User, Server),
+    LUser = From#jid.luser,
+    LServer = From#jid.lserver,
     case fxml:get_attr_s(<<"xmlns">>, Attrs) of
       ?NS_AUTH ->
 	  Password = fxml:get_tag_cdata(El),
@@ -128,29 +129,21 @@ xdb_data(User, Server, #xmlel{attrs = Attrs} = El) ->
 					 Status),
 	  ok;
       ?NS_VCARD ->
-	  catch mod_vcard:process_sm_iq(From,
-					jid:make(<<"">>, Server, <<"">>),
-					#iq{type = set, xmlns = ?NS_VCARD,
-					    sub_el = El}),
+	  catch mod_vcard:set_vcard(User, LServer, El),
 	  ok;
       <<"jabber:x:offline">> ->
 	  process_offline(Server, From, El), ok;
       XMLNS ->
 	  case fxml:get_attr_s(<<"j_private_flag">>, Attrs) of
 	    <<"1">> ->
-		catch mod_private:process_sm_iq(From,
-						jid:make(<<"">>, Server,
-							      <<"">>),
-						#iq{type = set,
-						    xmlns = ?NS_PRIVATE,
-						    sub_el =
-							#xmlel{name =
-								   <<"query">>,
-							       attrs = [],
-							       children =
-								   [jlib:remove_attr(<<"j_private_flag">>,
-										     jlib:remove_attr(<<"xdbns">>,
-												      El))]}});
+		NewAttrs = lists:filter(
+			     fun({<<"j_private_flag">>, _}) -> false;
+				({<<"xdbns">>, _}) -> false;
+				(_) -> true
+			     end, Attrs),
+		catch mod_private:set_data(
+			LUser, LServer,
+			[{XMLNS, El#xmlel{attrs = NewAttrs}}]);
 	    _ ->
 		?DEBUG("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS])
 	  end,
@@ -159,18 +152,21 @@ xdb_data(User, Server, #xmlel{attrs = Attrs} = El) ->
 
 process_offline(Server, To, #xmlel{children = Els}) ->
     LServer = jid:nameprep(Server),
-    lists:foreach(fun (#xmlel{attrs = Attrs} = El) ->
-			  FromS = fxml:get_attr_s(<<"from">>, Attrs),
-			  From = case FromS of
-				   <<"">> ->
-				       jid:make(<<"">>, Server, <<"">>);
-				   _ -> jid:from_string(FromS)
-				 end,
-			  case From of
-			    error -> ok;
-			    _ ->
-				ejabberd_hooks:run(offline_message_hook,
-						   LServer, [From, To, El])
-			  end
-		  end,
-		  Els).
+    lists:foreach(
+      fun(#xmlel{} = El) ->
+	      try xmpp:decode(El, [ignore_els]) of
+		  #message{from = JID} ->
+		      From = case JID of
+				 undefined -> jid:make(Server);
+				 _ -> JID
+			     end,
+		      ejabberd_hooks:run(offline_message_hook,
+					 LServer, [From, To, El]);
+		  _ ->
+		      ok
+	      catch _:{xmpp_codec, Why} ->
+		      Txt = xmpp:format_error(Why),
+		      ?ERROR_MSG("failed to decode XML '~s': ~s",
+				 [fxml:element_to_binary(El), Txt])
+	      end
+      end, Els).
-- 
cgit v1.2.3


From 8b81b9ecb1ee9287d848f6860dbc5abdaec72e96 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Thu, 4 Aug 2016 13:37:07 +0300
Subject: Rewrite PIEFXIS code to use XML generator

---
 src/ejabberd_piefxis.erl | 247 +++++++++++++++++++++--------------------------
 src/jd2ejd.erl           |   3 +-
 src/mod_privacy.erl      |   2 +-
 src/mod_roster.erl       |  11 +--
 4 files changed, 118 insertions(+), 145 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl
index 758001239..6a2b5e644 100644
--- a/src/ejabberd_piefxis.erl
+++ b/src/ejabberd_piefxis.erl
@@ -48,7 +48,7 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
 -include("mod_privacy.hrl").
 -include("mod_roster.hrl").
 
@@ -209,31 +209,28 @@ parse_scram_password(PassData) ->
     iterationcount = list_to_integer(binary_to_list(IterationCountBin))
   }.
 
+-spec get_vcard(binary(), binary()) -> [xmlel()].
 get_vcard(User, Server) ->
-    JID = jid:make(User, Server, <<>>),
-    case mod_vcard:process_sm_iq(JID, JID, #iq{type = get}) of
-        #iq{type = result, sub_el = [_|_] = VCardEls} ->
-            VCardEls;
-        _ ->
-            []
+    LUser = jid:nodeprep(User),
+    LServer = jid:nameprep(Server),
+    case mod_vcard:get_vcard(LUser, LServer) of
+	error -> [];
+	Els -> Els
     end.
 
+-spec get_offline(binary(), binary()) -> [xmlel()].
 get_offline(User, Server) ->
-    case mod_offline:get_offline_els(User, Server) of
+    LUser = jid:nodeprep(User),
+    LServer = jid:nameprep(Server),
+    case mod_offline:get_offline_els(LUser, LServer) of
         [] ->
             [];
         Els ->
-            NewEls = lists:map(
-                       fun(#xmlel{attrs = Attrs} = El) ->
-                               NewAttrs = lists:keystore(<<"xmlns">>, 1,
-                                                         Attrs,
-                                                         {<<"xmlns">>,
-                                                          <<"jabber:client">>}),
-                               El#xmlel{attrs = NewAttrs}
-                       end, Els),
+            NewEls = lists:map(fun xmpp:encode/1, Els),
             [#xmlel{name = <<"offline-messages">>, children = NewEls}]
     end.
 
+-spec get_privacy(binary(), binary()) -> [xmlel()].
 get_privacy(User, Server) ->
     case mod_privacy:get_user_lists(User, Server) of
         {ok, #privacy{default = Default,
@@ -241,25 +238,16 @@ get_privacy(User, Server) ->
             XLists = lists:map(
                        fun({Name, Items}) ->
                                XItems = lists:map(
-                                          fun mod_privacy:item_to_xml/1, Items),
-                               #xmlel{name = <<"list">>,
-                                      attrs = [{<<"name">>, Name}],
-                                      children = XItems}
+					  fun mod_privacy:encode_list_item/1,
+					  Items),
+			       #privacy_list{name = Name, items = XItems}
                        end, Lists),
-            DefaultEl = case Default of
-                            none ->
-                                [];
-                            _ ->
-                                [#xmlel{name = <<"default">>,
-                                        attrs = [{<<"name">>, Default}]}]
-                        end,
-            [#xmlel{name = <<"query">>,
-                    attrs = [{<<"xmlns">>, ?NS_PRIVACY}],
-                    children = DefaultEl ++ XLists}];
+	    [xmpp:encode(#privacy_query{default = Default, lists = XLists})];
         _ ->
             []
     end.
 
+-spec get_roster(binary(), binary()) -> [xmlel()].
 get_roster(User, Server) ->
     JID = jid:make(User, Server, <<>>),
     case mod_roster:get_roster(User, Server) of
@@ -272,18 +260,11 @@ get_roster(User, Server) ->
                           Status = if is_binary(Msg) -> (Msg);
                                       true -> <<"">>
                                    end,
-                          [#xmlel{name = <<"presence">>,
-                                  attrs =
-                                      [{<<"from">>,
-                                        jid:to_string(R#roster.jid)},
-                                       {<<"to">>, jid:to_string(JID)},
-                                       {<<"xmlns">>, <<"jabber:client">>},
-                                       {<<"type">>, <<"subscribe">>}],
-                                  children =
-                                      [#xmlel{name = <<"status">>,
-                                              attrs = [],
-                                              children =
-                                                  [{xmlcdata, Status}]}]}];
+			  [xmpp:encode(
+			     #presence{from = jid:make(R#roster.jid),
+				       to = JID,
+				       type = subscribe,
+				       status = xmpp:mk_text(Status)})];
                      (_) ->
                           []
                   end, Items),
@@ -291,21 +272,18 @@ get_roster(User, Server) ->
                    fun(#roster{ask = in, subscription = none}) ->
                            [];
                       (R) ->
-                           [mod_roster:item_to_xml(R)]
+                           [mod_roster:encode_item(R)]
                    end, Items),
-            [#xmlel{name = <<"query">>,
-                    attrs = [{<<"xmlns">>, ?NS_ROSTER}],
-                    children = Rs} | Subs];
+	    [xmpp:encode(#roster_query{items = Rs}) | Subs];
         _ ->
             []
     end.
 
+-spec get_private(binary(), binary()) -> [xmlel()].
 get_private(User, Server) ->
     case mod_private:get_data(User, Server) of
         [_|_] = Els ->
-            [#xmlel{name = <<"query">>,
-                    attrs = [{<<"xmlns">>, ?NS_PRIVATE}],
-                    children = Els}];
+	    [xmpp:encode(#private{xml_els = Els})];
         _ ->
             []
     end.
@@ -451,129 +429,124 @@ process_user_els([], State) ->
 
 process_user_el(#xmlel{name = Name, attrs = Attrs, children = Els} = El,
                 State) ->
-    case {Name, fxml:get_attr_s(<<"xmlns">>, Attrs)} of
-        {<<"query">>, ?NS_ROSTER} ->
-            process_roster(El, State);
-        {<<"query">>, ?NS_PRIVACY} ->
-            %% Make sure  elements go before  and 
-            NewEls = lists:reverse(lists:keysort(#xmlel.name, Els)),
-            process_privacy_el(El#xmlel{children = NewEls}, State);
-        {<<"query">>, ?NS_PRIVATE} ->
-            process_private(El, State);
-        {<<"vCard">>, ?NS_VCARD} ->
-            process_vcard(El, State);
-        {<<"offline-messages">>, _} ->
-            process_offline_msgs(Els, State);
-        {<<"presence">>, <<"jabber:client">>} ->
-            process_presence(El, State);
-        _ ->
-            {ok, State}
+    try
+	case {Name, fxml:get_attr_s(<<"xmlns">>, Attrs)} of
+	    {<<"query">>, ?NS_ROSTER} ->
+		process_roster(xmpp:decode(El), State);
+	    {<<"query">>, ?NS_PRIVACY} ->
+		%% Make sure  elements go before  and 
+		process_privacy(xmpp:decode(El), State);
+	    {<<"query">>, ?NS_PRIVATE} ->
+		process_private(xmpp:decode(El), State);
+	    {<<"vCard">>, ?NS_VCARD} ->
+		process_vcard(El, State);
+	    {<<"offline-messages">>, _} ->
+		Msgs = [xmpp:decode(E, [ignore_els]) || E <- Els],
+		process_offline_msgs(Msgs, State);
+	    {<<"presence">>, <<"jabber:client">>} ->
+		process_presence(xmpp:decode(El, [ignore_els]), State);
+	    _ ->
+		{ok, State}
+	end
+    catch _:{xmpp_codec, Why} ->
+	    ErrTxt = xmpp:format_error(Why),
+	    stop("failed to decode XML '~s': ~s",
+		 [fxml:element_to_binary(El), ErrTxt])
     end.
 
-process_privacy_el(#xmlel{children = [#xmlel{} = SubEl|SubEls]} = El, State) ->
-    case process_privacy(#xmlel{children = [SubEl]}, State) of
+-spec process_offline_msgs([stanza()], state()) -> {ok, state()} | {error, _}.
+process_offline_msgs([#message{} = Msg|Msgs], State) ->
+    case process_offline_msg(Msg, State) of
         {ok, NewState} ->
-            process_privacy_el(El#xmlel{children = SubEls}, NewState);
+            process_offline_msgs(Msgs, NewState);
         Err ->
             Err
     end;
-process_privacy_el(#xmlel{children = [_|SubEls]} = El, State) ->
-    process_privacy_el(El#xmlel{children = SubEls}, State);
-process_privacy_el(#xmlel{children = []}, State) ->
-    {ok, State}.
-
-process_offline_msgs([#xmlel{} = El|Els], State) ->
-    case process_offline_msg(El, State) of
-        {ok, NewState} ->
-            process_offline_msgs(Els, NewState);
-        Err ->
-            Err
-    end;
-process_offline_msgs([_|Els], State) ->
-    process_offline_msgs(Els, State);
+process_offline_msgs([_|Msgs], State) ->
+    process_offline_msgs(Msgs, State);
 process_offline_msgs([], State) ->
     {ok, State}.
 
-process_roster(El, State = #state{user = U, server = S}) ->
-    case mod_roster:set_items(U, S, El) of
+-spec process_roster(roster_query(), state()) -> {ok, state()} | {error, _}.
+process_roster(RosterQuery, State = #state{user = U, server = S}) ->
+    case mod_roster:set_items(U, S, RosterQuery) of
         {atomic, _} ->
             {ok, State};
         Err ->
             stop("Failed to write roster: ~p", [Err])
     end.
 
-process_privacy(El, State = #state{user = U, server = S}) ->
-    JID = jid:make(U, S, <<"">>),
-    case mod_privacy:process_iq_set(
-           [], JID, JID, #iq{type = set, sub_el = El}) of
-        {error, Error} = Err ->
-            #xmlel{children = Els} = El,
-            Name = case fxml:remove_cdata(Els) of
-              [#xmlel{name = N}] -> N;
-              _ -> undefined
-            end,
-            #xmlel{attrs = Attrs} = Error,
-            ErrorCode = case lists:keysearch(<<"code">>, 1, Attrs) of
-              {value, {_, V}} -> V;
-              false -> undefined
-            end,
-            if 
-              ErrorCode == <<"404">>, Name == <<"default">> ->
-                {ok, State};
-              true ->
-                stop("Failed to write privacy: ~p", [Err])
+-spec process_privacy(privacy_query(), state()) -> {ok, state()} | {error, _}.
+process_privacy(#privacy_query{lists = Lists,
+			       default = Default,
+			       active = Active} = PrivacyQuery,
+		State = #state{user = U, server = S}) ->
+    JID = jid:make(U, S),
+    IQ = #iq{type = set, id = randoms:get_string(),
+	     from = JID, to = JID, sub_els = [PrivacyQuery]},
+    Txt = <<"No module is handling this query">>,
+    Error = {error, xmpp:err_feature_not_implemented(Txt, ?MYLANG)},
+    case mod_privacy:process_iq_set(Error, IQ) of
+        {error, #error{reason = Reason}} = Err ->
+	    if Reason == 'item-not-found', Lists == [],
+	       Active == undefined, Default /= undefined ->
+		    %% Failed to set default list because there is no
+		    %% list with such name. We shouldn't stop here.
+		    {ok, State};
+	       true ->
+		    stop("Failed to write privacy: ~p", [Err])
             end;
         _ ->
             {ok, State}
     end.
 
-process_private(El, State = #state{user = U, server = S}) ->
-    JID = jid:make(U, S, <<"">>),
-    case mod_private:process_sm_iq(
-           JID, JID, #iq{type = set, sub_el = El}) of
+-spec process_private(private(), state()) -> {ok, state()} | {error, _}.
+process_private(Private, State = #state{user = U, server = S}) ->
+    JID = jid:make(U, S),
+    IQ = #iq{type = set, id = randoms:get_string(),
+	     from = JID, to = JID, sub_els = [Private]},
+    case mod_private:process_sm_iq(IQ) of
         #iq{type = result} ->
             {ok, State};
         Err ->
             stop("Failed to write private: ~p", [Err])
     end.
 
+-spec process_vcard(xmlel(), state()) -> {ok, state()} | {error, _}.
 process_vcard(El, State = #state{user = U, server = S}) ->
-    JID = jid:make(U, S, <<"">>),
-    case mod_vcard:process_sm_iq(
-           JID, JID, #iq{type = set, sub_el = El}) of
+    JID = jid:make(U, S),
+    IQ = #iq{type = set, id = randoms:get_string(),
+	     from = JID, to = JID, sub_els = [El]},
+    case mod_vcard:process_sm_iq(IQ) of
         #iq{type = result} ->
             {ok, State};
         Err ->
             stop("Failed to write vcard: ~p", [Err])
     end.
 
-process_offline_msg(El, State = #state{user = U, server = S}) ->
-    FromS = fxml:get_attr_s(<<"from">>, El#xmlel.attrs),
-    case jid:from_string(FromS) of
-        #jid{} = From ->
-            To = jid:make(U, S, <<>>),
-            NewEl = jlib:replace_from_to(From, To, El),
-            case catch mod_offline:store_packet(From, To, NewEl) of
-                {'EXIT', _} = Err ->
-                    stop("Failed to store offline message: ~p", [Err]);
-                _ ->
-                    {ok, State}
-            end;
-        _ ->
-            stop("Invalid 'from' = ~s", [FromS])
+-spec process_offline_msg(message(), state()) -> {ok, state()} | {error, _}.
+process_offline_msg(#message{from = undefined}, _State) ->
+    stop("No 'from' attribute found", []);
+process_offline_msg(Msg, State = #state{user = U, server = S}) ->
+    From = xmpp:get_from(Msg),
+    To = jid:make(U, S, <<>>),
+    NewMsg = xmpp:set_from_to(Msg, From, To),
+    case catch mod_offline:store_packet(From, To, NewMsg) of
+	{'EXIT', _} = Err ->
+	    stop("Failed to store offline message: ~p", [Err]);
+	_ ->
+	    {ok, State}
     end.
 
-process_presence(El, #state{user = U, server = S} = State) ->
-    FromS = fxml:get_attr_s(<<"from">>, El#xmlel.attrs),
-    case jid:from_string(FromS) of
-        #jid{} = From ->
-            To = jid:make(U, S, <<>>),
-            NewEl = jlib:replace_from_to(From, To, El),
-            ejabberd_router:route(From, To, NewEl),
-            {ok, State};
-        _ ->
-            stop("Invalid 'from' = ~s", [FromS])
-    end.
+-spec process_presence(presence(), state()) -> {ok, state()} | {error, _}.
+process_presence(#presence{from = undefined}, _State) ->
+    stop("No 'from' attribute found", []);
+process_presence(Pres, #state{user = U, server = S} = State) ->
+    From = xmpp:get_from(Pres),
+    To = jid:make(U, S, <<>>),
+    NewPres = xmpp:set_from_to(Pres, From, To),
+    ejabberd_router:route(From, To, NewPres),
+    {ok, State}.
 
 stop(Fmt, Args) ->
     ?ERROR_MSG(Fmt, Args),
diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
index 8afd9c80a..81732547b 100644
--- a/src/jd2ejd.erl
+++ b/src/jd2ejd.erl
@@ -120,7 +120,8 @@ xdb_data(User, Server, #xmlel{attrs = Attrs} = El) ->
 	  ejabberd_auth:set_password(User, Server, Password),
 	  ok;
       ?NS_ROSTER ->
-	  catch mod_roster:set_items(User, Server, El), ok;
+	  catch mod_roster:set_items(User, Server, xmpp:decode(El)),
+	  ok;
       ?NS_LAST ->
 	  TimeStamp = fxml:get_attr_s(<<"last">>, Attrs),
 	  Status = fxml:get_tag_cdata(El),
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index f61ba31d4..da947ace1 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -33,7 +33,7 @@
 
 -export([start/2, stop/1, process_iq/1, export/1, import/1,
 	 process_iq_set/2, process_iq_get/3, get_user_list/3,
-	 check_packet/6, remove_user/2,
+	 check_packet/6, remove_user/2, encode_list_item/1,
 	 is_list_needdb/1, updated_list/3,
          item_to_xml/1, get_user_lists/2, import/3,
 	 set_privacy_list/1, mod_opt_type/1, depends/2]).
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 58dc51983..51fe08ba5 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -688,15 +688,14 @@ send_unsubscribing_presence(From, Item) ->
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-set_items(User, Server, SubEl) ->
-    #xmlel{children = Els} = SubEl,
+-spec set_items(binary(), binary(), roster_query()) -> any().
+set_items(User, Server, #roster_query{items = Items}) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
     F = fun () ->
-		lists:foreach(fun (El) ->
-				      process_item_set_t(LUser, LServer, El)
-			      end,
-			      Els)
+		lists:foreach(fun (Item) ->
+				      process_item_set_t(LUser, LServer, Item)
+			      end, Items)
 	end,
     transaction(LServer, F).
 
-- 
cgit v1.2.3


From ca217dc1054cc4ba749559c1507f9101e76856bc Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Thu, 4 Aug 2016 13:41:38 +0300
Subject: Rewrite HTTP Bind and Web Admin code to use XML generator

---
 src/ejabberd_http_bind.erl | 2 +-
 src/ejabberd_web_admin.erl | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_http_bind.erl b/src/ejabberd_http_bind.erl
index 6fa38110c..1a238607a 100644
--- a/src/ejabberd_http_bind.erl
+++ b/src/ejabberd_http_bind.erl
@@ -62,7 +62,7 @@
 -include("ejabberd.hrl").
 -include("logger.hrl").
 
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 -include("ejabberd_http.hrl").
 
diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl
index 3281f6430..e62b4d257 100644
--- a/src/ejabberd_web_admin.erl
+++ b/src/ejabberd_web_admin.erl
@@ -38,7 +38,7 @@
 -include("ejabberd.hrl").
 -include("logger.hrl").
 
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 -include("ejabberd_http.hrl").
 
-- 
cgit v1.2.3


From b487ccfb34079dbd5d9839d329d8f07b54ad77c1 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Thu, 4 Aug 2016 16:45:33 +0300
Subject: Delete mod_configure2

The module doesn't work properly for many years and nobody reported
this, which means nobody is using it. Also, mod_configure does
the same (and more) in a standard compliant way (XEP-0133).
---
 src/mod_configure2.erl | 223 -------------------------------------------------
 1 file changed, 223 deletions(-)
 delete mode 100644 src/mod_configure2.erl

(limited to 'src')

diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl
deleted file mode 100644
index 85b7740d0..000000000
--- a/src/mod_configure2.erl
+++ /dev/null
@@ -1,223 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : mod_configure2.erl
-%%% Author  : Alexey Shchepin 
-%%% Purpose : Support for online configuration of ejabberd
-%%% Created : 26 Oct 2003 by Alexey Shchepin 
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2016   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_configure2).
-
--behaviour(ejabberd_config).
-
--author('alexey@process-one.net').
-
--behaviour(gen_mod).
-
--export([start/2, stop/1, process_local_iq/3,
-	 mod_opt_type/1, opt_type/1, depends/2]).
-
--include("ejabberd.hrl").
--include("logger.hrl").
-
--include("jlib.hrl").
-
--define(NS_ECONFIGURE,
-	<<"http://ejabberd.jabberstudio.org/protocol/con"
-	  "figure">>).
-
-start(Host, Opts) ->
-    IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
-                             one_queue),
-    gen_iq_handler:add_iq_handler(ejabberd_local, Host,
-				  ?NS_ECONFIGURE, ?MODULE, process_local_iq,
-				  IQDisc),
-    ok.
-
-stop(Host) ->
-    gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
-				     ?NS_ECONFIGURE).
-
-process_local_iq(From, To,
-		 #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
-    case acl:match_rule(To#jid.lserver, configure, From) of
-      deny ->
-	  Txt = <<"Denied by ACL">>,
-	  IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
-      allow ->
-	  case Type of
-	    set ->
-		Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
-		IQ#iq{type = error,
-		      sub_el = [SubEl, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)]};
-	    %%case fxml:get_tag_attr_s("type", SubEl) of
-	    %%    "cancel" ->
-	    %%        IQ#iq{type = result,
-	    %%		   sub_el = [{xmlelement, "query",
-	    %%			      [{"xmlns", XMLNS}], []}]};
-	    %%    "submit" ->
-	    %%        XData = jlib:parse_xdata_submit(SubEl),
-	    %%        case XData of
-	    %%    	invalid ->
-	    %%    	    IQ#iq{type = error,
-	    %%			  sub_el = [SubEl, ?ERR_BAD_REQUEST]};
-	    %%    	_ ->
-	    %%    	    Node =
-	    %%    		string:tokens(
-	    %%    		  fxml:get_tag_attr_s("node", SubEl),
-	    %%    		  "/"),
-	    %%    	    case set_form(Node, Lang, XData) of
-	    %%    		{result, Res} ->
-	    %%    		    IQ#iq{type = result,
-	    %%				  sub_el = [{xmlelement, "query",
-	    %%					     [{"xmlns", XMLNS}],
-	    %%					     Res
-	    %%					    }]};
-	    %%    		{error, Error} ->
-	    %%    		    IQ#iq{type = error,
-	    %%				  sub_el = [SubEl, Error]}
-	    %%    	    end
-	    %%        end;
-	    %%    _ ->
-	    %%        IQ#iq{type = error,
-	    %%		   sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
-	    %%end;
-	    get ->
-		case process_get(SubEl, Lang) of
-		  {result, Res} -> IQ#iq{type = result, sub_el = [Res]};
-		  {error, Error} ->
-		      IQ#iq{type = error, sub_el = [SubEl, Error]}
-		end
-	  end
-    end.
-
-process_get(#xmlel{name = <<"info">>}, _Lang) ->
-    S2SConns = ejabberd_s2s:dirty_get_connections(),
-    TConns = lists:usort([element(2, C) || C <- S2SConns]),
-    Attrs = [{<<"registered-users">>,
-	      iolist_to_binary(integer_to_list(mnesia:table_info(passwd,
-								 size)))},
-	     {<<"online-users">>,
-	      iolist_to_binary(integer_to_list(mnesia:table_info(presence,
-								 size)))},
-	     {<<"running-nodes">>,
-	      iolist_to_binary(integer_to_list(length(mnesia:system_info(running_db_nodes))))},
-	     {<<"stopped-nodes">>,
-	      iolist_to_binary(integer_to_list(length(lists:usort(mnesia:system_info(db_nodes)
-								     ++
-								     mnesia:system_info(extra_db_nodes))
-							 --
-							 mnesia:system_info(running_db_nodes))))},
-	     {<<"outgoing-s2s-servers">>,
-	      iolist_to_binary(integer_to_list(length(TConns)))}],
-    {result,
-     #xmlel{name = <<"info">>,
-	    attrs = [{<<"xmlns">>, ?NS_ECONFIGURE} | Attrs],
-	    children = []}};
-process_get(#xmlel{name = <<"welcome-message">>,
-		   attrs = Attrs}, _Lang) ->
-    {Subj, Body} = ejabberd_config:get_option(
-                     welcome_message,
-                     fun({Subj, Body}) ->
-                             {iolist_to_binary(Subj),
-                              iolist_to_binary(Body)}
-                     end,
-                     {<<"">>, <<"">>}),
-    {result,
-     #xmlel{name = <<"welcome-message">>, attrs = Attrs,
-	    children =
-		[#xmlel{name = <<"subject">>, attrs = [],
-			children = [{xmlcdata, Subj}]},
-		 #xmlel{name = <<"body">>, attrs = [],
-			children = [{xmlcdata, Body}]}]}};
-process_get(#xmlel{name = <<"registration-watchers">>,
-		   attrs = Attrs}, _Lang) ->
-    SubEls = ejabberd_config:get_option(
-               registration_watchers,
-               fun(JIDs) when is_list(JIDs) ->
-                       lists:map(
-                         fun(J) ->
-                                 #xmlel{name = <<"jid">>, attrs = [],
-                                        children = [{xmlcdata,
-                                                     iolist_to_binary(J)}]}
-                         end, JIDs)
-               end, []),
-    {result,
-     #xmlel{name = <<"registration_watchers">>,
-	    attrs = Attrs, children = SubEls}};
-process_get(#xmlel{name = <<"acls">>, attrs = Attrs}, _Lang) ->
-    Str = iolist_to_binary(io_lib:format("~p.",
-					 [ets:tab2list(acl)])),
-    {result,
-     #xmlel{name = <<"acls">>, attrs = Attrs,
-	    children = [{xmlcdata, Str}]}};
-process_get(#xmlel{name = <<"access">>,
-		   attrs = Attrs}, _Lang) ->
-    Str = iolist_to_binary(io_lib:format("~p.",
-					 [ets:select(local_config,
-						     [{{local_config, {access, '$1'},
-							'$2'},
-						       [],
-						       [{{access, '$1',
-							  '$2'}}]}])])),
-    {result,
-     #xmlel{name = <<"access">>, attrs = Attrs,
-	    children = [{xmlcdata, Str}]}};
-process_get(#xmlel{name = <<"last">>, attrs = Attrs}, Lang) ->
-    case catch mnesia:dirty_select(last_activity,
-				   [{{last_activity, '_', '$1', '_'}, [],
-				     ['$1']}])
-	of
-      {'EXIT', _Reason} ->
-	  Txt = <<"Database failure">>,
-	  {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)};
-      Vals ->
-	  TimeStamp = p1_time_compat:system_time(seconds),
-	  Str = list_to_binary(
-                  [[jlib:integer_to_binary(TimeStamp - V),
-                    <<" ">>] || V <- Vals]),
-	  {result,
-	   #xmlel{name = <<"last">>, attrs = Attrs,
-		  children = [{xmlcdata, Str}]}}
-    end;
-%%process_get({xmlelement, Name, Attrs, SubEls}) ->
-%%    {result, };
-process_get(_, _) -> {error, ?ERR_BAD_REQUEST}.
-
-depends(_Host, _Opts) ->
-    [].
-
-mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
-mod_opt_type(_) -> [iqdisc].
-
-opt_type(registration_watchers) ->
-    fun (JIDs) when is_list(JIDs) ->
-	    lists:map(fun (J) ->
-			      #xmlel{name = <<"jid">>, attrs = [],
-				     children =
-					 [{xmlcdata, iolist_to_binary(J)}]}
-		      end,
-		      JIDs)
-    end;
-opt_type(welcome_message) ->
-    fun ({Subj, Body}) ->
-	    {iolist_to_binary(Subj), iolist_to_binary(Body)}
-    end;
-opt_type(_) -> [registration_watchers, welcome_message].
-- 
cgit v1.2.3


From 4ff8d7918a0557414f8bf7b1aa1c0f875fb76216 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Fri, 5 Aug 2016 08:41:08 +0300
Subject: Change code to reflect recent changes in fxml_gen

---
 src/ejabberd_c2s.erl        |    4 +-
 src/mod_adhoc.erl           |    4 +-
 src/mod_announce.erl        |    3 +-
 src/mod_blocking.erl        |    9 +-
 src/mod_caps.erl            |   20 +-
 src/mod_configure.erl       |    5 +-
 src/mod_disco.erl           |   30 +-
 src/mod_irc.erl             |    4 +-
 src/mod_mam.erl             |    2 +-
 src/mod_muc.erl             |    6 +-
 src/mod_muc_room.erl        |   29 +-
 src/mod_offline.erl         |    5 +-
 src/mod_privacy.erl         |   17 +-
 src/mod_proxy65_service.erl |    5 -
 src/mod_vcard.erl           |   27 +-
 src/translate.erl           |    4 +-
 src/xmpp.erl                |  121 +++--
 src/xmpp_codec.erl          | 1110 ++++++++++++++++++-------------------------
 src/xmpp_util.erl           |    2 +-
 19 files changed, 596 insertions(+), 811 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 1ae9a7c29..b13e7fe00 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -519,10 +519,10 @@ wait_for_auth(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) ->
 wait_for_auth(#iq{type = get,
 		  sub_els = [#legacy_auth{username = U}]} = IQ, StateData) ->
     Username = case U of
-		   undefined -> none;
+		   undefined -> <<"">>;
 		   _ -> U
 	       end,
-    Auth = #legacy_auth{username = Username, password = none, resource = none},
+    Auth = #legacy_auth{username = Username, password = <<>>, resource = <<>>},
     Res = case ejabberd_auth:plain_password_required(StateData#state.server) of
 	      false ->
 		  xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = none});
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index 9c8238900..22bde2586 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -91,7 +91,7 @@ stop(Host) ->
 %-------------------------------------------------------------------------
 
 get_local_commands(Acc, _From,
-		   #jid{server = Server, lserver = LServer} = _To, undefined,
+		   #jid{server = Server, lserver = LServer} = _To, <<"">>,
 		   Lang) ->
     Display = gen_mod:get_module_opt(LServer, ?MODULE,
 				     report_commands_node,
@@ -122,7 +122,7 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
 %-------------------------------------------------------------------------
 
 get_sm_commands(Acc, _From,
-		#jid{lserver = LServer} = To, undefined, Lang) ->
+		#jid{lserver = LServer} = To, <<"">>, Lang) ->
     Display = gen_mod:get_module_opt(LServer, ?MODULE,
 				     report_commands_node,
                                      fun(B) when is_boolean(B) -> B end,
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index 4b7498447..1a42a460b 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -56,7 +56,6 @@
 -define(NS_ADMINL(Sub), [<<"http:">>, <<"jabber.org">>, <<"protocol">>,
                          <<"admin">>, <>]).
 
-tokenize(undefined) -> [];
 tokenize(Node) -> str:tokens(Node, <<"/#">>).
 
 start(Host, Opts) ->
@@ -280,7 +279,7 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
 		{result, Items}
 	end).
 
-disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, undefined, Lang) ->
+disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, <<"">>, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
 	false ->
 	    Acc;
diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl
index 743b78efd..bc3080871 100644
--- a/src/mod_blocking.erl
+++ b/src/mod_blocking.erl
@@ -135,7 +135,7 @@ list_to_blocklist_jids([_ | Items], JIDs) ->
     list_to_blocklist_jids(Items, JIDs).
 
 -spec process_blocklist_block(binary(), binary(), [ljid()],
-			      undefined | binary()) ->
+			      binary()) ->
 				     {error, error()} |
 				     {result, undefined, userlist()}.
 process_blocklist_block(LUser, LServer, JIDs, Lang) ->
@@ -170,7 +170,7 @@ process_blocklist_block(LUser, LServer, JIDs, Lang) ->
 	    {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)}
     end.
 
--spec process_blocklist_unblock_all(binary(), binary(), undefined | binary()) ->
+-spec process_blocklist_unblock_all(binary(), binary(), binary()) ->
 					   {error, error()} |
 					   {result, undefined} |
 					   {result, undefined, userlist()}.
@@ -194,8 +194,7 @@ process_blocklist_unblock_all(LUser, LServer, Lang) ->
 	    {error, xmpp:err_internal_server_error(<<"Database failure">>, Lang)}
     end.
 
--spec process_blocklist_unblock(binary(), binary(), [ljid()],
-				undefined | binary()) ->
+-spec process_blocklist_unblock(binary(), binary(), [ljid()], binary()) ->
 				       {error, error()} |
 				       {result, undefined} |
 				       {result, undefined, userlist()}.
@@ -243,7 +242,7 @@ broadcast_blocklist_event(LUser, LServer, Event) ->
     ejabberd_sm:route(JID, JID,
                       {broadcast, {blocking, Event}}).
 
--spec process_blocklist_get(binary(), binary(), undefined | binary()) ->
+-spec process_blocklist_get(binary(), binary(), binary()) ->
 				   {error, error()} | {result, block_list()}.
 process_blocklist_get(LUser, LServer, Lang) ->
     Mod = db_mod(LServer),
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 7c7ebf7b3..d5033ffd8 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -35,8 +35,6 @@
 
 -behaviour(gen_mod).
 
--compile(export_all).
-
 -export([read_caps/1, caps_stream_features/2,
 	 disco_features/5, disco_identity/5, disco_info/5,
 	 get_features/2, export/1, import_info/0, import/5,
@@ -162,38 +160,38 @@ caps_stream_features(Acc, MyHost) ->
 
 -spec disco_features({error, error()} | {result, [binary()]} | empty,
 		     jid(), jid(),
-		     undefined | binary(), undefined | binary()) ->
+		     binary(), binary()) ->
 			    {error, error()} | {result, [binary()]}.
 disco_features(Acc, From, To, Node, Lang) ->
     case is_valid_node(Node) of
         true ->
             ejabberd_hooks:run_fold(disco_local_features,
                                     To#jid.lserver, empty,
-                                    [From, To, undefined, Lang]);
+                                    [From, To, <<"">>, Lang]);
         false ->
             Acc
     end.
 
 -spec disco_identity([identity()], jid(), jid(),
-		     undefined | binary(), undefined | binary()) ->
+		     binary(), binary()) ->
 			    [identity()].
 disco_identity(Acc, From, To, Node, Lang) ->
     case is_valid_node(Node) of
         true ->
             ejabberd_hooks:run_fold(disco_local_identity,
                                     To#jid.lserver, [],
-                                    [From, To, undefined, Lang]);
+                                    [From, To, <<"">>, Lang]);
         false ->
             Acc
     end.
 
 -spec disco_info([xdata()], binary(), module(),
-		 undefined | binary(), undefined | binary()) ->	[xdata()].
+		 binary(), binary()) -> [xdata()].
 disco_info(Acc, Host, Module, Node, Lang) ->
     case is_valid_node(Node) of
         true ->
             ejabberd_hooks:run_fold(disco_info, Host, [],
-                                    [Host, Module, undefined, Lang]);
+                                    [Host, Module, <<"">>, Lang]);
         false ->
             Acc
     end.
@@ -485,7 +483,7 @@ concat_info(#disco_info{xdata = Xs}) ->
       [concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]).
 
 concat_xdata_fields(Fields) ->
-    Form = case lists:keysearch(<<"FORM_TYPE">>, #xdata_field.var, Fields) of
+    Form = case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, Fields) of
 	       #xdata_field{values = Values} -> Values;
 	       false -> []
 	   end,
@@ -509,9 +507,7 @@ gb_trees_fold_iter(F, Acc, Iter) ->
 now_ts() ->
     p1_time_compat:system_time(seconds).
 
--spec is_valid_node(undefined | binary()) -> boolean().
-is_valid_node(undefined) ->
-    false;
+-spec is_valid_node(binary()) -> boolean().
 is_valid_node(Node) ->
     case str:tokens(Node, <<"#">>) of
         [?EJABBERD_URI|_] ->
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index 342a15232..07a1c7333 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -121,7 +121,6 @@ depends(_Host, _Opts) ->
 	[<<"http:">>, <<"jabber.org">>, <<"protocol">>,
 	 <<"admin">>, Sub]).
 
-tokenize(undefined) -> [];
 tokenize(Node) -> str:tokens(Node, <<"/#">>).
 
 get_sm_identity(Acc, _From, _To, Node, Lang) ->
@@ -300,7 +299,7 @@ get_sm_items(Acc, From,
 		    empty -> []
 		  end,
 	  case {acl:match_rule(LServer, configure, From), Node} of
-	    {allow, undefined} ->
+	    {allow, <<"">>} ->
 		Nodes = [?NODEJID(To, <<"Configuration">>,
 				  <<"config">>),
 			 ?NODEJID(To, <<"User Management">>, <<"user">>)],
@@ -399,7 +398,7 @@ get_permission_level(JID) ->
 	end).
 
 get_local_items(Acc, From, #jid{lserver = LServer} = To,
-		undefined, Lang) ->
+		<<"">>, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
       false -> Acc;
       _ ->
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index 0d3f242a0..e78b8f72f 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -190,9 +190,8 @@ process_local_iq_info(#iq{type = get, lang = Lang,
     end.
 
 -spec get_local_identity([identity()], jid(), jid(),
-			 undefined | binary(), undefined | binary()) ->
-				[identity()].
-get_local_identity(Acc, _From, _To, undefined, _Lang) ->
+			 binary(), binary()) ->	[identity()].
+get_local_identity(Acc, _From, _To, <<"">>, _Lang) ->
     Acc ++ [#identity{category = <<"server">>,
 		      type = <<"im">>,
 		      name = <<"ejabberd">>}];
@@ -200,13 +199,12 @@ get_local_identity(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
 -spec get_local_features({error, error()} | {result, [binary()]} | empty,
-			 jid(), jid(),
-			 undefined | binary(), undefined | binary()) ->
+			 jid(), jid(), binary(), binary()) ->
 				{error, error()} | {result, [binary()]}.
 get_local_features({error, _Error} = Acc, _From, _To,
 		   _Node, _Lang) ->
     Acc;
-get_local_features(Acc, _From, To, undefined, _Lang) ->
+get_local_features(Acc, _From, To, <<"">>, _Lang) ->
     Feats = case Acc of
 		{result, Features} -> Features;
 		empty -> []
@@ -226,12 +224,12 @@ get_local_features(Acc, _From, _To, _Node, Lang) ->
 
 -spec get_local_services({error, error()} | {result, [disco_item()]} | empty,
 			 jid(), jid(),
-			 undefined | binary(), undefined | binary()) ->
+			 binary(), binary()) ->
 				{error, error()} | {result, [disco_item()]}.
 get_local_services({error, _Error} = Acc, _From, _To,
 		   _Node, _Lang) ->
     Acc;
-get_local_services(Acc, _From, To, undefined, _Lang) ->
+get_local_services(Acc, _From, To, <<"">>, _Lang) ->
     Items = case Acc of
 	      {result, Its} -> Its;
 	      empty -> []
@@ -300,13 +298,13 @@ process_sm_iq_items(#iq{type = get, lang = Lang,
 
 -spec get_sm_items({error, error()} | {result, [disco_item()]} | empty,
 		   jid(), jid(),
-		   undefined | binary(), undefined | binary()) ->
+		   binary(), binary()) ->
 			  {error, error()} | {result, [disco_item()]}.
 get_sm_items({error, _Error} = Acc, _From, _To, _Node,
 	     _Lang) ->
     Acc;
 get_sm_items(Acc, From,
-	     #jid{user = User, server = Server} = To, undefined, _Lang) ->
+	     #jid{user = User, server = Server} = To, <<"">>, _Lang) ->
     Items = case Acc of
 	      {result, Its} -> Its;
 	      empty -> []
@@ -375,8 +373,7 @@ process_sm_iq_info(#iq{type = get, lang = Lang,
     end.
 
 -spec get_sm_identity([identity()], jid(), jid(),
-		      undefined | binary(), undefined | binary()) ->
-			     [identity()].
+		      binary(), binary()) -> [identity()].
 get_sm_identity(Acc, _From,
 		#jid{luser = LUser, lserver = LServer}, _Node, _Lang) ->
     Acc ++
@@ -387,8 +384,7 @@ get_sm_identity(Acc, _From,
       end.
 
 -spec get_sm_features({error, error()} | {result, [binary()]} | empty,
-		      jid(), jid(),
-		      undefined | binary(), undefined | binary()) ->
+		      jid(), jid(), binary(), binary()) ->
 			     {error, error()} | {result, [binary()]}.
 get_sm_features(empty, From, To, _Node, Lang) ->
     #jid{luser = LFrom, lserver = LSFrom} = From,
@@ -428,10 +424,8 @@ transform_module_options(Opts) ->
 
 %%% Support for: XEP-0157 Contact Addresses for XMPP Services
 
--spec get_info([xdata()], binary(), module(),
-	       undefined | binary(), undefined | binary()) ->
-		      [xdata()].
-get_info(_A, Host, Mod, Node, _Lang) when Node == undefined ->
+-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()].
+get_info(_A, Host, Mod, Node, _Lang) when Node == <<"">> ->
     Module = case Mod of
 	       undefined -> ?MODULE;
 	       _ -> Mod
diff --git a/src/mod_irc.erl b/src/mod_irc.erl
index 1960c988d..3c094ef9c 100644
--- a/src/mod_irc.erl
+++ b/src/mod_irc.erl
@@ -257,7 +257,7 @@ process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
 process_disco_items(#iq{type = get, lang = Lang, to = To,
 			sub_els = [#disco_items{node = Node}]} = IQ) ->
     case Node of
-	undefined ->
+	<<"">> ->
 	    xmpp:make_iq_result(IQ, #disco_items{});
 	<<"join">> ->
 	    xmpp:make_iq_result(IQ, #disco_items{});
@@ -401,7 +401,7 @@ sm_route(Host, ServerHost, From, To, Packet) ->
 closed_connection(Host, From, Server) ->
     ets:delete(irc_connection, {From, Server, Host}).
 
-iq_disco(_ServerHost, undefined, Lang) ->
+iq_disco(_ServerHost, <<"">>, Lang) ->
     #disco_info{
        identities = [#identity{category = <<"conference">>,
 			       type = <<"irc">>,
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index 0aaf484c5..b83c423c7 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -363,7 +363,7 @@ disco_sm_features(empty, From, To, Node, Lang) ->
     disco_sm_features({result, []}, From, To, Node, Lang);
 disco_sm_features({result, OtherFeatures},
 		  #jid{luser = U, lserver = S},
-		  #jid{luser = U, lserver = S}, undefined, _Lang) ->
+		  #jid{luser = U, lserver = S}, <<"">>, _Lang) ->
     {result, [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1 | OtherFeatures]};
 disco_sm_features(Acc, _From, _To, _Node, _Lang) ->
     Acc.
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index 294456ee2..3eca79fec 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -450,10 +450,10 @@ process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
     Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_info(#iq{type = get, to = To, lang = Lang,
-		       sub_els = [#disco_info{node = undefined}]} = IQ) ->
+		       sub_els = [#disco_info{node = <<"">>}]} = IQ) ->
     ServerHost = ejabberd_router:host_of_route(To#jid.lserver),
     X = ejabberd_hooks:run_fold(disco_info, ServerHost, [],
-				[ServerHost, ?MODULE, undefined, Lang]),
+				[ServerHost, ?MODULE, <<"">>, Lang]),
     MAMFeatures = case gen_mod:is_loaded(ServerHost, mod_mam) of
 		      true -> [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1];
 		      false -> []
@@ -562,7 +562,7 @@ register_room(Host, Room, Pid) ->
     end,
     mnesia:transaction(F).
 
-iq_disco_items(Host, From, Lang, undefined, undefined) ->
+iq_disco_items(Host, From, Lang, <<"">>, undefined) ->
     Rooms = get_vh_rooms(Host),
     case erlang:length(Rooms) < ?MAX_ROOMS_DISCOITEMS of
 	true ->
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index 68064fcb7..5814ca832 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -277,7 +277,7 @@ normal_state({route, From, <<"">>,
 			       process_iq_admin(From, IQ, StateData);
 			   ?NS_MUC_OWNER ->
 			       process_iq_owner(From, IQ, StateData);
-			   ?NS_DISCO_INFO when SubEl#disco_info.node == undefined ->
+			   ?NS_DISCO_INFO when SubEl#disco_info.node == <<>> ->
 			       process_iq_disco_info(From, IQ, StateData);
 			   ?NS_DISCO_INFO ->
 			       Txt = <<"Disco info is not available for this node">>,
@@ -2146,11 +2146,7 @@ send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) ->
 			  true -> Item0#muc_item{jid = RealJID};
 			  false -> Item0
 		      end,
-	      Item = if is_binary(Reason), Reason /= <<"">> ->
-			     Item1#muc_item{reason = Reason};
-			true ->
-			     Item1
-		     end,
+	      Item = Item1#muc_item{reason = Reason},
 	      StatusCodes = status_codes(IsInitialPresence, NJID, Info,
 					 StateData),
 	      Pres = if Presence == undefined -> #presence{};
@@ -2526,11 +2522,7 @@ items_with_affiliation(SAffiliation, StateData) ->
     lists:map(
       fun({JID, {Affiliation, Reason}}) ->
 	      #muc_item{affiliation = Affiliation, jid = JID,
-			reason = if is_binary(Reason), Reason /= <<"">> ->
-					 Reason;
-				    true ->
-					 undefined
-				 end};
+			reason = Reason};
 	 ({JID, Affiliation}) ->
 	      #muc_item{affiliation = Affiliation, jid = JID}
       end,
@@ -2563,7 +2555,7 @@ search_affiliation(Affiliation, StateData) ->
 		 end,
 		 (?DICT):to_list(StateData#state.affiliations)).
 
--spec process_admin_items_set(jid(), [muc_item()], binary() | undefined,
+-spec process_admin_items_set(jid(), [muc_item()], binary(),
 			      #state{}) -> {result, undefined, #state{}} |
 					   {error, error()}.
 process_admin_items_set(UJID, Items, Lang, StateData) ->
@@ -2666,13 +2658,13 @@ find_changed_items(_UJID, _UAffiliation, _URole,
     Txt = <<"Neither 'role' nor 'affiliation' attribute found">>,
     throw({error, xmpp:err_bad_request(Txt, Lang)});
 find_changed_items(UJID, UAffiliation, URole,
-		   [#muc_item{jid = J, nick = Nick, reason = Reason0,
+		   [#muc_item{jid = J, nick = Nick, reason = Reason,
 			      role = Role, affiliation = Affiliation}|Items],
 		   Lang, StateData, Res) ->
     [JID | _] = JIDs = 
 	if J /= undefined ->
 		[J];
-	   Nick /= undefined ->
+	   Nick /= <<"">> ->
 		case find_jids_by_nick(Nick, StateData) of
 		    [] ->
 			ErrText = iolist_to_binary(
@@ -2717,9 +2709,6 @@ find_changed_items(UJID, UAffiliation, URole,
 			       Items, Lang, StateData,
 			       Res);
 	true ->
-	    Reason = if is_binary(Reason0) -> Reason0;
-			true -> <<"">>
-		     end,
 	    MoreRes = [{jid:remove_resource(Jidx),
 			RoleOrAff, RoleOrAffValue, Reason}
 		       || Jidx <- JIDs],
@@ -2914,11 +2903,7 @@ send_kickban_presence1(MJID, UJID, Reason, Code, Affiliation,
 			  true -> Item0#muc_item{jid = RealJID};
 			  false -> Item0
 		      end,
-	      Item2 = if is_binary(Reason), Reason /= <<"">> ->
-			      Item1#muc_item{reason = Reason};
-			 true ->
-			      Item1
-		      end,
+	      Item2 = Item1#muc_item{reason = Reason},
 	      Item = case ActorNick of
 			 <<"">> -> Item2;
 			 _ -> Item2#muc_item{actor = #muc_actor{nick = ActorNick}}
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 66edb6a7c..4d597a52c 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -250,7 +250,7 @@ receive_all(US, Msgs, DBType) ->
 		end
     end.
 
-get_sm_features(Acc, _From, _To, undefined, _Lang) ->
+get_sm_features(Acc, _From, _To, <<"">>, _Lang) ->
     Feats = case Acc of
 		{result, I} -> I;
 		_ -> []
@@ -297,8 +297,7 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID,
 get_sm_items(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
--spec get_info([xdata()], jid(), jid(),
-	       undefined | binary(), undefined | binary()) -> [xdata()].
+-spec get_info([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
 get_info(_Acc, #jid{luser = U, lserver = S, lresource = R},
 	 #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) ->
     N = jlib:integer_to_binary(count_offline_messages(U, S)),
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index da947ace1..1da040d43 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -116,7 +116,7 @@ process_iq_get(_, #iq{from = From, lang = Lang,
 	    {error, xmpp:err_bad_request(Txt, Lang)}
     end.
 
--spec process_lists_get(binary(), binary(), binary(), undefined | binary()) ->
+-spec process_lists_get(binary(), binary(), binary(), binary()) ->
 			       {error, error()} | {result, privacy_query()}.
 process_lists_get(LUser, LServer, Active, Lang) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
@@ -134,7 +134,7 @@ process_lists_get(LUser, LServer, Active, Lang) ->
 				     || ListName <- ListNames]}}
     end.
 
--spec process_list_get(binary(), binary(), binary(), undefined | binary()) ->
+-spec process_list_get(binary(), binary(), binary(), binary()) ->
 			      {error, error()} | {result, privacy_query()}.
 process_list_get(LUser, LServer, Name, Lang) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
@@ -183,7 +183,7 @@ encode_list_item(#listitem{action = Action,
 			      presence_out = MatchPresenceOut}
     end.
 
--spec encode_value(listitem_type(), listitem_value()) -> undefined | binary().
+-spec encode_value(listitem_type(), listitem_value()) -> binary().
 encode_value(Type, Val) ->
     case Type of
 	jid -> jid:to_string(Val);
@@ -195,7 +195,7 @@ encode_value(Type, Val) ->
 		from -> <<"from">>;
 		none -> <<"none">>
 	    end;
-	none -> undefined
+	none -> <<"">>
     end.
 
 -spec decode_value(jid | subscription | group | undefined, binary()) ->
@@ -239,8 +239,7 @@ process_iq_set(_, #iq{from = From, lang = Lang,
     end.
 
 -spec process_default_set(binary(), binary(), none | binary(),
-			  undefined | binary()) -> {error, error()} |
-						   {result, undefined}.			 
+			  binary()) -> {error, error()} | {result, undefined}.
 process_default_set(LUser, LServer, Value, Lang) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     case Mod:process_default_set(LUser, LServer, Value) of
@@ -258,8 +257,7 @@ process_default_set(LUser, LServer, Value, Lang) ->
 	    {error, xmpp:err_internal_server_error()}
     end.
 
--spec process_active_set(binary(), binary(), none | binary(),
-			 undefined | binary()) ->
+-spec process_active_set(binary(), binary(), none | binary(), binary()) ->
 				{error, error()} |
 				{result, undefined, userlist()}.
 process_active_set(_LUser, _LServer, none, _Lang) ->
@@ -282,8 +280,7 @@ set_privacy_list(#privacy{us = {_, LServer}} = Privacy) ->
     Mod:set_privacy_list(Privacy).
 
 -spec process_lists_set(binary(), binary(), binary(), [privacy_item()],
-			undefined | binary()) -> {error, error()} |
-						 {result, undefined}.
+			binary()) -> {error, error()} | {result, undefined}.
 process_lists_set(LUser, LServer, Name, [], Lang) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     case Mod:remove_privacy_list(LUser, LServer, Name) of
diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl
index e90ff21bd..789771d7d 100644
--- a/src/mod_proxy65_service.erl
+++ b/src/mod_proxy65_service.erl
@@ -156,11 +156,6 @@ process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) ->
 	deny ->
 	    xmpp:make_error(IQ, xmpp:err_forbidden(<<"Denied by ACL">>, Lang))
     end;
-process_bytestreams(#iq{type = set, lang = Lang,
-			sub_els = [#bytestreams{sid = undefined}]} = IQ) ->
-    Why = {missing_attr, <<"sid">>, <<"query">>, ?NS_BYTESTREAMS},
-    Txt = xmpp:format_error(Why),
-    xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
 process_bytestreams(#iq{type = set, lang = Lang,
 			sub_els = [#bytestreams{sid = SID}]} = IQ)
   when SID == <<"">> orelse length(SID) > 128 ->
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 231c42dc0..4653d6e2c 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -151,15 +151,14 @@ do_route(_, _, _) ->
     ok.
 
 -spec get_sm_features({error, error()} | empty | {result, [binary()]},
-		      jid(), jid(),
-		      undefined | binary(), undefined | binary()) ->
+		      jid(), jid(), binary(), binary()) ->
 			     {error, error()} | empty | {result, [binary()]}.
 get_sm_features({error, _Error} = Acc, _From, _To,
 		_Node, _Lang) ->
     Acc;
 get_sm_features(Acc, _From, _To, Node, _Lang) ->
     case Node of
-      undefined ->
+      <<"">> ->
 	  case Acc of
 	    {result, Features} ->
 		{result, [?NS_DISCO_INFO, ?NS_VCARD | Features]};
@@ -232,10 +231,9 @@ process_search(#iq{type = set, lang = Lang} = IQ) ->
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
 
 -spec disco_items({error, error()} | {result, [disco_item()]} | empty,
-		  jid(), jid(),
-		  undefined | binary(), undefined | binary()) ->
+		  jid(), jid(), binary(), binary()) ->
 			 {error, error()} | {result, [disco_item()]}.
-disco_items(empty, _From, _To, undefined, _Lang) ->
+disco_items(empty, _From, _To, <<"">>, _Lang) ->
     {result, []};
 disco_items(empty, _From, _To, _Node, Lang) ->
     {error, xmpp:err_item_not_found(<<"No services available">>, Lang)};
@@ -243,12 +241,11 @@ disco_items(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
 -spec disco_features({error, error()} | {result, [binary()]} | empty,
-		     jid(), jid(),
-		     undefined | binary(), undefined | binary()) ->
+		     jid(), jid(), binary(), binary()) ->
 			    {error, error()} | {result, [binary()]}.
 disco_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
     Acc;
-disco_features(Acc, _From, _To, undefined, _Lang) ->
+disco_features(Acc, _From, _To, <<"">>, _Lang) ->
     Features = case Acc of
 		   {result, Fs} -> Fs;
 		   empty -> []
@@ -261,9 +258,9 @@ disco_features(empty, _From, _To, _Node, Lang) ->
 disco_features(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
--spec disco_identity([identity()], jid(), jid(), undefined | binary(),
-		     undefined | binary()) -> [identity()].
-disco_identity(Acc, _From, _To, undefined, Lang) ->
+-spec disco_identity([identity()], jid(), jid(),
+		     binary(),  binary()) -> [identity()].
+disco_identity(Acc, _From, _To, <<"">>, Lang) ->
     [#identity{category = <<"directory">>,
 	       type = <<"user">>,
 	       name = translate:translate(Lang, <<"vCard User Search">>)}|Acc];
@@ -362,7 +359,7 @@ string2lower(String) ->
       error -> str:to_lower(String)
     end.
 
--spec mk_tfield(binary(), binary(), undefined | binary()) -> xdata_field().
+-spec mk_tfield(binary(), binary(), binary()) -> xdata_field().
 mk_tfield(Label, Var, Lang) ->
     #xdata_field{type = 'text-single',
 		 label = translate:translate(Lang, Label),
@@ -372,7 +369,7 @@ mk_tfield(Label, Var, Lang) ->
 mk_field(Var, Val) ->
     #xdata_field{var = Var, values = [Val]}.
 
--spec mk_search_form(jid(), binary(), undefined | binary()) -> search().
+-spec mk_search_form(jid(), binary(), binary()) -> search().
 mk_search_form(JID, ServerHost, Lang) ->
     Title = <<(translate:translate(Lang, <<"Search users in ">>))/binary,
 	      (jid:to_string(JID))/binary>>,
@@ -393,7 +390,7 @@ mk_search_form(JID, ServerHost, Lang) ->
 		  Lang, <<"You need an x:data capable client to search">>),
 	    xdata = X}.
 
--spec search_result(undefined | binary(), jid(), binary(), [xdata_field()]) -> xdata().
+-spec search_result(binary(), jid(), binary(), [xdata_field()]) -> xdata().
 search_result(Lang, JID, ServerHost, XFields) ->
     Mod = gen_mod:db_mod(ServerHost, ?MODULE),
     Reported = [mk_tfield(Label, Var, Lang) ||
diff --git a/src/translate.erl b/src/translate.erl
index c8a924585..e9f61ab8c 100644
--- a/src/translate.erl
+++ b/src/translate.erl
@@ -126,10 +126,8 @@ load_file_loop(Fd, Line, File, Lang) ->
             ok
     end.
 
--spec translate(binary() | undefined, binary()) -> binary().
+-spec translate(binary(), binary()) -> binary().
 
-translate(undefined, Msg) ->
-    translate(?MYLANG, Msg);
 translate(Lang, Msg) ->
     LLang = ascii_tolower(Lang),
     case ets:lookup(translations, {LLang, Msg}) of
diff --git a/src/xmpp.erl b/src/xmpp.erl
index b43243157..c81474f10 100644
--- a/src/xmpp.erl
+++ b/src/xmpp.erl
@@ -119,15 +119,11 @@ make_error(#xmlel{attrs = Attrs, children = Els} = El, Err) ->
     Attrs3 = lists:keystore(<<"type">>, 1, Attrs2, {<<"type">>, <<"error">>}),
     El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err)]}.
 
--spec get_id(iq() | message() | presence() | xmlel()) -> undefined | binary().
+-spec get_id(iq() | message() | presence() | xmlel()) -> binary().
 get_id(#iq{id = ID}) -> ID;
 get_id(#message{id = ID}) -> ID;
 get_id(#presence{id = ID}) -> ID;
-get_id(#xmlel{attrs = Attrs}) ->
-    case fxml:get_attr(<<"id">>, Attrs) of
-	{value, ID} -> ID;
-	false -> undefined
-    end.
+get_id(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"id">>, Attrs).
 
 -spec get_type(iq()) -> iq_type();
 	      (message()) -> message_type();
@@ -138,15 +134,11 @@ get_type(#message{type = T}) -> T;
 get_type(#presence{type = T}) -> T;
 get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs).
 
--spec get_lang(iq() | message() | presence()) -> undefined | binary().
+-spec get_lang(iq() | message() | presence()) -> binary().
 get_lang(#iq{lang = L}) -> L;
 get_lang(#message{lang = L}) -> L;
 get_lang(#presence{lang = L}) -> L;
-get_lang(#xmlel{attrs = Attrs}) ->
-    case fxml:get_attr(<<"xml:lang">>, Attrs) of
-	{value, L} -> L;
-	false -> undefined
-    end.
+get_lang(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"xml:lang">>, Attrs).
 
 -spec get_from(iq() | message() | presence()) -> undefined | jid:jid().
 get_from(#iq{from = J}) -> J;
@@ -371,14 +363,13 @@ has_subtag([], _, _) ->
 
 -spec get_text([text()]) -> binary().
 get_text([]) -> <<"">>;
-get_text([#text{data = undefined}|_]) -> <<"">>;
 get_text([#text{data = Data}|_]) -> Data.
 
 -spec mk_text(binary()) -> [text()].
 mk_text(Text) ->
-    mk_text(Text, undefined).
+    mk_text(Text, <<"">>).
 
--spec mk_text(binary(), binary() | undefined) -> [text()].
+-spec mk_text(binary(), binary()) -> [text()].
 mk_text(<<"">>, _) ->
     [];
 mk_text(Text, Lang) ->
@@ -396,7 +387,7 @@ pp(Term) ->
 err_bad_request() ->
     err(modify, 'bad-request', 400).
 
--spec err_bad_request(binary(), binary() | undefined) -> error().
+-spec err_bad_request(binary(), binary()) -> error().
 err_bad_request(Text, Lang) ->
     err(modify, 'bad-request', 400, Text, Lang).
 
@@ -404,7 +395,7 @@ err_bad_request(Text, Lang) ->
 err_conflict() ->
     err(cancel, 'conflict', 409).
 
--spec err_conflict(binary(), binary() | undefined) -> error().
+-spec err_conflict(binary(), binary()) -> error().
 err_conflict(Text, Lang) ->
     err(cancel, 'conflict', 409, Text, Lang).
 
@@ -412,7 +403,7 @@ err_conflict(Text, Lang) ->
 err_feature_not_implemented() ->
     err(cancel, 'feature-not-implemented', 501).
 
--spec err_feature_not_implemented(binary(), binary() | undefined) -> error().
+-spec err_feature_not_implemented(binary(), binary()) -> error().
 err_feature_not_implemented(Text, Lang) ->
     err(cancel, 'feature-not-implemented', 501, Text, Lang).
 
@@ -420,7 +411,7 @@ err_feature_not_implemented(Text, Lang) ->
 err_forbidden() ->
     err(auth, 'forbidden', 403).
 
--spec err_forbidden(binary(), binary() | undefined) -> error().
+-spec err_forbidden(binary(), binary()) -> error().
 err_forbidden(Text, Lang) ->
     err(auth, 'forbidden', 403, Text, Lang).
 
@@ -430,7 +421,7 @@ err_forbidden(Text, Lang) ->
 err_gone() ->
     err(modify, 'gone', 302).
 
--spec err_gone(binary(), binary() | undefined) -> error().
+-spec err_gone(binary(), binary()) -> error().
 err_gone(Text, Lang) ->
     err(modify, 'gone', 302, Text, Lang).
 
@@ -440,7 +431,7 @@ err_gone(Text, Lang) ->
 err_internal_server_error() ->
     err(wait, 'internal-server-error', 500).
 
--spec err_internal_server_error(binary(), binary() | undefined) -> error().
+-spec err_internal_server_error(binary(), binary()) -> error().
 err_internal_server_error(Text, Lang) ->
     err(wait, 'internal-server-error', 500, Text, Lang).
 
@@ -448,7 +439,7 @@ err_internal_server_error(Text, Lang) ->
 err_item_not_found() ->
     err(cancel, 'item-not-found', 404).
 
--spec err_item_not_found(binary(), binary() | undefined) -> error().
+-spec err_item_not_found(binary(), binary()) -> error().
 err_item_not_found(Text, Lang) ->
     err(cancel, 'item-not-found', 404, Text, Lang).
 
@@ -456,7 +447,7 @@ err_item_not_found(Text, Lang) ->
 err_jid_malformed() ->
     err(modify, 'jid-malformed', 400).
 
--spec err_jid_malformed(binary(), binary() | undefined) -> error().
+-spec err_jid_malformed(binary(), binary()) -> error().
 err_jid_malformed(Text, Lang) ->
     err(modify, 'jid-malformed', 400, Text, Lang).
 
@@ -464,7 +455,7 @@ err_jid_malformed(Text, Lang) ->
 err_not_acceptable() ->
     err(modify, 'not-acceptable', 406).
 
--spec err_not_acceptable(binary(), binary() | undefined) -> error().
+-spec err_not_acceptable(binary(), binary()) -> error().
 err_not_acceptable(Text, Lang) ->
     err(modify, 'not-acceptable', 406, Text, Lang).
 
@@ -472,7 +463,7 @@ err_not_acceptable(Text, Lang) ->
 err_not_allowed() ->
     err(cancel, 'not-allowed', 405).
 
--spec err_not_allowed(binary(), binary() | undefined) -> error().
+-spec err_not_allowed(binary(), binary()) -> error().
 err_not_allowed(Text, Lang) ->
     err(cancel, 'not-allowed', 405, Text, Lang).
 
@@ -480,7 +471,7 @@ err_not_allowed(Text, Lang) ->
 err_not_authorized() ->
     err(auth, 'not-authorized', 401).
 
--spec err_not_authorized(binary(), binary() | undefined) -> error().
+-spec err_not_authorized(binary(), binary()) -> error().
 err_not_authorized(Text, Lang) ->
     err(auth, 'not-authorized', 401, Text, Lang).
 
@@ -488,7 +479,7 @@ err_not_authorized(Text, Lang) ->
 err_payment_required() ->
     err(auth, 'not-authorized', 402).
 
--spec err_payment_required(binary(), binary() | undefined) -> error().
+-spec err_payment_required(binary(), binary()) -> error().
 err_payment_required(Text, Lang) ->
     err(auth, 'not-authorized', 402, Text, Lang).
 
@@ -498,7 +489,7 @@ err_payment_required(Text, Lang) ->
 err_policy_violation() ->
     err(modify, 'policy-violation', 403).
 
--spec err_policy_violation(binary(), binary() | undefined) -> error().
+-spec err_policy_violation(binary(), binary()) -> error().
 err_policy_violation(Text, Lang) ->
     err(modify, 'policy-violation', 403, Text, Lang).
 
@@ -506,7 +497,7 @@ err_policy_violation(Text, Lang) ->
 err_recipient_unavailable() ->
     err(wait, 'recipient-unavailable', 404).
 
--spec err_recipient_unavailable(binary(), binary() | undefined) -> error().
+-spec err_recipient_unavailable(binary(), binary()) -> error().
 err_recipient_unavailable(Text, Lang) ->
     err(wait, 'recipient-unavailable', 404, Text, Lang).
 
@@ -514,7 +505,7 @@ err_recipient_unavailable(Text, Lang) ->
 err_redirect() ->
     err(modify, 'redirect', 302).
 
--spec err_redirect(binary(), binary() | undefined) -> error().
+-spec err_redirect(binary(), binary()) -> error().
 err_redirect(Text, Lang) ->
     err(modify, 'redirect', 302, Text, Lang).
 
@@ -522,7 +513,7 @@ err_redirect(Text, Lang) ->
 err_registration_required() ->
     err(auth, 'registration-required', 407).
 
--spec err_registration_required(binary(), binary() | undefined) -> error().
+-spec err_registration_required(binary(), binary()) -> error().
 err_registration_required(Text, Lang) ->
     err(auth, 'registration-required', 407, Text, Lang).
 
@@ -530,7 +521,7 @@ err_registration_required(Text, Lang) ->
 err_remote_server_not_found() ->
     err(cancel, 'remote-server-not-found', 404).
 
--spec err_remote_server_not_found(binary(), binary() | undefined) -> error().
+-spec err_remote_server_not_found(binary(), binary()) -> error().
 err_remote_server_not_found(Text, Lang) ->
     err(cancel, 'remote-server-not-found', 404, Text, Lang).
 
@@ -538,7 +529,7 @@ err_remote_server_not_found(Text, Lang) ->
 err_remote_server_timeout() ->
     err(wait, 'remote-server-timeout', 504).
 
--spec err_remote_server_timeout(binary(), binary() | undefined) -> error().
+-spec err_remote_server_timeout(binary(), binary()) -> error().
 err_remote_server_timeout(Text, Lang) ->
     err(wait, 'remote-server-timeout', 504, Text, Lang).
 
@@ -546,7 +537,7 @@ err_remote_server_timeout(Text, Lang) ->
 err_resource_constraint() ->
     err(wait, 'resource-constraint', 500).
 
--spec err_resource_constraint(binary(), binary() | undefined) -> error().
+-spec err_resource_constraint(binary(), binary()) -> error().
 err_resource_constraint(Text, Lang) ->
     err(wait, 'resource-constraint', 500, Text, Lang).
 
@@ -554,7 +545,7 @@ err_resource_constraint(Text, Lang) ->
 err_service_unavailable() ->
     err(cancel, 'service-unavailable', 503).
 
--spec err_service_unavailable(binary(), binary() | undefined) -> error().
+-spec err_service_unavailable(binary(), binary()) -> error().
 err_service_unavailable(Text, Lang) ->
     err(cancel, 'service-unavailable', 503, Text, Lang).
 
@@ -562,7 +553,7 @@ err_service_unavailable(Text, Lang) ->
 err_subscription_required() ->
     err(auth, 'subscription-required', 407).
 
--spec err_subscription_required(binary(), binary() | undefined) -> error().
+-spec err_subscription_required(binary(), binary()) -> error().
 err_subscription_required(Text, Lang) ->
     err(auth, 'subscription-required', 407, Text, Lang).
 
@@ -574,7 +565,7 @@ err_undefined_condition(Type) ->
     err(Type, 'undefined-condition', 500).
 
 -spec err_undefined_condition('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
-			      binary(), binary() | undefined) -> error().
+			      binary(), binary()) -> error().
 err_undefined_condition(Type, Text, Lang) ->
     err(Type, 'undefined-condition', 500, Text, Lang).
 
@@ -584,7 +575,7 @@ err_undefined_condition(Type, Text, Lang) ->
 err_unexpected_request() ->
     err(wait, 'unexpected-request', 400).
 
--spec err_unexpected_request(binary(), binary() | undefined) -> error().
+-spec err_unexpected_request(binary(), binary()) -> error().
 err_unexpected_request(Text, Lang) ->
     err(wait, 'unexpected-request', 400, Text, Lang).
 
@@ -595,7 +586,7 @@ err_unexpected_request(Text, Lang) ->
 serr_bad_format() ->
     serr('bad-format').
 
--spec serr_bad_format(binary(), binary() | undefined) -> stream_error().
+-spec serr_bad_format(binary(), binary()) -> stream_error().
 serr_bad_format(Text, Lang) ->
     serr('bad-format', Text, Lang).
 
@@ -603,7 +594,7 @@ serr_bad_format(Text, Lang) ->
 serr_bad_namespace_prefix() ->
     serr('bad-namespace-prefix').
 
--spec serr_bad_namespace_prefix(binary(), binary() | undefined) -> stream_error().
+-spec serr_bad_namespace_prefix(binary(), binary()) -> stream_error().
 serr_bad_namespace_prefix(Text, Lang) ->
     serr('bad-namespace-prefix', Text, Lang).
 
@@ -611,7 +602,7 @@ serr_bad_namespace_prefix(Text, Lang) ->
 serr_conflict() ->
     serr('conflict').
 
--spec serr_conflict(binary(), binary() | undefined) -> stream_error().
+-spec serr_conflict(binary(), binary()) -> stream_error().
 serr_conflict(Text, Lang) ->
     serr('conflict', Text, Lang).
 
@@ -619,7 +610,7 @@ serr_conflict(Text, Lang) ->
 serr_connection_timeout() ->
     serr('connection-timeout').
 
--spec serr_connection_timeout(binary(), binary() | undefined) -> stream_error().
+-spec serr_connection_timeout(binary(), binary()) -> stream_error().
 serr_connection_timeout(Text, Lang) ->
     serr('connection-timeout', Text, Lang).
 
@@ -627,7 +618,7 @@ serr_connection_timeout(Text, Lang) ->
 serr_host_gone() ->
     serr('host-gone').
 
--spec serr_host_gone(binary(), binary() | undefined) -> stream_error().
+-spec serr_host_gone(binary(), binary()) -> stream_error().
 serr_host_gone(Text, Lang) ->
     serr('host-gone', Text, Lang).
 
@@ -635,7 +626,7 @@ serr_host_gone(Text, Lang) ->
 serr_host_unknown() ->
     serr('host-unknown').
 
--spec serr_host_unknown(binary(), binary() | undefined) -> stream_error().
+-spec serr_host_unknown(binary(), binary()) -> stream_error().
 serr_host_unknown(Text, Lang) ->
     serr('host-unknown', Text, Lang).
 
@@ -643,7 +634,7 @@ serr_host_unknown(Text, Lang) ->
 serr_improper_addressing() ->
     serr('improper-addressing').
 
--spec serr_improper_addressing(binary(), binary() | undefined) -> stream_error().
+-spec serr_improper_addressing(binary(), binary()) -> stream_error().
 serr_improper_addressing(Text, Lang) ->
     serr('improper-addressing', Text, Lang).
 
@@ -651,7 +642,7 @@ serr_improper_addressing(Text, Lang) ->
 serr_internal_server_error() ->
     serr('internal-server-error').
 
--spec serr_internal_server_error(binary(), binary() | undefined) -> stream_error().
+-spec serr_internal_server_error(binary(), binary()) -> stream_error().
 serr_internal_server_error(Text, Lang) ->
     serr('internal-server-error', Text, Lang).
 
@@ -659,7 +650,7 @@ serr_internal_server_error(Text, Lang) ->
 serr_invalid_from() ->
     serr('invalid-from').
 
--spec serr_invalid_from(binary(), binary() | undefined) -> stream_error().
+-spec serr_invalid_from(binary(), binary()) -> stream_error().
 serr_invalid_from(Text, Lang) ->
     serr('invalid-from', Text, Lang).
 
@@ -667,7 +658,7 @@ serr_invalid_from(Text, Lang) ->
 serr_invalid_id() ->
     serr('invalid-id').
 
--spec serr_invalid_id(binary(), binary() | undefined) -> stream_error().
+-spec serr_invalid_id(binary(), binary()) -> stream_error().
 serr_invalid_id(Text, Lang) ->
     serr('invalid-id', Text, Lang).
 
@@ -675,7 +666,7 @@ serr_invalid_id(Text, Lang) ->
 serr_invalid_namespace() ->
     serr('invalid-namespace').
 
--spec serr_invalid_namespace(binary(), binary() | undefined) -> stream_error().
+-spec serr_invalid_namespace(binary(), binary()) -> stream_error().
 serr_invalid_namespace(Text, Lang) ->
     serr('invalid-namespace', Text, Lang).
 
@@ -683,7 +674,7 @@ serr_invalid_namespace(Text, Lang) ->
 serr_invalid_xml() ->
     serr('invalid-xml').
 
--spec serr_invalid_xml(binary(), binary() | undefined) -> stream_error().
+-spec serr_invalid_xml(binary(), binary()) -> stream_error().
 serr_invalid_xml(Text, Lang) ->
     serr('invalid-xml', Text, Lang).
 
@@ -691,7 +682,7 @@ serr_invalid_xml(Text, Lang) ->
 serr_not_authorized() ->
     serr('not-authorized').
 
--spec serr_not_authorized(binary(), binary() | undefined) -> stream_error().
+-spec serr_not_authorized(binary(), binary()) -> stream_error().
 serr_not_authorized(Text, Lang) ->
     serr('not-authorized', Text, Lang).
 
@@ -699,7 +690,7 @@ serr_not_authorized(Text, Lang) ->
 serr_not_well_formed() ->
     serr('not-well-formed').
 
--spec serr_not_well_formed(binary(), binary() | undefined) -> stream_error().
+-spec serr_not_well_formed(binary(), binary()) -> stream_error().
 serr_not_well_formed(Text, Lang) ->
     serr('not-well-formed', Text, Lang).
 
@@ -707,7 +698,7 @@ serr_not_well_formed(Text, Lang) ->
 serr_policy_violation() ->
     serr('policy-violation').
 
--spec serr_policy_violation(binary(), binary() | undefined) -> stream_error().
+-spec serr_policy_violation(binary(), binary()) -> stream_error().
 serr_policy_violation(Text, Lang) ->
     serr('policy-violation', Text, Lang).
 
@@ -715,7 +706,7 @@ serr_policy_violation(Text, Lang) ->
 serr_remote_connection_failed() ->
     serr('remote-connection-failed').
 
--spec serr_remote_connection_failed(binary(), binary() | undefined) -> stream_error().
+-spec serr_remote_connection_failed(binary(), binary()) -> stream_error().
 serr_remote_connection_failed(Text, Lang) ->
     serr('remote-connection-failed', Text, Lang).
 
@@ -723,7 +714,7 @@ serr_remote_connection_failed(Text, Lang) ->
 serr_reset() ->
     serr('reset').
 
--spec serr_reset(binary(), binary() | undefined) -> stream_error().
+-spec serr_reset(binary(), binary()) -> stream_error().
 serr_reset(Text, Lang) ->
     serr('reset', Text, Lang).
 
@@ -731,7 +722,7 @@ serr_reset(Text, Lang) ->
 serr_resource_constraint() ->
     serr('resource-constraint').
 
--spec serr_resource_constraint(binary(), binary() | undefined) -> stream_error().
+-spec serr_resource_constraint(binary(), binary()) -> stream_error().
 serr_resource_constraint(Text, Lang) ->
     serr('resource-constraint', Text, Lang).
 
@@ -739,7 +730,7 @@ serr_resource_constraint(Text, Lang) ->
 serr_restricted_xml() ->
     serr('restricted-xml').
 
--spec serr_restricted_xml(binary(), binary() | undefined) -> stream_error().
+-spec serr_restricted_xml(binary(), binary()) -> stream_error().
 serr_restricted_xml(Text, Lang) ->
     serr('restricted-xml', Text, Lang).
 
@@ -747,7 +738,7 @@ serr_restricted_xml(Text, Lang) ->
 serr_see_other_host() ->
     serr('see-other-host').
 
--spec serr_see_other_host(binary(), binary() | undefined) -> stream_error().
+-spec serr_see_other_host(binary(), binary()) -> stream_error().
 serr_see_other_host(Text, Lang) ->
     serr('see-other-host', Text, Lang).
 
@@ -755,7 +746,7 @@ serr_see_other_host(Text, Lang) ->
 serr_system_shutdown() ->
     serr('system-shutdown').
 
--spec serr_system_shutdown(binary(), binary() | undefined) -> stream_error().
+-spec serr_system_shutdown(binary(), binary()) -> stream_error().
 serr_system_shutdown(Text, Lang) ->
     serr('system-shutdown', Text, Lang).
 
@@ -763,7 +754,7 @@ serr_system_shutdown(Text, Lang) ->
 serr_undefined_condition() ->
     serr('undefined-condition').
 
--spec serr_undefined_condition(binary(), binary() | undefined) -> stream_error().
+-spec serr_undefined_condition(binary(), binary()) -> stream_error().
 serr_undefined_condition(Text, Lang) ->
     serr('undefined-condition', Text, Lang).
 
@@ -771,7 +762,7 @@ serr_undefined_condition(Text, Lang) ->
 serr_unsupported_encoding() ->
     serr('unsupported-encoding').
 
--spec serr_unsupported_encoding(binary(), binary() | undefined) -> stream_error().
+-spec serr_unsupported_encoding(binary(), binary()) -> stream_error().
 serr_unsupported_encoding(Text, Lang) ->
     serr('unsupported-encoding', Text, Lang).
 
@@ -779,7 +770,7 @@ serr_unsupported_encoding(Text, Lang) ->
 serr_unsupported_stanza_type() ->
     serr('unsupported-stanza-type').
 
--spec serr_unsupported_stanza_type(binary(), binary() | undefined) -> stream_error().
+-spec serr_unsupported_stanza_type(binary(), binary()) -> stream_error().
 serr_unsupported_stanza_type(Text, Lang) ->
     serr('unsupported-stanza-type', Text, Lang).
 
@@ -787,7 +778,7 @@ serr_unsupported_stanza_type(Text, Lang) ->
 serr_unsupported_version() ->
     serr('unsupported-version').
 
--spec serr_unsupported_version(binary(), binary() | undefined) -> stream_error().
+-spec serr_unsupported_version(binary(), binary()) -> stream_error().
 serr_unsupported_version(Text, Lang) ->
     serr('unsupported-version', Text, Lang).
 
@@ -801,7 +792,7 @@ err(Type, Reason, Code) ->
 
 -spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
 	  atom() | gone() | redirect(), non_neg_integer(),
-	  binary(), binary() | undefined) -> error().
+	  binary(), binary()) -> error().
 err(Type, Reason, Code, Text, Lang) ->
     #error{type = Type, reason = Reason, code = Code,
 	   text = #text{lang = Lang,
@@ -812,7 +803,7 @@ serr(Reason) ->
     #stream_error{reason = Reason}.
 
 -spec serr(atom() | 'see-other-host'(), binary(),
-	   binary() | undefined) -> stream_error().
+	   binary()) -> stream_error().
 serr(Reason, Text, Lang) ->
     #stream_error{reason = Reason,
 		  text = #text{lang = Lang,
diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl
index e0a5d47c9..905e48f3c 100644
--- a/src/xmpp_codec.erl
+++ b/src/xmpp_codec.erl
@@ -2399,7 +2399,7 @@ encode({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _,
 	   Vcard) ->
     encode_vcard_temp(Vcard,
 		      [{<<"xmlns">>, <<"vcard-temp">>}]);
-encode({vcard_xupdate, undefined, _} = X) ->
+encode({vcard_xupdate, _, _} = X) ->
     encode_vcard_xupdate(X,
 			 [{<<"xmlns">>, <<"vcard-temp:x:update">>}]);
 encode({xdata_option, _, _} = Option) ->
@@ -2801,7 +2801,7 @@ get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _,
 	  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
 	  _}) ->
     <<"vCard">>;
-get_name({vcard_xupdate, undefined, _}) -> <<"x">>;
+get_name({vcard_xupdate, _, _}) -> <<"x">>;
 get_name({xdata_option, _, _}) -> <<"option">>;
 get_name({xdata_field, _, _, _, _, _, _, _, _}) ->
     <<"field">>;
@@ -3033,7 +3033,7 @@ get_ns({vcard_key, _, _}) -> <<"vcard-temp">>;
 get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _,
 	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) ->
     <<"vcard-temp">>;
-get_ns({vcard_xupdate, undefined, _}) ->
+get_ns({vcard_xupdate, _, _}) ->
     <<"vcard-temp:x:update">>;
 get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>;
 get_ns({xdata_field, _, _, _, _, _, _, _, _}) ->
@@ -3331,7 +3331,6 @@ pp(vcard_temp, 29) ->
      email, jabberid, mailer, tz, geo, title, role, logo,
      org, categories, note, prodid, rev, sort_string, sound,
      uid, url, class, key, desc];
-pp(vcard_xupdate, 2) -> [us, hash];
 pp(xdata_option, 2) -> [label, value];
 pp(xdata_field, 8) ->
     [label, type, var, required, desc, values, options,
@@ -3355,7 +3354,6 @@ pp(pubsub, 8) ->
     [subscriptions, affiliations, publish, subscribe,
      unsubscribe, options, items, retract];
 pp(shim, 1) -> [headers];
-pp(chatstate, 1) -> [type];
 pp(delay, 3) -> [stamp, from, desc];
 pp(streamhost, 3) -> [jid, host, port];
 pp(bytestreams, 6) ->
@@ -3396,7 +3394,6 @@ pp(carbons_private, 0) -> [];
 pp(carbons_received, 1) -> [forwarded];
 pp(carbons_sent, 1) -> [forwarded];
 pp(feature_csi, 1) -> [xmlns];
-pp(csi, 1) -> [type];
 pp(feature_sm, 1) -> [xmlns];
 pp(sm_enable, 3) -> [max, resume, xmlns];
 pp(sm_enabled, 5) -> [id, location, max, resume, xmlns];
@@ -3410,7 +3407,6 @@ pp(offline, 3) -> [items, purge, fetch];
 pp(mix_join, 2) -> [jid, subscribe];
 pp(mix_leave, 0) -> [];
 pp(mix_participant, 2) -> [jid, nick];
-pp(hint, 1) -> [type];
 pp(search_item, 5) -> [jid, first, last, nick, email];
 pp(search, 7) ->
     [instructions, first, last, nick, email, items, xdata];
@@ -3445,6 +3441,27 @@ pp(upload_slot, 3) -> [get, put, xmlns];
 pp(thumbnail, 4) -> [uri, 'media-type', width, height];
 pp(_, _) -> no.
 
+enc_host_port(Host) when is_binary(Host) -> Host;
+enc_host_port({{_, _, _, _, _, _, _, _} = IPv6,
+	       Port}) ->
+    enc_host_port({<<$[, (enc_ip(IPv6))/binary, $]>>,
+		   Port});
+enc_host_port({{_, _, _, _} = IPv4, Port}) ->
+    enc_host_port({enc_ip(IPv4), Port});
+enc_host_port({Host, Port}) ->
+    <>;
+enc_host_port(Addr) -> enc_ip(Addr).
+
+dec_host_port(<<$[, T/binary>>) ->
+    [IP, <<$:, Port/binary>>] = binary:split(T, <<$]>>),
+    {dec_ip(IP), dec_int(Port, 0, 65535)};
+dec_host_port(S) ->
+    case binary:split(S, <<$:>>) of
+      [S] -> try dec_ip(S) catch _:_ -> S end;
+      [S, P] ->
+	  {try dec_ip(S) catch _:_ -> S end, dec_int(P, 0, 65535)}
+    end.
+
 enc_ip({0, 0, 0, 0, 0, 65535, A, B}) ->
     enc_ip({(A bsr 8) band 255, A band 255,
 	    (B bsr 8) band 255, B band 255});
@@ -3693,10 +3710,10 @@ encode_upload_slot({upload_slot, Get, Put, Xmlns},
     [encode_upload_get(Get, []) | _acc].
 
 decode_upload_slot_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_upload_slot_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_upload_slot_attr_xmlns(undefined, _acc) -> _acc;
+encode_upload_slot_attr_xmlns(<<>>, _acc) -> _acc;
 encode_upload_slot_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -3916,12 +3933,11 @@ encode_upload_request({upload_request, Filename, Size,
 
 decode_upload_request_attr_xmlns(__TopXMLNS,
 				 undefined) ->
-    undefined;
+    <<>>;
 decode_upload_request_attr_xmlns(__TopXMLNS, _val) ->
     _val.
 
-encode_upload_request_attr_xmlns(undefined, _acc) ->
-    _acc;
+encode_upload_request_attr_xmlns(<<>>, _acc) -> _acc;
 encode_upload_request_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -4094,11 +4110,10 @@ encode_sic({sic, Ip, Port, Xmlns}, _xmlns_attrs) ->
 'encode_sic_$port'(Port, _acc) ->
     [encode_sip_port(Port, []) | _acc].
 
-decode_sic_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+decode_sic_attr_xmlns(__TopXMLNS, undefined) -> <<>>;
 decode_sic_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sic_attr_xmlns(undefined, _acc) -> _acc;
+encode_sic_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sic_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -4571,10 +4586,10 @@ encode_bob_data_attr_cid(_val, _acc) ->
     [{<<"max-age">>, enc_int(_val)} | _acc].
 
 decode_bob_data_attr_type(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_bob_data_attr_type(__TopXMLNS, _val) -> _val.
 
-encode_bob_data_attr_type(undefined, _acc) -> _acc;
+encode_bob_data_attr_type(<<>>, _acc) -> _acc;
 encode_bob_data_attr_type(_val, _acc) ->
     [{<<"type">>, _val} | _acc].
 
@@ -4707,11 +4722,11 @@ encode_stream_start_attr_to(_val, _acc) ->
     [{<<"to">>, enc_jid(_val)} | _acc].
 
 decode_stream_start_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_stream_start_attr_xmlns(__TopXMLNS, _val) ->
     _val.
 
-encode_stream_start_attr_xmlns(undefined, _acc) -> _acc;
+encode_stream_start_attr_xmlns(<<>>, _acc) -> _acc;
 encode_stream_start_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -5207,24 +5222,23 @@ encode_adhoc_command_attr_node(_val, _acc) ->
 
 'decode_adhoc_command_attr_xml:lang'(__TopXMLNS,
 				     undefined) ->
-    undefined;
+    <<>>;
 'decode_adhoc_command_attr_xml:lang'(__TopXMLNS,
 				     _val) ->
     _val.
 
-'encode_adhoc_command_attr_xml:lang'(undefined, _acc) ->
+'encode_adhoc_command_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_adhoc_command_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
 decode_adhoc_command_attr_sessionid(__TopXMLNS,
 				    undefined) ->
-    undefined;
+    <<>>;
 decode_adhoc_command_attr_sessionid(__TopXMLNS, _val) ->
     _val.
 
-encode_adhoc_command_attr_sessionid(undefined, _acc) ->
-    _acc;
+encode_adhoc_command_attr_sessionid(<<>>, _acc) -> _acc;
 encode_adhoc_command_attr_sessionid(_val, _acc) ->
     [{<<"sessionid">>, _val} | _acc].
 
@@ -5723,19 +5737,17 @@ encode_address_attr_jid(undefined, _acc) -> _acc;
 encode_address_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_address_attr_desc(__TopXMLNS, undefined) ->
-    undefined;
+decode_address_attr_desc(__TopXMLNS, undefined) -> <<>>;
 decode_address_attr_desc(__TopXMLNS, _val) -> _val.
 
-encode_address_attr_desc(undefined, _acc) -> _acc;
+encode_address_attr_desc(<<>>, _acc) -> _acc;
 encode_address_attr_desc(_val, _acc) ->
     [{<<"desc">>, _val} | _acc].
 
-decode_address_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+decode_address_attr_node(__TopXMLNS, undefined) -> <<>>;
 decode_address_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_address_attr_node(undefined, _acc) -> _acc;
+encode_address_attr_node(<<>>, _acc) -> _acc;
 encode_address_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -6001,10 +6013,10 @@ encode_xevent_id(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"id">>, _attrs, _els}.
 
-decode_xevent_id_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_xevent_id_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_xevent_id_cdata(__TopXMLNS, _val) -> _val.
 
-encode_xevent_id_cdata(undefined, _acc) -> _acc;
+encode_xevent_id_cdata(<<>>, _acc) -> _acc;
 encode_xevent_id_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -6519,12 +6531,11 @@ encode_search_instructions(Cdata, _xmlns_attrs) ->
     {xmlel, <<"instructions">>, _attrs, _els}.
 
 decode_search_instructions_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_search_instructions_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_search_instructions_cdata(undefined, _acc) ->
-    _acc;
+encode_search_instructions_cdata(<<>>, _acc) -> _acc;
 encode_search_instructions_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -6641,12 +6652,11 @@ encode_mix_participant_attr_jid(_val, _acc) ->
 
 decode_mix_participant_attr_nick(__TopXMLNS,
 				 undefined) ->
-    undefined;
+    <<>>;
 decode_mix_participant_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_mix_participant_attr_nick(undefined, _acc) ->
-    _acc;
+encode_mix_participant_attr_nick(<<>>, _acc) -> _acc;
 encode_mix_participant_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -6889,10 +6899,10 @@ encode_offline_item({offline_item, Node, Action},
     {xmlel, <<"item">>, _attrs, _els}.
 
 decode_offline_item_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_offline_item_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_offline_item_attr_node(undefined, _acc) -> _acc;
+encode_offline_item_attr_node(<<>>, _acc) -> _acc;
 encode_offline_item_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -7413,10 +7423,10 @@ encode_sm_failed_attr_h(_val, _acc) ->
     [{<<"h">>, enc_int(_val)} | _acc].
 
 decode_sm_failed_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_failed_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_failed_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_failed_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_failed_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7458,11 +7468,10 @@ decode_sm_a_attr_h(__TopXMLNS, _val) ->
 encode_sm_a_attr_h(_val, _acc) ->
     [{<<"h">>, enc_int(_val)} | _acc].
 
-decode_sm_a_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+decode_sm_a_attr_xmlns(__TopXMLNS, undefined) -> <<>>;
 decode_sm_a_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_a_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_a_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_a_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7485,11 +7494,10 @@ encode_sm_r({sm_r, Xmlns}, _xmlns_attrs) ->
     _attrs = encode_sm_r_attr_xmlns(Xmlns, _xmlns_attrs),
     {xmlel, <<"r">>, _attrs, _els}.
 
-decode_sm_r_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+decode_sm_r_attr_xmlns(__TopXMLNS, undefined) -> <<>>;
 decode_sm_r_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_r_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_r_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_r_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7546,10 +7554,10 @@ encode_sm_resumed_attr_h(_val, _acc) ->
     [{<<"h">>, enc_int(_val)} | _acc].
 
 decode_sm_resumed_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_resumed_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_resumed_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_resumed_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_resumed_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7615,10 +7623,10 @@ encode_sm_resume_attr_h(_val, _acc) ->
     [{<<"h">>, enc_int(_val)} | _acc].
 
 decode_sm_resume_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_resume_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_resume_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_resume_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_resume_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7688,29 +7696,28 @@ encode_sm_enabled({sm_enabled, Id, Location, Max,
     {xmlel, <<"enabled">>, _attrs, _els}.
 
 decode_sm_enabled_attr_id(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_enabled_attr_id(__TopXMLNS, _val) -> _val.
 
-encode_sm_enabled_attr_id(undefined, _acc) -> _acc;
+encode_sm_enabled_attr_id(<<>>, _acc) -> _acc;
 encode_sm_enabled_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
 decode_sm_enabled_attr_location(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_sm_enabled_attr_location(__TopXMLNS, _val) ->
     _val.
 
-encode_sm_enabled_attr_location(undefined, _acc) ->
-    _acc;
+encode_sm_enabled_attr_location(<<>>, _acc) -> _acc;
 encode_sm_enabled_attr_location(_val, _acc) ->
     [{<<"location">>, _val} | _acc].
 
 decode_sm_enabled_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_enabled_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_enabled_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_enabled_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_enabled_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7797,10 +7804,10 @@ encode_sm_enable_attr_max(_val, _acc) ->
     [{<<"max">>, enc_int(_val)} | _acc].
 
 decode_sm_enable_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_sm_enable_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_sm_enable_attr_xmlns(undefined, _acc) -> _acc;
+encode_sm_enable_attr_xmlns(<<>>, _acc) -> _acc;
 encode_sm_enable_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7841,10 +7848,10 @@ encode_feature_sm({feature_sm, Xmlns}, _xmlns_attrs) ->
     {xmlel, <<"sm">>, _attrs, _els}.
 
 decode_feature_sm_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_feature_sm_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_feature_sm_attr_xmlns(undefined, _acc) -> _acc;
+encode_feature_sm_attr_xmlns(<<>>, _acc) -> _acc;
 encode_feature_sm_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -7889,10 +7896,10 @@ encode_feature_csi({feature_csi, Xmlns},
     {xmlel, <<"csi">>, _attrs, _els}.
 
 decode_feature_csi_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_feature_csi_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_feature_csi_attr_xmlns(undefined, _acc) -> _acc;
+encode_feature_csi_attr_xmlns(<<>>, _acc) -> _acc;
 encode_feature_csi_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -8137,10 +8144,10 @@ encode_mam_fin({mam_fin, Id, Rsm, Stable, Complete},
      | _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(<<>>, _acc) -> _acc;
 encode_mam_fin_attr_queryid(_val, _acc) ->
     [{<<"queryid">>, _val} | _acc].
 
@@ -8301,10 +8308,10 @@ 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(<<>>, _acc) -> _acc;
 encode_mam_prefs_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -8325,36 +8332,23 @@ decode_mam_always_els(__TopXMLNS, __IgnoreEls,
 	       __TopXMLNS == <<"urn:xmpp:mam:0">>;
 	       __TopXMLNS == <<"urn:xmpp:mam:tmp">> ->
 	  decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_mam_jid(__TopXMLNS, __IgnoreEls,
-						    _el)
-				    of
-				  undefined -> Jids;
-				  _new_el -> [_new_el | Jids]
-				end);
+				[decode_mam_jid(__TopXMLNS, __IgnoreEls, _el)
+				 | Jids]);
       <<"urn:xmpp:mam:0">> ->
 	  decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_mam_jid(<<"urn:xmpp:mam:0">>,
-						    __IgnoreEls, _el)
-				    of
-				  undefined -> Jids;
-				  _new_el -> [_new_el | Jids]
-				end);
+				[decode_mam_jid(<<"urn:xmpp:mam:0">>,
+						__IgnoreEls, _el)
+				 | Jids]);
       <<"urn:xmpp:mam:1">> ->
 	  decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_mam_jid(<<"urn:xmpp:mam:1">>,
-						    __IgnoreEls, _el)
-				    of
-				  undefined -> Jids;
-				  _new_el -> [_new_el | Jids]
-				end);
+				[decode_mam_jid(<<"urn:xmpp:mam:1">>,
+						__IgnoreEls, _el)
+				 | Jids]);
       <<"urn:xmpp:mam:tmp">> ->
 	  decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_mam_jid(<<"urn:xmpp:mam:tmp">>,
-						    __IgnoreEls, _el)
-				    of
-				  undefined -> Jids;
-				  _new_el -> [_new_el | Jids]
-				end);
+				[decode_mam_jid(<<"urn:xmpp:mam:tmp">>,
+						__IgnoreEls, _el)
+				 | Jids]);
       _ ->
 	  decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
 				Jids)
@@ -8392,35 +8386,23 @@ decode_mam_never_els(__TopXMLNS, __IgnoreEls,
 	       __TopXMLNS == <<"urn:xmpp:mam:0">>;
 	       __TopXMLNS == <<"urn:xmpp:mam:tmp">> ->
 	  decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_mam_jid(__TopXMLNS, __IgnoreEls, _el)
-				   of
-				 undefined -> Jids;
-				 _new_el -> [_new_el | Jids]
-			       end);
+			       [decode_mam_jid(__TopXMLNS, __IgnoreEls, _el)
+				| Jids]);
       <<"urn:xmpp:mam:0">> ->
 	  decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_mam_jid(<<"urn:xmpp:mam:0">>,
-						   __IgnoreEls, _el)
-				   of
-				 undefined -> Jids;
-				 _new_el -> [_new_el | Jids]
-			       end);
+			       [decode_mam_jid(<<"urn:xmpp:mam:0">>,
+					       __IgnoreEls, _el)
+				| Jids]);
       <<"urn:xmpp:mam:1">> ->
 	  decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_mam_jid(<<"urn:xmpp:mam:1">>,
-						   __IgnoreEls, _el)
-				   of
-				 undefined -> Jids;
-				 _new_el -> [_new_el | Jids]
-			       end);
+			       [decode_mam_jid(<<"urn:xmpp:mam:1">>,
+					       __IgnoreEls, _el)
+				| Jids]);
       <<"urn:xmpp:mam:tmp">> ->
 	  decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_mam_jid(<<"urn:xmpp:mam:tmp">>,
-						   __IgnoreEls, _el)
-				   of
-				 undefined -> Jids;
-				 _new_el -> [_new_el | Jids]
-			       end);
+			       [decode_mam_jid(<<"urn:xmpp:mam:tmp">>,
+					       __IgnoreEls, _el)
+				| Jids]);
       _ ->
 	  decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
 			       Jids)
@@ -8544,27 +8526,27 @@ encode_mam_result({mam_result, Xmlns, Queryid, Id,
     {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(<<>>, _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(<<>>, _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(<<>>, _acc) -> _acc;
 encode_mam_result_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
@@ -8596,10 +8578,10 @@ encode_mam_archived({mam_archived, By, Id},
     {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(<<>>, _acc) -> _acc;
 encode_mam_archived_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
@@ -8797,18 +8779,18 @@ encode_mam_query({mam_query, Xmlns, Id, Start, End,
      | _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(<<>>, _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(<<>>, _acc) -> _acc;
 encode_mam_query_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -9205,10 +9187,10 @@ 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, <<>>) -> <<>>;
 decode_rsm_first_cdata(__TopXMLNS, _val) -> _val.
 
-encode_rsm_first_cdata(undefined, _acc) -> _acc;
+encode_rsm_first_cdata(<<>>, _acc) -> _acc;
 encode_rsm_first_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -9343,10 +9325,10 @@ encode_rsm_last(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"last">>, _attrs, _els}.
 
-decode_rsm_last_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_last_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_rsm_last_cdata(__TopXMLNS, _val) -> _val.
 
-encode_rsm_last_cdata(undefined, _acc) -> _acc;
+encode_rsm_last_cdata(<<>>, _acc) -> _acc;
 encode_rsm_last_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -9403,10 +9385,10 @@ encode_rsm_after(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"after">>, _attrs, _els}.
 
-decode_rsm_after_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_after_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_rsm_after_cdata(__TopXMLNS, _val) -> _val.
 
-encode_rsm_after_cdata(undefined, _acc) -> _acc;
+encode_rsm_after_cdata(<<>>, _acc) -> _acc;
 encode_rsm_after_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -9540,24 +9522,17 @@ decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls,
       <<"">> when __TopXMLNS == <<"urn:xmpp:mucsub:0">> ->
 	  decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls,
 				       _els,
-				       case decode_muc_subscription(__TopXMLNS,
-								    __IgnoreEls,
-								    _el)
-					   of
-					 undefined -> List;
-					 _new_el -> [_new_el | List]
-				       end);
+				       [decode_muc_subscription(__TopXMLNS,
+								__IgnoreEls,
+								_el)
+					| List]);
       <<"urn:xmpp:mucsub:0">> ->
 	  decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls,
 				       _els,
-				       case
-					 decode_muc_subscription(<<"urn:xmpp:mucsub:0">>,
-								 __IgnoreEls,
-								 _el)
-					   of
-					 undefined -> List;
-					 _new_el -> [_new_el | List]
-				       end);
+				       [decode_muc_subscription(<<"urn:xmpp:mucsub:0">>,
+								__IgnoreEls,
+								_el)
+					| List]);
       _ ->
 	  decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls,
 				       _els, List)
@@ -9913,13 +9888,12 @@ encode_muc_admin_continue(Thread, _xmlns_attrs) ->
 
 decode_muc_admin_continue_attr_thread(__TopXMLNS,
 				      undefined) ->
-    undefined;
+    <<>>;
 decode_muc_admin_continue_attr_thread(__TopXMLNS,
 				      _val) ->
     _val.
 
-encode_muc_admin_continue_attr_thread(undefined,
-				      _acc) ->
+encode_muc_admin_continue_attr_thread(<<>>, _acc) ->
     _acc;
 encode_muc_admin_continue_attr_thread(_val, _acc) ->
     [{<<"thread">>, _val} | _acc].
@@ -9973,12 +9947,11 @@ encode_muc_admin_actor_attr_jid(_val, _acc) ->
 
 decode_muc_admin_actor_attr_nick(__TopXMLNS,
 				 undefined) ->
-    undefined;
+    <<>>;
 decode_muc_admin_actor_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_muc_admin_actor_attr_nick(undefined, _acc) ->
-    _acc;
+encode_muc_admin_actor_attr_nick(<<>>, _acc) -> _acc;
 encode_muc_admin_actor_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -10188,12 +10161,11 @@ encode_muc_admin_item_attr_jid(_val, _acc) ->
 
 decode_muc_admin_item_attr_nick(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_muc_admin_item_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_muc_admin_item_attr_nick(undefined, _acc) ->
-    _acc;
+encode_muc_admin_item_attr_nick(<<>>, _acc) -> _acc;
 encode_muc_admin_item_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -10394,12 +10366,11 @@ encode_muc_owner_item_attr_jid(_val, _acc) ->
 
 decode_muc_owner_item_attr_nick(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_muc_owner_item_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_muc_owner_item_attr_nick(undefined, _acc) ->
-    _acc;
+encode_muc_owner_item_attr_nick(<<>>, _acc) -> _acc;
 encode_muc_owner_item_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -10526,11 +10497,10 @@ encode_muc_password(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"password">>, _attrs, _els}.
 
-decode_muc_password_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_muc_password_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_muc_password_cdata(__TopXMLNS, _val) -> _val.
 
-encode_muc_password_cdata(undefined, _acc) -> _acc;
+encode_muc_password_cdata(<<>>, _acc) -> _acc;
 encode_muc_password_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -10969,11 +10939,11 @@ encode_muc_user_item_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
 decode_muc_user_item_attr_nick(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_muc_user_item_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_muc_user_item_attr_nick(undefined, _acc) -> _acc;
+encode_muc_user_item_attr_nick(<<>>, _acc) -> _acc;
 encode_muc_user_item_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -11042,12 +11012,12 @@ encode_muc_user_continue(Thread, _xmlns_attrs) ->
 
 decode_muc_user_continue_attr_thread(__TopXMLNS,
 				     undefined) ->
-    undefined;
+    <<>>;
 decode_muc_user_continue_attr_thread(__TopXMLNS,
 				     _val) ->
     _val.
 
-encode_muc_user_continue_attr_thread(undefined, _acc) ->
+encode_muc_user_continue_attr_thread(<<>>, _acc) ->
     _acc;
 encode_muc_user_continue_attr_thread(_val, _acc) ->
     [{<<"thread">>, _val} | _acc].
@@ -11099,12 +11069,11 @@ encode_muc_user_actor_attr_jid(_val, _acc) ->
 
 decode_muc_user_actor_attr_nick(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_muc_user_actor_attr_nick(__TopXMLNS, _val) ->
     _val.
 
-encode_muc_user_actor_attr_nick(undefined, _acc) ->
-    _acc;
+encode_muc_user_actor_attr_nick(<<>>, _acc) -> _acc;
 encode_muc_user_actor_attr_nick(_val, _acc) ->
     [{<<"nick">>, _val} | _acc].
 
@@ -11378,10 +11347,10 @@ encode_muc_destroy_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
 decode_muc_destroy_attr_xmlns(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_muc_destroy_attr_xmlns(__TopXMLNS, _val) -> _val.
 
-encode_muc_destroy_attr_xmlns(undefined, _acc) -> _acc;
+encode_muc_destroy_attr_xmlns(<<>>, _acc) -> _acc;
 encode_muc_destroy_attr_xmlns(_val, _acc) ->
     [{<<"xmlns">>, _val} | _acc].
 
@@ -11518,10 +11487,10 @@ encode_muc_reason(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"reason">>, _attrs, _els}.
 
-decode_muc_reason_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_muc_reason_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_muc_reason_cdata(__TopXMLNS, _val) -> _val.
 
-encode_muc_reason_cdata(undefined, _acc) -> _acc;
+encode_muc_reason_cdata(<<>>, _acc) -> _acc;
 encode_muc_reason_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -11781,20 +11750,19 @@ encode_bytestreams({bytestreams, Hosts, Used, Activate,
 
 decode_bytestreams_attr_dstaddr(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_bytestreams_attr_dstaddr(__TopXMLNS, _val) ->
     _val.
 
-encode_bytestreams_attr_dstaddr(undefined, _acc) ->
-    _acc;
+encode_bytestreams_attr_dstaddr(<<>>, _acc) -> _acc;
 encode_bytestreams_attr_dstaddr(_val, _acc) ->
     [{<<"dstaddr">>, _val} | _acc].
 
 decode_bytestreams_attr_sid(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_bytestreams_attr_sid(__TopXMLNS, _val) -> _val.
 
-encode_bytestreams_attr_sid(undefined, _acc) -> _acc;
+encode_bytestreams_attr_sid(<<>>, _acc) -> _acc;
 encode_bytestreams_attr_sid(_val, _acc) ->
     [{<<"sid">>, _val} | _acc].
 
@@ -12206,10 +12174,10 @@ decode_shim_header_attr_name(__TopXMLNS, _val) -> _val.
 encode_shim_header_attr_name(_val, _acc) ->
     [{<<"name">>, _val} | _acc].
 
-decode_shim_header_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_shim_header_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_shim_header_cdata(__TopXMLNS, _val) -> _val.
 
-encode_shim_header_cdata(undefined, _acc) -> _acc;
+encode_shim_header_cdata(<<>>, _acc) -> _acc;
 encode_shim_header_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -12642,23 +12610,21 @@ encode_pubsub_options({pubsub_options, Node, Jid, Subid,
 
 decode_pubsub_options_attr_node(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_options_attr_node(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_options_attr_node(undefined, _acc) ->
-    _acc;
+encode_pubsub_options_attr_node(<<>>, _acc) -> _acc;
 encode_pubsub_options_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
 decode_pubsub_options_attr_subid(__TopXMLNS,
 				 undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_options_attr_subid(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_options_attr_subid(undefined, _acc) ->
-    _acc;
+encode_pubsub_options_attr_subid(<<>>, _acc) -> _acc;
 encode_pubsub_options_attr_subid(_val, _acc) ->
     [{<<"subid">>, _val} | _acc].
 
@@ -12790,23 +12756,22 @@ encode_pubsub_unsubscribe({pubsub_unsubscribe, Node,
 
 decode_pubsub_unsubscribe_attr_node(__TopXMLNS,
 				    undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_unsubscribe_attr_node(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_unsubscribe_attr_node(undefined, _acc) ->
-    _acc;
+encode_pubsub_unsubscribe_attr_node(<<>>, _acc) -> _acc;
 encode_pubsub_unsubscribe_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
 decode_pubsub_unsubscribe_attr_subid(__TopXMLNS,
 				     undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_unsubscribe_attr_subid(__TopXMLNS,
 				     _val) ->
     _val.
 
-encode_pubsub_unsubscribe_attr_subid(undefined, _acc) ->
+encode_pubsub_unsubscribe_attr_subid(<<>>, _acc) ->
     _acc;
 encode_pubsub_unsubscribe_attr_subid(_val, _acc) ->
     [{<<"subid">>, _val} | _acc].
@@ -12861,12 +12826,11 @@ encode_pubsub_subscribe({pubsub_subscribe, Node, Jid},
 
 decode_pubsub_subscribe_attr_node(__TopXMLNS,
 				  undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_subscribe_attr_node(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_subscribe_attr_node(undefined, _acc) ->
-    _acc;
+encode_pubsub_subscribe_attr_node(<<>>, _acc) -> _acc;
 encode_pubsub_subscribe_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -13021,12 +12985,12 @@ encode_pubsub_subscriptions({Node, Subscriptions},
 
 decode_pubsub_subscriptions_attr_node(__TopXMLNS,
 				      undefined) ->
-    none;
+    <<>>;
 decode_pubsub_subscriptions_attr_node(__TopXMLNS,
 				      _val) ->
     _val.
 
-encode_pubsub_subscriptions_attr_node(none, _acc) ->
+encode_pubsub_subscriptions_attr_node(<<>>, _acc) ->
     _acc;
 encode_pubsub_subscriptions_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
@@ -13251,35 +13215,32 @@ encode_pubsub_event_item({pubsub_event_item, Id, Node,
 
 decode_pubsub_event_item_attr_id(__TopXMLNS,
 				 undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_event_item_attr_id(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_event_item_attr_id(undefined, _acc) ->
-    _acc;
+encode_pubsub_event_item_attr_id(<<>>, _acc) -> _acc;
 encode_pubsub_event_item_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
 decode_pubsub_event_item_attr_node(__TopXMLNS,
 				   undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_event_item_attr_node(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_event_item_attr_node(undefined, _acc) ->
-    _acc;
+encode_pubsub_event_item_attr_node(<<>>, _acc) -> _acc;
 encode_pubsub_event_item_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
 decode_pubsub_event_item_attr_publisher(__TopXMLNS,
 					undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_event_item_attr_publisher(__TopXMLNS,
 					_val) ->
     _val.
 
-encode_pubsub_event_item_attr_publisher(undefined,
-					_acc) ->
+encode_pubsub_event_item_attr_publisher(<<>>, _acc) ->
     _acc;
 encode_pubsub_event_item_attr_publisher(_val, _acc) ->
     [{<<"publisher">>, _val} | _acc].
@@ -13421,11 +13382,11 @@ encode_pubsub_items_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
 decode_pubsub_items_attr_subid(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_items_attr_subid(__TopXMLNS, _val) ->
     _val.
 
-encode_pubsub_items_attr_subid(undefined, _acc) -> _acc;
+encode_pubsub_items_attr_subid(<<>>, _acc) -> _acc;
 encode_pubsub_items_attr_subid(_val, _acc) ->
     [{<<"subid">>, _val} | _acc].
 
@@ -13465,10 +13426,10 @@ encode_pubsub_item({pubsub_item, Id, __Xmls},
     {xmlel, <<"item">>, _attrs, _els}.
 
 decode_pubsub_item_attr_id(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_item_attr_id(__TopXMLNS, _val) -> _val.
 
-encode_pubsub_item_attr_id(undefined, _acc) -> _acc;
+encode_pubsub_item_attr_id(<<>>, _acc) -> _acc;
 encode_pubsub_item_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
@@ -13613,25 +13574,24 @@ encode_pubsub_subscription_attr_jid(_val, _acc) ->
 
 decode_pubsub_subscription_attr_node(__TopXMLNS,
 				     undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_subscription_attr_node(__TopXMLNS,
 				     _val) ->
     _val.
 
-encode_pubsub_subscription_attr_node(undefined, _acc) ->
+encode_pubsub_subscription_attr_node(<<>>, _acc) ->
     _acc;
 encode_pubsub_subscription_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
 decode_pubsub_subscription_attr_subid(__TopXMLNS,
 				      undefined) ->
-    undefined;
+    <<>>;
 decode_pubsub_subscription_attr_subid(__TopXMLNS,
 				      _val) ->
     _val.
 
-encode_pubsub_subscription_attr_subid(undefined,
-				      _acc) ->
+encode_pubsub_subscription_attr_subid(<<>>, _acc) ->
     _acc;
 encode_pubsub_subscription_attr_subid(_val, _acc) ->
     [{<<"subid">>, _val} | _acc].
@@ -13679,22 +13639,16 @@ decode_xdata_els(__TopXMLNS, __IgnoreEls,
       <<"">> when __TopXMLNS == <<"jabber:x:data">> ->
 	  decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields,
 			   Items,
-			   case decode_xdata_instructions(__TopXMLNS,
-							  __IgnoreEls, _el)
-			       of
-			     undefined -> Instructions;
-			     _new_el -> [_new_el | Instructions]
-			   end,
+			   [decode_xdata_instructions(__TopXMLNS, __IgnoreEls,
+						      _el)
+			    | Instructions],
 			   Reported, Title);
       <<"jabber:x:data">> ->
 	  decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields,
 			   Items,
-			   case decode_xdata_instructions(<<"jabber:x:data">>,
-							  __IgnoreEls, _el)
-			       of
-			     undefined -> Instructions;
-			     _new_el -> [_new_el | Instructions]
-			   end,
+			   [decode_xdata_instructions(<<"jabber:x:data">>,
+						      __IgnoreEls, _el)
+			    | Instructions],
 			   Reported, Title);
       _ ->
 	  decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields,
@@ -13951,10 +13905,10 @@ encode_xdata_title(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"title">>, _attrs, _els}.
 
-decode_xdata_title_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_xdata_title_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_xdata_title_cdata(__TopXMLNS, _val) -> _val.
 
-encode_xdata_title_cdata(undefined, _acc) -> _acc;
+encode_xdata_title_cdata(<<>>, _acc) -> _acc;
 encode_xdata_title_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -13982,12 +13936,11 @@ encode_xdata_instructions(Cdata, _xmlns_attrs) ->
     {xmlel, <<"instructions">>, _attrs, _els}.
 
 decode_xdata_instructions_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_xdata_instructions_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_xdata_instructions_cdata(undefined, _acc) ->
-    _acc;
+encode_xdata_instructions_cdata(<<>>, _acc) -> _acc;
 encode_xdata_instructions_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -14053,23 +14006,16 @@ decode_xdata_field_els(__TopXMLNS, __IgnoreEls,
       <<"">> when __TopXMLNS == <<"jabber:x:data">> ->
 	  decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els,
 				 Options,
-				 case decode_xdata_field_value(__TopXMLNS,
-							       __IgnoreEls, _el)
-				     of
-				   undefined -> Values;
-				   _new_el -> [_new_el | Values]
-				 end,
+				 [decode_xdata_field_value(__TopXMLNS,
+							   __IgnoreEls, _el)
+				  | Values],
 				 Desc, Required, __Els);
       <<"jabber:x:data">> ->
 	  decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els,
 				 Options,
-				 case
-				   decode_xdata_field_value(<<"jabber:x:data">>,
-							    __IgnoreEls, _el)
-				     of
-				   undefined -> Values;
-				   _new_el -> [_new_el | Values]
-				 end,
+				 [decode_xdata_field_value(<<"jabber:x:data">>,
+							   __IgnoreEls, _el)
+				  | Values],
 				 Desc, Required, __Els);
       _ ->
 	  decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els,
@@ -14175,10 +14121,10 @@ encode_xdata_field({xdata_field, Label, Type, Var,
     [encode_xdata_field_required(Required, []) | _acc].
 
 decode_xdata_field_attr_label(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_xdata_field_attr_label(__TopXMLNS, _val) -> _val.
 
-encode_xdata_field_attr_label(undefined, _acc) -> _acc;
+encode_xdata_field_attr_label(<<>>, _acc) -> _acc;
 encode_xdata_field_attr_label(_val, _acc) ->
     [{<<"label">>, _val} | _acc].
 
@@ -14201,10 +14147,10 @@ encode_xdata_field_attr_type(_val, _acc) ->
     [{<<"type">>, enc_enum(_val)} | _acc].
 
 decode_xdata_field_attr_var(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_xdata_field_attr_var(__TopXMLNS, _val) -> _val.
 
-encode_xdata_field_attr_var(undefined, _acc) -> _acc;
+encode_xdata_field_attr_var(<<>>, _acc) -> _acc;
 encode_xdata_field_attr_var(_val, _acc) ->
     [{<<"var">>, _val} | _acc].
 
@@ -14277,12 +14223,12 @@ encode_xdata_field_option({xdata_option, Label, Value},
 
 decode_xdata_field_option_attr_label(__TopXMLNS,
 				     undefined) ->
-    undefined;
+    <<>>;
 decode_xdata_field_option_attr_label(__TopXMLNS,
 				     _val) ->
     _val.
 
-encode_xdata_field_option_attr_label(undefined, _acc) ->
+encode_xdata_field_option_attr_label(<<>>, _acc) ->
     _acc;
 encode_xdata_field_option_attr_label(_val, _acc) ->
     [{<<"label">>, _val} | _acc].
@@ -14311,11 +14257,11 @@ encode_xdata_field_value(Cdata, _xmlns_attrs) ->
     {xmlel, <<"value">>, _attrs, _els}.
 
 decode_xdata_field_value_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_xdata_field_value_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_xdata_field_value_cdata(undefined, _acc) -> _acc;
+encode_xdata_field_value_cdata(<<>>, _acc) -> _acc;
 encode_xdata_field_value_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -14342,11 +14288,10 @@ encode_xdata_field_desc(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"desc">>, _attrs, _els}.
 
-decode_xdata_field_desc_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_xdata_field_desc_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_xdata_field_desc_cdata(__TopXMLNS, _val) -> _val.
 
-encode_xdata_field_desc_cdata(undefined, _acc) -> _acc;
+encode_xdata_field_desc_cdata(<<>>, _acc) -> _acc;
 encode_xdata_field_desc_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -14363,7 +14308,7 @@ decode_vcard_xupdate(__TopXMLNS, __IgnoreEls,
 		     {xmlel, <<"x">>, _attrs, _els}) ->
     Hash = decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls,
 				    _els, undefined),
-    {vcard_xupdate, undefined, Hash}.
+    {vcard_xupdate, {<<>>, <<>>}, Hash}.
 
 decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, [],
 			 Hash) ->
@@ -14391,7 +14336,7 @@ decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls,
     decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els,
 			     Hash).
 
-encode_vcard_xupdate({vcard_xupdate, undefined, Hash},
+encode_vcard_xupdate({vcard_xupdate, _, Hash},
 		     _xmlns_attrs) ->
     _els = lists:reverse('encode_vcard_xupdate_$hash'(Hash,
 						      [])),
@@ -14426,12 +14371,11 @@ encode_vcard_xupdate_photo(Cdata, _xmlns_attrs) ->
     {xmlel, <<"photo">>, _attrs, _els}.
 
 decode_vcard_xupdate_photo_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_vcard_xupdate_photo_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_vcard_xupdate_photo_cdata(undefined, _acc) ->
-    _acc;
+encode_vcard_xupdate_photo_cdata(<<>>, _acc) -> _acc;
 encode_vcard_xupdate_photo_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -15677,23 +15621,15 @@ decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls,
       <<"">> when __TopXMLNS == <<"vcard-temp">> ->
 	  decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls,
 				      _els,
-				      case decode_vcard_KEYWORD(__TopXMLNS,
-								__IgnoreEls,
-								_el)
-					  of
-					undefined -> Keywords;
-					_new_el -> [_new_el | Keywords]
-				      end);
+				      [decode_vcard_KEYWORD(__TopXMLNS,
+							    __IgnoreEls, _el)
+				       | Keywords]);
       <<"vcard-temp">> ->
 	  decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls,
 				      _els,
-				      case
-					decode_vcard_KEYWORD(<<"vcard-temp">>,
-							     __IgnoreEls, _el)
-					  of
-					undefined -> Keywords;
-					_new_el -> [_new_el | Keywords]
-				      end);
+				      [decode_vcard_KEYWORD(<<"vcard-temp">>,
+							    __IgnoreEls, _el)
+				       | Keywords]);
       _ ->
 	  decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls,
 				      _els, Keywords)
@@ -15909,21 +15845,15 @@ decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls,
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">> when __TopXMLNS == <<"vcard-temp">> ->
 	  decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_vcard_ORGUNIT(__TopXMLNS,
-							 __IgnoreEls, _el)
-				   of
-				 undefined -> Units;
-				 _new_el -> [_new_el | Units]
-			       end,
+			       [decode_vcard_ORGUNIT(__TopXMLNS, __IgnoreEls,
+						     _el)
+				| Units],
 			       Name);
       <<"vcard-temp">> ->
 	  decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els,
-			       case decode_vcard_ORGUNIT(<<"vcard-temp">>,
-							 __IgnoreEls, _el)
-				   of
-				 undefined -> Units;
-				 _new_el -> [_new_el | Units]
-			       end,
+			       [decode_vcard_ORGUNIT(<<"vcard-temp">>,
+						     __IgnoreEls, _el)
+				| Units],
 			       Name);
       _ ->
 	  decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els,
@@ -16157,8 +16087,7 @@ encode_vcard_BINVAL(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"BINVAL">>, _attrs, _els}.
 
-decode_vcard_BINVAL_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_BINVAL_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_BINVAL_cdata(__TopXMLNS, _val) ->
     case catch base64:decode(_val) of
       {'EXIT', _} ->
@@ -16167,7 +16096,7 @@ decode_vcard_BINVAL_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_vcard_BINVAL_cdata(undefined, _acc) -> _acc;
+encode_vcard_BINVAL_cdata(<<>>, _acc) -> _acc;
 encode_vcard_BINVAL_cdata(_val, _acc) ->
     [{xmlcdata, base64:encode(_val)} | _acc].
 
@@ -16977,21 +16906,15 @@ decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls,
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">> when __TopXMLNS == <<"vcard-temp">> ->
 	  decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els,
-				 case decode_vcard_LINE(__TopXMLNS, __IgnoreEls,
-							_el)
-				     of
-				   undefined -> Line;
-				   _new_el -> [_new_el | Line]
-				 end,
+				 [decode_vcard_LINE(__TopXMLNS, __IgnoreEls,
+						    _el)
+				  | Line],
 				 Home, Pref, Work, Intl, Parcel, Postal, Dom);
       <<"vcard-temp">> ->
 	  decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els,
-				 case decode_vcard_LINE(<<"vcard-temp">>,
-							__IgnoreEls, _el)
-				     of
-				   undefined -> Line;
-				   _new_el -> [_new_el | Line]
-				 end,
+				 [decode_vcard_LINE(<<"vcard-temp">>,
+						    __IgnoreEls, _el)
+				  | Line],
 				 Home, Pref, Work, Intl, Parcel, Postal, Dom);
       _ ->
 	  decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els,
@@ -17679,11 +17602,10 @@ encode_vcard_EXTVAL(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"EXTVAL">>, _attrs, _els}.
 
-decode_vcard_EXTVAL_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_EXTVAL_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_EXTVAL_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_EXTVAL_cdata(undefined, _acc) -> _acc;
+encode_vcard_EXTVAL_cdata(<<>>, _acc) -> _acc;
 encode_vcard_EXTVAL_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17710,10 +17632,10 @@ encode_vcard_TYPE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"TYPE">>, _attrs, _els}.
 
-decode_vcard_TYPE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_TYPE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_TYPE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_TYPE_cdata(undefined, _acc) -> _acc;
+encode_vcard_TYPE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_TYPE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17740,10 +17662,10 @@ encode_vcard_DESC(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"DESC">>, _attrs, _els}.
 
-decode_vcard_DESC_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_DESC_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_DESC_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_DESC_cdata(undefined, _acc) -> _acc;
+encode_vcard_DESC_cdata(<<>>, _acc) -> _acc;
 encode_vcard_DESC_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17770,10 +17692,10 @@ encode_vcard_URL(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"URL">>, _attrs, _els}.
 
-decode_vcard_URL_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_URL_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_URL_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_URL_cdata(undefined, _acc) -> _acc;
+encode_vcard_URL_cdata(<<>>, _acc) -> _acc;
 encode_vcard_URL_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17800,10 +17722,10 @@ encode_vcard_UID(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"UID">>, _attrs, _els}.
 
-decode_vcard_UID_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_UID_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_UID_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_UID_cdata(undefined, _acc) -> _acc;
+encode_vcard_UID_cdata(<<>>, _acc) -> _acc;
 encode_vcard_UID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17831,11 +17753,11 @@ encode_vcard_SORT_STRING(Cdata, _xmlns_attrs) ->
     {xmlel, <<"SORT-STRING">>, _attrs, _els}.
 
 decode_vcard_SORT_STRING_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_vcard_SORT_STRING_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_vcard_SORT_STRING_cdata(undefined, _acc) -> _acc;
+encode_vcard_SORT_STRING_cdata(<<>>, _acc) -> _acc;
 encode_vcard_SORT_STRING_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17862,10 +17784,10 @@ encode_vcard_REV(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"REV">>, _attrs, _els}.
 
-decode_vcard_REV_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_REV_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_REV_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_REV_cdata(undefined, _acc) -> _acc;
+encode_vcard_REV_cdata(<<>>, _acc) -> _acc;
 encode_vcard_REV_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17892,11 +17814,10 @@ encode_vcard_PRODID(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"PRODID">>, _attrs, _els}.
 
-decode_vcard_PRODID_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_PRODID_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_PRODID_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_PRODID_cdata(undefined, _acc) -> _acc;
+encode_vcard_PRODID_cdata(<<>>, _acc) -> _acc;
 encode_vcard_PRODID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17923,10 +17844,10 @@ encode_vcard_NOTE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"NOTE">>, _attrs, _els}.
 
-decode_vcard_NOTE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_NOTE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_NOTE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_NOTE_cdata(undefined, _acc) -> _acc;
+encode_vcard_NOTE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_NOTE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17953,11 +17874,10 @@ encode_vcard_KEYWORD(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"KEYWORD">>, _attrs, _els}.
 
-decode_vcard_KEYWORD_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_KEYWORD_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_KEYWORD_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_KEYWORD_cdata(undefined, _acc) -> _acc;
+encode_vcard_KEYWORD_cdata(<<>>, _acc) -> _acc;
 encode_vcard_KEYWORD_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -17984,10 +17904,10 @@ encode_vcard_ROLE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"ROLE">>, _attrs, _els}.
 
-decode_vcard_ROLE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_ROLE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_ROLE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_ROLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_ROLE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_ROLE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18014,10 +17934,10 @@ encode_vcard_TITLE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"TITLE">>, _attrs, _els}.
 
-decode_vcard_TITLE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_TITLE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_TITLE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_TITLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_TITLE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_TITLE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18044,10 +17964,10 @@ encode_vcard_TZ(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"TZ">>, _attrs, _els}.
 
-decode_vcard_TZ_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_TZ_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_TZ_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_TZ_cdata(undefined, _acc) -> _acc;
+encode_vcard_TZ_cdata(<<>>, _acc) -> _acc;
 encode_vcard_TZ_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18074,11 +17994,10 @@ encode_vcard_MAILER(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"MAILER">>, _attrs, _els}.
 
-decode_vcard_MAILER_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_MAILER_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_MAILER_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_MAILER_cdata(undefined, _acc) -> _acc;
+encode_vcard_MAILER_cdata(<<>>, _acc) -> _acc;
 encode_vcard_MAILER_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18105,11 +18024,10 @@ encode_vcard_JABBERID(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"JABBERID">>, _attrs, _els}.
 
-decode_vcard_JABBERID_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_JABBERID_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_JABBERID_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_JABBERID_cdata(undefined, _acc) -> _acc;
+encode_vcard_JABBERID_cdata(<<>>, _acc) -> _acc;
 encode_vcard_JABBERID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18136,10 +18054,10 @@ encode_vcard_BDAY(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"BDAY">>, _attrs, _els}.
 
-decode_vcard_BDAY_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_BDAY_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_BDAY_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_BDAY_cdata(undefined, _acc) -> _acc;
+encode_vcard_BDAY_cdata(<<>>, _acc) -> _acc;
 encode_vcard_BDAY_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18166,11 +18084,10 @@ encode_vcard_NICKNAME(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"NICKNAME">>, _attrs, _els}.
 
-decode_vcard_NICKNAME_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_NICKNAME_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_NICKNAME_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_NICKNAME_cdata(undefined, _acc) -> _acc;
+encode_vcard_NICKNAME_cdata(<<>>, _acc) -> _acc;
 encode_vcard_NICKNAME_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18197,10 +18114,10 @@ encode_vcard_FN(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"FN">>, _attrs, _els}.
 
-decode_vcard_FN_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_FN_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_FN_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_FN_cdata(undefined, _acc) -> _acc;
+encode_vcard_FN_cdata(<<>>, _acc) -> _acc;
 encode_vcard_FN_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18227,11 +18144,10 @@ encode_vcard_VERSION(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"VERSION">>, _attrs, _els}.
 
-decode_vcard_VERSION_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_VERSION_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_VERSION_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_VERSION_cdata(undefined, _acc) -> _acc;
+encode_vcard_VERSION_cdata(<<>>, _acc) -> _acc;
 encode_vcard_VERSION_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18258,10 +18174,10 @@ encode_vcard_CRED(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"CRED">>, _attrs, _els}.
 
-decode_vcard_CRED_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_CRED_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_CRED_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_CRED_cdata(undefined, _acc) -> _acc;
+encode_vcard_CRED_cdata(<<>>, _acc) -> _acc;
 encode_vcard_CRED_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18288,11 +18204,10 @@ encode_vcard_PHONETIC(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"PHONETIC">>, _attrs, _els}.
 
-decode_vcard_PHONETIC_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_PHONETIC_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_PHONETIC_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_PHONETIC_cdata(undefined, _acc) -> _acc;
+encode_vcard_PHONETIC_cdata(<<>>, _acc) -> _acc;
 encode_vcard_PHONETIC_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18319,11 +18234,10 @@ encode_vcard_ORGUNIT(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"ORGUNIT">>, _attrs, _els}.
 
-decode_vcard_ORGUNIT_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_ORGUNIT_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_ORGUNIT_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_ORGUNIT_cdata(undefined, _acc) -> _acc;
+encode_vcard_ORGUNIT_cdata(<<>>, _acc) -> _acc;
 encode_vcard_ORGUNIT_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18350,11 +18264,10 @@ encode_vcard_ORGNAME(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"ORGNAME">>, _attrs, _els}.
 
-decode_vcard_ORGNAME_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_ORGNAME_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_ORGNAME_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_ORGNAME_cdata(undefined, _acc) -> _acc;
+encode_vcard_ORGNAME_cdata(<<>>, _acc) -> _acc;
 encode_vcard_ORGNAME_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18381,10 +18294,10 @@ encode_vcard_LON(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"LON">>, _attrs, _els}.
 
-decode_vcard_LON_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_LON_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_LON_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_LON_cdata(undefined, _acc) -> _acc;
+encode_vcard_LON_cdata(<<>>, _acc) -> _acc;
 encode_vcard_LON_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18411,10 +18324,10 @@ encode_vcard_LAT(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"LAT">>, _attrs, _els}.
 
-decode_vcard_LAT_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_LAT_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_LAT_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_LAT_cdata(undefined, _acc) -> _acc;
+encode_vcard_LAT_cdata(<<>>, _acc) -> _acc;
 encode_vcard_LAT_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18441,11 +18354,10 @@ encode_vcard_USERID(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"USERID">>, _attrs, _els}.
 
-decode_vcard_USERID_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_USERID_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_USERID_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_USERID_cdata(undefined, _acc) -> _acc;
+encode_vcard_USERID_cdata(<<>>, _acc) -> _acc;
 encode_vcard_USERID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18472,11 +18384,10 @@ encode_vcard_NUMBER(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"NUMBER">>, _attrs, _els}.
 
-decode_vcard_NUMBER_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_NUMBER_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_NUMBER_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_NUMBER_cdata(undefined, _acc) -> _acc;
+encode_vcard_NUMBER_cdata(<<>>, _acc) -> _acc;
 encode_vcard_NUMBER_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18503,10 +18414,10 @@ encode_vcard_LINE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"LINE">>, _attrs, _els}.
 
-decode_vcard_LINE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_LINE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_LINE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_LINE_cdata(undefined, _acc) -> _acc;
+encode_vcard_LINE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_LINE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18533,10 +18444,10 @@ encode_vcard_CTRY(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"CTRY">>, _attrs, _els}.
 
-decode_vcard_CTRY_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_CTRY_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_CTRY_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_CTRY_cdata(undefined, _acc) -> _acc;
+encode_vcard_CTRY_cdata(<<>>, _acc) -> _acc;
 encode_vcard_CTRY_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18563,10 +18474,10 @@ encode_vcard_PCODE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"PCODE">>, _attrs, _els}.
 
-decode_vcard_PCODE_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_PCODE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_PCODE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_PCODE_cdata(undefined, _acc) -> _acc;
+encode_vcard_PCODE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_PCODE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18593,11 +18504,10 @@ encode_vcard_REGION(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"REGION">>, _attrs, _els}.
 
-decode_vcard_REGION_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_REGION_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_REGION_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_REGION_cdata(undefined, _acc) -> _acc;
+encode_vcard_REGION_cdata(<<>>, _acc) -> _acc;
 encode_vcard_REGION_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18624,11 +18534,10 @@ encode_vcard_LOCALITY(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"LOCALITY">>, _attrs, _els}.
 
-decode_vcard_LOCALITY_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_LOCALITY_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_LOCALITY_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_LOCALITY_cdata(undefined, _acc) -> _acc;
+encode_vcard_LOCALITY_cdata(<<>>, _acc) -> _acc;
 encode_vcard_LOCALITY_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18655,11 +18564,10 @@ encode_vcard_STREET(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"STREET">>, _attrs, _els}.
 
-decode_vcard_STREET_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_STREET_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_STREET_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_STREET_cdata(undefined, _acc) -> _acc;
+encode_vcard_STREET_cdata(<<>>, _acc) -> _acc;
 encode_vcard_STREET_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18686,11 +18594,10 @@ encode_vcard_EXTADD(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"EXTADD">>, _attrs, _els}.
 
-decode_vcard_EXTADD_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_EXTADD_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_EXTADD_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_EXTADD_cdata(undefined, _acc) -> _acc;
+encode_vcard_EXTADD_cdata(<<>>, _acc) -> _acc;
 encode_vcard_EXTADD_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18717,10 +18624,10 @@ encode_vcard_POBOX(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"POBOX">>, _attrs, _els}.
 
-decode_vcard_POBOX_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_POBOX_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_POBOX_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_POBOX_cdata(undefined, _acc) -> _acc;
+encode_vcard_POBOX_cdata(<<>>, _acc) -> _acc;
 encode_vcard_POBOX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18747,11 +18654,10 @@ encode_vcard_SUFFIX(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"SUFFIX">>, _attrs, _els}.
 
-decode_vcard_SUFFIX_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_SUFFIX_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_SUFFIX_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_SUFFIX_cdata(undefined, _acc) -> _acc;
+encode_vcard_SUFFIX_cdata(<<>>, _acc) -> _acc;
 encode_vcard_SUFFIX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18778,11 +18684,10 @@ encode_vcard_PREFIX(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"PREFIX">>, _attrs, _els}.
 
-decode_vcard_PREFIX_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_PREFIX_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_PREFIX_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_PREFIX_cdata(undefined, _acc) -> _acc;
+encode_vcard_PREFIX_cdata(<<>>, _acc) -> _acc;
 encode_vcard_PREFIX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18809,11 +18714,10 @@ encode_vcard_MIDDLE(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"MIDDLE">>, _attrs, _els}.
 
-decode_vcard_MIDDLE_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_MIDDLE_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_MIDDLE_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_MIDDLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_MIDDLE_cdata(<<>>, _acc) -> _acc;
 encode_vcard_MIDDLE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18840,10 +18744,10 @@ encode_vcard_GIVEN(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"GIVEN">>, _attrs, _els}.
 
-decode_vcard_GIVEN_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_vcard_GIVEN_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_GIVEN_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_GIVEN_cdata(undefined, _acc) -> _acc;
+encode_vcard_GIVEN_cdata(<<>>, _acc) -> _acc;
 encode_vcard_GIVEN_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -18870,11 +18774,10 @@ encode_vcard_FAMILY(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"FAMILY">>, _attrs, _els}.
 
-decode_vcard_FAMILY_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_vcard_FAMILY_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_vcard_FAMILY_cdata(__TopXMLNS, _val) -> _val.
 
-encode_vcard_FAMILY_cdata(undefined, _acc) -> _acc;
+encode_vcard_FAMILY_cdata(<<>>, _acc) -> _acc;
 encode_vcard_FAMILY_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -19722,10 +19625,16 @@ decode_stream_error_see_other_host_cdata(__TopXMLNS,
 		   __TopXMLNS}});
 decode_stream_error_see_other_host_cdata(__TopXMLNS,
 					 _val) ->
-    _val.
+    case catch dec_host_port(_val) of
+      {'EXIT', _} ->
+	  erlang:error({xmpp_codec,
+			{bad_cdata_value, <<>>, <<"see-other-host">>,
+			 __TopXMLNS}});
+      _res -> _res
+    end.
 
 encode_stream_error_see_other_host_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+    [{xmlcdata, enc_host_port(_val)} | _acc].
 
 decode_stream_error_restricted_xml(__TopXMLNS,
 				   __IgnoreEls,
@@ -19981,23 +19890,22 @@ encode_stream_error_text({text, Lang, Data},
 
 'decode_stream_error_text_attr_xml:lang'(__TopXMLNS,
 					 undefined) ->
-    undefined;
+    <<>>;
 'decode_stream_error_text_attr_xml:lang'(__TopXMLNS,
 					 _val) ->
     _val.
 
-'encode_stream_error_text_attr_xml:lang'(undefined,
-					 _acc) ->
+'encode_stream_error_text_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_stream_error_text_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
 decode_stream_error_text_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_stream_error_text_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_stream_error_text_cdata(undefined, _acc) -> _acc;
+encode_stream_error_text_cdata(<<>>, _acc) -> _acc;
 encode_stream_error_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -20993,10 +20901,10 @@ encode_register_key(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"key">>, _attrs, _els}.
 
-decode_register_key_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_key_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_key_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_key_cdata(none, _acc) -> _acc;
+encode_register_key_cdata(<<>>, _acc) -> _acc;
 encode_register_key_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21023,10 +20931,10 @@ encode_register_text(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"text">>, _attrs, _els}.
 
-decode_register_text_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_text_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_text_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_text_cdata(none, _acc) -> _acc;
+encode_register_text_cdata(<<>>, _acc) -> _acc;
 encode_register_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21053,10 +20961,10 @@ encode_register_misc(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"misc">>, _attrs, _els}.
 
-decode_register_misc_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_misc_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_misc_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_misc_cdata(none, _acc) -> _acc;
+encode_register_misc_cdata(<<>>, _acc) -> _acc;
 encode_register_misc_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21083,10 +20991,10 @@ encode_register_date(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"date">>, _attrs, _els}.
 
-decode_register_date_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_date_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_date_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_date_cdata(none, _acc) -> _acc;
+encode_register_date_cdata(<<>>, _acc) -> _acc;
 encode_register_date_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21113,10 +21021,10 @@ encode_register_url(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"url">>, _attrs, _els}.
 
-decode_register_url_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_url_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_url_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_url_cdata(none, _acc) -> _acc;
+encode_register_url_cdata(<<>>, _acc) -> _acc;
 encode_register_url_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21143,10 +21051,10 @@ encode_register_phone(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"phone">>, _attrs, _els}.
 
-decode_register_phone_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_phone_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_phone_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_phone_cdata(none, _acc) -> _acc;
+encode_register_phone_cdata(<<>>, _acc) -> _acc;
 encode_register_phone_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21173,10 +21081,10 @@ encode_register_zip(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"zip">>, _attrs, _els}.
 
-decode_register_zip_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_zip_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_zip_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_zip_cdata(none, _acc) -> _acc;
+encode_register_zip_cdata(<<>>, _acc) -> _acc;
 encode_register_zip_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21203,10 +21111,10 @@ encode_register_state(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"state">>, _attrs, _els}.
 
-decode_register_state_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_state_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_state_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_state_cdata(none, _acc) -> _acc;
+encode_register_state_cdata(<<>>, _acc) -> _acc;
 encode_register_state_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21233,10 +21141,10 @@ encode_register_city(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"city">>, _attrs, _els}.
 
-decode_register_city_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_city_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_city_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_city_cdata(none, _acc) -> _acc;
+encode_register_city_cdata(<<>>, _acc) -> _acc;
 encode_register_city_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21263,10 +21171,10 @@ encode_register_address(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"address">>, _attrs, _els}.
 
-decode_register_address_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_address_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_address_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_address_cdata(none, _acc) -> _acc;
+encode_register_address_cdata(<<>>, _acc) -> _acc;
 encode_register_address_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21293,10 +21201,10 @@ encode_register_email(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"email">>, _attrs, _els}.
 
-decode_register_email_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_email_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_email_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_email_cdata(none, _acc) -> _acc;
+encode_register_email_cdata(<<>>, _acc) -> _acc;
 encode_register_email_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21323,10 +21231,10 @@ encode_register_last(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"last">>, _attrs, _els}.
 
-decode_register_last_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_last_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_last_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_last_cdata(none, _acc) -> _acc;
+encode_register_last_cdata(<<>>, _acc) -> _acc;
 encode_register_last_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21353,10 +21261,10 @@ encode_register_first(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"first">>, _attrs, _els}.
 
-decode_register_first_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_first_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_first_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_first_cdata(none, _acc) -> _acc;
+encode_register_first_cdata(<<>>, _acc) -> _acc;
 encode_register_first_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21383,10 +21291,10 @@ encode_register_name(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"name">>, _attrs, _els}.
 
-decode_register_name_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_name_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_name_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_name_cdata(none, _acc) -> _acc;
+encode_register_name_cdata(<<>>, _acc) -> _acc;
 encode_register_name_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21414,11 +21322,11 @@ encode_register_password(Cdata, _xmlns_attrs) ->
     {xmlel, <<"password">>, _attrs, _els}.
 
 decode_register_password_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_register_password_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_register_password_cdata(none, _acc) -> _acc;
+encode_register_password_cdata(<<>>, _acc) -> _acc;
 encode_register_password_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21445,10 +21353,10 @@ encode_register_nick(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"nick">>, _attrs, _els}.
 
-decode_register_nick_cdata(__TopXMLNS, <<>>) -> none;
+decode_register_nick_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_register_nick_cdata(__TopXMLNS, _val) -> _val.
 
-encode_register_nick_cdata(none, _acc) -> _acc;
+encode_register_nick_cdata(<<>>, _acc) -> _acc;
 encode_register_nick_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21476,11 +21384,11 @@ encode_register_username(Cdata, _xmlns_attrs) ->
     {xmlel, <<"username">>, _attrs, _els}.
 
 decode_register_username_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_register_username_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_register_username_cdata(none, _acc) -> _acc;
+encode_register_username_cdata(<<>>, _acc) -> _acc;
 encode_register_username_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21510,12 +21418,11 @@ encode_register_instructions(Cdata, _xmlns_attrs) ->
     {xmlel, <<"instructions">>, _attrs, _els}.
 
 decode_register_instructions_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_register_instructions_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_register_instructions_cdata(undefined, _acc) ->
-    _acc;
+encode_register_instructions_cdata(<<>>, _acc) -> _acc;
 encode_register_instructions_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21595,19 +21502,17 @@ encode_caps({caps, Node, Version, Hash, Exts},
 												   _xmlns_attrs)))),
     {xmlel, <<"c">>, _attrs, _els}.
 
-decode_caps_attr_hash(__TopXMLNS, undefined) ->
-    undefined;
+decode_caps_attr_hash(__TopXMLNS, undefined) -> <<>>;
 decode_caps_attr_hash(__TopXMLNS, _val) -> _val.
 
-encode_caps_attr_hash(undefined, _acc) -> _acc;
+encode_caps_attr_hash(<<>>, _acc) -> _acc;
 encode_caps_attr_hash(_val, _acc) ->
     [{<<"hash">>, _val} | _acc].
 
-decode_caps_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+decode_caps_attr_node(__TopXMLNS, undefined) -> <<>>;
 decode_caps_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_caps_attr_node(undefined, _acc) -> _acc;
+encode_caps_attr_node(<<>>, _acc) -> _acc;
 encode_caps_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -21624,11 +21529,10 @@ encode_caps_attr_ext([], _acc) -> _acc;
 encode_caps_attr_ext(_val, _acc) ->
     [{<<"ext">>, join(_val, 32)} | _acc].
 
-decode_caps_attr_ver(__TopXMLNS, undefined) ->
-    undefined;
+decode_caps_attr_ver(__TopXMLNS, undefined) -> <<>>;
 decode_caps_attr_ver(__TopXMLNS, _val) -> _val.
 
-encode_caps_attr_ver(undefined, _acc) -> _acc;
+encode_caps_attr_ver(<<>>, _acc) -> _acc;
 encode_caps_attr_ver(_val, _acc) ->
     [{<<"ver">>, _val} | _acc].
 
@@ -21711,22 +21615,14 @@ decode_compression_els(__TopXMLNS, __IgnoreEls,
 	  when __TopXMLNS ==
 		 <<"http://jabber.org/features/compress">> ->
 	  decode_compression_els(__TopXMLNS, __IgnoreEls, _els,
-				 case decode_compression_method(__TopXMLNS,
-								__IgnoreEls,
-								_el)
-				     of
-				   undefined -> Methods;
-				   _new_el -> [_new_el | Methods]
-				 end);
+				 [decode_compression_method(__TopXMLNS,
+							    __IgnoreEls, _el)
+				  | Methods]);
       <<"http://jabber.org/features/compress">> ->
 	  decode_compression_els(__TopXMLNS, __IgnoreEls, _els,
-				 case
-				   decode_compression_method(<<"http://jabber.org/features/compress">>,
-							     __IgnoreEls, _el)
-				     of
-				   undefined -> Methods;
-				   _new_el -> [_new_el | Methods]
-				 end);
+				 [decode_compression_method(<<"http://jabber.org/features/compress">>,
+							    __IgnoreEls, _el)
+				  | Methods]);
       _ ->
 	  decode_compression_els(__TopXMLNS, __IgnoreEls, _els,
 				 Methods)
@@ -21774,12 +21670,11 @@ encode_compression_method(Cdata, _xmlns_attrs) ->
     {xmlel, <<"method">>, _attrs, _els}.
 
 decode_compression_method_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_compression_method_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_compression_method_cdata(undefined, _acc) ->
-    _acc;
+encode_compression_method_cdata(<<>>, _acc) -> _acc;
 encode_compression_method_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -21809,21 +21704,14 @@ decode_compress_els(__TopXMLNS, __IgnoreEls,
 	  when __TopXMLNS ==
 		 <<"http://jabber.org/protocol/compress">> ->
 	  decode_compress_els(__TopXMLNS, __IgnoreEls, _els,
-			      case decode_compress_method(__TopXMLNS,
-							  __IgnoreEls, _el)
-				  of
-				undefined -> Methods;
-				_new_el -> [_new_el | Methods]
-			      end);
+			      [decode_compress_method(__TopXMLNS, __IgnoreEls,
+						      _el)
+			       | Methods]);
       <<"http://jabber.org/protocol/compress">> ->
 	  decode_compress_els(__TopXMLNS, __IgnoreEls, _els,
-			      case
-				decode_compress_method(<<"http://jabber.org/protocol/compress">>,
-						       __IgnoreEls, _el)
-				  of
-				undefined -> Methods;
-				_new_el -> [_new_el | Methods]
-			      end);
+			      [decode_compress_method(<<"http://jabber.org/protocol/compress">>,
+						      __IgnoreEls, _el)
+			       | Methods]);
       _ ->
 	  decode_compress_els(__TopXMLNS, __IgnoreEls, _els,
 			      Methods)
@@ -21867,11 +21755,10 @@ encode_compress_method(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"method">>, _attrs, _els}.
 
-decode_compress_method_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_compress_method_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_compress_method_cdata(__TopXMLNS, _val) -> _val.
 
-encode_compress_method_cdata(undefined, _acc) -> _acc;
+encode_compress_method_cdata(<<>>, _acc) -> _acc;
 encode_compress_method_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -22110,23 +21997,15 @@ decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls,
 		 <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
 	  decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls,
 				     _els,
-				     case decode_sasl_mechanism(__TopXMLNS,
-								__IgnoreEls,
-								_el)
-					 of
-				       undefined -> List;
-				       _new_el -> [_new_el | List]
-				     end);
+				     [decode_sasl_mechanism(__TopXMLNS,
+							    __IgnoreEls, _el)
+				      | List]);
       <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
 	  decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls,
 				     _els,
-				     case
-				       decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>,
-							     __IgnoreEls, _el)
-					 of
-				       undefined -> List;
-				       _new_el -> [_new_el | List]
-				     end);
+				     [decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+							    __IgnoreEls, _el)
+				      | List]);
       _ ->
 	  decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls,
 				     _els, List)
@@ -22171,11 +22050,10 @@ encode_sasl_mechanism(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"mechanism">>, _attrs, _els}.
 
-decode_sasl_mechanism_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_sasl_mechanism_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_sasl_mechanism_cdata(__TopXMLNS, _val) -> _val.
 
-encode_sasl_mechanism_cdata(undefined, _acc) -> _acc;
+encode_sasl_mechanism_cdata(<<>>, _acc) -> _acc;
 encode_sasl_mechanism_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -22737,23 +22615,22 @@ encode_sasl_failure_text({text, Lang, Data},
 
 'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS,
 					 undefined) ->
-    undefined;
+    <<>>;
 'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS,
 					 _val) ->
     _val.
 
-'encode_sasl_failure_text_attr_xml:lang'(undefined,
-					 _acc) ->
+'encode_sasl_failure_text_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_sasl_failure_text_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
 decode_sasl_failure_text_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_sasl_failure_text_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_sasl_failure_text_cdata(undefined, _acc) -> _acc;
+encode_sasl_failure_text_cdata(<<>>, _acc) -> _acc;
 encode_sasl_failure_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -22781,8 +22658,7 @@ encode_sasl_success({sasl_success, Text},
     _attrs = _xmlns_attrs,
     {xmlel, <<"success">>, _attrs, _els}.
 
-decode_sasl_success_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_sasl_success_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_sasl_success_cdata(__TopXMLNS, _val) ->
     case catch base64:decode(_val) of
       {'EXIT', _} ->
@@ -22791,7 +22667,7 @@ decode_sasl_success_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_sasl_success_cdata(undefined, _acc) -> _acc;
+encode_sasl_success_cdata(<<>>, _acc) -> _acc;
 encode_sasl_success_cdata(_val, _acc) ->
     [{xmlcdata, base64:encode(_val)} | _acc].
 
@@ -22819,8 +22695,7 @@ encode_sasl_response({sasl_response, Text},
     _attrs = _xmlns_attrs,
     {xmlel, <<"response">>, _attrs, _els}.
 
-decode_sasl_response_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_sasl_response_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_sasl_response_cdata(__TopXMLNS, _val) ->
     case catch base64:decode(_val) of
       {'EXIT', _} ->
@@ -22829,7 +22704,7 @@ decode_sasl_response_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_sasl_response_cdata(undefined, _acc) -> _acc;
+encode_sasl_response_cdata(<<>>, _acc) -> _acc;
 encode_sasl_response_cdata(_val, _acc) ->
     [{xmlcdata, base64:encode(_val)} | _acc].
 
@@ -22857,8 +22732,7 @@ encode_sasl_challenge({sasl_challenge, Text},
     _attrs = _xmlns_attrs,
     {xmlel, <<"challenge">>, _attrs, _els}.
 
-decode_sasl_challenge_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_sasl_challenge_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_sasl_challenge_cdata(__TopXMLNS, _val) ->
     case catch base64:decode(_val) of
       {'EXIT', _} ->
@@ -22867,7 +22741,7 @@ decode_sasl_challenge_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_sasl_challenge_cdata(undefined, _acc) -> _acc;
+encode_sasl_challenge_cdata(<<>>, _acc) -> _acc;
 encode_sasl_challenge_cdata(_val, _acc) ->
     [{xmlcdata, base64:encode(_val)} | _acc].
 
@@ -22927,7 +22801,7 @@ decode_sasl_auth_attr_mechanism(__TopXMLNS, _val) ->
 encode_sasl_auth_attr_mechanism(_val, _acc) ->
     [{<<"mechanism">>, _val} | _acc].
 
-decode_sasl_auth_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_sasl_auth_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_sasl_auth_cdata(__TopXMLNS, _val) ->
     case catch base64:decode(_val) of
       {'EXIT', _} ->
@@ -22936,7 +22810,7 @@ decode_sasl_auth_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_sasl_auth_cdata(undefined, _acc) -> _acc;
+encode_sasl_auth_cdata(<<>>, _acc) -> _acc;
 encode_sasl_auth_cdata(_val, _acc) ->
     [{xmlcdata, base64:encode(_val)} | _acc].
 
@@ -23083,11 +22957,11 @@ encode_legacy_auth_resource(Cdata, _xmlns_attrs) ->
     {xmlel, <<"resource">>, _attrs, _els}.
 
 decode_legacy_auth_resource_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_legacy_auth_resource_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_legacy_auth_resource_cdata(none, _acc) -> _acc;
+encode_legacy_auth_resource_cdata(<<>>, _acc) -> _acc;
 encode_legacy_auth_resource_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -23115,11 +22989,11 @@ encode_legacy_auth_digest(Cdata, _xmlns_attrs) ->
     {xmlel, <<"digest">>, _attrs, _els}.
 
 decode_legacy_auth_digest_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_legacy_auth_digest_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_legacy_auth_digest_cdata(none, _acc) -> _acc;
+encode_legacy_auth_digest_cdata(<<>>, _acc) -> _acc;
 encode_legacy_auth_digest_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -23147,11 +23021,11 @@ encode_legacy_auth_password(Cdata, _xmlns_attrs) ->
     {xmlel, <<"password">>, _attrs, _els}.
 
 decode_legacy_auth_password_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_legacy_auth_password_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_legacy_auth_password_cdata(none, _acc) -> _acc;
+encode_legacy_auth_password_cdata(<<>>, _acc) -> _acc;
 encode_legacy_auth_password_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -23179,11 +23053,11 @@ encode_legacy_auth_username(Cdata, _xmlns_attrs) ->
     {xmlel, <<"username">>, _attrs, _els}.
 
 decode_legacy_auth_username_cdata(__TopXMLNS, <<>>) ->
-    none;
+    <<>>;
 decode_legacy_auth_username_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_legacy_auth_username_cdata(none, _acc) -> _acc;
+encode_legacy_auth_username_cdata(<<>>, _acc) -> _acc;
 encode_legacy_auth_username_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -23275,8 +23149,7 @@ encode_bind_resource(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"resource">>, _attrs, _els}.
 
-decode_bind_resource_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_bind_resource_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_bind_resource_cdata(__TopXMLNS, _val) ->
     case catch resourceprep(_val) of
       {'EXIT', _} ->
@@ -23285,7 +23158,7 @@ decode_bind_resource_cdata(__TopXMLNS, _val) ->
       _res -> _res
     end.
 
-encode_bind_resource_cdata(undefined, _acc) -> _acc;
+encode_bind_resource_cdata(<<>>, _acc) -> _acc;
 encode_bind_resource_cdata(_val, _acc) ->
     [{xmlcdata, resourceprep(_val)} | _acc].
 
@@ -23889,11 +23762,10 @@ encode_error_attr_code(undefined, _acc) -> _acc;
 encode_error_attr_code(_val, _acc) ->
     [{<<"code">>, enc_int(_val)} | _acc].
 
-decode_error_attr_by(__TopXMLNS, undefined) ->
-    undefined;
+decode_error_attr_by(__TopXMLNS, undefined) -> <<>>;
 decode_error_attr_by(__TopXMLNS, _val) -> _val.
 
-encode_error_attr_by(undefined, _acc) -> _acc;
+encode_error_attr_by(<<>>, _acc) -> _acc;
 encode_error_attr_by(_val, _acc) ->
     [{<<"by">>, _val} | _acc].
 
@@ -23934,19 +23806,18 @@ encode_error_text({text, Lang, Data}, _xmlns_attrs) ->
 
 'decode_error_text_attr_xml:lang'(__TopXMLNS,
 				  undefined) ->
-    undefined;
+    <<>>;
 'decode_error_text_attr_xml:lang'(__TopXMLNS, _val) ->
     _val.
 
-'encode_error_text_attr_xml:lang'(undefined, _acc) ->
-    _acc;
+'encode_error_text_attr_xml:lang'(<<>>, _acc) -> _acc;
 'encode_error_text_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
-decode_error_text_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_error_text_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_error_text_cdata(__TopXMLNS, _val) -> _val.
 
-encode_error_text_cdata(undefined, _acc) -> _acc;
+encode_error_text_cdata(<<>>, _acc) -> _acc;
 encode_error_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24068,11 +23939,10 @@ encode_error_redirect({redirect, Uri}, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"redirect">>, _attrs, _els}.
 
-decode_error_redirect_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_error_redirect_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_error_redirect_cdata(__TopXMLNS, _val) -> _val.
 
-encode_error_redirect_cdata(undefined, _acc) -> _acc;
+encode_error_redirect_cdata(<<>>, _acc) -> _acc;
 encode_error_redirect_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24192,10 +24062,10 @@ encode_error_gone({gone, Uri}, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"gone">>, _attrs, _els}.
 
-decode_error_gone_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_error_gone_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_error_gone_cdata(__TopXMLNS, _val) -> _val.
 
-encode_error_gone_cdata(undefined, _acc) -> _acc;
+encode_error_gone_cdata(<<>>, _acc) -> _acc;
 encode_error_gone_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24401,11 +24271,10 @@ encode_presence({presence, Id, Type, Lang, From, To,
 'encode_presence_$priority'(Priority, _acc) ->
     [encode_presence_priority(Priority, []) | _acc].
 
-decode_presence_attr_id(__TopXMLNS, undefined) ->
-    undefined;
+decode_presence_attr_id(__TopXMLNS, undefined) -> <<>>;
 decode_presence_attr_id(__TopXMLNS, _val) -> _val.
 
-encode_presence_attr_id(undefined, _acc) -> _acc;
+encode_presence_attr_id(<<>>, _acc) -> _acc;
 encode_presence_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
@@ -24459,12 +24328,11 @@ encode_presence_attr_to(_val, _acc) ->
 
 'decode_presence_attr_xml:lang'(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 'decode_presence_attr_xml:lang'(__TopXMLNS, _val) ->
     _val.
 
-'encode_presence_attr_xml:lang'(undefined, _acc) ->
-    _acc;
+'encode_presence_attr_xml:lang'(<<>>, _acc) -> _acc;
 'encode_presence_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
@@ -24544,22 +24412,20 @@ encode_presence_status({text, Lang, Data},
 
 'decode_presence_status_attr_xml:lang'(__TopXMLNS,
 				       undefined) ->
-    undefined;
+    <<>>;
 'decode_presence_status_attr_xml:lang'(__TopXMLNS,
 				       _val) ->
     _val.
 
-'encode_presence_status_attr_xml:lang'(undefined,
-				       _acc) ->
+'encode_presence_status_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_presence_status_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
-decode_presence_status_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_presence_status_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_presence_status_cdata(__TopXMLNS, _val) -> _val.
 
-encode_presence_status_cdata(undefined, _acc) -> _acc;
+encode_presence_status_cdata(<<>>, _acc) -> _acc;
 encode_presence_status_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24765,11 +24631,10 @@ encode_message({message, Id, Type, Lang, From, To,
     'encode_message_$body'(_els,
 			   [encode_message_body(Body, []) | _acc]).
 
-decode_message_attr_id(__TopXMLNS, undefined) ->
-    undefined;
+decode_message_attr_id(__TopXMLNS, undefined) -> <<>>;
 decode_message_attr_id(__TopXMLNS, _val) -> _val.
 
-encode_message_attr_id(undefined, _acc) -> _acc;
+encode_message_attr_id(<<>>, _acc) -> _acc;
 encode_message_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
@@ -24820,11 +24685,11 @@ encode_message_attr_to(_val, _acc) ->
     [{<<"to">>, enc_jid(_val)} | _acc].
 
 'decode_message_attr_xml:lang'(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 'decode_message_attr_xml:lang'(__TopXMLNS, _val) ->
     _val.
 
-'encode_message_attr_xml:lang'(undefined, _acc) -> _acc;
+'encode_message_attr_xml:lang'(<<>>, _acc) -> _acc;
 'encode_message_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
@@ -24851,11 +24716,10 @@ encode_message_thread(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"thread">>, _attrs, _els}.
 
-decode_message_thread_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_message_thread_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_message_thread_cdata(__TopXMLNS, _val) -> _val.
 
-encode_message_thread_cdata(undefined, _acc) -> _acc;
+encode_message_thread_cdata(<<>>, _acc) -> _acc;
 encode_message_thread_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24896,20 +24760,18 @@ encode_message_body({text, Lang, Data}, _xmlns_attrs) ->
 
 'decode_message_body_attr_xml:lang'(__TopXMLNS,
 				    undefined) ->
-    undefined;
+    <<>>;
 'decode_message_body_attr_xml:lang'(__TopXMLNS, _val) ->
     _val.
 
-'encode_message_body_attr_xml:lang'(undefined, _acc) ->
-    _acc;
+'encode_message_body_attr_xml:lang'(<<>>, _acc) -> _acc;
 'encode_message_body_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
-decode_message_body_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_message_body_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_message_body_cdata(__TopXMLNS, _val) -> _val.
 
-encode_message_body_cdata(undefined, _acc) -> _acc;
+encode_message_body_cdata(<<>>, _acc) -> _acc;
 encode_message_body_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -24952,22 +24814,20 @@ encode_message_subject({text, Lang, Data},
 
 'decode_message_subject_attr_xml:lang'(__TopXMLNS,
 				       undefined) ->
-    undefined;
+    <<>>;
 'decode_message_subject_attr_xml:lang'(__TopXMLNS,
 				       _val) ->
     _val.
 
-'encode_message_subject_attr_xml:lang'(undefined,
-				       _acc) ->
+'encode_message_subject_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_message_subject_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
-decode_message_subject_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_message_subject_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_message_subject_cdata(__TopXMLNS, _val) -> _val.
 
-encode_message_subject_cdata(undefined, _acc) -> _acc;
+encode_message_subject_cdata(<<>>, _acc) -> _acc;
 encode_message_subject_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -25096,10 +24956,10 @@ encode_iq_attr_to(_val, _acc) ->
     [{<<"to">>, enc_jid(_val)} | _acc].
 
 'decode_iq_attr_xml:lang'(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 'decode_iq_attr_xml:lang'(__TopXMLNS, _val) -> _val.
 
-'encode_iq_attr_xml:lang'(undefined, _acc) -> _acc;
+'encode_iq_attr_xml:lang'(<<>>, _acc) -> _acc;
 'encode_iq_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
@@ -25618,12 +25478,11 @@ encode_conference_password(Cdata, _xmlns_attrs) ->
     {xmlel, <<"password">>, _attrs, _els}.
 
 decode_conference_password_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+    <<>>;
 decode_conference_password_cdata(__TopXMLNS, _val) ->
     _val.
 
-encode_conference_password_cdata(undefined, _acc) ->
-    _acc;
+encode_conference_password_cdata(<<>>, _acc) -> _acc;
 encode_conference_password_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -25650,11 +25509,10 @@ encode_conference_nick(Cdata, _xmlns_attrs) ->
     _attrs = _xmlns_attrs,
     {xmlel, <<"nick">>, _attrs, _els}.
 
-decode_conference_nick_cdata(__TopXMLNS, <<>>) ->
-    undefined;
+decode_conference_nick_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_conference_nick_cdata(__TopXMLNS, _val) -> _val.
 
-encode_conference_nick_cdata(undefined, _acc) -> _acc;
+encode_conference_nick_cdata(<<>>, _acc) -> _acc;
 encode_conference_nick_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
@@ -25762,10 +25620,10 @@ encode_disco_items({disco_items, Node, Items, Rsm},
      | _acc].
 
 decode_disco_items_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_disco_items_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_disco_items_attr_node(undefined, _acc) -> _acc;
+encode_disco_items_attr_node(<<>>, _acc) -> _acc;
 encode_disco_items_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -25822,18 +25680,18 @@ encode_disco_item_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
 decode_disco_item_attr_name(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_disco_item_attr_name(__TopXMLNS, _val) -> _val.
 
-encode_disco_item_attr_name(undefined, _acc) -> _acc;
+encode_disco_item_attr_name(<<>>, _acc) -> _acc;
 encode_disco_item_attr_name(_val, _acc) ->
     [{<<"name">>, _val} | _acc].
 
 decode_disco_item_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_disco_item_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_disco_item_attr_node(undefined, _acc) -> _acc;
+encode_disco_item_attr_node(<<>>, _acc) -> _acc;
 encode_disco_item_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -25957,10 +25815,10 @@ encode_disco_info({disco_info, Node, Identities,
 				     | _acc]).
 
 decode_disco_info_attr_node(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_disco_info_attr_node(__TopXMLNS, _val) -> _val.
 
-encode_disco_info_attr_node(undefined, _acc) -> _acc;
+encode_disco_info_attr_node(<<>>, _acc) -> _acc;
 encode_disco_info_attr_node(_val, _acc) ->
     [{<<"node">>, _val} | _acc].
 
@@ -26067,25 +25925,23 @@ encode_disco_identity_attr_type(_val, _acc) ->
 
 'decode_disco_identity_attr_xml:lang'(__TopXMLNS,
 				      undefined) ->
-    undefined;
+    <<>>;
 'decode_disco_identity_attr_xml:lang'(__TopXMLNS,
 				      _val) ->
     _val.
 
-'encode_disco_identity_attr_xml:lang'(undefined,
-				      _acc) ->
+'encode_disco_identity_attr_xml:lang'(<<>>, _acc) ->
     _acc;
 'encode_disco_identity_attr_xml:lang'(_val, _acc) ->
     [{<<"xml:lang">>, _val} | _acc].
 
 decode_disco_identity_attr_name(__TopXMLNS,
 				undefined) ->
-    undefined;
+    <<>>;
 decode_disco_identity_attr_name(__TopXMLNS, _val) ->
     _val.
 
-encode_disco_identity_attr_name(undefined, _acc) ->
-    _acc;
+encode_disco_identity_attr_name(<<>>, _acc) -> _acc;
 encode_disco_identity_attr_name(_val, _acc) ->
     [{<<"name">>, _val} | _acc].
 
@@ -26103,20 +25959,13 @@ decode_block_list_els(__TopXMLNS, __IgnoreEls,
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> ->
 	  decode_block_list_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_block_item(__TopXMLNS, __IgnoreEls,
-						       _el)
-				    of
-				  undefined -> Items;
-				  _new_el -> [_new_el | Items]
-				end);
+				[decode_block_item(__TopXMLNS, __IgnoreEls, _el)
+				 | Items]);
       <<"urn:xmpp:blocking">> ->
 	  decode_block_list_els(__TopXMLNS, __IgnoreEls, _els,
-				case decode_block_item(<<"urn:xmpp:blocking">>,
-						       __IgnoreEls, _el)
-				    of
-				  undefined -> Items;
-				  _new_el -> [_new_el | Items]
-				end);
+				[decode_block_item(<<"urn:xmpp:blocking">>,
+						   __IgnoreEls, _el)
+				 | Items]);
       _ ->
 	  decode_block_list_els(__TopXMLNS, __IgnoreEls, _els,
 				Items)
@@ -26151,20 +26000,13 @@ decode_unblock_els(__TopXMLNS, __IgnoreEls,
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> ->
 	  decode_unblock_els(__TopXMLNS, __IgnoreEls, _els,
-			     case decode_block_item(__TopXMLNS, __IgnoreEls,
-						    _el)
-				 of
-			       undefined -> Items;
-			       _new_el -> [_new_el | Items]
-			     end);
+			     [decode_block_item(__TopXMLNS, __IgnoreEls, _el)
+			      | Items]);
       <<"urn:xmpp:blocking">> ->
 	  decode_unblock_els(__TopXMLNS, __IgnoreEls, _els,
-			     case decode_block_item(<<"urn:xmpp:blocking">>,
-						    __IgnoreEls, _el)
-				 of
-			       undefined -> Items;
-			       _new_el -> [_new_el | Items]
-			     end);
+			     [decode_block_item(<<"urn:xmpp:blocking">>,
+						__IgnoreEls, _el)
+			      | Items]);
       _ ->
 	  decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, Items)
     end;
@@ -26197,19 +26039,13 @@ decode_block_els(__TopXMLNS, __IgnoreEls,
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> ->
 	  decode_block_els(__TopXMLNS, __IgnoreEls, _els,
-			   case decode_block_item(__TopXMLNS, __IgnoreEls, _el)
-			       of
-			     undefined -> Items;
-			     _new_el -> [_new_el | Items]
-			   end);
+			   [decode_block_item(__TopXMLNS, __IgnoreEls, _el)
+			    | Items]);
       <<"urn:xmpp:blocking">> ->
 	  decode_block_els(__TopXMLNS, __IgnoreEls, _els,
-			   case decode_block_item(<<"urn:xmpp:blocking">>,
-						  __IgnoreEls, _el)
-			       of
-			     undefined -> Items;
-			     _new_el -> [_new_el | Items]
-			   end);
+			   [decode_block_item(<<"urn:xmpp:blocking">>,
+					      __IgnoreEls, _el)
+			    | Items]);
       _ ->
 	  decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items)
     end;
@@ -26692,11 +26528,11 @@ encode_privacy_item_attr_type(_val, _acc) ->
     [{<<"type">>, enc_enum(_val)} | _acc].
 
 decode_privacy_item_attr_value(__TopXMLNS, undefined) ->
-    undefined;
+    <<>>;
 decode_privacy_item_attr_value(__TopXMLNS, _val) ->
     _val.
 
-encode_privacy_item_attr_value(undefined, _acc) -> _acc;
+encode_privacy_item_attr_value(<<>>, _acc) -> _acc;
 encode_privacy_item_attr_value(_val, _acc) ->
     [{<<"value">>, _val} | _acc].
 
diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl
index a4f37c926..20231fffa 100644
--- a/src/xmpp_util.erl
+++ b/src/xmpp_util.erl
@@ -94,7 +94,7 @@ make_adhoc_response(#adhoc_command{lang = Lang, node = Node, sid = SID},
     Command#adhoc_command{lang = Lang, node = Node, sid = SID}.
 
 -spec make_adhoc_response(adhoc_command()) -> adhoc_command().
-make_adhoc_response(#adhoc_command{sid = undefined} = Command) ->
+make_adhoc_response(#adhoc_command{sid = <<"">>} = Command) ->
     SID = jlib:now_to_utc_string(p1_time_compat:timestamp()),
     Command#adhoc_command{sid = SID};
 make_adhoc_response(Command) ->
-- 
cgit v1.2.3


From 522a186a3822a3fdb04a423b2238aab2fcfb4b1c Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Tue, 9 Aug 2016 10:56:32 +0300
Subject: Improve some type specs

---
 src/ejabberd_auth_anonymous.erl   |   2 +
 src/ejabberd_c2s.erl              |  98 +++++++++++++++++++++-------
 src/ejabberd_config.erl           |   2 +-
 src/ejabberd_local.erl            |   5 +-
 src/ejabberd_router_multicast.erl |   2 +-
 src/ejabberd_s2s_in.erl           |  31 ++++-----
 src/ejabberd_s2s_out.erl          |   8 +--
 src/ejabberd_service.erl          |   2 +-
 src/ejabberd_sm.erl               |   8 +--
 src/ejabberd_socket.erl           |   2 +-
 src/ejabberd_system_monitor.erl   |   3 +-
 src/ejabberd_web_admin.erl        |  35 +++++-----
 src/gen_iq_handler.erl            |   1 +
 src/gen_mod.erl                   |   2 +-
 src/mod_adhoc.erl                 |  24 +++++--
 src/mod_announce.erl              |  43 ++++++-------
 src/mod_blocking.erl              |   7 +-
 src/mod_caps.erl                  |  28 +++++---
 src/mod_carboncopy.erl            |   2 +-
 src/mod_client_state.erl          |  26 ++++----
 src/mod_configure.erl             |  16 +++--
 src/mod_disco.erl                 |   5 +-
 src/mod_fail2ban.erl              |   8 ++-
 src/mod_http_upload.erl           |   9 ++-
 src/mod_ip_blacklist.erl          |   4 ++
 src/mod_irc.erl                   |   6 +-
 src/mod_irc_connection.erl        |  18 +++---
 src/mod_mam.erl                   |  12 ++--
 src/mod_metrics.erl               |  41 ++++++++----
 src/mod_mix.erl                   |   4 ++
 src/mod_muc_room.erl              | 132 ++++++++++++++++++++------------------
 src/mod_offline.erl               |   7 +-
 src/mod_ping.erl                  |   4 +-
 src/mod_privacy.erl               |   1 +
 src/mod_private.erl               |   1 +
 src/mod_pubsub.erl                |  16 ++++-
 src/mod_register.erl              |   4 ++
 src/mod_roster.erl                |   7 +-
 src/mod_shared_roster.erl         |  10 ++-
 src/mod_shared_roster_ldap.erl    |   3 +
 src/mod_vcard_xupdate.erl         |   3 +-
 src/node_online.erl               |   1 +
 src/xmpp.erl                      |   2 +-
 src/xmpp_codec.erl                |  22 ++++---
 44 files changed, 417 insertions(+), 250 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl
index c0ad1fb21..c84321ad9 100644
--- a/src/ejabberd_auth_anonymous.erl
+++ b/src/ejabberd_auth_anonymous.erl
@@ -139,6 +139,7 @@ remove_connection(SID, LUser, LServer) ->
     mnesia:transaction(F).
 
 %% Register connection
+-spec register_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
 register_connection(SID,
 		    #jid{luser = LUser, lserver = LServer}, Info) ->
     AuthModule = proplists:get_value(auth_module, Info, undefined),
@@ -155,6 +156,7 @@ register_connection(SID,
     end.
 
 %% Remove an anonymous user from the anonymous users table
+-spec unregister_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
 unregister_connection(SID,
 		      #jid{luser = LUser, lserver = LServer}, _) ->
     purge_hook(anonymous_user_exist(LUser, LServer), LUser,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index b13e7fe00..9c1d99091 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -125,6 +125,7 @@
 -type state() :: #state{}.
 -type fsm_stop() :: {stop, normal, state()}.
 -type fsm_next() :: {next_state, state_name(), state(), non_neg_integer()}.
+-type fsm_reply() :: {reply, any(), state_name(), state(), non_neg_integer()}.
 -type fsm_transition() :: fsm_stop() | fsm_next().
 -export_type([state/0]).
 
@@ -184,9 +185,9 @@ get_presence(FsmRef) ->
 
 -spec get_aux_field(any(), state()) -> {ok, any()} | error.
 get_aux_field(Key, #state{aux_fields = Opts}) ->
-    case lists:keysearch(Key, 1, Opts) of
-      {value, {_, Val}} -> {ok, Val};
-      _ -> error
+    case lists:keyfind(Key, 1, Opts) of
+	{_, Val} -> {ok, Val};
+	false -> error
     end.
 
 -spec set_aux_field(any(), any(), state()) -> state().
@@ -525,7 +526,7 @@ wait_for_auth(#iq{type = get,
     Auth = #legacy_auth{username = Username, password = <<>>, resource = <<>>},
     Res = case ejabberd_auth:plain_password_required(StateData#state.server) of
 	      false ->
-		  xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = none});
+		  xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = <<>>});
 	      true ->
 		  xmpp:make_iq_result(IQ, Auth)
 	  end,
@@ -1067,7 +1068,6 @@ session_established2(Pkt, StateData) ->
 		J -> J
 	    end,
     Lang = case xmpp:get_lang(Pkt) of
-	       undefined -> StateData#state.lang;
 	       <<"">> -> StateData#state.lang;
 	       L -> L
 	   end,
@@ -1252,7 +1252,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Pac
 			process_presence_probe(From, To, NewStateData),
 			{false, NewStateData};
 		    error ->
-			NewA = remove_element(jid:tolower(From), State#state.pres_a),
+			NewA = ?SETS:del_element(jid:tolower(From), State#state.pres_a),
 			{true, State#state{pres_a = NewA}};
 		    subscribe ->
 			SRes = is_privacy_allow(State, From, To, Packet, in),
@@ -1666,6 +1666,7 @@ get_conn_type(StateData) ->
 	websocket -> websocket
     end.
 
+-spec process_presence_probe(jid(), jid(), state()) -> ok.
 process_presence_probe(From, To, StateData) ->
     LFrom = jid:tolower(From),
     LBFrom = setelement(3, LFrom, <<"">>),
@@ -1702,6 +1703,7 @@ process_presence_probe(From, To, StateData) ->
     end.
 
 %% User updates his presence (non-directed presence packet)
+-spec presence_update(jid(), presence(), state()) -> state().
 presence_update(From, Packet, StateData) ->
     #presence{type = Type} = Packet,
     case Type of
@@ -1761,6 +1763,7 @@ presence_update(From, Packet, StateData) ->
     end.
 
 %% User sends a directed presence packet
+-spec presence_track(jid(), jid(), presence(), state()) -> state().
 presence_track(From, To, Packet, StateData) ->
     #presence{type = Type} = Packet,
     LTo = jid:tolower(To),
@@ -1768,7 +1771,7 @@ presence_track(From, To, Packet, StateData) ->
     Server = StateData#state.server,
     case Type of
       unavailable ->
-	  A = remove_element(LTo, StateData#state.pres_a),
+	  A = ?SETS:del_element(LTo, StateData#state.pres_a),
 	  check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet);
       subscribe ->
 	  try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData);
@@ -1793,6 +1796,7 @@ presence_track(From, To, Packet, StateData) ->
 	  check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet)
     end.
 
+-spec check_privacy_route(jid(), state(), jid(), jid(), stanza()) -> state().
 check_privacy_route(From, StateData, FromRoute, To,
 		    Packet) ->
     case privacy_check_packet(StateData, From, To, Packet,
@@ -1812,6 +1816,7 @@ check_privacy_route(From, StateData, FromRoute, To,
     end.
 
 %% Check if privacy rules allow this delivery
+-spec privacy_check_packet(state(), jid(), jid(), stanza(), in | out) -> allow | deny.
 privacy_check_packet(StateData, From, To, Packet,
 		     Dir) ->
     ejabberd_hooks:run_fold(privacy_check_packet,
@@ -1820,11 +1825,14 @@ privacy_check_packet(StateData, From, To, Packet,
 			     StateData#state.privacy_list, {From, To, Packet},
 			     Dir]).
 
+-spec is_privacy_allow(state(), jid(), jid(), stanza(), in | out) -> boolean().
 is_privacy_allow(StateData, From, To, Packet, Dir) ->
     allow ==
       privacy_check_packet(StateData, From, To, Packet, Dir).
 
 %%% Check ACL before allowing to send a subscription stanza
+-spec try_roster_subscribe(subscribe | unsubscribe, binary(), binary(),
+			   jid(), jid(), presence(), state()) -> state().
 try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
     JID1 = jid:make(User, Server, <<"">>),
     Access = gen_mod:get_module_opt(Server, mod_roster, access, fun(A) when is_atom(A) -> A end, all),
@@ -1841,21 +1849,24 @@ try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
     end.
 
 %% Send presence when disconnecting
+-spec presence_broadcast(state(), jid(), ?SETS:set(), presence()) -> ok.
 presence_broadcast(StateData, From, JIDSet, Packet) ->
     JIDs = ?SETS:to_list(JIDSet),
     JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs, out),
     Server = StateData#state.server,
     send_multiple(From, Server, JIDs2, Packet).
 
+-spec presence_broadcast_to_trusted(
+	state(), jid(), ?SETS:set(), ?SETS:set(), presence()) -> ok.
 %% Send presence when updating presence
 presence_broadcast_to_trusted(StateData, From, Trusted, JIDSet, Packet) ->
-    JIDs = ?SETS:to_list(JIDSet),
-    JIDs_trusted = [JID || JID <- JIDs, ?SETS:is_element(JID, Trusted)],
-    JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs_trusted, out),
+    JIDs = ?SETS:to_list(?SETS:intersection(Trusted, JIDSet)),
+    JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs, out),
     Server = StateData#state.server,
     send_multiple(From, Server, JIDs2, Packet).
 
 %% Send presence when connecting
+-spec presence_broadcast_first(jid(), state(), presence()) -> state().
 presence_broadcast_first(From, StateData, Packet) ->
     JIDsProbe =
 	?SETS:fold(
@@ -1877,6 +1888,8 @@ presence_broadcast_first(From, StateData, Packet) ->
     send_multiple(From, Server, JIDs2, Packet),
     StateData#state{pres_a = As}.
 
+-spec format_and_check_privacy(
+	jid(), state(), stanza(), [ljid()], in | out) -> [jid()].
 format_and_check_privacy(From, StateData, Packet, JIDs, Dir) ->
     FJIDs = [jid:make(JID) || JID <- JIDs],
     lists:filter(
@@ -1895,15 +1908,11 @@ format_and_check_privacy(From, StateData, Packet, JIDs, Dir) ->
       end,
       FJIDs).
 
+-spec send_multiple(jid(), binary(), [jid()], stanza()) -> ok.
 send_multiple(From, Server, JIDs, Packet) ->
     ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet).
 
-remove_element(E, Set) ->
-    case (?SETS):is_element(E, Set) of
-      true -> (?SETS):del_element(E, Set);
-      _ -> Set
-    end.
-
+-spec roster_change(jid(), both | from | none | remove | to, state()) -> state().
 roster_change(IJID, ISubscription, StateData) ->
     LIJID = jid:tolower(IJID),
     IsFrom = (ISubscription == both) or (ISubscription == from),
@@ -1911,11 +1920,11 @@ roster_change(IJID, ISubscription, StateData) ->
     OldIsFrom = (?SETS):is_element(LIJID, StateData#state.pres_f),
     FSet = if
 	       IsFrom -> (?SETS):add_element(LIJID, StateData#state.pres_f);
-	       true -> remove_element(LIJID, StateData#state.pres_f)
+	       true -> ?SETS:del_element(LIJID, StateData#state.pres_f)
 	   end,
     TSet = if
 	       IsTo -> (?SETS):add_element(LIJID, StateData#state.pres_t);
-	       true -> remove_element(LIJID, StateData#state.pres_t)
+	       true -> ?SETS:del_element(LIJID, StateData#state.pres_t)
 	   end,
     case StateData#state.pres_last of
       undefined ->
@@ -1946,13 +1955,14 @@ roster_change(IJID, ISubscription, StateData) ->
 		   deny -> ok;
 		   allow -> ejabberd_router:route(From, To, PU)
 		 end,
-		 A = remove_element(LIJID, StateData#state.pres_a),
+		 A = ?SETS:del_element(LIJID, StateData#state.pres_a),
 		 StateData#state{pres_a = A, pres_f = FSet,
 				 pres_t = TSet};
 	     true -> StateData#state{pres_f = FSet, pres_t = TSet}
 	  end
     end.
 
+-spec update_priority(integer(), presence(), state()) -> ok.
 update_priority(Priority, Packet, StateData) ->
     Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
 	    {auth_module, StateData#state.auth_module}],
@@ -1960,12 +1970,14 @@ update_priority(Priority, Packet, StateData) ->
 			     StateData#state.user, StateData#state.server,
 			     StateData#state.resource, Priority, Packet, Info).
 
+-spec get_priority_from_presence(presence()) -> integer().
 get_priority_from_presence(#presence{priority = Prio}) ->
     case Prio of
 	undefined -> 0;
 	_ -> Prio
     end.
 
+-spec process_privacy_iq(iq(), state()) -> state().
 process_privacy_iq(#iq{from = From, to = To,
 		       type = Type, lang = Lang} = IQ, StateData) ->
     Txt = <<"No module is handling this query">>,
@@ -2001,6 +2013,7 @@ process_privacy_iq(#iq{from = From, to = To,
     ejabberd_router:route(To, From, IQRes),
     NewStateData.
 
+-spec resend_offline_messages(state()) -> ok.
 resend_offline_messages(#state{ask_offline = true} = StateData) ->
     case ejabberd_hooks:run_fold(resend_offline_messages_hook,
 				 StateData#state.server, [],
@@ -2025,6 +2038,7 @@ resend_offline_messages(#state{ask_offline = true} = StateData) ->
 resend_offline_messages(_StateData) ->
     ok.
 
+-spec resend_subscription_requests(state()) -> state().
 resend_subscription_requests(#state{user = User,
 				    server = Server} = StateData) ->
     PendingSubscriptions =
@@ -2036,13 +2050,16 @@ resend_subscription_requests(#state{user = User,
 		StateData,
 		PendingSubscriptions).
 
+-spec get_showtag(undefined | presence()) -> binary().
 get_showtag(undefined) -> <<"unavailable">>;
 get_showtag(#presence{show = undefined}) -> <<"available">>;
 get_showtag(#presence{show = Show}) -> atom_to_binary(Show, utf8).
 
-get_statustag(#presence{status = [#text{data = Status}|_]}) -> Status;
-get_statustag(_) -> <<"">>.
+-spec get_statustag(undefined | presence()) -> binary().
+get_statustag(#presence{status = Status}) -> xmpp:get_text(Status);
+get_statustag(undefined) -> <<"">>.
 
+-spec process_unauthenticated_stanza(state(), iq()) -> ok | {error, any()}.
 process_unauthenticated_stanza(StateData, #iq{type = T, lang = L} = IQ)
   when T == set; T == get ->
     Lang = if L == undefined; L == <<"">> -> StateData#state.lang;
@@ -2067,6 +2084,9 @@ process_unauthenticated_stanza(_StateData, _) ->
     %% Drop any stanza, which isn't IQ stanza
     ok.
 
+-spec peerip(ejabberd_socket:sockmod(),
+	     ejabberd_socket:socket()) ->
+		    {inet:ip_address(), non_neg_integer()} | undefined.
 peerip(SockMod, Socket) ->
     IP = case SockMod of
 	   gen_tcp -> inet:peername(Socket);
@@ -2124,6 +2144,7 @@ fsm_next_state(StateName, StateData) ->
 
 %% fsm_reply: Generate the reply FSM tuple with different timeout,
 %% depending on the future state
+-spec fsm_reply(_, state_name(), state()) -> fsm_reply().
 fsm_reply(Reply, session_established, StateData) ->
     {reply, Reply, session_established, StateData,
      ?C2S_HIBERNATE_TIMEOUT};
@@ -2135,6 +2156,8 @@ fsm_reply(Reply, StateName, StateData) ->
     {reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.
 
 %% Used by c2s blacklist plugins
+-spec is_ip_blacklisted(undefined | {inet:ip_address(), non_neg_integer()},
+			binary()) -> false | {true, binary(), binary()}.
 is_ip_blacklisted(undefined, _Lang) -> false;
 is_ip_blacklisted({IP, _Port}, Lang) ->
     ejabberd_hooks:run_fold(check_bl_c2s, false, [IP, Lang]).
@@ -2174,6 +2197,7 @@ fsm_limit_opts(Opts) ->
 	  end
     end.
 
+-spec bounce_messages() -> ok.
 bounce_messages() ->
     receive
       {route, From, To, El} ->
@@ -2181,6 +2205,7 @@ bounce_messages() ->
       after 0 -> ok
     end.
 
+-spec process_compression_request(compress(), state_name(), state()) -> fsm_next().
 process_compression_request(#compress{methods = []}, StateName, StateData) ->
     send_element(StateData, #compress_failure{reason = 'setup-failed'}),
     fsm_next_state(StateName, StateData);
@@ -2203,6 +2228,8 @@ process_compression_request(#compress{methods = Ms}, StateName, StateData) ->
 %%% XEP-0191
 %%%----------------------------------------------------------------------
 
+-spec route_blocking(
+	{block, [jid()]} | {unblock, [jid()]} | unblock_all, state()) -> state().
 route_blocking(What, StateData) ->
     SubEl = case What of
 		{block, JIDs} ->
@@ -2223,12 +2250,13 @@ route_blocking(What, StateData) ->
 %%%----------------------------------------------------------------------
 %%% XEP-0198
 %%%----------------------------------------------------------------------
-
+-spec stream_mgmt_enabled(state()) -> boolean().
 stream_mgmt_enabled(#state{mgmt_state = disabled}) ->
     false;
 stream_mgmt_enabled(_StateData) ->
     true.
 
+-spec dispatch_stream_mgmt(xmpp_element(), state()) -> state().
 dispatch_stream_mgmt(El, #state{mgmt_state = MgmtState} = StateData)
     when MgmtState == active;
 	 MgmtState == pending ->
@@ -2236,6 +2264,7 @@ dispatch_stream_mgmt(El, #state{mgmt_state = MgmtState} = StateData)
 dispatch_stream_mgmt(El, StateData) ->
     negotiate_stream_mgmt(El, StateData).
 
+-spec negotiate_stream_mgmt(xmpp_element(), state()) -> state().
 negotiate_stream_mgmt(_El, #state{resource = <<"">>} = StateData) ->
     %% XEP-0198 says: "For client-to-server connections, the client MUST NOT
     %% attempt to enable stream management until after it has completed Resource
@@ -2272,6 +2301,7 @@ negotiate_stream_mgmt(Pkt, StateData) ->
 	    StateData
     end.
 
+-spec perform_stream_mgmt(xmpp_element(), state()) -> state().
 perform_stream_mgmt(Pkt, StateData) ->
     case xmpp:get_ns(Pkt) of
 	Xmlns when Xmlns == StateData#state.mgmt_xmlns ->
@@ -2298,6 +2328,7 @@ perform_stream_mgmt(Pkt, StateData) ->
 				    xmlns = StateData#state.mgmt_xmlns})
     end.
 
+-spec handle_enable(state(), sm_enable()) -> state().
 handle_enable(#state{mgmt_timeout = DefaultTimeout,
 		     mgmt_max_timeout = MaxTimeout} = StateData,
 	      #sm_enable{resume = Resume, max = Max}) ->
@@ -2325,15 +2356,18 @@ handle_enable(#state{mgmt_timeout = DefaultTimeout,
 		    mgmt_queue = queue:new(),
 		    mgmt_timeout = Timeout * 1000}.
 
+-spec handle_r(state()) -> state().
 handle_r(StateData) ->
     Res = #sm_a{xmlns = StateData#state.mgmt_xmlns,
 		h = StateData#state.mgmt_stanzas_in},
     send_element(StateData, Res),
     StateData.
 
+-spec handle_a(state(), sm_a()) -> state().
 handle_a(StateData, #sm_a{h = H}) ->
     check_h_attribute(StateData, H).
 
+-spec handle_resume(state(), sm_resume()) -> {ok, state()} | error.
 handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) ->
     R = case stream_mgmt_enabled(StateData) of
 	    true ->
@@ -2379,6 +2413,7 @@ handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) ->
 	  error
     end.
 
+-spec check_h_attribute(state(), non_neg_integer()) -> state().
 check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H)
     when H > NumStanzasOut ->
     ?DEBUG("~s acknowledged ~B stanzas, but only ~B were sent",
@@ -2389,6 +2424,7 @@ check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H) ->
 	   [jid:to_string(StateData#state.jid), H, NumStanzasOut]),
     mgmt_queue_drop(StateData, H).
 
+-spec update_num_stanzas_in(state(), xmpp_element()) -> state().
 update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El)
     when MgmtState == active;
 	 MgmtState == pending ->
@@ -2404,6 +2440,7 @@ update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El)
 update_num_stanzas_in(StateData, _El) ->
     StateData.
 
+-spec send_stanza_and_ack_req(state(), stanza()) -> state().
 send_stanza_and_ack_req(StateData, Stanza) ->
     AckReq = #sm_r{xmlns = StateData#state.mgmt_xmlns},
     case send_element(StateData, Stanza) == ok andalso
@@ -2414,6 +2451,7 @@ send_stanza_and_ack_req(StateData, Stanza) ->
 	  StateData#state{mgmt_state = pending}
     end.
 
+-spec mgmt_queue_add(state(), xmpp_element()) -> state().
 mgmt_queue_add(StateData, El) ->
     NewNum = case StateData#state.mgmt_stanzas_out of
 	       4294967295 ->
@@ -2426,11 +2464,13 @@ mgmt_queue_add(StateData, El) ->
 			       mgmt_stanzas_out = NewNum},
     check_queue_length(NewState).
 
+-spec mgmt_queue_drop(state(), non_neg_integer()) -> state().
 mgmt_queue_drop(StateData, NumHandled) ->
     NewQueue = jlib:queue_drop_while(fun({N, _T, _E}) -> N =< NumHandled end,
 				     StateData#state.mgmt_queue),
     StateData#state{mgmt_queue = NewQueue}.
 
+-spec check_queue_length(state()) -> state().
 check_queue_length(#state{mgmt_max_queue = Limit} = StateData)
     when Limit == infinity;
 	 Limit == exceeded ->
@@ -2444,6 +2484,7 @@ check_queue_length(#state{mgmt_queue = Queue,
 	  StateData
     end.
 
+-spec handle_unacked_stanzas(state(), fun((_, _, _, _) -> _)) -> ok.
 handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F)
     when MgmtState == active;
 	 MgmtState == pending;
@@ -2465,6 +2506,7 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F)
 handle_unacked_stanzas(_StateData, _F) ->
     ok.
 
+-spec handle_unacked_stanzas(state()) -> ok.
 handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData)
     when MgmtState == active;
 	 MgmtState == pending;
@@ -2537,6 +2579,7 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData)
 handle_unacked_stanzas(_StateData) ->
     ok.
 
+-spec is_encapsulated_forward(stanza()) -> boolean().
 is_encapsulated_forward(#message{} = Msg) ->
     xmpp:has_subtag(Msg, #forwarded{}) orelse
 	xmpp:has_subtag(Msg, #carbons_sent{}) orelse
@@ -2544,6 +2587,9 @@ is_encapsulated_forward(#message{} = Msg) ->
 is_encapsulated_forward(_El) ->
     false.
 
+-spec inherit_session_state(state(), binary()) -> {ok, state()} |
+						  {error, binary()} |
+						  {error, binary(), non_neg_integer()}.
 inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
     case jlib:base64_to_term(ResumeID) of
       {term, {R, Time}} ->
@@ -2604,13 +2650,16 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
 	  {error, <<"Invalid 'previd' value">>}
     end.
 
+-spec resume_session({integer(), pid()}) -> any().
 resume_session({Time, PID}) ->
     (?GEN_FSM):sync_send_all_state_event(PID, {resume_session, Time}, 5000).
 
+-spec make_resume_id(state()) -> binary().
 make_resume_id(StateData) ->
     {Time, _} = StateData#state.sid,
     jlib:term_to_base64({StateData#state.resource, Time}).
 
+-spec add_resent_delay_info(state(), stanza(), erlang:timestamp()) -> stanza().
 add_resent_delay_info(_State, #iq{} = El, _Time) ->
     El;
 add_resent_delay_info(#state{server = From}, El, Time) ->
@@ -2619,7 +2668,7 @@ add_resent_delay_info(#state{server = From}, El, Time) ->
 %%%----------------------------------------------------------------------
 %%% XEP-0352
 %%%----------------------------------------------------------------------
-
+-spec csi_filter_stanza(state(), stanza()) -> state().
 csi_filter_stanza(#state{csi_state = CsiState, server = Server} = StateData,
 		  Stanza) ->
     {StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_filter_stanza, Server,
@@ -2631,6 +2680,7 @@ csi_filter_stanza(#state{csi_state = CsiState, server = Server} = StateData,
 			     Stanzas),
     StateData2#state{csi_state = CsiState}.
 
+-spec csi_flush_queue(state()) -> state().
 csi_flush_queue(#state{csi_state = CsiState, server = Server} = StateData) ->
     {StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_flush_queue, Server,
 						    {StateData, []}, [Server]),
@@ -2646,6 +2696,7 @@ csi_flush_queue(#state{csi_state = CsiState, server = Server} = StateData) ->
 
 %% Try to reduce the heap footprint of the four presence sets
 %% by ensuring that we re-use strings and Jids wherever possible.
+-spec pack(state()) -> state().
 pack(S = #state{pres_a = A, pres_f = F,
 		pres_t = T}) ->
     {NewA, Pack2} = pack_jid_set(A, gb_trees:empty()),
@@ -2682,6 +2733,7 @@ pack_string(String, Pack) ->
 transform_listen_option(Opt, Opts) ->
     [Opt|Opts].
 
+-spec identity([{atom(), binary()}]) -> binary().
 identity(Props) ->
     case proplists:get_value(authzid, Props, <<>>) of
 	<<>> -> proplists:get_value(username, Props, <<>>);
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 5a39df043..d82e32b9a 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -877,7 +877,7 @@ v_db(Mod, Type) ->
 	[] -> erlang:error(badarg)
     end.
 
--spec default_db(binary(), module()) -> atom().
+-spec default_db(global | binary(), module()) -> atom().
 
 default_db(Host, Module) ->
     case ejabberd_config:get_option(
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index dca456427..c2bf453a5 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -183,14 +183,13 @@ unregister_iq_handler(Host, XMLNS) ->
 refresh_iq_handlers() ->
     ejabberd_local ! refresh_iq_handlers.
 
--spec bounce_resource_packet(jid(), jid(), stanza()) -> stop.
+-spec bounce_resource_packet(jid(), jid(), stanza()) -> ok.
 bounce_resource_packet(From, To, Packet) ->
     Lang = xmpp:get_lang(Packet),
     Txt = <<"No available resource found">>,
     Err = xmpp:make_error(Packet,
 			  xmpp:err_item_not_found(Txt, Lang)),
-    ejabberd_router:route(To, From, Err),
-    stop.
+    ejabberd_router:route(To, From, Err).
 
 %%====================================================================
 %% gen_server callbacks
diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl
index 967699007..283bcac25 100644
--- a/src/ejabberd_router_multicast.erl
+++ b/src/ejabberd_router_multicast.erl
@@ -45,7 +45,7 @@
 -include("logger.hrl").
 -include("xmpp.hrl").
 
--record(route_multicast, {domain = <<"">> :: binary(),
+-record(route_multicast, {domain = <<"">> :: binary() | '_',
 			  pid = self() :: pid()}).
 -record(state, {}).
 
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 04b961b3d..7be4906fb 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -62,7 +62,7 @@
 	 connections = (?DICT):new() :: ?TDICT,
          timer = make_ref()          :: reference()}).
 
--type state_name() :: wait_for_stream | wait_for_features | stream_established.
+-type state_name() :: wait_for_stream | wait_for_feature_request | stream_established.
 -type state() :: #state{}.
 -type fsm_next() :: {next_state, state_name(), state()}.
 -type fsm_stop() :: {stop, normal, state()}.
@@ -287,7 +287,8 @@ wait_for_feature_request(#starttls{},
 		      end,
 	    TLSSocket = (StateData#state.sockmod):starttls(
 			  Socket, TLSOpts,
-			  fxml:element_to_binary(#starttls_proceed{})),
+			  fxml:element_to_binary(
+			    xmpp:encode(#starttls_proceed{}))),
 	    {next_state, wait_for_stream,
 	     StateData#state{socket = TLSSocket, streamid = new_id(),
 			     tls_enabled = true, tls_options = TLSOpts}};
@@ -342,19 +343,17 @@ stream_established({xmlstreamelement, El}, StateData) ->
 stream_established(#db_result{to = To, from = From, key = Key},
 		   StateData) ->
     ?DEBUG("GET KEY: ~p", [{To, From, Key}]),
-    LTo = To#jid.lserver,
-    LFrom = From#jid.lserver,
-    case {ejabberd_s2s:allow_host(LTo, LFrom),
-	  lists:member(LTo, ejabberd_router:dirty_get_all_domains())} of
+    case {ejabberd_s2s:allow_host(To, From),
+	  lists:member(To, ejabberd_router:dirty_get_all_domains())} of
 	{true, true} ->
-	    ejabberd_s2s_out:terminate_if_waiting_delay(LTo, LFrom),
-	    ejabberd_s2s_out:start(LTo, LFrom,
+	    ejabberd_s2s_out:terminate_if_waiting_delay(To, From),
+	    ejabberd_s2s_out:start(To, From,
 				   {verify, self(), Key,
 				    StateData#state.streamid}),
-	    Conns = (?DICT):store({LFrom, LTo},
+	    Conns = (?DICT):store({From, To},
 				  wait_for_verification,
 				  StateData#state.connections),
-	    change_shaper(StateData, LTo, jid:make(LFrom)),
+	    change_shaper(StateData, To, jid:make(From)),
 	    {next_state, stream_established,
 	     StateData#state{connections = Conns}};
 	{_, false} ->
@@ -367,9 +366,7 @@ stream_established(#db_result{to = To, from = From, key = Key},
 stream_established(#db_verify{to = To, from = From, id = Id, key = Key},
 		   StateData) ->
     ?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]),
-    LTo = jid:nameprep(To),
-    LFrom = jid:nameprep(From),
-    Type = case ejabberd_s2s:make_key({LTo, LFrom}, Id) of
+    Type = case ejabberd_s2s:make_key({To, From}, Id) of
 	       Key -> valid;
 	       _ -> invalid
 	   end,
@@ -412,19 +409,15 @@ stream_established({valid, From, To}, StateData) ->
 		 #db_result{from = To, to = From, type = valid}),
     ?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)",
 	      [From, StateData#state.tls_enabled]),
-    LFrom = jid:nameprep(From),
-    LTo = jid:nameprep(To),
     NSD = StateData#state{connections =
-			      (?DICT):store({LFrom, LTo}, established,
+			      (?DICT):store({From, To}, established,
 					    StateData#state.connections)},
     {next_state, stream_established, NSD};
 stream_established({invalid, From, To}, StateData) ->
     send_element(StateData,
 		 #db_result{from = To, to = From, type = invalid}),
-    LFrom = jid:nameprep(From),
-    LTo = jid:nameprep(To),
     NSD = StateData#state{connections =
-			      (?DICT):erase({LFrom, LTo},
+			      (?DICT):erase({From, To},
 					    StateData#state.connections)},
     {next_state, stream_established, NSD};
 stream_established({xmlstreamend, _Name}, StateData) ->
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 024e51e7a..4284f7f7b 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -832,15 +832,15 @@ send_db_request(StateData) ->
 		       {StateData#state.myname, Server},
 		       StateData#state.remote_streamid),
 	      send_element(StateData,
-			   #db_result{from = jid:make(StateData#state.myname),
-				      to = jid:make(Server),
+			   #db_result{from = StateData#state.myname,
+				      to = Server,
 				      key = Key1})
 	end,
 	case StateData#state.verify of
 	  false -> ok;
 	  {_Pid, Key2, SID} ->
 	      send_element(StateData,
-			   #db_verify{from = jid:make(StateData#state.myname),
+			   #db_verify{from = StateData#state.myname,
 				      to = StateData#state.server,
 				      id = SID,
 				      key = Key2})
@@ -1067,7 +1067,7 @@ get_max_retry_delay() ->
     end.
 
 %% Terminate s2s_out connections that are in state wait_before_retry
--spec terminate_if_waiting_delay(ljid(), ljid()) -> ok.
+-spec terminate_if_waiting_delay(binary(), binary()) -> ok.
 terminate_if_waiting_delay(From, To) ->
     FromTo = {From, To},
     Pids = ejabberd_s2s:get_connections_pids(FromTo),
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index 432253e09..3df39438a 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -127,7 +127,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
     try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of
 	#stream_start{xmlns = ?NS_COMPONENT, to = To} when is_record(To, jid) ->
 	    Host = To#jid.lserver,
-	    send_header(StateData, To),
+	    send_header(StateData, Host),
 	    HostOpts = case dict:is_key(Host, StateData#state.host_opts) of
 			   true ->
 			       StateData#state.host_opts;
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index bc550ef44..3ff9f2908 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -110,7 +110,7 @@
 %%====================================================================
 %% API
 %%====================================================================
--export_type([sid/0]).
+-export_type([sid/0, info/0]).
 
 start() ->
     ChildSpec = {?MODULE, {?MODULE, start_link, []},
@@ -168,7 +168,7 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
       false -> {stop, false}
     end.
 
--spec bounce_offline_message(jid(), jid(), xmlel()) -> stop.
+-spec bounce_offline_message(jid(), jid(), message()) -> stop.
 
 bounce_offline_message(From, To, Packet) ->
     Lang = xmpp:get_lang(Packet),
@@ -234,7 +234,7 @@ get_user_info(User, Server, Resource) ->
     end.
 
 -spec set_presence(sid(), binary(), binary(), binary(),
-                   prio(), xmlel(), info()) -> ok.
+                   prio(), presence(), info()) -> ok.
 
 set_presence(SID, User, Server, Resource, Priority,
 	     Presence, Info) ->
@@ -750,7 +750,7 @@ process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set ->
 process_iq(_From, _To, #iq{}) ->
     ok.
 
--spec force_update_presence({binary(), binary()}) -> any().
+-spec force_update_presence({binary(), binary()}) -> ok.
 
 force_update_presence({LUser, LServer}) ->
     Mod = get_sm_backend(LServer),
diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl
index 7160025e7..f8dc84630 100644
--- a/src/ejabberd_socket.erl
+++ b/src/ejabberd_socket.erl
@@ -65,7 +65,7 @@
 
 -type socket_state() :: #socket_state{}.
 
--export_type([socket_state/0, sockmod/0]).
+-export_type([socket/0, socket_state/0, sockmod/0]).
 
 
 %%====================================================================
diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl
index ae7cb2d88..7f815a57e 100644
--- a/src/ejabberd_system_monitor.erl
+++ b/src/ejabberd_system_monitor.erl
@@ -61,6 +61,7 @@ start_link() ->
     gen_server:start_link({local, ?MODULE}, ?MODULE, Opts,
 			  []).
 
+-spec process_command(jid(), jid(), stanza()) -> ok.
 process_command(From, To, Packet) ->
     case To of
       #jid{luser = <<"">>, lresource = <<"watchdog">>} ->
@@ -75,7 +76,7 @@ process_command(From, To, Packet) ->
 				    process_flag(priority, high),
 				    process_command1(From, To, BodyText)
 			    end),
-		      stop;
+		      ok;
 		  false -> ok
 		end;
 	    _ -> ok
diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl
index e62b4d257..2740e2879 100644
--- a/src/ejabberd_web_admin.erl
+++ b/src/ejabberd_web_admin.erl
@@ -1045,17 +1045,21 @@ process_admin(Host,
 process_admin(Host,
 	      #request{lang = Lang, auth = {_, _Auth, AJID}} =
 		  Request) ->
-    {Hook, Opts} = case Host of
-		     global -> {webadmin_page_main, [Request]};
-		     Host -> {webadmin_page_host, [Host, Request]}
-		   end,
-    case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of
+    Res = case Host of
+	      global ->
+		  ejabberd_hooks:run_fold(
+		    webadmin_page_main, Host, [], [Request]);
+	      _ ->
+		  ejabberd_hooks:run_fold(
+		    webadmin_page_host, Host, [], [Host, Request])
+	  end,
+    case Res of
       [] ->
 	  setelement(1,
 		     make_xhtml([?XC(<<"h1">>, <<"Not Found">>)], Host, Lang,
 				AJID),
 		     404);
-      Res -> make_xhtml(Res, Host, Lang, AJID)
+      _ -> make_xhtml(Res, Host, Lang, AJID)
     end.
 
 %%%==================================
@@ -2269,16 +2273,17 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
 	       ?BR,
 	       ?INPUTT(<<"submit">>, <<"update">>, <<"Update">>)])];
 get_node(Host, Node, NPath, Query, Lang) ->
-    {Hook, Opts} = case Host of
-		     global ->
-			 {webadmin_page_node, [Node, NPath, Query, Lang]};
-		     Host ->
-			 {webadmin_page_hostnode,
-			  [Host, Node, NPath, Query, Lang]}
-		   end,
-    case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of
+    Res = case Host of
+	      global ->
+		  ejabberd_hooks:run_fold(webadmin_page_node, Host, [],
+					  [Node, NPath, Query, Lang]);
+	      _ ->
+		  ejabberd_hooks:run_fold(webadmin_page_hostnode, Host, [],
+					  [Host, Node, NPath, Query, Lang])
+	  end,
+    case Res of
       [] -> [?XC(<<"h1">>, <<"Not Found">>)];
-      Res -> Res
+      _ -> Res
     end.
 
 %%%==================================
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index f78ba7e40..fcfe9f3a7 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -47,6 +47,7 @@
 -type component() :: ejabberd_sm | ejabberd_local.
 -type type() :: no_queue | one_queue | pos_integer() | parallel.
 -type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
+-export_type([opts/0]).
 
 %%====================================================================
 %% API
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index e5b504897..476e19e9d 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -378,7 +378,7 @@ db_type(Host, Module) when is_atom(Module) ->
 	    undefined
     end.
 
--spec db_type(binary(), opts(), module()) -> db_type().
+-spec db_type(global | binary(), opts(), module()) -> db_type().
 
 db_type(Host, Opts, Module) ->
     case catch Module:mod_opt_type(db_type) of
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index 22bde2586..e6d94e40a 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -173,7 +173,9 @@ get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
 get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
 
 %-------------------------------------------------------------------------
-
+-spec get_local_features({error, error()} | {result, [binary()]} | empty,
+			 jid(), jid(), binary(), binary()) ->
+				{error, error()} | {result, [binary()]} | empty.
 get_local_features(Acc, _From, _To, <<"">>, _Lang) ->
     Feats = case Acc of
 	      {result, I} -> I;
@@ -205,16 +207,24 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
 %-------------------------------------------------------------------------
 
 process_local_iq(IQ) ->
-    process_adhoc_request(IQ, adhoc_local_commands).
+    process_adhoc_request(IQ, local).
 
 process_sm_iq(IQ) ->
-    process_adhoc_request(IQ, adhoc_sm_commands).
+    process_adhoc_request(IQ, sm).
 
 process_adhoc_request(#iq{from = From, to = To,
 			  type = set, lang = Lang,
-			  sub_els = [#adhoc_command{} = SubEl]} = IQ, Hook) ->
+			  sub_els = [#adhoc_command{} = SubEl]} = IQ, Type) ->
     Host = To#jid.lserver,
-    case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, SubEl]) of
+    Res = case Type of
+	      local ->
+		  ejabberd_hooks:run_fold(adhoc_local_commands, Host, empty,
+					  [From, To, SubEl]);
+	      sm ->
+		  ejabberd_hooks:run_fold(adhoc_sm_commands, Host, empty,
+					  [From, To, SubEl])
+	  end,
+    case Res of
 	ignore ->
 	    ignore;
 	empty ->
@@ -228,6 +238,8 @@ process_adhoc_request(#iq{from = From, to = To,
 process_adhoc_request(#iq{} = IQ, _Hooks) ->
     xmpp:make_error(IQ, xmpp:err_bad_request()).
 
+-spec ping_item(empty | {error, error()} | {result, [disco_item()]},
+		jid(), jid(), binary()) -> {result, [disco_item()]}.
 ping_item(Acc, _From, #jid{server = Server} = _To,
 	  Lang) ->
     Items = case Acc of
@@ -239,6 +251,8 @@ ping_item(Acc, _From, #jid{server = Server} = _To,
 			 name = translate:translate(Lang, <<"Ping">>)}],
     {result, Items ++ Nodes}.
 
+-spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) ->
+			  adhoc_command() | {error, error()}.
 ping_command(_Acc, _From, _To,
 	     #adhoc_command{lang = Lang, node = <<"ping">>,
 			    action = Action} = Request) ->
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index 1a42a460b..eb201fc88 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -130,42 +130,34 @@ stop(Host) ->
     {wait, Proc}.
 
 %% Announcing via messages to a custom resource
+-spec announce(jid(), jid(), stanza()) -> ok.
 announce(From, #jid{luser = <<>>} = To, #message{} = Packet) ->
     Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
     case To#jid.lresource of
         <<"announce/all">> ->
-            Proc ! {announce_all, From, To, Packet},
-            stop;
+            Proc ! {announce_all, From, To, Packet};
         <<"announce/all-hosts/all">> ->
-            Proc ! {announce_all_hosts_all, From, To, Packet},
-            stop;
+            Proc ! {announce_all_hosts_all, From, To, Packet};
         <<"announce/online">> ->
-            Proc ! {announce_online, From, To, Packet},
-            stop;
+            Proc ! {announce_online, From, To, Packet};
         <<"announce/all-hosts/online">> ->
-            Proc ! {announce_all_hosts_online, From, To, Packet},
-            stop;
+            Proc ! {announce_all_hosts_online, From, To, Packet};
         <<"announce/motd">> ->
-            Proc ! {announce_motd, From, To, Packet},
-            stop;
+            Proc ! {announce_motd, From, To, Packet};
         <<"announce/all-hosts/motd">> ->
-            Proc ! {announce_all_hosts_motd, From, To, Packet},
-            stop;
+            Proc ! {announce_all_hosts_motd, From, To, Packet};
         <<"announce/motd/update">> ->
-            Proc ! {announce_motd_update, From, To, Packet},
-            stop;
+            Proc ! {announce_motd_update, From, To, Packet};
         <<"announce/all-hosts/motd/update">> ->
-            Proc ! {announce_all_hosts_motd_update, From, To, Packet},
-            stop;
+            Proc ! {announce_all_hosts_motd_update, From, To, Packet};
         <<"announce/motd/delete">> ->
-            Proc ! {announce_motd_delete, From, To, Packet},
-            stop;
+            Proc ! {announce_motd_delete, From, To, Packet};
         <<"announce/all-hosts/motd/delete">> ->
-            Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
-            stop;
+            Proc ! {announce_all_hosts_motd_delete, From, To, Packet};
         _ ->
             ok
-    end;
+    end,
+    ok;
 announce(_From, _To, _Packet) ->
     ok.
 
@@ -344,7 +336,10 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
     end.
 
 %%-------------------------------------------------------------------------
-
+-spec announce_items(empty | {error, error()} | {result, [disco_item()]},
+			jid(), jid(), binary()) -> {error, error()} |
+						   {result, [disco_item()]} |
+						   empty.
 announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
     Access1 = get_access(LServer),
     Nodes1 = case acl:match_rule(LServer, Access1, From) of
@@ -390,7 +385,8 @@ commands_result(Allow, From, To, Request) ->
 	    announce_commands(From, To, Request)
     end.
 
-
+-spec announce_commands(adhoc_command(), jid(), jid(), adhoc_command()) ->
+			       adhoc_command() | {error, error()}.
 announce_commands(Acc, From, #jid{lserver = LServer} = To,
 		  #adhoc_command{node = Node} = Request) ->
     LNode = tokenize(Node),
@@ -764,6 +760,7 @@ announce_motd_delete(LServer) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:delete_motd(LServer).
 
+-spec send_motd(jid()) -> ok | {atomic, any()}.
 send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     case Mod:get_motd(LServer) of
diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl
index bc3080871..98fb1e441 100644
--- a/src/mod_blocking.erl
+++ b/src/mod_blocking.erl
@@ -227,16 +227,13 @@ make_userlist(Name, List) ->
     NeedDb = mod_privacy:is_list_needdb(List),
     #userlist{name = Name, list = List, needdb = NeedDb}.
 
--spec broadcast_list_update(binary(), binary(), binary(), userlist()) ->
-				   {broadcast,
-				    {privacy_list, userlist(), binary() | none}}.
+-spec broadcast_list_update(binary(), binary(), binary(), userlist()) -> ok.
 broadcast_list_update(LUser, LServer, Name, UserList) ->
     ejabberd_sm:route(jid:make(LUser, LServer, <<"">>),
                       jid:make(LUser, LServer, <<"">>),
                       {broadcast, {privacy_list, UserList, Name}}).
 
--spec broadcast_blocklist_event(binary(), binary(), block_event()) ->
-				       {broadcast, {blocking, block_event()}}.
+-spec broadcast_blocklist_event(binary(), binary(), block_event()) -> ok.
 broadcast_blocklist_event(LUser, LServer, Event) ->
     JID = jid:make(LUser, LServer, <<"">>),
     ejabberd_sm:route(JID, JID,
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index d5033ffd8..e57bc7928 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -161,7 +161,7 @@ caps_stream_features(Acc, MyHost) ->
 -spec disco_features({error, error()} | {result, [binary()]} | empty,
 		     jid(), jid(),
 		     binary(), binary()) ->
-			    {error, error()} | {result, [binary()]}.
+			    {error, error()} | {result, [binary()]} | empty.
 disco_features(Acc, From, To, Node, Lang) ->
     case is_valid_node(Node) of
         true ->
@@ -185,16 +185,18 @@ disco_identity(Acc, From, To, Node, Lang) ->
             Acc
     end.
 
--spec disco_info([xdata()], binary(), module(),
-		 binary(), binary()) -> [xdata()].
-disco_info(Acc, Host, Module, Node, Lang) ->
+-spec disco_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
+		([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
+disco_info(Acc, Host, Module, Node, Lang) when is_atom(Module) ->
     case is_valid_node(Node) of
         true ->
             ejabberd_hooks:run_fold(disco_info, Host, [],
                                     [Host, Module, <<"">>, Lang]);
         false ->
             Acc
-    end.
+    end;
+disco_info(Acc, _, _, _Node, _Lang) ->
+    Acc.
 
 -spec c2s_presence_in(ejabberd_c2s:state(), {jid(), jid(), presence()}) ->
 			     ejabberd_c2s:state().
@@ -277,6 +279,7 @@ c2s_broadcast_recipients(InAcc, Host, C2SState,
     end;
 c2s_broadcast_recipients(Acc, _, _, _, _, _) -> Acc.
 
+-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
 depends(_Host, _Opts) ->
     [].
 
@@ -403,13 +406,13 @@ feature_response(_IQResult, Host, From, Caps,
 		 [_SubNode | SubNodes]) ->
     feature_request(Host, From, Caps, SubNodes).
 
--spec caps_read_fun(binary(), binary()) -> function().
+-spec caps_read_fun(binary(), {binary(), binary()}) -> function().
 caps_read_fun(Host, Node) ->
     LServer = jid:nameprep(Host),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     fun() -> Mod:caps_read(LServer, Node) end.
 
--spec caps_write_fun(binary(), binary(), [binary()]) -> function().
+-spec caps_write_fun(binary(), {binary(), binary()}, [binary()]) -> function().
 caps_write_fun(Host, Node, Features) ->
     LServer = jid:nameprep(Host),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
@@ -437,8 +440,8 @@ make_my_disco_hash(Host) ->
       _Err -> <<"">>
     end.
 
--spec make_disco_hash(disco_info(), crypto:digest_type()) -> binary().
-
+-type digest_type() :: md5 | sha | sha224 | sha256 | sha384 | sha512.
+-spec make_disco_hash(disco_info(), digest_type()) -> binary().
 make_disco_hash(DiscoInfo, Algo) ->
     Concat = list_to_binary([concat_identities(DiscoInfo),
                              concat_features(DiscoInfo), concat_info(DiscoInfo)]),
@@ -469,19 +472,23 @@ check_hash(Caps, DiscoInfo) ->
       _ -> true
     end.
 
+-spec concat_features(disco_info()) -> iolist().
 concat_features(#disco_info{features = Features}) ->
     lists:usort([[Feat, $<] || Feat <- Features]).
 
+-spec concat_identities(disco_info()) -> iolist().
 concat_identities(#disco_info{identities = Identities}) ->
     lists:sort(
       [[Cat, $/, T, $/, Lang, $/, Name, $<] ||
 	  #identity{category = Cat, type = T,
 		    lang = Lang, name = Name} <- Identities]).
 
+-spec concat_info(disco_info()) -> iolist().
 concat_info(#disco_info{xdata = Xs}) ->
     lists:sort(
       [concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]).
 
+-spec concat_xdata_fields([xdata_field()]) -> iolist().
 concat_xdata_fields(Fields) ->
     Form = case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, Fields) of
 	       #xdata_field{values = Values} -> Values;
@@ -492,10 +499,12 @@ concat_xdata_fields(Fields) ->
 	      is_binary(Var), Var /= <<"FORM_TYPE">>],
     [Form, $<, lists:sort(Res)].
 
+-spec gb_trees_fold(fun((_, _, T) -> T), T, gb_trees:tree()) -> T.
 gb_trees_fold(F, Acc, Tree) ->
     Iter = gb_trees:iterator(Tree),
     gb_trees_fold_iter(F, Acc, Iter).
 
+-spec gb_trees_fold_iter(fun((_, _, T) -> T), T, gb_trees:iter()) -> T.
 gb_trees_fold_iter(F, Acc, Iter) ->
     case gb_trees:next(Iter) of
       {Key, Val, NewIter} ->
@@ -504,6 +513,7 @@ gb_trees_fold_iter(F, Acc, Iter) ->
       _ -> Acc
     end.
 
+-spec now_ts() -> integer().
 now_ts() ->
     p1_time_compat:system_time(seconds).
 
diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl
index b70ccbc2a..e35caa1c7 100644
--- a/src/mod_carboncopy.erl
+++ b/src/mod_carboncopy.erl
@@ -197,7 +197,7 @@ send_copies(JID, To, Packet, Direction)->
 
 -spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message().
 build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) ->
-    Forwarded = #forwarded{sub_els = complete_packet(JID, Msg, Direction)},
+    Forwarded = #forwarded{sub_els = [complete_packet(JID, Msg, Direction)]},
     Carbon = case Direction of
 		 sent -> #carbons_sent{forwarded = Forwarded};
 		 received -> #carbons_received{forwarded = Forwarded}
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index a6a6ddc20..042c59702 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -151,12 +151,13 @@ depends(_Host, _Opts) ->
 %% ejabberd_hooks callbacks.
 %%--------------------------------------------------------------------
 
--spec filter_presence({term(), [stanza()]}, binary(), stanza())
-      -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
+-spec filter_presence({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
+      -> {ejabberd_c2s:state(), [stanza()]} |
+	 {stop, {ejabberd_c2s:state(), [stanza()]}}.
 
 filter_presence({C2SState, _OutStanzas} = Acc, Host,
 		#presence{type = Type} = Stanza) ->
-    if Type == available, Type == unavailable ->
+    if Type == available; Type == unavailable ->
 	    ?DEBUG("Got availability presence stanza", []),
 	    queue_add(presence, Stanza, Host, C2SState);
        true ->
@@ -164,8 +165,9 @@ filter_presence({C2SState, _OutStanzas} = Acc, Host,
     end;
 filter_presence(Acc, _Host, _Stanza) -> Acc.
 
--spec filter_chat_states({term(), [stanza()]}, binary(), stanza())
-      -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
+-spec filter_chat_states({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
+      -> {ejabberd_c2s:state(), [stanza()]} |
+	 {stop, {ejabberd_c2s:state(), [stanza()]}}.
 
 filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
 		   #message{from = From, to = To} = Stanza) ->
@@ -186,8 +188,9 @@ filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
     end;
 filter_chat_states(Acc, _Host, _Stanza) -> Acc.
 
--spec filter_pep({term(), [stanza()]}, binary(), stanza())
-      -> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
+-spec filter_pep({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
+      -> {ejabberd_c2s:state(), [stanza()]} |
+	 {stop, {ejabberd_c2s:state(), [stanza()]}}.
 
 filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) ->
     case get_pep_node(Stanza) of
@@ -199,14 +202,15 @@ filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) ->
     end;
 filter_pep(Acc, _Host, _Stanza) -> Acc.
 
--spec filter_other({term(), [stanza()]}, binary(), stanza())
-      -> {stop, {term(), [stanza()]}}.
+-spec filter_other({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
+      -> {stop, {ejabberd_c2s:state(), [stanza()]}}.
 
 filter_other({C2SState, _OutStanzas}, Host, Stanza) ->
     ?DEBUG("Won't add stanza to CSI queue", []),
     queue_take(Stanza, Host, C2SState).
 
--spec flush_queue({term(), [stanza()]}, binary()) -> {term(), [stanza()]}.
+-spec flush_queue({ejabberd_c2s:state(), [stanza()]}, binary())
+      -> {ejabberd_c2s:state(), [stanza()]}.
 
 flush_queue({C2SState, _OutStanzas}, Host) ->
     ?DEBUG("Going to flush CSI queue", []),
@@ -284,7 +288,7 @@ get_pep_node(#message{from = #jid{luser = <<>>}}) ->
     undefined;
 get_pep_node(#message{} = Msg) ->
     case xmpp:get_subtag(Msg, #pubsub_event{}) of
-	#pubsub_event{items = [#pubsub_event_item{node = Node}]} ->
+	#pubsub_event{items = [#pubsub_event_items{node = Node}]} ->
 	    Node;
 	_ ->
 	    undefined
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index 07a1c7333..a798d010f 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -270,7 +270,10 @@ get_local_features(Acc, From,
     end.
 
 %%%-----------------------------------------------------------------------
-
+-spec adhoc_sm_items(empty | {error, error()} | {result, [disco_item()]},
+		     jid(), jid(), binary()) -> {error, error()} |
+						{result, [disco_item()]} |
+						empty.
 adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To,
 	       Lang) ->
     case acl:match_rule(LServer, configure, From) of
@@ -322,6 +325,10 @@ get_user_resources(User, Server) ->
 
 %%%-----------------------------------------------------------------------
 
+-spec adhoc_local_items(empty | {error, error()} | {result, [disco_item()]},
+			jid(), jid(), binary()) -> {error, error()} |
+						   {result, [disco_item()]} |
+						   empty.
 adhoc_local_items(Acc, From,
 		  #jid{lserver = LServer, server = Server} = To, Lang) ->
     case acl:match_rule(LServer, configure, From) of
@@ -765,6 +772,8 @@ get_stopped_nodes(_Lang) ->
 	  allow -> adhoc_local_commands(From, To, Request)
 	end).
 
+-spec adhoc_local_commands(adhoc_command(), jid(), jid(), adhoc_command()) ->
+				  adhoc_command() | {error, error()}.
 adhoc_local_commands(Acc, From,
 		     #jid{lserver = LServer} = To,
 		     #adhoc_command{node = Node, lang = Lang} = Request) ->
@@ -1672,8 +1681,7 @@ set_form(_From, _Host, _, _Lang, _XData) ->
 get_value(Field, XData) -> hd(get_values(Field, XData)).
 
 get_values(Field, XData) ->
-    [_|_] = Values = xmpp_util:get_xdata_values(Field, XData),
-    Values.
+    xmpp_util:get_xdata_values(Field, XData).
 
 search_running_node(SNode) ->
     search_running_node(SNode,
@@ -1723,7 +1731,7 @@ get_last_info(User, Server) ->
     end.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
+-spec adhoc_sm_commands(adhoc_command(), jid(), jid(), adhoc_command()) -> adhoc_command().
 adhoc_sm_commands(_Acc, From,
 		  #jid{user = User, server = Server, lserver = LServer},
 		  #adhoc_command{lang = Lang, node = <<"config">>,
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index e78b8f72f..e33241928 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -424,8 +424,9 @@ transform_module_options(Opts) ->
 
 %%% Support for: XEP-0157 Contact Addresses for XMPP Services
 
--spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()].
-get_info(_A, Host, Mod, Node, _Lang) when Node == <<"">> ->
+-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
+	      ([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
+get_info(_A, Host, Mod, Node, _Lang) when is_atom(Mod), Node == <<"">> ->
     Module = case Mod of
 	       undefined -> ?MODULE;
 	       _ -> Mod
diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl
index c57ac21b0..cc3b4bf7f 100644
--- a/src/mod_fail2ban.erl
+++ b/src/mod_fail2ban.erl
@@ -52,6 +52,8 @@ start_link(Host, Opts) ->
     Proc = gen_mod:get_module_proc(Host, ?MODULE),
     gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
 
+-spec c2s_auth_result(boolean(), binary(), binary(),
+		      {inet:ip_address(), non_neg_integer()}) -> ok.
 c2s_auth_result(false, _User, LServer, {Addr, _Port}) ->
     case is_whitelisted(LServer, Addr) of
 	true ->
@@ -71,11 +73,15 @@ c2s_auth_result(false, _User, LServer, {Addr, _Port}) ->
 		    ets:insert(failed_auth, {Addr, N+1, UnbanTS, MaxFailures});
 		[] ->
 		    ets:insert(failed_auth, {Addr, 1, UnbanTS, MaxFailures})
-	    end
+	    end,
+	    ok
     end;
 c2s_auth_result(true, _User, _Server, _AddrPort) ->
     ok.
 
+-spec check_bl_c2s({true, binary(), binary()} | false,
+		   {inet:ip_address(), non_neg_integer()},
+		   binary()) -> {stop, {true, binary(), binary()}} | false.
 check_bl_c2s(_Acc, Addr, Lang) ->
     case ets:lookup(failed_auth, Addr) of
 	[{Addr, N, TS, MaxFailures}] when N >= MaxFailures ->
diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl
index 63dc2dfe2..babdbb7b6 100644
--- a/src/mod_http_upload.erl
+++ b/src/mod_http_upload.erl
@@ -553,8 +553,8 @@ process_iq(From, #iq{type = get, lang = Lang,
 						   {slot_timed_out,
 						    Slot}),
 		    NewState = add_slot(Slot, Size, Timer, State),
-		    Slot = mk_slot(Slot, State, XMLNS),
-		    {xmpp:make_iq_result(IQ, Slot), NewState};
+		    NewSlot = mk_slot(Slot, State, XMLNS),
+		    {xmpp:make_iq_result(IQ, NewSlot), NewState};
 		{ok, PutURL, GetURL} ->
 		    Slot = mk_slot(PutURL, GetURL, XMLNS),
 		    xmpp:make_iq_result(IQ, Slot);
@@ -668,11 +668,14 @@ del_slot(Slot, #state{slots = Slots} = State) ->
     NewSlots = maps:remove(Slot, Slots),
     State#state{slots = NewSlots}.
 
--spec mk_slot(slot() | binary(), state() | binary(), binary()) -> xmlel().
+-spec mk_slot(slot(), state(), binary()) -> upload_slot();
+	     (binary(), binary(), binary()) -> upload_slot().
 
 mk_slot(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) ->
     PutURL = str:join([PutPrefix | Slot], <<$/>>),
     GetURL = str:join([GetPrefix | Slot], <<$/>>),
+    mk_slot(PutURL, GetURL, XMLNS);
+mk_slot(PutURL, GetURL, XMLNS) ->
     #upload_slot{get = GetURL, put = PutURL, xmlns = XMLNS}.
 
 -spec make_user_string(jid(), sha1 | node) -> binary().
diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl
index 4f54ecd79..897810927 100644
--- a/src/mod_ip_blacklist.erl
+++ b/src/mod_ip_blacklist.erl
@@ -109,6 +109,10 @@ update_bl_c2s() ->
 %% Return: false: IP not blacklisted
 %%         true: IP is blacklisted
 %% IPV4 IP tuple:
+-spec is_ip_in_c2s_blacklist(
+	{true, binary(), binary()} | false,
+	{inet:ip_address(), non_neg_integer()},
+	binary()) -> {stop, {true, binary(), binary()}} | false.
 is_ip_in_c2s_blacklist(_Val, IP, Lang) when is_tuple(IP) ->
     BinaryIP = jlib:ip_to_list(IP),
     case ets:lookup(bl_c2s, BinaryIP) of
diff --git a/src/mod_irc.erl b/src/mod_irc.erl
index 3c094ef9c..a833287c8 100644
--- a/src/mod_irc.erl
+++ b/src/mod_irc.erl
@@ -66,10 +66,8 @@
 
 -callback init(binary(), gen_mod:opts()) -> any().
 -callback import(binary(), #irc_custom{}) -> ok | pass.
--callback get_data(binary(), binary(), {binary(), binary()}) ->
-    error | empty | irc_data().
--callback set_data(binary(), binary(), {binary(), binary()}, irc_data()) ->
-    {atomic, any()}.
+-callback get_data(binary(), binary(), jid()) -> error | empty | irc_data().
+-callback set_data(binary(), binary(), jid(), irc_data()) -> {atomic, any()}.
 
 %%====================================================================
 %% API
diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl
index 694accf45..c9b460ad0 100644
--- a/src/mod_irc_connection.erl
+++ b/src/mod_irc_connection.erl
@@ -584,12 +584,12 @@ handle_info({ircstring, <<$:, String/binary>>},
 		     [From, <<"MODE">>, <<$#, Chan/binary>>, <<"+o">>, Nick
 		      | _] ->
 			 process_mode_o(StateData, Chan, From, Nick,
-					<<"admin">>, <<"moderator">>),
+					admin, moderator),
 			 StateData;
 		     [From, <<"MODE">>, <<$#, Chan/binary>>, <<"-o">>, Nick
 		      | _] ->
 			 process_mode_o(StateData, Chan, From, Nick,
-					<<"member">>, <<"participant">>),
+					member, participant),
 			 StateData;
 		     [From, <<"KICK">>, <<$#, Chan/binary>>, Nick | _] ->
 			 process_kick(StateData, Chan, From, Nick, String),
@@ -756,16 +756,16 @@ process_channel_list_user(StateData, Chan, User) ->
 	    end,
     {User2, Affiliation, Role} = case User1 of
 				   <<$@, U2/binary>> ->
-				       {U2, <<"admin">>, <<"moderator">>};
+				       {U2, admin, moderator};
 				   <<$+, U2/binary>> ->
-				       {U2, <<"member">>, <<"participant">>};
+				       {U2, member, participant};
 				   <<$%, U2/binary>> ->
-				       {U2, <<"admin">>, <<"moderator">>};
+				       {U2, admin, moderator};
 				   <<$&, U2/binary>> ->
-				       {U2, <<"admin">>, <<"moderator">>};
+				       {U2, admin, moderator};
 				   <<$~, U2/binary>> ->
-				       {U2, <<"admin">>, <<"moderator">>};
-				   _ -> {User1, <<"member">>, <<"participant">>}
+				       {U2, admin, moderator};
+				   _ -> {User1, member, participant}
 				 end,
     ejabberd_router:route(
       jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
@@ -1157,8 +1157,6 @@ remove_element(E, Set) ->
 iq_admin(StateData, Channel, From, To,
 	 #iq{type = Type, sub_els = [SubEl]} = IQ) ->
     try process_iq_admin(StateData, Channel, Type, SubEl) of
-	ignore ->
-	    ignore;
 	{result, Result} ->
 	    ejabberd_router:route(To, From, xmpp:make_iq_result(IQ, Result));
 	{error, Error} ->
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index b83c423c7..7e93a3166 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -175,17 +175,21 @@ stop(Host) ->
 depends(_Host, _Opts) ->
     [].
 
+-spec remove_user(binary(), binary()) -> ok.
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:remove_user(LUser, LServer).
+    Mod:remove_user(LUser, LServer),
+    ok.
 
+-spec remove_room(binary(), binary(), binary()) -> ok.
 remove_room(LServer, Name, Host) ->
     LName = jid:nodeprep(Name),
     LHost = jid:nameprep(Host),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:remove_room(LServer, LName, LHost).
+    Mod:remove_room(LServer, LName, LHost),
+    ok.
 
 get_room_config(X, RoomState, _From, Lang) ->
     Config = RoomState#state.config,
@@ -621,9 +625,7 @@ should_archive_muc(#message{type = groupchat,
 		    end;
 		_ ->
 		    true
-	    end;
-	_ ->
-	    false
+	    end
     end;
 should_archive_muc(_) ->
     false.
diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl
index cb7946a28..605fe3d6b 100644
--- a/src/mod_metrics.erl
+++ b/src/mod_metrics.erl
@@ -31,13 +31,7 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("jid.hrl").
-
--define(HOOKS, [offline_message_hook,
-                sm_register_connection_hook, sm_remove_connection_hook,
-                user_send_packet, user_receive_packet,
-                s2s_send_packet, s2s_receive_packet,
-                remove_user, register_user]).
+-include("xmpp.hrl").
 
 -export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1,
 	 depends/2]).
@@ -53,12 +47,26 @@
 %%====================================================================
 
 start(Host, _Opts) ->
-    [ejabberd_hooks:add(Hook, Host, ?MODULE, Hook, 20)
-     || Hook <- ?HOOKS].
+    ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, offline_message_hook, 20),
+    ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE, sm_register_connection_hook, 20),
+    ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, sm_remove_connection_hook, 20),
+    ejabberd_hooks:add(user_send_packet, Host, ?MODULE, user_send_packet, 20),
+    ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, user_receive_packet, 20),
+    ejabberd_hooks:add(s2s_send_packet, Host, ?MODULE, s2s_send_packet, 20),
+    ejabberd_hooks:add(s2s_receive_packet, Host, ?MODULE, s2s_receive_packet, 20),
+    ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 20),
+    ejabberd_hooks:add(register_user, Host, ?MODULE, register_user, 20).
 
 stop(Host) ->
-    [ejabberd_hooks:delete(Hook, Host, ?MODULE, Hook, 20)
-     || Hook <- ?HOOKS].
+    ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, offline_message_hook, 20),
+    ejabberd_hooks:delete(sm_register_connection_hook, Host, ?MODULE, sm_register_connection_hook, 20),
+    ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE, sm_remove_connection_hook, 20),
+    ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, user_send_packet, 20),
+    ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, user_receive_packet, 20),
+    ejabberd_hooks:delete(s2s_send_packet, Host, ?MODULE, s2s_send_packet, 20),
+    ejabberd_hooks:delete(s2s_receive_packet, Host, ?MODULE, s2s_receive_packet, 20),
+    ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 20),
+    ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 20).
 
 depends(_Host, _Opts) ->
     [].
@@ -66,12 +74,15 @@ depends(_Host, _Opts) ->
 %%====================================================================
 %% Hooks handlers
 %%====================================================================
-
+-spec offline_message_hook(jid(), jid(), message()) -> any().
 offline_message_hook(_From, #jid{lserver=LServer}, _Packet) ->
     push(LServer, offline_message).
 
+-spec sm_register_connection_hook(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
 sm_register_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
     push(LServer, sm_register_connection).
+
+-spec sm_remove_connection_hook(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
 sm_remove_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
     push(LServer, sm_remove_connection).
 
@@ -82,13 +93,19 @@ user_receive_packet(Packet, _C2SState, _JID, _From, #jid{lserver=LServer}) ->
     push(LServer, user_receive_packet),
     Packet.
 
+-spec s2s_send_packet(jid(), jid(), stanza()) -> any().
 s2s_send_packet(#jid{lserver=LServer}, _To, _Packet) ->
     push(LServer, s2s_send_packet).
+
+-spec s2s_receive_packet(jid(), jid(), stanza()) -> any().
 s2s_receive_packet(_From, #jid{lserver=LServer}, _Packet) ->
     push(LServer, s2s_receive_packet).
 
+-spec remove_user(binary(), binary()) -> any().
 remove_user(_User, Server) ->
     push(jid:nameprep(Server), remove_user).
+
+-spec register_user(binary(), binary()) -> any().
 register_user(_User, Server) ->
     push(jid:nameprep(Server), register_user).
 
diff --git a/src/mod_mix.erl b/src/mod_mix.erl
index 3ba173b9f..52a3c8ed8 100644
--- a/src/mod_mix.erl
+++ b/src/mod_mix.erl
@@ -52,6 +52,8 @@ stop(Host) ->
     supervisor:delete_child(ejabberd_sup, Proc),
     ok.
 
+-spec disco_features({error, error()} | {result, [binary()]} | empty,
+		     jid(), jid(), binary(), binary()) -> {result, [binary()]}.
 disco_features(_Acc, _From, _To, _Node, _Lang) ->
     {result, [?NS_MIX_0]}.
 
@@ -69,6 +71,8 @@ disco_identity(Acc, _From, _To, _Node, _Lang) ->
     Acc ++ [#identity{category = <<"conference">>,
 		      type = <<"mix">>}].
 
+-spec disco_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
+		([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
 disco_info(_Acc, _From, To, _Node, _Lang) when is_atom(To) ->
     [#xdata{type = result,
 	    fields = [#xdata_field{var = <<"FORM_TYPE">>,
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index 5814ca832..b470c093e 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -3317,28 +3317,34 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
 	Err -> Err
     end.
 
+get_config_opt_name(Pos) ->
+    Fs = [config|record_info(fields, config)],
+    lists:nth(Pos, Fs).
+
 -define(SET_BOOL_XOPT(Opt, Val),
 	case Val of
 	  <<"0">> ->
-	      set_xoption(Opts, Config#config{Opt = false}, ServerHost, Lang);
+	      set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang);
 	  <<"false">> ->
-	      set_xoption(Opts, Config#config{Opt = false}, ServerHost, Lang);
-	  <<"1">> -> set_xoption(Opts, Config#config{Opt = true}, ServerHost, Lang);
+	      set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang);
+	  <<"1">> -> set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang);
 	  <<"true">> ->
-	      set_xoption(Opts, Config#config{Opt = true}, ServerHost, Lang);
+	      set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang);
 	  _ ->
 	      Txt = <<"Value of '~s' should be boolean">>,
-	      ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+	      OptName = get_config_opt_name(Opt),
+	      ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
 	      {error, xmpp:err_bad_request(ErrTxt, Lang)}
 	end).
 
 -define(SET_NAT_XOPT(Opt, Val),
 	case catch binary_to_integer(Val) of
 	  I when is_integer(I), I > 0 ->
-	      set_xoption(Opts, Config#config{Opt = I}, ServerHost, Lang);
+	      set_xoption(Opts, setelement(Opt, Config, I), ServerHost, Lang);
 	  _ ->
 	      Txt = <<"Value of '~s' should be integer">>,
-	      ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+	      OptName = get_config_opt_name(Opt),
+	      ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
 	      {error, xmpp:err_bad_request(ErrTxt, Lang)}
 	end).
 
@@ -3349,10 +3355,11 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
 		    [Val] -> Val;
 		    _ when is_atom(Vals) -> Vals
 		end,
-	    set_xoption(Opts, Config#config{Opt = V}, ServerHost, Lang)
+	    set_xoption(Opts, setelement(Opt, Config, V), ServerHost, Lang)
 	catch _:_ ->
 		Txt = <<"Incorrect value of option '~s'">>,
-		ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+		OptName = get_config_opt_name(Opt),
+		ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
 		{error, xmpp:err_bad_request(ErrTxt, Lang)}
 	end).
 
@@ -3366,7 +3373,7 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
 				(_, Set1) -> Set1
 			    end,
 			    (?SETS):empty(), Vals),
-	  set_xoption(Opts, Config#config{Opt = Set}, ServerHost, Lang)
+	  set_xoption(Opts, setelement(Opt, Config, Set), ServerHost, Lang)
 	end).
 
 -spec set_xoption([{binary(), [binary()]}], #config{},
@@ -3375,35 +3382,35 @@ set_xoption([], Config, _ServerHost, _Lang) -> Config;
 set_xoption([{<<"muc#roomconfig_roomname">>, Vals}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_STRING_XOPT(title, Vals);
+    ?SET_STRING_XOPT(#config.title, Vals);
 set_xoption([{<<"muc#roomconfig_roomdesc">>, Vals}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_STRING_XOPT(description, Vals);
+    ?SET_STRING_XOPT(#config.description, Vals);
 set_xoption([{<<"muc#roomconfig_changesubject">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_change_subj, Val);
+    ?SET_BOOL_XOPT(#config.allow_change_subj, Val);
 set_xoption([{<<"allow_query_users">>, [Val]} | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_query_users, Val);
+    ?SET_BOOL_XOPT(#config.allow_query_users, Val);
 set_xoption([{<<"allow_private_messages">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_private_messages, Val);
+    ?SET_BOOL_XOPT(#config.allow_private_messages, Val);
 set_xoption([{<<"allow_private_messages_from_visitors">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
     case Val of
       <<"anyone">> ->
-	  ?SET_STRING_XOPT(allow_private_messages_from_visitors,
+	  ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
 			   anyone);
       <<"moderators">> ->
-	  ?SET_STRING_XOPT(allow_private_messages_from_visitors,
+	  ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
 			   moderators);
       <<"nobody">> ->
-	  ?SET_STRING_XOPT(allow_private_messages_from_visitors,
+	  ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
 			   nobody);
       _ ->
 	  Txt = <<"Value of 'allow_private_messages_from_visitors' "
@@ -3414,58 +3421,58 @@ set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_visitor_status, Val);
+    ?SET_BOOL_XOPT(#config.allow_visitor_status, Val);
 set_xoption([{<<"muc#roomconfig_allowvisitornickchange">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_visitor_nickchange, Val);
+    ?SET_BOOL_XOPT(#config.allow_visitor_nickchange, Val);
 set_xoption([{<<"muc#roomconfig_publicroom">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(public, Val);
+    ?SET_BOOL_XOPT(#config.public, Val);
 set_xoption([{<<"public_list">>, [Val]} | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(public_list, Val);
+    ?SET_BOOL_XOPT(#config.public_list, Val);
 set_xoption([{<<"muc#roomconfig_persistentroom">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(persistent, Val);
+    ?SET_BOOL_XOPT(#config.persistent, Val);
 set_xoption([{<<"muc#roomconfig_moderatedroom">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(moderated, Val);
+    ?SET_BOOL_XOPT(#config.moderated, Val);
 set_xoption([{<<"members_by_default">>, [Val]} | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(members_by_default, Val);
+    ?SET_BOOL_XOPT(#config.members_by_default, Val);
 set_xoption([{<<"muc#roomconfig_membersonly">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(members_only, Val);
+    ?SET_BOOL_XOPT(#config.members_only, Val);
 set_xoption([{<<"captcha_protected">>, [Val]} | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(captcha_protected, Val);
+    ?SET_BOOL_XOPT(#config.captcha_protected, Val);
 set_xoption([{<<"muc#roomconfig_allowinvites">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_user_invites, Val);
+    ?SET_BOOL_XOPT(#config.allow_user_invites, Val);
 set_xoption([{<<"muc#roomconfig_allow_subscription">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_subscription, Val);
+    ?SET_BOOL_XOPT(#config.allow_subscription, Val);
 set_xoption([{<<"muc#roomconfig_passwordprotectedroom">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(password_protected, Val);
+    ?SET_BOOL_XOPT(#config.password_protected, Val);
 set_xoption([{<<"muc#roomconfig_roomsecret">>, Vals}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_STRING_XOPT(password, Vals);
+    ?SET_STRING_XOPT(#config.password, Vals);
 set_xoption([{<<"anonymous">>, [Val]} | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(anonymous, Val);
+    ?SET_BOOL_XOPT(#config.anonymous, Val);
 set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
 	    Config, ServerHost, Lang) ->
     Roles =
@@ -3496,21 +3503,21 @@ set_xoption([{<<"muc#roomconfig_allowvoicerequests">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(allow_voice_requests, Val);
+    ?SET_BOOL_XOPT(#config.allow_voice_requests, Val);
 set_xoption([{<<"muc#roomconfig_voicerequestmininterval">>,
 	      [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_NAT_XOPT(voice_request_min_interval, Val);
+    ?SET_NAT_XOPT(#config.voice_request_min_interval, Val);
 set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
     case Val of
       <<"moderators">> ->
-	  ?SET_BOOL_XOPT(anonymous,
+	  ?SET_BOOL_XOPT(#config.anonymous,
 			 (iolist_to_binary(integer_to_list(1))));
       <<"anyone">> ->
-	  ?SET_BOOL_XOPT(anonymous,
+	  ?SET_BOOL_XOPT(#config.anonymous,
 			 (iolist_to_binary(integer_to_list(0))));
       _ ->
 	  Txt = <<"Value of 'muc#roomconfig_whois' should be "
@@ -3521,19 +3528,19 @@ set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
     case Val of
-      <<"none">> -> ?SET_STRING_XOPT(max_users, none);
-      _ -> ?SET_NAT_XOPT(max_users, Val)
+      <<"none">> -> ?SET_STRING_XOPT(#config.max_users, none);
+      _ -> ?SET_NAT_XOPT(#config.max_users, Val)
     end;
 set_xoption([{<<"muc#roomconfig_enablelogging">>, [Val]}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
-    ?SET_BOOL_XOPT(logging, Val);
+    ?SET_BOOL_XOPT(#config.logging, Val);
 set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
 	      Vals}
 	     | Opts],
 	    Config, ServerHost, Lang) ->
     JIDs = [jid:from_string(Val) || Val <- Vals],
-    ?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
+    ?SET_JIDMULTI_XOPT(#config.captcha_whitelist, JIDs);
 set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config, ServerHost, Lang) ->
     set_xoption(Opts, Config, ServerHost, Lang);
 set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) ->
@@ -3752,7 +3759,8 @@ set_opts([{Opt, Val} | Opts], StateData) ->
 	  end,
     set_opts(Opts, NSD).
 
--define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}).
+-define(MAKE_CONFIG_OPT(Opt),
+	{get_config_opt_name(Opt), element(Opt, Config)}).
 
 -spec make_opts(state()) -> [{atom(), any()}].
 make_opts(StateData) ->
@@ -3764,27 +3772,27 @@ make_opts(StateData) ->
 		       (_, _, Acc) ->
 			    Acc
 		    end, [], StateData#state.users),
-    [?MAKE_CONFIG_OPT(title), ?MAKE_CONFIG_OPT(description),
-     ?MAKE_CONFIG_OPT(allow_change_subj),
-     ?MAKE_CONFIG_OPT(allow_query_users),
-     ?MAKE_CONFIG_OPT(allow_private_messages),
-     ?MAKE_CONFIG_OPT(allow_private_messages_from_visitors),
-     ?MAKE_CONFIG_OPT(allow_visitor_status),
-     ?MAKE_CONFIG_OPT(allow_visitor_nickchange),
-     ?MAKE_CONFIG_OPT(public), ?MAKE_CONFIG_OPT(public_list),
-     ?MAKE_CONFIG_OPT(persistent),
-     ?MAKE_CONFIG_OPT(moderated),
-     ?MAKE_CONFIG_OPT(members_by_default),
-     ?MAKE_CONFIG_OPT(members_only),
-     ?MAKE_CONFIG_OPT(allow_user_invites),
-     ?MAKE_CONFIG_OPT(password_protected),
-     ?MAKE_CONFIG_OPT(captcha_protected),
-     ?MAKE_CONFIG_OPT(password), ?MAKE_CONFIG_OPT(anonymous),
-     ?MAKE_CONFIG_OPT(logging), ?MAKE_CONFIG_OPT(max_users),
-     ?MAKE_CONFIG_OPT(allow_voice_requests),
-     ?MAKE_CONFIG_OPT(mam),
-     ?MAKE_CONFIG_OPT(voice_request_min_interval),
-     ?MAKE_CONFIG_OPT(vcard),
+    [?MAKE_CONFIG_OPT(#config.title), ?MAKE_CONFIG_OPT(#config.description),
+     ?MAKE_CONFIG_OPT(#config.allow_change_subj),
+     ?MAKE_CONFIG_OPT(#config.allow_query_users),
+     ?MAKE_CONFIG_OPT(#config.allow_private_messages),
+     ?MAKE_CONFIG_OPT(#config.allow_private_messages_from_visitors),
+     ?MAKE_CONFIG_OPT(#config.allow_visitor_status),
+     ?MAKE_CONFIG_OPT(#config.allow_visitor_nickchange),
+     ?MAKE_CONFIG_OPT(#config.public), ?MAKE_CONFIG_OPT(#config.public_list),
+     ?MAKE_CONFIG_OPT(#config.persistent),
+     ?MAKE_CONFIG_OPT(#config.moderated),
+     ?MAKE_CONFIG_OPT(#config.members_by_default),
+     ?MAKE_CONFIG_OPT(#config.members_only),
+     ?MAKE_CONFIG_OPT(#config.allow_user_invites),
+     ?MAKE_CONFIG_OPT(#config.password_protected),
+     ?MAKE_CONFIG_OPT(#config.captcha_protected),
+     ?MAKE_CONFIG_OPT(#config.password), ?MAKE_CONFIG_OPT(#config.anonymous),
+     ?MAKE_CONFIG_OPT(#config.logging), ?MAKE_CONFIG_OPT(#config.max_users),
+     ?MAKE_CONFIG_OPT(#config.allow_voice_requests),
+     ?MAKE_CONFIG_OPT(#config.mam),
+     ?MAKE_CONFIG_OPT(#config.voice_request_min_interval),
+     ?MAKE_CONFIG_OPT(#config.vcard),
      {captcha_whitelist,
       (?SETS):to_list((StateData#state.config)#config.captcha_whitelist)},
      {affiliations,
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 4d597a52c..03eb3c59a 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -297,7 +297,8 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID,
 get_sm_items(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
--spec get_info([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
+-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
+	      ([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
 get_info(_Acc, #jid{luser = U, lserver = S, lresource = R},
 	 #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) ->
     N = jlib:integer_to_binary(count_offline_messages(U, S)),
@@ -570,11 +571,13 @@ remove_old_messages(Days, Server) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:remove_old_messages(Days, LServer).
 
+-spec remove_user(binary(), binary()) -> ok.
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:remove_user(LUser, LServer).
+    Mod:remove_user(LUser, LServer),
+    ok.
 
 %% Helper functions:
 
diff --git a/src/mod_ping.erl b/src/mod_ping.erl
index b09ca9ab2..5e861b7f7 100644
--- a/src/mod_ping.erl
+++ b/src/mod_ping.erl
@@ -207,11 +207,11 @@ iq_ping(#iq{lang = Lang} = IQ) ->
     Txt = <<"Ping query is incorrect">>,
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
 
--spec user_online(ejabberd_sm:sid(), jid(), any()) -> ok.
+-spec user_online(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
 user_online(_SID, JID, _Info) ->
     start_ping(JID#jid.lserver, JID).
 
--spec user_offline(ejabberd_sm:sid(), jid(), any()) -> ok.
+-spec user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
 user_offline(_SID, JID, _Info) ->
     stop_ping(JID#jid.lserver, JID).
 
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index 1da040d43..f94c422b3 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -515,6 +515,7 @@ is_type_match(Type, Value, JID, Subscription, Groups) ->
       group -> lists:member(Value, Groups)
     end.
 
+-spec remove_user(binary(), binary()) -> any().
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
diff --git a/src/mod_private.erl b/src/mod_private.erl
index 6236b1012..565500d4a 100644
--- a/src/mod_private.erl
+++ b/src/mod_private.erl
@@ -117,6 +117,7 @@ get_data(LUser, LServer) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:get_all_data(LUser, LServer).
 
+-spec remove_user(binary(), binary()) -> any().
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 81afc9a06..0796a20bb 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -660,6 +660,7 @@ disco_items(Host, Node, From) ->
 %% presence hooks handling functions
 %%
 
+-spec caps_add(jid(), jid(), [binary()]) -> ok.
 caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features)
 	when Host =/= S ->
     %% When a remote contact goes online while the local user is offline, the
@@ -675,9 +676,11 @@ caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID
 caps_add(_From, _To, _Feature) ->
     ok.
 
+-spec caps_update(jid(), jid(), [binary()]) -> ok.
 caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) ->
     presence(Host, {presence, U, S, [R], JID}).
 
+-spec presence_probe(jid(), jid(), pid()) -> ok.
 presence_probe(#jid{luser = U, lserver = S, lresource = R} = JID, JID, Pid) ->
     presence(S, {presence, JID, Pid}),
     presence(S, {presence, U, S, [R], JID});
@@ -697,12 +700,16 @@ presence(ServerHost, Presence) ->
 	undefined -> init_send_loop(ServerHost);
 	Pid -> {Pid, undefined}
     end,
-    SendLoop ! Presence.
+    SendLoop ! Presence,
+    ok.
 
 %% -------
 %% subscription hooks handling functions
 %%
 
+-spec out_subscription(
+	binary(), binary(), jid(),
+	subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
 out_subscription(User, Server, JID, subscribed) ->
     Owner = jid:make(User, Server, <<>>),
     {PUser, PServer, PResource} = jid:tolower(JID),
@@ -763,6 +770,7 @@ unsubscribe_user(Host, Entity, Owner) ->
 %% user remove hook handling function
 %%
 
+-spec remove_user(binary(), binary()) -> ok.
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
@@ -802,7 +810,8 @@ remove_user(User, Server) ->
 				Affs)
 		    end,
 		    plugins(Host))
-	end).
+	  end),
+    ok.
 
 handle_call(server_host, _From, State) ->
     {reply, State#state.server_host, State};
@@ -4224,11 +4233,12 @@ extended_headers(Jids) ->
 	    attrs = [{<<"type">>, <<"replyto">>}, {<<"jid">>, Jid}]}
 	|| Jid <- Jids].
 
+-spec on_user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
 on_user_offline(_, JID, _) ->
     {User, Server, Resource} = jid:tolower(JID),
     case user_resources(User, Server) of
 	[] -> purge_offline({User, Server, Resource});
-	_ -> true
+	_ -> ok
     end.
 
 purge_offline(LJID) ->
diff --git a/src/mod_register.erl b/src/mod_register.erl
index 1ed266d47..334af4514 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -74,6 +74,7 @@ stop(Host) ->
 depends(_Host, _Opts) ->
     [].
 
+-spec stream_feature_register([xmpp_element()], binary()) -> [xmpp_element()].
 stream_feature_register(Acc, Host) ->
     AF = gen_mod:get_module_opt(Host, ?MODULE, access_from,
                                           fun(A) -> A end,
@@ -85,6 +86,9 @@ stream_feature_register(Acc, Host) ->
 	    Acc
     end.
 
+-spec unauthenticated_iq_register(empty | iq(), binary(), iq(),
+				  {inet:ip_address(), non_neg_integer()}) ->
+					 empty | iq().
 unauthenticated_iq_register(_Acc, Server,
 			    #iq{sub_els = [#register{}]} = IQ, IP) ->
     Address = case IP of
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 51fe08ba5..c118a61ff 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -452,6 +452,9 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
     process_subscription(in, User, Server, JID, Type,
 			 Reason).
 
+-spec out_subscription(
+	binary(), binary(), jid(),
+	subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
 out_subscription(User, Server, JID, Type) ->
     process_subscription(out, User, Server, JID, Type, <<"">>).
 
@@ -643,12 +646,14 @@ in_auto_reply(from, out, unsubscribe) -> unsubscribed;
 in_auto_reply(both, none, unsubscribe) -> unsubscribed;
 in_auto_reply(_, _, _) -> none.
 
+-spec remove_user(binary(), binary()) -> ok.
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
     send_unsubscription_to_rosteritems(LUser, LServer),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:remove_user(LUser, LServer).
+    Mod:remove_user(LUser, LServer),
+    ok.
 
 %% For each contact with Subscription:
 %% Both or From, send a "unsubscribed" presence stanza;
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 079a2f44c..ac3717bd3 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -336,6 +336,9 @@ in_subscription(Acc, User, Server, JID, Type,
 		_Reason) ->
     process_subscription(in, User, Server, JID, Type, Acc).
 
+-spec out_subscription(
+	binary(), binary(), jid(),
+	subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
 out_subscription(UserFrom, ServerFrom, JIDTo,
 		 unsubscribed) ->
     #jid{luser = UserTo, lserver = ServerTo} = JIDTo,
@@ -629,12 +632,15 @@ broadcast_members_to_user(LUser, LServer, Group, Host, Subscription) ->
 	      broadcast_subscription(U, S, {LUser, LServer, <<"">>}, Subscription)
       end, Members).
 
+-spec register_user(binary(), binary()) -> ok.
 register_user(User, Server) ->
     Groups = get_user_groups({User, Server}),
     [push_user_to_displayed(User, Server, Group, Server,
 			    both, displayed_to_groups(Group, Server))
-     || Group <- Groups].
+     || Group <- Groups],
+    ok.
 
+-spec remove_user(binary(), binary()) -> ok.
 remove_user(User, Server) ->
     push_user_to_members(User, Server, remove).
 
@@ -724,6 +730,7 @@ push_roster_item(User, Server, ContactU, ContactS,
 		   groups = [GroupName]},
     push_item(User, Server, Item).
 
+-spec user_available(jid()) -> ok.
 user_available(New) ->
     LUser = New#jid.luser,
     LServer = New#jid.lserver,
@@ -747,6 +754,7 @@ user_available(New) ->
       _ -> ok
     end.
 
+-spec unset_presence(binary(), binary(), binary(), binary()) -> ok.
 unset_presence(LUser, LServer, Resource, Status) ->
     Resources = ejabberd_sm:get_user_resources(LUser,
 					       LServer),
diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl
index 06dd0e3a9..809887237 100644
--- a/src/mod_shared_roster_ldap.erl
+++ b/src/mod_shared_roster_ldap.erl
@@ -191,6 +191,9 @@ in_subscription(Acc, User, Server, JID, Type,
 		_Reason) ->
     process_subscription(in, User, Server, JID, Type, Acc).
 
+-spec out_subscription(
+	binary(), binary(), jid(),
+	subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
 out_subscription(User, Server, JID, Type) ->
     process_subscription(out, User, Server, JID, Type,
 			 false).
diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl
index 27ea8461a..5cc87056e 100644
--- a/src/mod_vcard_xupdate.erl
+++ b/src/mod_vcard_xupdate.erl
@@ -51,11 +51,12 @@ depends(_Host, _Opts) ->
 %%====================================================================
 %% Hooks
 %%====================================================================
-
+-spec update_presence(presence(), binary(), binary()) -> presence().
 update_presence(#presence{type = undefined} = Packet, User, Host) ->
     presence_with_xupdate(Packet, User, Host);
 update_presence(Packet, _User, _Host) -> Packet.
 
+-spec vcard_set(binary(), binary(), xmlel()) -> ok.
 vcard_set(LUser, LServer, VCARD) ->
     US = {LUser, LServer},
     case fxml:get_path_s(VCARD,
diff --git a/src/node_online.erl b/src/node_online.erl
index 4b01d2a2c..2620e6a49 100644
--- a/src/node_online.erl
+++ b/src/node_online.erl
@@ -57,6 +57,7 @@ terminate(Host, ServerHost) ->
 			  ?MODULE, user_offline, 75),
     ok.
 
+-spec user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> _.
 user_offline(_SID, #jid{luser=LUser,lserver=LServer}, _Info) ->
     mod_pubsub:remove_user(LUser, LServer).
 
diff --git a/src/xmpp.erl b/src/xmpp.erl
index c81474f10..8dbc49532 100644
--- a/src/xmpp.erl
+++ b/src/xmpp.erl
@@ -134,7 +134,7 @@ get_type(#message{type = T}) -> T;
 get_type(#presence{type = T}) -> T;
 get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs).
 
--spec get_lang(iq() | message() | presence()) -> binary().
+-spec get_lang(iq() | message() | presence() | xmlel()) -> binary().
 get_lang(#iq{lang = L}) -> L;
 get_lang(#message{lang = L}) -> L;
 get_lang(#presence{lang = L}) -> L;
diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl
index 905e48f3c..afe6ff1ad 100644
--- a/src/xmpp_codec.erl
+++ b/src/xmpp_codec.erl
@@ -3483,6 +3483,12 @@ dec_bool(<<"0">>) -> false;
 dec_bool(<<"true">>) -> true;
 dec_bool(<<"1">>) -> true.
 
+nameprep(S) ->
+    case jid:nameprep(S) of
+      error -> erlang:error(badarg);
+      S1 -> S1
+    end.
+
 resourceprep(R) ->
     case jid:resourceprep(R) of
       error -> erlang:error(badarg);
@@ -4887,7 +4893,7 @@ decode_db_verify_attr_from(__TopXMLNS, undefined) ->
 		  {missing_attr, <<"from">>, <<"db:verify">>,
 		   __TopXMLNS}});
 decode_db_verify_attr_from(__TopXMLNS, _val) ->
-    case catch dec_jid(_val) of
+    case catch nameprep(_val) of
       {'EXIT', _} ->
 	  erlang:error({xmpp_codec,
 			{bad_attr_value, <<"from">>, <<"db:verify">>,
@@ -4896,13 +4902,13 @@ decode_db_verify_attr_from(__TopXMLNS, _val) ->
     end.
 
 encode_db_verify_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+    [{<<"from">>, nameprep(_val)} | _acc].
 
 decode_db_verify_attr_to(__TopXMLNS, undefined) ->
     erlang:error({xmpp_codec,
 		  {missing_attr, <<"to">>, <<"db:verify">>, __TopXMLNS}});
 decode_db_verify_attr_to(__TopXMLNS, _val) ->
-    case catch dec_jid(_val) of
+    case catch nameprep(_val) of
       {'EXIT', _} ->
 	  erlang:error({xmpp_codec,
 			{bad_attr_value, <<"to">>, <<"db:verify">>,
@@ -4911,7 +4917,7 @@ decode_db_verify_attr_to(__TopXMLNS, _val) ->
     end.
 
 encode_db_verify_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
+    [{<<"to">>, nameprep(_val)} | _acc].
 
 decode_db_verify_attr_id(__TopXMLNS, undefined) ->
     erlang:error({xmpp_codec,
@@ -5014,7 +5020,7 @@ decode_db_result_attr_from(__TopXMLNS, undefined) ->
 		  {missing_attr, <<"from">>, <<"db:result">>,
 		   __TopXMLNS}});
 decode_db_result_attr_from(__TopXMLNS, _val) ->
-    case catch dec_jid(_val) of
+    case catch nameprep(_val) of
       {'EXIT', _} ->
 	  erlang:error({xmpp_codec,
 			{bad_attr_value, <<"from">>, <<"db:result">>,
@@ -5023,13 +5029,13 @@ decode_db_result_attr_from(__TopXMLNS, _val) ->
     end.
 
 encode_db_result_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+    [{<<"from">>, nameprep(_val)} | _acc].
 
 decode_db_result_attr_to(__TopXMLNS, undefined) ->
     erlang:error({xmpp_codec,
 		  {missing_attr, <<"to">>, <<"db:result">>, __TopXMLNS}});
 decode_db_result_attr_to(__TopXMLNS, _val) ->
-    case catch dec_jid(_val) of
+    case catch nameprep(_val) of
       {'EXIT', _} ->
 	  erlang:error({xmpp_codec,
 			{bad_attr_value, <<"to">>, <<"db:result">>,
@@ -5038,7 +5044,7 @@ decode_db_result_attr_to(__TopXMLNS, _val) ->
     end.
 
 encode_db_result_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
+    [{<<"to">>, nameprep(_val)} | _acc].
 
 decode_db_result_attr_type(__TopXMLNS, undefined) ->
     undefined;
-- 
cgit v1.2.3


From 31faa4eb9ad881c7884cd24f5d374d8b20e4b6c5 Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Fri, 12 Aug 2016 13:17:42 +0300
Subject: Add more type specs

---
 src/ejabberd_sm.erl            |  6 +++---
 src/mod_http_upload_quota.erl  |  4 ++--
 src/mod_last.erl               |  1 +
 src/mod_mam.erl                | 17 +++++++++++++++--
 src/mod_metrics.erl            |  3 +++
 src/mod_offline.erl            |  3 +++
 src/mod_pres_counter.erl       |  2 ++
 src/mod_pubsub.erl             |  3 +++
 src/mod_roster.erl             | 10 ++++++++++
 src/mod_service_log.erl        |  3 +++
 src/mod_shared_roster.erl      |  9 +++++++++
 src/mod_shared_roster_ldap.erl |  9 +++++++++
 src/mod_vcard.erl              |  1 +
 13 files changed, 64 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 3ff9f2908..f6d0e765d 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -159,9 +159,9 @@ close_session(SID, User, Server, Resource) ->
     ejabberd_hooks:run(sm_remove_connection_hook,
 		       JID#jid.lserver, [SID, JID, Info]).
 
--spec check_in_subscription(any(), binary(), binary(),
-                            any(), any(), any()) -> any().
-
+-spec check_in_subscription(boolean(), binary(), binary(), jid(),
+			    subscribe | subscribed | unsubscribe | unsubscribed,
+			    binary()) -> boolean() | {stop, false}.
 check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
     case ejabberd_auth:is_user_exists(User, Server) of
       true -> Acc;
diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl
index 056edbedb..fa37b801f 100644
--- a/src/mod_http_upload_quota.erl
+++ b/src/mod_http_upload_quota.erl
@@ -263,8 +263,8 @@ code_change(_OldVsn, #state{server_host = ServerHost} = State, _Extra) ->
 %% ejabberd_hooks callback.
 %%--------------------------------------------------------------------
 
--spec handle_slot_request(term(), jid(), binary(), non_neg_integer(), binary())
-      -> term().
+-spec handle_slot_request(allow | deny, jid(), binary(),
+			  non_neg_integer(), binary()) -> allow | deny.
 
 handle_slot_request(allow, #jid{lserver = ServerHost} = JID, Path, Size,
 		    _Lang) ->
diff --git a/src/mod_last.erl b/src/mod_last.erl
index 6d0edebf0..56e3b1c5e 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -200,6 +200,7 @@ get_last_info(LUser, LServer) ->
       Res -> Res
     end.
 
+-spec remove_user(binary(), binary()) -> any().
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index 7e93a3166..2529b7389 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -191,7 +191,9 @@ remove_room(LServer, Name, Host) ->
     Mod:remove_room(LServer, LName, LHost),
     ok.
 
-get_room_config(X, RoomState, _From, Lang) ->
+-spec get_room_config([xdata_field()], mod_muc_room:state(), jid(), binary())
+      -> [xdata_field()].			     
+get_room_config(XFields, RoomState, _From, Lang) ->
     Config = RoomState#state.config,
     Label = <<"Enable message archiving">>,
     Var = <<"muc#roomconfig_mam">>,
@@ -203,8 +205,10 @@ get_room_config(X, RoomState, _From, Lang) ->
 			  label = translate:translate(Lang, Label),
 			  var = Var,
 			  values = [Val]},
-    X ++ [XField].
+    XFields ++ [XField].
 
+-spec set_room_option({pos_integer(), _}, binary(), [binary()], binary())
+      -> {pos_integer(), _}.
 set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) ->
     try
 	Val = case Vals of
@@ -222,6 +226,7 @@ set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) ->
 set_room_option(Acc, _Opt, _Vals, _Lang) ->
     Acc.
 
+-spec user_receive_packet(stanza(), ejabberd_c2s:state(), jid(), jid(), jid()) -> stanza().
 user_receive_packet(Pkt, C2SState, JID, Peer, To) ->
     LUser = JID#jid.luser,
     LServer = JID#jid.lserver,
@@ -239,6 +244,7 @@ user_receive_packet(Pkt, C2SState, JID, Peer, To) ->
 	    Pkt
     end.
 
+-spec user_send_packet(stanza(), ejabberd_c2s:state(), jid(), jid()) -> stanza().
 user_send_packet(Pkt, C2SState, JID, Peer) ->
     LUser = JID#jid.luser,
     LServer = JID#jid.lserver,
@@ -256,10 +262,14 @@ user_send_packet(Pkt, C2SState, JID, Peer) ->
 	    Pkt
     end.
 
+-spec user_send_packet_strip_tag(stanza(), ejabberd_c2s:state(),
+				 jid(), jid()) -> stanza().
 user_send_packet_strip_tag(Pkt, _C2SState, JID, _Peer) ->
     LServer = JID#jid.lserver,
     strip_my_archived_tag(Pkt, LServer).
 
+-spec muc_filter_message(message(), mod_muc_room:state(),
+			 jid(), jid(), binary()) -> message().
 muc_filter_message(Pkt, #state{config = Config} = MUCState,
 		   RoomJID, From, FromNick) ->
     if Config#config.mam ->
@@ -302,6 +312,7 @@ process_iq_v0_3(#iq{from = #jid{lserver = LServer},
 process_iq_v0_3(IQ) ->
     process_iq(IQ).
 
+-spec muc_process_iq(ignore | iq(), mod_muc_room:state()) -> ignore | iq().
 muc_process_iq(#iq{type = T, lang = Lang,
 		   from = From,
 		   sub_els = [#mam_query{xmlns = NS}]} = IQ,
@@ -372,6 +383,8 @@ disco_sm_features({result, OtherFeatures},
 disco_sm_features(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
+-spec message_is_archived(boolean(), ejabberd_c2s:state(),
+			  jid(), jid(), message()) -> boolean().
 message_is_archived(true, _C2SState, _Peer, _JID, _Pkt) ->
     true;
 message_is_archived(false, C2SState, Peer,
diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl
index 605fe3d6b..7861542c5 100644
--- a/src/mod_metrics.erl
+++ b/src/mod_metrics.erl
@@ -86,9 +86,12 @@ sm_register_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
 sm_remove_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
     push(LServer, sm_remove_connection).
 
+-spec user_send_packet(stanza(), ejabberd_c2s:state(), jid(), jid()) -> stanza().
 user_send_packet(Packet, _C2SState, #jid{lserver=LServer}, _To) ->
     push(LServer, user_send_packet),
     Packet.
+
+-spec user_receive_packet(stanza(), ejabberd_c2s:state(), jid(), jid(), jid()) -> stanza().
 user_receive_packet(Packet, _C2SState, _JID, _From, #jid{lserver=LServer}) ->
     push(LServer, user_receive_packet),
     Packet.
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 03eb3c59a..509406aa4 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -533,6 +533,9 @@ resend_offline_messages(User, Server) ->
       _ -> ok
     end.
 
+-spec pop_offline_messages([{route, jid(), jid(), message()}],
+			   binary(), binary()) ->
+      [{route, jid(), jid(), message()}].
 pop_offline_messages(Ls, User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl
index 786ba97f2..955e53f6f 100644
--- a/src/mod_pres_counter.erl
+++ b/src/mod_pres_counter.erl
@@ -51,6 +51,8 @@ stop(Host) ->
 depends(_Host, _Opts) ->
     [].
 
+-spec check_packet(allow | deny, binary(), binary(), _,
+		   {jid(), jid(), stanza()}, in | out) -> allow | deny.
 check_packet(_, _User, Server, _PrivacyList,
 	     {From, To, #presence{type = Type}}, Dir) ->
     IsSubscription = case Type of
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 0796a20bb..fadc7720c 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -722,6 +722,9 @@ out_subscription(User, Server, JID, subscribed) ->
 out_subscription(_, _, _, _) ->
     true.
 
+-spec in_subscription(boolean(), binary(), binary(), jid(),
+		      subscribe | subscribed | unsubscribe | unsubscribed,
+		      binary()) -> true.
 in_subscription(_, User, Server, Owner, unsubscribed, _) ->
     unsubscribe_user(jid:make(User, Server, <<>>), Owner),
     true;
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index c118a61ff..2a41907a4 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -175,6 +175,7 @@ roster_version_on_db(Host) ->
 			   false).
 
 %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled.
+-spec get_versioning_feature([xmpp_element()], binary()) -> [xmpp_element()].
 get_versioning_feature(Acc, Host) ->
     case roster_versioning_enabled(Host) of
       true ->
@@ -274,6 +275,7 @@ process_iq_get(#iq{from = From, to = To, lang = Lang,
 	    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
+-spec get_user_roster([#roster{}], {binary(), binary()}) -> [#roster{}].
 get_user_roster(Acc, {LUser, LServer}) ->
     Items = get_roster(LUser, LServer),
     lists:filter(fun (#roster{subscription = none,
@@ -416,6 +418,8 @@ push_item_version(Server, User, From, Item,
 		  end,
 		  ejabberd_sm:get_user_resources(User, Server)).
 
+-spec get_subscription_lists({[ljid()], [ljid()]}, binary(), binary())
+      -> {[ljid()], [ljid()]}.
 get_subscription_lists(_Acc, User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
@@ -448,6 +452,9 @@ transaction(LServer, F) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:transaction(LServer, F).
 
+-spec in_subscription(boolean(), binary(), binary(), jid(),
+		      subscribe | subscribed | unsubscribe | unsubscribed,
+		      binary()) -> boolean().
 in_subscription(_, User, Server, JID, Type, Reason) ->
     process_subscription(in, User, Server, JID, Type,
 			 Reason).
@@ -726,6 +733,7 @@ process_item_set_t(LUser, LServer, #roster_item{jid = JID1} = QueryItem) ->
     end;
 process_item_set_t(_LUser, _LServer, _) -> ok.
 
+-spec get_in_pending_subscriptions([presence()], binary(), binary()) -> [presence()].
 get_in_pending_subscriptions(Ls, User, Server) ->
     LServer = jid:nameprep(Server),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
@@ -755,6 +763,8 @@ read_subscription_and_groups(User, Server, LJID) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:read_subscription_and_groups(LUser, LServer, LJID).
 
+-spec get_jid_info({subscription(), [binary()]}, binary(), binary(), jid())
+      -> {subscription(), [binary()]}.
 get_jid_info(_, User, Server, JID) ->
     LJID = jid:tolower(JID),
     case read_subscription_and_groups(User, Server, LJID) of
diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl
index a88b04b58..ea7768bca 100644
--- a/src/mod_service_log.erl
+++ b/src/mod_service_log.erl
@@ -54,14 +54,17 @@ stop(Host) ->
 depends(_Host, _Opts) ->
     [].
 
+-spec log_user_send(stanza(), ejabberd_c2s:state(), jid(), jid()) -> stanza().
 log_user_send(Packet, _C2SState, From, To) ->
     log_packet(From, To, Packet, From#jid.lserver),
     Packet.
 
+-spec log_user_receive(stanza(), ejabberd_c2s:state(), jid(), jid(), jid()) -> stanza().
 log_user_receive(Packet, _C2SState, _JID, From, To) ->
     log_packet(From, To, Packet, To#jid.lserver),
     Packet.
 
+-spec log_packet(jid(), jid(), stanza(), binary()) -> ok.
 log_packet(From, To, Packet, Host) ->
     Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers,
                                      fun(L) ->
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index ac3717bd3..8b620514b 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -135,6 +135,7 @@ stop(Host) ->
 depends(_Host, _Opts) ->
     [].
 
+-spec get_user_roster([#roster{}], {binary(), binary()}) -> [#roster{}].
 get_user_roster(Items, US) ->
     {U, S} = US,
     DisplayedGroups = get_user_displayed_groups(US),
@@ -202,6 +203,7 @@ get_rosteritem_name_vcard(_) ->
 
 %% This function rewrites the roster entries when moving or renaming
 %% them in the user contact list.
+-spec process_item(#roster{}, binary()) -> #roster{}.
 process_item(RosterItem, Host) ->
     USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us,
     {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid,
@@ -292,6 +294,8 @@ set_item(User, Server, Resource, Item) ->
 			  jid:make(Server),
 			  ResIQ).
 
+-spec get_subscription_lists({[ljid()], [ljid()]}, binary(), binary())
+      -> {[ljid()], [ljid()]}.
 get_subscription_lists({F, T}, User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
@@ -304,6 +308,8 @@ get_subscription_lists({F, T}, User, Server) ->
     SRJIDs = [{U1, S1, <<"">>} || {U1, S1} <- SRUsers],
     {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}.
 
+-spec get_jid_info({subscription(), [binary()]}, binary(), binary(), jid())
+      -> {subscription(), [binary()]}.
 get_jid_info({Subscription, Groups}, User, Server,
 	     JID) ->
     LUser = jid:nodeprep(User),
@@ -332,6 +338,9 @@ get_jid_info({Subscription, Groups}, User, Server,
       error -> {Subscription, Groups}
     end.
 
+-spec in_subscription(boolean(), binary(), binary(), jid(),
+		      subscribe | subscribed | unsubscribe | unsubscribed,
+		      binary()) -> boolean().
 in_subscription(Acc, User, Server, JID, Type,
 		_Reason) ->
     process_subscription(in, User, Server, JID, Type, Acc).
diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl
index 809887237..97ead9f3d 100644
--- a/src/mod_shared_roster_ldap.erl
+++ b/src/mod_shared_roster_ldap.erl
@@ -111,6 +111,7 @@ depends(_Host, _Opts) ->
 %%--------------------------------------------------------------------
 %% Hooks
 %%--------------------------------------------------------------------
+-spec get_user_roster([#roster{}], {binary(), binary()}) -> [#roster{}].
 get_user_roster(Items, {U, S} = US) ->
     SRUsers = get_user_to_groups_map(US, true),
     {NewItems1, SRUsersRest} = lists:mapfoldl(fun (Item,
@@ -143,6 +144,7 @@ get_user_roster(Items, {U, S} = US) ->
 
 %% This function in use to rewrite the roster entries when moving or renaming
 %% them in the user contact list.
+-spec process_item(#roster{}, binary()) -> #roster{}.
 process_item(RosterItem, _Host) ->
     USFrom = RosterItem#roster.us,
     {User, Server, _Resource} = RosterItem#roster.jid,
@@ -158,6 +160,8 @@ process_item(RosterItem, _Host) ->
       _ -> RosterItem#roster{subscription = both, ask = none}
     end.
 
+-spec get_subscription_lists({[ljid()], [ljid()]}, binary(), binary())
+      -> {[ljid()], [ljid()]}.
 get_subscription_lists({F, T}, User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
@@ -170,6 +174,8 @@ get_subscription_lists({F, T}, User, Server) ->
     SRJIDs = [{U1, S1, <<"">>} || {U1, S1} <- SRUsers],
     {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}.
 
+-spec get_jid_info({subscription(), [binary()]}, binary(), binary(), jid())
+      -> {subscription(), [binary()]}.
 get_jid_info({Subscription, Groups}, User, Server,
 	     JID) ->
     LUser = jid:nodeprep(User),
@@ -187,6 +193,9 @@ get_jid_info({Subscription, Groups}, User, Server,
       error -> {Subscription, Groups}
     end.
 
+-spec in_subscription(boolean(), binary(), binary(), jid(),
+		      subscribe | subscribed | unsubscribe | unsubscribed,
+		      binary()) -> boolean().
 in_subscription(Acc, User, Server, JID, Type,
 		_Reason) ->
     process_subscription(in, User, Server, JID, Type, Acc).
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 4653d6e2c..f0fb556ba 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -423,6 +423,7 @@ search(LServer, XFields) ->
     Mod:search(LServer, Data, AllowReturnAll, MaxMatch).
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec remove_user(binary(), binary()) -> any().
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
-- 
cgit v1.2.3


From 45eb49125ba46cd692a9fb430c567c0c2cf4a84d Mon Sep 17 00:00:00 2001
From: Evgeniy Khramtsov 
Date: Tue, 30 Aug 2016 09:48:08 +0300
Subject: Rewrite mod_pubsub to use XML codec

---
 src/gen_pubsub_node.erl  |   21 +-
 src/mod_caps.erl         |    6 +-
 src/mod_client_state.erl |    4 +-
 src/mod_muc_room.erl     |   12 +-
 src/mod_pubsub.erl       | 2897 ++++++++++++++---------------
 src/node_flat_sql.erl    |  533 +++---
 src/xmpp.erl             |   10 +-
 src/xmpp_codec.erl       | 4537 +++++++++++++++++++++++++++++++++++-----------
 8 files changed, 5058 insertions(+), 2962 deletions(-)

(limited to 'src')

diff --git a/src/gen_pubsub_node.erl b/src/gen_pubsub_node.erl
index 27cb032bd..cc94ea147 100644
--- a/src/gen_pubsub_node.erl
+++ b/src/gen_pubsub_node.erl
@@ -25,7 +25,7 @@
 
 -module(gen_pubsub_node).
 
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 -type(host() :: mod_pubsub:host()).
 -type(nodeId() :: mod_pubsub:nodeId()).
@@ -175,20 +175,13 @@
     ok |
     {error, xmlel()}.
 
--callback get_items(NodeIdx :: nodeIdx(),
-	JID :: jid(),
-	AccessModel :: accessModel(),
-	Presence_Subscription :: boolean(),
-	RosterGroup :: boolean(),
-	SubId :: subId(),
-	RSM :: none | rsm_in()) ->
-    {result, {[pubsubItem()], none | rsm_out()}} |
-    {error, xmlel()}.
+-callback get_items(nodeIdx(), jid(), accessModel(),
+		    boolean(), boolean(), binary(),
+		    undefined | rsm_set()) ->
+    {result, {[pubsubItem()], undefined | rsm_set()}} | {error, error()}.
 
--callback get_items(NodeIdx :: nodeIdx(),
-	From :: jid(),
-	RSM :: none | rsm_in()) ->
-    {result, {[pubsubItem()], none | rsm_out()}}.
+-callback get_items(nodeIdx(), jid(), undefined | rsm_set()) ->
+    {result, {[pubsubItem()], undefined | rsm_set()}}.
 
 -callback get_item(NodeIdx :: nodeIdx(),
 	ItemId :: itemId(),
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index e57bc7928..a388b085f 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -406,13 +406,15 @@ feature_response(_IQResult, Host, From, Caps,
 		 [_SubNode | SubNodes]) ->
     feature_request(Host, From, Caps, SubNodes).
 
--spec caps_read_fun(binary(), {binary(), binary()}) -> function().
+-spec caps_read_fun(binary(), {binary(), binary()})
+      -> fun(() -> {ok, [binary()] | non_neg_integer()} | error).
 caps_read_fun(Host, Node) ->
     LServer = jid:nameprep(Host),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     fun() -> Mod:caps_read(LServer, Node) end.
 
--spec caps_write_fun(binary(), {binary(), binary()}, [binary()]) -> function().
+-spec caps_write_fun(binary(), {binary(), binary()},
+		     [binary()] | non_neg_integer()) -> fun().
 caps_write_fun(Host, Node, Features) ->
     LServer = jid:nameprep(Host),
     Mod = gen_mod:db_mod(LServer, ?MODULE),
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index 042c59702..f72f334f3 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -287,8 +287,8 @@ get_pep_node(#message{from = #jid{luser = <<>>}}) ->
     %% It's not PEP.
     undefined;
 get_pep_node(#message{} = Msg) ->
-    case xmpp:get_subtag(Msg, #pubsub_event{}) of
-	#pubsub_event{items = [#pubsub_event_items{node = Node}]} ->
+    case xmpp:get_subtag(Msg, #ps_event{}) of
+	#ps_event{items = #ps_items{node = Node}} ->
 	    Node;
 	_ ->
 	    undefined
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index b470c093e..2f2962b97 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -4377,12 +4377,12 @@ send_wrapped(From, To, Packet, Node, State) ->
 wrap(From, To, Packet, Node) ->
     El = xmpp:encode(xmpp:set_from_to(Packet, From, To)),
     #message{
-       sub_els = [#pubsub_event{
-		     items = [#pubsub_event_items{
-				 node = Node,
-				 items = [#pubsub_event_item{
-					     id = randoms:get_string(),
-					     xml_els = [El]}]}]}]}.
+       sub_els = [#ps_event{
+		     items = #ps_items{
+				node = Node,
+				items = [#ps_item{
+					    id = randoms:get_string(),
+					    xml_els = [El]}]}}]}.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% Multicast
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index fadc7720c..c84fb5fe8 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -41,8 +41,9 @@
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("adhoc.hrl").
--include("jlib.hrl").
+%%-include("adhoc.hrl").
+%%-include("jlib.hrl").
+-include("xmpp.hrl").
 -include("pubsub.hrl").
 
 -define(STDTREE, <<"tree">>).
@@ -58,7 +59,9 @@
     disco_sm_features/5, disco_sm_items/5]).
 
 %% exported iq handlers
--export([iq_sm/3]).
+-export([iq_sm/1, process_disco_info/1, process_disco_items/1,
+	 process_pubsub/1, process_pubsub_owner/1, process_vcard/1,
+	 process_commands/1]).
 
 %% exports for console debug manual use
 -export([create_node/5, create_node/7, delete_node/3,
@@ -70,10 +73,21 @@
 %% general helpers for plugins
 -export([subscription_to_string/1, affiliation_to_string/1,
     string_to_subscription/1, string_to_affiliation/1,
-    extended_error/2, extended_error/3, service_jid/1,
+    extended_error/2, service_jid/1,
     tree/1, tree/2, plugin/2, plugins/1, config/3,
     host/1, serverhost/1]).
 
+%% pubsub#errors
+-export([err_closed_node/0, err_configuration_required/0,
+	 err_invalid_jid/0, err_invalid_options/0, err_invalid_payload/0,
+	 err_invalid_subid/0, err_item_forbidden/0, err_item_required/0,
+	 err_jid_required/0, err_max_items_exceeded/0, err_max_nodes_exceeded/0,
+	 err_nodeid_required/0, err_not_in_roster_group/0, err_not_subscribed/0,
+	 err_payload_too_big/0, err_payload_required/0,
+	 err_pending_subscription/0, err_presence_subscription_required/0,
+	 err_subid_required/0, err_too_many_subscriptions/0, err_unsupported/1,
+	 err_unsupported_access_model/0]).
+
 %% API and gen_server callbacks
 -export([start_link/2, start/2, stop/1, init/1,
     handle_call/3, handle_cast/2, handle_info/2,
@@ -295,6 +309,18 @@ init([ServerHost, Opts]) ->
 	?MODULE, remove_user, 50),
     ejabberd_hooks:add(anonymous_purge_hook, ServerHost,
 	?MODULE, remove_user, 50),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
+				  ?MODULE, process_disco_info, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
+				  ?MODULE, process_disco_items, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB,
+				  ?MODULE, process_pubsub, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER,
+				  ?MODULE, process_pubsub_owner, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
+				  ?MODULE, process_vcard, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
+				  ?MODULE, process_commands, IQDisc),
     case lists:member(?PEPNODE, Plugins) of
 	true ->
 	    ejabberd_hooks:add(caps_add, ServerHost,
@@ -489,27 +515,21 @@ send_loop(State) ->
 %% disco hooks handling functions
 %%
 
--spec disco_local_identity(Acc :: [xmlel()], _From :: jid(),
-			   To :: jid(), Node :: <<>> | mod_pubsub:nodeId(),
-			   Lang :: binary()) -> [xmlel()].
-
+-spec disco_local_identity([identity()], jid(), jid(),
+			   binary(), binary()) -> [identity()].
 disco_local_identity(Acc, _From, To, <<>>, _Lang) ->
     case lists:member(?PEPNODE, plugins(host(To#jid.lserver))) of
 	true ->
-	    [#xmlel{name = <<"identity">>,
-		    attrs = [{<<"category">>, <<"pubsub">>},
-			{<<"type">>, <<"pep">>}]}
-		| Acc];
+	    [#identity{category = <<"pubsub">>, type = <<"pep">>} | Acc];
 	false ->
 	    Acc
     end;
 disco_local_identity(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
--spec disco_local_features(Acc :: [xmlel()], _From :: jid(),
-			   To :: jid(), Node :: <<>> | mod_pubsub:nodeId(),
-			   Lang :: binary()) -> [binary(),...].
-
+-spec disco_local_features({error, error()} | {result, [binary()]} | empty,
+			   jid(), jid(), binary(), binary()) ->
+				  {error, error()} | {result, [binary()]} | empty.
 disco_local_features(Acc, _From, To, <<>>, _Lang) ->
     Host = host(To#jid.lserver),
     Feats = case Acc of
@@ -520,88 +540,83 @@ disco_local_features(Acc, _From, To, <<>>, _Lang) ->
 disco_local_features(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
+-spec disco_local_items({error, error()} | {result, [disco_item()]} | empty,
+			jid(), jid(), binary(), binary()) ->
+			       {error, error()} | {result, [disco_item()]} | empty.
 disco_local_items(Acc, _From, _To, <<>>, _Lang) -> Acc;
 disco_local_items(Acc, _From, _To, _Node, _Lang) -> Acc.
 
-%disco_sm_identity(Acc, From, To, Node, Lang)
-%    when is_binary(Node) ->
-%    disco_sm_identity(Acc, From, To, iolist_to_binary(Node),
-%                      Lang);
--spec disco_sm_identity(Acc :: empty | [xmlel()], From :: jid(),
-			To :: jid(), Node :: mod_pubsub:nodeId(),
-			Lang :: binary()) -> [xmlel()].
-
-disco_sm_identity(empty, From, To, Node, Lang) ->
-    disco_sm_identity([], From, To, Node, Lang);
+-spec disco_sm_identity([identity()], jid(), jid(),
+			binary(), binary()) -> [identity()].
 disco_sm_identity(Acc, From, To, Node, _Lang) ->
     disco_identity(jid:tolower(jid:remove_resource(To)), Node, From)
     ++ Acc.
 
+-spec disco_identity(binary(), binary(), jid()) -> [identity()].
 disco_identity(_Host, <<>>, _From) ->
-    [#xmlel{name = <<"identity">>,
-	    attrs = [{<<"category">>, <<"pubsub">>},
-		{<<"type">>, <<"pep">>}]}];
+    [#identity{category = <<"pubsub">>, type = <<"pep">>}];
 disco_identity(Host, Node, From) ->
-    Action = fun (#pubsub_node{id = Nidx, type = Type, options = Options, owners = O}) ->
-	    Owners = node_owners_call(Host, Type, Nidx, O),
-	    case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
-		{result, _} ->
-		    {result, [#xmlel{name = <<"identity">>,
-				attrs = [{<<"category">>, <<"pubsub">>},
-				    {<<"type">>, <<"pep">>}]},
-			    #xmlel{name = <<"identity">>,
-				attrs = [{<<"category">>, <<"pubsub">>},
-				    {<<"type">>, <<"leaf">>}
-				    | case get_option(Options, title) of
-					false -> [];
-					[Title] -> [{<<"name">>, Title}]
-				    end]}]};
-		_ ->
-		    {result, []}
-	    end
-    end,
+    Action =
+	fun(#pubsub_node{id = Nidx, type = Type,
+			 options = Options, owners = O}) ->
+		Owners = node_owners_call(Host, Type, Nidx, O),
+		case get_allowed_items_call(Host, Nidx, From, Type,
+					    Options, Owners) of
+		    {result, _} ->
+			{result, [#identity{category = <<"pubsub">>,
+					    type = <<"pep">>},
+				  #identity{category = <<"pubsub">>,
+					    type = <<"leaf">>,
+					    name = case get_option(Options, title) of
+						       false -> <<>>;
+						       [Title] -> Title
+						   end}]};
+		    _ ->
+			{result, []}
+		end
+	end,
     case transaction(Host, Node, Action, sync_dirty) of
 	{result, {_, Result}} -> Result;
 	_ -> []
     end.
 
--spec disco_sm_features(Acc :: empty | {result, Features::[Feature::binary()]},
-			From :: jid(), To :: jid(), Node :: mod_pubsub:nodeId(),
-			Lang :: binary()) -> {result, Features::[Feature::binary()]}.
-%disco_sm_features(Acc, From, To, Node, Lang)
-%    when is_binary(Node) ->
-%    disco_sm_features(Acc, From, To, iolist_to_binary(Node),
-%                      Lang);
+-spec disco_sm_features({error, error()} | {result, [binary()]} | empty,
+			jid(), jid(), binary(), binary()) ->
+			       {error, error()} | {result, [binary()]}.
 disco_sm_features(empty, From, To, Node, Lang) ->
     disco_sm_features({result, []}, From, To, Node, Lang);
 disco_sm_features({result, OtherFeatures} = _Acc, From, To, Node, _Lang) ->
     {result,
-	OtherFeatures ++
-	disco_features(jid:tolower(jid:remove_resource(To)), Node, From)};
+     OtherFeatures ++
+	 disco_features(jid:tolower(jid:remove_resource(To)), Node, From)};
 disco_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
 
+-spec disco_features(ljid(), binary(), jid()) -> [binary()].
 disco_features(Host, <<>>, _From) ->
     [?NS_PUBSUB | [feature(F) || F <- plugin_features(Host, <<"pep">>)]];
 disco_features(Host, Node, From) ->
-    Action = fun (#pubsub_node{id = Nidx, type = Type, options = Options, owners = O}) ->
-	    Owners = node_owners_call(Host, Type, Nidx, O),
-	    case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
-		{result, _} -> {result, [?NS_PUBSUB | [feature(F) || F <- plugin_features(Host, <<"pep">>)]]};
-		_ -> {result, []}
-	    end
-    end,
+    Action =
+	fun(#pubsub_node{id = Nidx, type = Type,
+			 options = Options, owners = O}) ->
+		Owners = node_owners_call(Host, Type, Nidx, O),
+		case get_allowed_items_call(Host, Nidx, From,
+					    Type, Options, Owners) of
+		    {result, _} ->
+			{result,
+			 [?NS_PUBSUB |
+			  [feature(F) || F <- plugin_features(Host, <<"pep">>)]]};
+		    _ ->
+			{result, []}
+		end
+	end,
     case transaction(Host, Node, Action, sync_dirty) of
 	{result, {_, Result}} -> Result;
 	_ -> []
     end.
 
--spec disco_sm_items(Acc :: empty | {result, [xmlel()]}, From :: jid(),
-		     To :: jid(), Node :: mod_pubsub:nodeId(),
-		     Lang :: binary()) -> {result, [xmlel()]}.
-%disco_sm_items(Acc, From, To, Node, Lang)
-%    when is_binary(Node) ->
-%    disco_sm_items(Acc, From, To, iolist_to_binary(Node),
-%                   Lang);
+-spec disco_sm_items({error, error()} | {result, [disco_item()]} | empty,
+		     jid(), jid(), binary(), binary()) ->
+			    {error, error()} | {result, [disco_item()]}.
 disco_sm_items(empty, From, To, Node, Lang) ->
     disco_sm_items({result, []}, From, To, Node, Lang);
 disco_sm_items({result, OtherItems}, From, To, Node, _Lang) ->
@@ -609,48 +624,48 @@ disco_sm_items({result, OtherItems}, From, To, Node, _Lang) ->
 	    disco_items(jid:tolower(jid:remove_resource(To)), Node, From))};
 disco_sm_items(Acc, _From, _To, _Node, _Lang) -> Acc.
 
--spec disco_items(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(),
-		  From :: jid()) -> [xmlel()].
+-spec disco_items(ljid(), binary(), jid()) -> [disco_item()].
 disco_items(Host, <<>>, From) ->
-    Action = fun (#pubsub_node{nodeid = {_, Node},
-			options = Options, type = Type, id = Nidx, owners = O},
-		    Acc) ->
-	    Owners = node_owners_call(Host, Type, Nidx, O),
-	    case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
-		{result, _} ->
-		    [#xmlel{name = <<"item">>,
-			    attrs = [{<<"node">>, (Node)},
-				{<<"jid">>, jid:to_string(Host)}
-				| case get_option(Options, title) of
-				    false -> [];
-				    [Title] -> [{<<"name">>, Title}]
-				end]}
-			| Acc];
-		_ ->
-		    Acc
-	    end
-    end,
+    Action =
+	fun(#pubsub_node{nodeid = {_, Node}, options = Options,
+			 type = Type, id = Nidx, owners = O}, Acc) ->
+		Owners = node_owners_call(Host, Type, Nidx, O),
+		case get_allowed_items_call(Host, Nidx, From,
+					    Type, Options, Owners) of
+		    {result, _} ->
+			[#disco_item{node = Node,
+				     jid = jid:make(Host),
+				     name = case get_option(Options, title) of
+						false -> <<>>;
+						[Title] -> Title
+					    end} | Acc];
+		    _ ->
+			Acc
+		end
+	end,
     NodeBloc = fun() ->
-	    {result,
-		lists:foldl(Action, [], tree_call(Host, get_nodes, [Host]))}
-    end,
+		       {result,
+			lists:foldl(Action, [], tree_call(Host, get_nodes, [Host]))}
+	       end,
     case transaction(Host, NodeBloc, sync_dirty) of
 	{result, Items} -> Items;
 	_ -> []
     end;
 disco_items(Host, Node, From) ->
-    Action = fun (#pubsub_node{id = Nidx, type = Type, options = Options, owners = O}) ->
-	    Owners = node_owners_call(Host, Type, Nidx, O),
-	    case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
-		{result, Items} ->
-		    {result, [#xmlel{name = <<"item">>,
-				attrs = [{<<"jid">>, jid:to_string(Host)},
-				    {<<"name">>, ItemId}]}
-			    || #pubsub_item{itemid = {ItemId, _}} <- Items]};
-		_ ->
-		    {result, []}
-	    end
-    end,
+    Action =
+	fun(#pubsub_node{id = Nidx, type = Type,
+			 options = Options, owners = O}) ->
+		Owners = node_owners_call(Host, Type, Nidx, O),
+		case get_allowed_items_call(Host, Nidx, From,
+					    Type, Options, Owners) of
+		    {result, Items} ->
+			{result, [#disco_item{jid = jid:make(Host),
+					      name = ItemId}
+				  || #pubsub_item{itemid = {ItemId, _}} <- Items]};
+		    _ ->
+			{result, []}
+		end
+	end,
     case transaction(Host, Node, Action, sync_dirty) of
 	{result, {_, Result}} -> Result;
 	_ -> []
@@ -836,9 +851,6 @@ handle_call(stop, _From, State) ->
 %% @private
 handle_cast(_Msg, State) -> {noreply, State}.
 
--spec handle_info(_ :: {route, From::jid(), To::jid(), Packet::xmlel()},
-		  State :: state()) -> {noreply, state()}.
-
 %%--------------------------------------------------------------------
 %% Function: handle_info(Info, State) -> {noreply, State} |
 %%                                       {noreply, State, Timeout} |
@@ -846,9 +858,12 @@ handle_cast(_Msg, State) -> {noreply, State}.
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
 %% @private
-handle_info({route, From, To, Packet},
-	    #state{server_host = ServerHost, access = Access, plugins = Plugins} = State) ->
-    case catch do_route(ServerHost, Access, Plugins, To#jid.lserver, From, To, Packet) of
+handle_info({route, From, To, #iq{} = IQ},
+	    State) when To#jid.lresource == <<"">> ->
+    ejabberd_router:process_iq(From, To, IQ),
+    {noreply, State};
+handle_info({route, From, To, Packet}, State) ->
+    case catch do_route(To#jid.lserver, From, To, Packet) of
 	{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
 	_ -> ok
     end,
@@ -903,6 +918,12 @@ terminate(_Reason,
 	?MODULE, remove_user, 50),
     ejabberd_hooks:delete(anonymous_purge_hook, ServerHost,
 	?MODULE, remove_user, 50),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PUBSUB_OWNER),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS),
     mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB),
     case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of
 	undefined ->
@@ -920,187 +941,163 @@ terminate(_Reason,
 %% @private
 code_change(_OldVsn, State, _Extra) -> {ok, State}.
 
--spec do_route(ServerHost :: binary(), Access :: atom(),
-	       Plugins :: [binary(),...], Host :: mod_pubsub:hostPubsub(),
-	       From :: jid(), To :: jid(), Packet :: xmlel()) -> ok.
-
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
-do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
-    #xmlel{name = Name, attrs = Attrs} = Packet,
+-spec process_disco_info(iq()) -> iq().
+process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_disco_info(#iq{from = From, to = To, lang = Lang, type = get,
+		       sub_els = [#disco_info{node = Node}]} = IQ) ->
+    Host = To#jid.lserver,
+    ServerHost = ejabberd_router:host_of_route(Host),
+    Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
+				   [],
+				   [ServerHost, ?MODULE, <<>>, <<>>]),
+    case iq_disco_info(Host, Node, From, Lang) of
+	{result, IQRes} ->
+	    xmpp:make_iq_result(IQ, IQRes#disco_info{node = Node, xdata = Info});
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
+    end.
+
+-spec process_disco_items(iq()) -> iq().
+process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_disco_items(#iq{type = get, from = From, to = To,
+                        sub_els = [#disco_items{node = Node} = SubEl]} = IQ) ->
+    Host = To#jid.lserver,
+    case iq_disco_items(Host, Node, From, SubEl#disco_items.rsm) of
+	{result, IQRes} ->
+	    xmpp:make_iq_result(IQ, IQRes#disco_items{node = Node});
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
+    end.
+
+-spec process_pubsub(iq()) -> iq().
+process_pubsub(#iq{to = To} = IQ) ->
+    Host = To#jid.lserver,
+    ServerHost = ejabberd_router:host_of_route(Host),
+    Access = config(ServerHost, access),
+    case iq_pubsub(Host, Access, IQ) of
+	{result, IQRes} ->
+	    xmpp:make_iq_result(IQ, IQRes);
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
+    end.
+
+-spec process_pubsub_owner(iq()) -> iq().
+process_pubsub_owner(#iq{to = To} = IQ) ->
+    Host = To#jid.lserver,
+    case iq_pubsub_owner(Host, IQ) of
+	{result, IQRes} ->
+	    xmpp:make_iq_result(IQ, IQRes);
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
+    end.
+
+-spec process_vcard(iq()) -> iq().
+process_vcard(#iq{type = get, lang = Lang} = IQ) ->
+    xmpp:make_iq_result(IQ, iq_get_vcard(Lang));
+process_vcard(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
+
+-spec process_commands(iq()) -> iq().
+process_commands(#iq{type = set, to = To, from = From,
+		     sub_els = [#adhoc_command{} = Request]} = IQ) ->
+    Host = To#jid.lserver,
+    ServerHost = ejabberd_router:host_of_route(Host),
+    Plugins = config(ServerHost, plugins),
+    Access = config(ServerHost, access),
+    case adhoc_request(Host, ServerHost, From, Request, Access, Plugins) of
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error);
+	Response ->
+	    xmpp:make_iq_result(
+	      IQ, xmpp_util:make_adhoc_response(Request, Response))
+    end;
+process_commands(#iq{type = get, lang = Lang} = IQ) ->
+    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
+
+-spec do_route(binary(), jid(), jid(), stanza()) -> ok.
+do_route(Host, From, To, Packet) ->
     case To of
 	#jid{luser = <<>>, lresource = <<>>} ->
-	    case Name of
-		<<"iq">> ->
-		    case jlib:iq_query_info(Packet) of
-			#iq{type = get, xmlns = ?NS_DISCO_INFO, sub_el = SubEl, lang = Lang} = IQ ->
-			    #xmlel{attrs = QAttrs} = SubEl,
-			    Node = fxml:get_attr_s(<<"node">>, QAttrs),
-			    Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
-				    [],
-				    [ServerHost, ?MODULE, <<>>, <<>>]),
-			    Res = case iq_disco_info(Host, Node, From, Lang) of
-				{result, IQRes} ->
-				    jlib:iq_to_xml(IQ#iq{type = result,
-					    sub_el =
-					    [#xmlel{name = <<"query">>,
-						    attrs = QAttrs,
-						    children = IQRes ++ Info}]});
-				{error, Error} ->
-				    jlib:make_error_reply(Packet, Error)
-			    end,
-			    ejabberd_router:route(To, From, Res);
-			#iq{type = get, xmlns = ?NS_DISCO_ITEMS, sub_el = SubEl} = IQ ->
-			    #xmlel{attrs = QAttrs} = SubEl,
-			    Node = fxml:get_attr_s(<<"node">>, QAttrs),
-			    Res = case iq_disco_items(Host, Node, From, jlib:rsm_decode(IQ)) of
-				{result, IQRes} ->
-				    jlib:iq_to_xml(IQ#iq{type = result,
-					    sub_el =
-					    [#xmlel{name = <<"query">>,
-						    attrs = QAttrs,
-						    children = IQRes}]})
-				    %{error, Error} ->
-				    %     jlib:make_error_reply(Packet, Error)
-			    end,
-			    ejabberd_router:route(To, From, Res);
-			#iq{type = IQType, xmlns = ?NS_PUBSUB, lang = Lang, sub_el = SubEl} = IQ ->
-			    Res = case iq_pubsub(Host, ServerHost, From, IQType,
-				    SubEl, Lang, Access, Plugins)
-			    of
-				{result, IQRes} ->
-				    jlib:iq_to_xml(IQ#iq{type = result, sub_el = IQRes});
-				{error, Error} ->
-				    jlib:make_error_reply(Packet, Error)
-			    end,
-			    ejabberd_router:route(To, From, Res);
-			#iq{type = IQType, xmlns = ?NS_PUBSUB_OWNER, lang = Lang, sub_el = SubEl} = IQ ->
-			    Res = case iq_pubsub_owner(Host, ServerHost, From,
-				    IQType, SubEl, Lang)
-			    of
-				{result, IQRes} ->
-				    jlib:iq_to_xml(IQ#iq{type = result, sub_el = IQRes});
-				{error, Error} ->
-				    jlib:make_error_reply(Packet, Error)
-			    end,
-			    ejabberd_router:route(To, From, Res);
-			#iq{type = get, xmlns = (?NS_VCARD) = XMLNS, lang = Lang, sub_el = _SubEl} = IQ ->
-			    Res = IQ#iq{type = result,
-				    sub_el =
-				    [#xmlel{name = <<"vCard">>,
-					    attrs = [{<<"xmlns">>, XMLNS}],
-					    children = iq_get_vcard(Lang)}]},
-			    ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
-			#iq{type = set, xmlns = ?NS_COMMANDS} = IQ ->
-			    Res = case iq_command(Host, ServerHost, From, IQ, Access, Plugins) of
-				{error, Error} ->
-				    jlib:make_error_reply(Packet, Error);
-				{result, IQRes} ->
-				    jlib:iq_to_xml(IQ#iq{type = result, sub_el = IQRes})
-			    end,
-			    ejabberd_router:route(To, From, Res);
-			#iq{} ->
-			    Err = jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
-			    ejabberd_router:route(To, From, Err);
-			_ ->
-			    ok
-		    end;
-		<<"message">> ->
-		    case fxml:get_attr_s(<<"type">>, Attrs) of
-			<<"error">> ->
+	    case Packet of
+		#message{type = T} when T /= error ->
+		    case find_authorization_response(Packet) of
+			undefined ->
 			    ok;
-			_ ->
-			    case find_authorization_response(Packet) of
-				none ->
-				    ok;
-				invalid ->
-				    Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
-				    Txt = <<"Incorrect authorization response">>,
-				    Err = jlib:make_error_reply(
-					    Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
-				    ejabberd_router:route(To, From, Err);
-				XFields ->
-				    handle_authorization_response(Host, From, To, Packet, XFields)
-			    end
+			XData ->
+			    handle_authorization_response(Host, From, To, Packet, XData)
 		    end;
 		_ ->
-		    ok
+		    Err = xmpp:err_service_unavailable(),
+		    ejabberd_router:route_error(To, From, Packet, Err)
 	    end;
 	_ ->
-	    case fxml:get_attr_s(<<"type">>, Attrs) of
-		<<"error">> ->
-		    ok;
-		<<"result">> ->
-		    ok;
-		_ ->
-		    Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
-		    ejabberd_router:route(To, From, Err)
-	    end
+	    Err = xmpp:err_item_not_found(),
+	    ejabberd_router:route_error(To, From, Packet, Err)
     end.
 
+-spec command_disco_info(binary(), binary(), jid()) -> {result, disco_info()}.
 command_disco_info(_Host, ?NS_COMMANDS, _From) ->
-    IdentityEl = #xmlel{name = <<"identity">>,
-	    attrs = [{<<"category">>, <<"automation">>},
-		{<<"type">>, <<"command-list">>}]},
-    {result, [IdentityEl]};
+    {result, #disco_info{identities = [#identity{category = <<"automation">>,
+						 type = <<"command-list">>}]}};
 command_disco_info(_Host, ?NS_PUBSUB_GET_PENDING, _From) ->
-    IdentityEl = #xmlel{name = <<"identity">>,
-	    attrs = [{<<"category">>, <<"automation">>},
-		{<<"type">>, <<"command-node">>}]},
-    FeaturesEl = #xmlel{name = <<"feature">>,
-	    attrs = [{<<"var">>, ?NS_COMMANDS}]},
-    {result, [IdentityEl, FeaturesEl]}.
+    {result, #disco_info{identities = [#identity{category = <<"automation">>,
+						 type = <<"command-node">>}],
+			 features = [?NS_COMMANDS]}}.
 
+-spec node_disco_info(binary(), binary(), jid()) -> {result, disco_info()} |
+						    {error, error()}.
 node_disco_info(Host, Node, From) ->
     node_disco_info(Host, Node, From, true, true).
 
+-spec node_disco_info(binary(), binary(), jid(), boolean(), boolean()) ->
+			     {result, disco_info()} | {error, error()}.
 node_disco_info(Host, Node, _From, _Identity, _Features) ->
-    Action = fun (#pubsub_node{type = Type, options = Options}) ->
-	    NodeType = case get_option(Options, node_type) of
-		collection -> <<"collection">>;
-		_ -> <<"leaf">>
-	    end,
-	    I = #xmlel{name = <<"identity">>,
-			attrs = [{<<"category">>, <<"pubsub">>},
-				 {<<"type">>, NodeType}]},
-	    F = [#xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_PUBSUB}]}
-		    | [#xmlel{name = <<"feature">>,
-			    attrs = [{<<"var">>, feature(F)}]}
-			|| F <- plugin_features(Host, Type)]],
-	    {result, [I | F]}
-    end,
+    Action =
+	fun(#pubsub_node{type = Type, options = Options}) ->
+		NodeType = case get_option(Options, node_type) of
+			       collection -> <<"collection">>;
+			       _ -> <<"leaf">>
+			   end,
+		Is = [#identity{category = <<"pubsub">>, type = NodeType}],
+		Fs = [?NS_PUBSUB | [feature(F) || F <- plugin_features(Host, Type)]],
+		{result, #disco_info{identities = Is, features = Fs}}
+	end,
     case transaction(Host, Node, Action, sync_dirty) of
 	{result, {_, Result}} -> {result, Result};
 	Other -> Other
     end.
 
+-spec iq_disco_info(binary(), binary(), jid(), binary())
+		   -> {result, disco_info()} | {error, error()}.
 iq_disco_info(Host, SNode, From, Lang) ->
     [Node | _] = case SNode of
-	<<>> -> [<<>>];
-	_ -> str:tokens(SNode, <<"!">>)
-    end,
-    %   Node = string_to_node(RealSNode),
+		     <<>> -> [<<>>];
+		     _ -> str:tokens(SNode, <<"!">>)
+		 end,
     case Node of
 	<<>> ->
-	    {result, [#xmlel{name = <<"identity">>,
-			attrs = [{<<"category">>, <<"pubsub">>},
-			    {<<"type">>, <<"service">>},
-			    {<<"name">>, translate:translate(Lang, <<"Publish-Subscribe">>)}]},
-		    #xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_DISCO_INFO}]},
-		    #xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_DISCO_ITEMS}]},
-		    #xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_PUBSUB}]},
-		    #xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_COMMANDS}]},
-		    #xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, ?NS_VCARD}]}]
-		++ [#xmlel{name = <<"feature">>,
-			attrs = [{<<"var">>, feature(F)}]}
-		    || F <- features(Host, Node)]};
+	    {result,
+	     #disco_info{
+		identities = [#identity{
+				 category = <<"pubsub">>,
+				 type = <<"service">>,
+				 name = translate:translate(
+					  Lang, <<"Publish-Subscribe">>)}],
+		features = [?NS_DISCO_INFO,
+			    ?NS_DISCO_ITEMS,
+			    ?NS_PUBSUB,
+			    ?NS_COMMANDS,
+			    ?NS_VCARD |
+			    [feature(F) || F <- features(Host, Node)]]}};
 	?NS_COMMANDS ->
 	    command_disco_info(Host, Node, From);
 	?NS_PUBSUB_GET_PENDING ->
@@ -1109,34 +1106,34 @@ iq_disco_info(Host, SNode, From, Lang) ->
 	    node_disco_info(Host, Node, From)
     end.
 
--spec iq_disco_items(Host :: mod_pubsub:host(), Node :: <<>> | mod_pubsub:nodeId(),
-		     From :: jid(), Rsm :: none | rsm_in()) -> {result, [xmlel()]}.
+-spec iq_disco_items(host(), binary(), jid(), undefined | rsm_set()) ->
+			    {result, disco_items()} | {error, error()}.
 iq_disco_items(Host, <<>>, From, _RSM) ->
-    {result,
-	lists:map(fun (#pubsub_node{nodeid = {_, SubNode}, options = Options}) ->
-		    Attrs = case get_option(Options, title) of
-			false ->
-			    [{<<"jid">>, Host}
-				| nodeAttr(SubNode)];
-			Title ->
-			    [{<<"jid">>, Host},
-				{<<"name">>, Title}
-				| nodeAttr(SubNode)]
-		    end,
-		    #xmlel{name = <<"item">>, attrs = Attrs}
-	    end,
-	    tree_action(Host, get_subnodes, [Host, <<>>, From]))};
+    Items = 
+	lists:map(
+	  fun(#pubsub_node{nodeid = {_, SubNode}, options = Options}) ->
+		  case get_option(Options, title) of
+		      false ->
+			  #disco_item{jid = jid:make(Host),
+				      node = SubNode};
+		      Title ->
+			  #disco_item{jid = jid:make(Host),
+				      name = Title,
+				      node = SubNode}
+		  end
+	  end, tree_action(Host, get_subnodes, [Host, <<>>, From])),
+    {result, #disco_items{items = Items}};
 iq_disco_items(Host, ?NS_COMMANDS, _From, _RSM) ->
-    {result, [#xmlel{name = <<"item">>,
-		attrs = [{<<"jid">>, Host},
-		    {<<"node">>, ?NS_PUBSUB_GET_PENDING},
-		    {<<"name">>, <<"Get Pending">>}]}]};
+    {result,
+     #disco_items{items = [#disco_item{jid = jid:make(Host),
+				       node = ?NS_PUBSUB_GET_PENDING,
+				       name = <<"Get Pending">>}]}};
 iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From, _RSM) ->
-    {result, []};
+    {result, #disco_items{}};
 iq_disco_items(Host, Item, From, RSM) ->
     case str:tokens(Item, <<"!">>) of
 	[_Node, _ItemId] ->
-	    {result, []};
+	    {result, #disco_items{}};
 	[Node] ->
 	    Action = fun (#pubsub_node{id = Nidx, type = Type, options = Options, owners = O}) ->
 		    Owners = node_owners_call(Host, Type, Nidx, O),
@@ -1144,28 +1141,28 @@ iq_disco_items(Host, Item, From, RSM) ->
 			    From, Type, Options, Owners, RSM)
 		    of
 			{result, R} -> R;
-			_ -> {[], none}
+			_ -> {[], undefined}
 		    end,
-		    Nodes = lists:map(fun (#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) ->
-				    Attrs = case get_option(SubOptions, title) of
-					false ->
-					    [{<<"jid">>, Host}
-						| nodeAttr(SubNode)];
-					Title ->
-					    [{<<"jid">>, Host},
-						{<<"name">>, Title}
-						| nodeAttr(SubNode)]
-				    end,
-				    #xmlel{name = <<"item">>, attrs = Attrs}
-			    end,
-			    tree_call(Host, get_subnodes, [Host, Node, From])),
-		    Items = lists:map(fun (#pubsub_item{itemid = {RN, _}}) ->
-				    {result, Name} = node_call(Host, Type, get_item_name, [Host, Node, RN]),
-				    #xmlel{name = <<"item">>,
-					attrs = [{<<"jid">>, Host}, {<<"name">>, Name}]}
-			    end,
-			    NodeItems),
-		    {result, Nodes ++ Items ++ jlib:rsm_encode(RsmOut)}
+		    Nodes = lists:map(
+			      fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) ->
+				      case get_option(SubOptions, title) of
+					  false ->
+					      #disco_item{jid = jid:make(Host),
+							  node = SubNode};
+					  Title ->
+					      #disco_item{jid = jid:make(Host),
+							  name = Title,
+							  node = SubNode}
+				      end
+			      end, tree_call(Host, get_subnodes, [Host, Node, From])),
+		    Items = lists:map(
+			      fun(#pubsub_item{itemid = {RN, _}}) ->
+				      {result, Name} = node_call(Host, Type, get_item_name, [Host, Node, RN]),
+				      #disco_item{jid = jid:make(Host), name = Name}
+			      end, NodeItems),
+		    {result,
+		     #disco_items{items = Nodes ++ Items,
+				  rsm = RsmOut}}
 	    end,
 	    case transaction(Host, Node, Action, sync_dirty) of
 		{result, {_, Result}} -> {result, Result};
@@ -1173,477 +1170,348 @@ iq_disco_items(Host, Item, From, RSM) ->
 	    end
     end.
 
--spec iq_sm(From :: jid(), To :: jid(), IQ :: iq_request()) -> iq_result() | iq_error().
-iq_sm(From, To, #iq{type = Type, sub_el = SubEl, xmlns = XMLNS, lang = Lang} = IQ) ->
-    ServerHost = To#jid.lserver,
+-spec iq_sm(iq()) -> iq().
+iq_sm(#iq{to = To, sub_els = [SubEl]} = IQ) ->
     LOwner = jid:tolower(jid:remove_resource(To)),
-    Res = case XMLNS of
-	?NS_PUBSUB ->
-	    iq_pubsub(LOwner, ServerHost, From, Type, SubEl, Lang);
-	?NS_PUBSUB_OWNER ->
-	    iq_pubsub_owner(LOwner, ServerHost, From, Type, SubEl, Lang)
-    end,
+    Res = case xmpp:get_ns(SubEl) of
+	      ?NS_PUBSUB ->
+		  iq_pubsub(LOwner, all, IQ);
+	      ?NS_PUBSUB_OWNER ->
+		  iq_pubsub_owner(LOwner, IQ)
+	  end,
     case Res of
-	{result, IQRes} -> IQ#iq{type = result, sub_el = IQRes};
-	{error, Error} -> IQ#iq{type = error, sub_el = [Error, SubEl]}
+	{result, IQRes} ->
+	    xmpp:make_iq_result(IQ, IQRes);
+	{error, Error} ->
+	    xmpp:make_error(IQ, Error)
     end.
 
+-spec iq_get_vcard(binary()) -> vcard_temp().
 iq_get_vcard(Lang) ->
-    [#xmlel{name = <<"FN">>, attrs = [],
-	    children = [{xmlcdata, <<"ejabberd/mod_pubsub">>}]},
-	#xmlel{name = <<"URL">>, attrs = [],
-	    children = [{xmlcdata, ?EJABBERD_URI}]},
-	#xmlel{name = <<"DESC">>, attrs = [],
-	    children = [{xmlcdata,
-		    <<(translate:translate(Lang, <<"ejabberd Publish-Subscribe module">>))/binary,
-			"\nCopyright (c) 2004-2016 ProcessOne">>}]}].
-
--spec iq_pubsub(Host :: mod_pubsub:host(), ServerHost :: binary(), From :: jid(),
-		IQType :: 'get' | 'set', SubEl :: xmlel(), Lang :: binary()) ->
-		       {result, [xmlel()]} | {error, xmlel()}.
-
-iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang) ->
-    iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, all, plugins(Host)).
-
--spec iq_pubsub(Host :: mod_pubsub:host(), ServerHost :: binary(), From :: jid(),
-		IQType :: 'get' | 'set', SubEl :: xmlel(), Lang :: binary(),
-		Access :: atom(), Plugins :: [binary(),...]) ->
-		       {result, [xmlel()]} | {error, xmlel()}.
-
-iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) ->
-    #xmlel{children = SubEls} = SubEl,
-    case fxml:remove_cdata(SubEls) of
-	[#xmlel{name = Name, attrs = Attrs, children = Els} | Rest] ->
-	    Node = fxml:get_attr_s(<<"node">>, Attrs),
-	    case {IQType, Name} of
-		{set, <<"create">>} ->
-		    Config = case Rest of
-			[#xmlel{name = <<"configure">>, children = C}] -> C;
-			_ -> []
-		    end,
-		    Type = case fxml:get_attr_s(<<"type">>, Attrs) of
-			<<>> -> hd(Plugins);
-			T -> T
-		    end,
-		    case lists:member(Type, Plugins) of
-			false ->
-			    {error,
-				extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"create-nodes">>)};
-			true ->
-			    create_node(Host, ServerHost, Node, From, Type, Access, Config)
-		    end;
-		{set, <<"publish">>} ->
-		    case fxml:remove_cdata(Els) of
-			[#xmlel{name = <<"item">>, attrs = ItemAttrs,
-					children = Payload}] ->
-			    ItemId = fxml:get_attr_s(<<"id">>, ItemAttrs),
-			    PubOpts = case [C || #xmlel{name = <<"publish-options">>,
-							children = [C]} <- Rest] of
-				[XEl] ->
-				    case jlib:parse_xdata_submit(XEl) of
-				      invalid -> [];
-				      Form -> Form
-				    end;
-				_ -> []
-			    end,
-			    publish_item(Host, ServerHost, Node, From, ItemId, Payload, PubOpts, Access);
-			[] ->
-			    {error,
-				extended_error(?ERR_BAD_REQUEST, <<"item-required">>)};
-			_ ->
-			    {error,
-				extended_error(?ERR_BAD_REQUEST, <<"invalid-payload">>)}
-		    end;
-		{set, <<"retract">>} ->
-		    ForceNotify = case fxml:get_attr_s(<<"notify">>, Attrs) of
-			<<"1">> -> true;
-			<<"true">> -> true;
-			_ -> false
-		    end,
-		    case fxml:remove_cdata(Els) of
-			[#xmlel{name = <<"item">>, attrs = ItemAttrs}] ->
-			    ItemId = fxml:get_attr_s(<<"id">>, ItemAttrs),
-			    delete_item(Host, Node, From, ItemId, ForceNotify);
-			_ ->
-			    {error,
-				extended_error(?ERR_BAD_REQUEST, <<"item-required">>)}
-		    end;
-		{set, <<"subscribe">>} ->
-		    Config = case Rest of
-			[#xmlel{name = <<"options">>, children = C}] -> C;
-			_ -> []
-		    end,
-		    JID = fxml:get_attr_s(<<"jid">>, Attrs),
-		    subscribe_node(Host, Node, From, JID, Config);
-		{set, <<"unsubscribe">>} ->
-		    JID = fxml:get_attr_s(<<"jid">>, Attrs),
-		    SubId = fxml:get_attr_s(<<"subid">>, Attrs),
-		    unsubscribe_node(Host, Node, From, JID, SubId);
-		{get, <<"items">>} ->
-		    MaxItems = fxml:get_attr_s(<<"max_items">>, Attrs),
-		    SubId = fxml:get_attr_s(<<"subid">>, Attrs),
-		    ItemIds = lists:foldl(fun
-				(#xmlel{name = <<"item">>, attrs = ItemAttrs}, Acc) ->
-				    case fxml:get_attr_s(<<"id">>, ItemAttrs) of
-					<<>> -> Acc;
-					ItemId -> [ItemId | Acc]
-				    end;
-				(_, Acc) ->
-				    Acc
-			    end,
-			    [], fxml:remove_cdata(Els)),
-		    get_items(Host, Node, From, SubId, MaxItems, ItemIds, jlib:rsm_decode(SubEl));
-		{get, <<"subscriptions">>} ->
-		    get_subscriptions(Host, Node, From, Plugins);
-		{get, <<"affiliations">>} ->
-		    get_affiliations(Host, Node, From, Plugins);
-		{get, <<"options">>} ->
-		    SubId = fxml:get_attr_s(<<"subid">>, Attrs),
-		    JID = fxml:get_attr_s(<<"jid">>, Attrs),
-		    get_options(Host, Node, JID, SubId, Lang);
-		{set, <<"options">>} ->
-		    SubId = fxml:get_attr_s(<<"subid">>, Attrs),
-		    JID = fxml:get_attr_s(<<"jid">>, Attrs),
-		    set_options(Host, Node, JID, SubId, Els);
+    Desc = translate:translate(Lang, <<"ejabberd Publish-Subscribe module">>),
+    Copyright = <<"Copyright (c) 2004-2016 ProcessOne">>,
+    #vcard_temp{fn = <<"ejabberd/mod_pubsub">>,
+		url = ?EJABBERD_URI,
+		desc = <>}.
+
+-spec iq_pubsub(binary() | ljid(), atom(), iq()) ->
+		       {result, pubsub()} | {error, error()}.
+iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang,
+			    sub_els = [SubEl]}) ->
+    case {IQType, SubEl} of
+	{set, #pubsub{create = Node, configure = {_, XData},
+		      _ = undefined}} when is_binary(Node) ->
+	    ServerHost = serverhost(Host),
+	    Plugins = config(ServerHost, plugins),
+	    Config = get_xdata_fields(XData),
+	    Type = hd(Plugins),
+	    create_node(Host, ServerHost, Node, From, Type, Access, Config);
+	{set, #pubsub{publish = #ps_publish{node = Node, items = Items},
+		      publish_options = XData, _ = undefined}} ->
+	    ServerHost = serverhost(Host),
+	    case Items of
+		[#ps_item{id = ItemId, xml_els = Payload}] ->
+		    PubOpts = get_xdata_fields(XData),
+		    publish_item(Host, ServerHost, Node, From, ItemId,
+				 Payload, PubOpts, Access);
+		[] ->
+		    {error, extended_error(xmpp:err_bad_request(), err_item_required())};
 		_ ->
-		    {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
+		    {error, extended_error(xmpp:err_bad_request(), err_invalid_payload())}
 	    end;
-	Other ->
-	    ?INFO_MSG("Too many actions: ~p", [Other]),
-	    {error, ?ERR_BAD_REQUEST}
-    end.
-
-
--spec iq_pubsub_owner(Host :: mod_pubsub:host(), ServerHost :: binary(), From :: jid(),
-		      IQType :: 'get' | 'set', SubEl :: xmlel(), Lang :: binary()) ->
-			     {result, [xmlel()]} | {error, xmlel()}.
-
-iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
-    #xmlel{children = SubEls} = SubEl,
-    Action = fxml:remove_cdata(SubEls),
-    case Action of
-	[#xmlel{name = Name, attrs = Attrs, children = Els}] ->
-	    Node = fxml:get_attr_s(<<"node">>, Attrs),
-	    case {IQType, Name} of
-		{get, <<"configure">>} ->
-		    get_configure(Host, ServerHost, Node, From, Lang);
-		{set, <<"configure">>} ->
-		    set_configure(Host, Node, From, Els, Lang);
-		{get, <<"default">>} ->
-		    get_default(Host, Node, From, Lang);
-		{set, <<"delete">>} ->
-		    delete_node(Host, Node, From);
-		{set, <<"purge">>} ->
-		    purge_node(Host, Node, From);
-		{get, <<"subscriptions">>} ->
-		    get_subscriptions(Host, Node, From);
-		{set, <<"subscriptions">>} ->
-		    set_subscriptions(Host, Node, From, fxml:remove_cdata(Els));
-		{get, <<"affiliations">>} ->
-		    get_affiliations(Host, Node, From);
-		{set, <<"affiliations">>} ->
-		    set_affiliations(Host, Node, From, fxml:remove_cdata(Els));
+	{set, #pubsub{retract = #ps_retract{node = Node, notify = Notify, items = Items},
+		      _ = undefined}} ->
+	    case Items of
+		[#ps_item{id = ItemId}] ->
+		    delete_item(Host, Node, From, ItemId, Notify);
+		[] ->
+		    {error, extended_error(xmpp:err_bad_request(), err_item_required())};
 		_ ->
-		    {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
+		    {error, extended_error(xmpp:err_bad_request(), err_invalid_payload())}
 	    end;
+	{set, #pubsub{subscribe = #ps_subscribe{node = Node, jid = JID},
+		      options = Options, _ = undefined}} ->
+	    Config = case Options of
+			 #ps_options{xdata = XData} -> get_xdata_fields(XData);
+			 _ -> []
+		     end,
+	    subscribe_node(Host, Node, From, JID, Config);
+	{set, #pubsub{unsubscribe = #ps_unsubscribe{node = Node, jid = JID, subid = SubId},
+		      _ = undefined}} ->
+	    unsubscribe_node(Host, Node, From, JID, SubId);
+	{get, #pubsub{items = #ps_items{node = Node,
+					max_items = MaxItems,
+					subid = SubId,
+					items = Items},
+		      rsm = RSM, _ = undefined}} ->
+	    ItemIds = [ItemId || #ps_item{id = ItemId} <- Items, ItemId /= <<>>],
+	    get_items(Host, Node, From, SubId, MaxItems, ItemIds, RSM);
+	{get, #pubsub{subscriptions = {Node, _}, _ = undefined}} ->
+	    Plugins = config(serverhost(Host), plugins),
+	    get_subscriptions(Host, Node, From, Plugins);
+	{get, #pubsub{affiliations = {Node, _}, _ = undefined}} ->
+	    Plugins = config(serverhost(Host), plugins),
+	    get_affiliations(Host, Node, From, Plugins);
+	{get, #pubsub{options = #ps_options{node = Node, subid = SubId, jid = JID},
+		      _ = undefined}} ->
+	    get_options(Host, Node, JID, SubId, Lang);
+	{set, #pubsub{options = #ps_options{node = Node, subid = SubId,
+					    jid = JID, xdata = XData},
+		      _ = undefined}} ->
+	    set_options(Host, Node, JID, SubId, get_xdata_fields(XData));
 	_ ->
-	    ?INFO_MSG("Too many actions: ~p", [Action]),
-	    {error, ?ERR_BAD_REQUEST}
+	    {error, xmpp:err_feature_not_implemented()}
     end.
 
-iq_command(Host, ServerHost, From, IQ, Access, Plugins) ->
-    case adhoc:parse_request(IQ) of
-	Req when is_record(Req, adhoc_request) ->
-	    case adhoc_request(Host, ServerHost, From, Req, Access, Plugins) of
-		Resp when is_record(Resp, adhoc_response) ->
-		    {result, [adhoc:produce_response(Req, Resp)]};
-		Error ->
-		    Error
+-spec iq_pubsub_owner(binary() | ljid(), iq()) -> {result, pubsub()} | {error, error()}.
+iq_pubsub_owner(Host, #iq{type = IQType, from = From,
+			  lang = Lang, sub_els = [SubEl]}) ->
+    case {IQType, SubEl} of
+	{get, #pubsub_owner{configure = {Node, undefined}, _ = undefined}} ->
+	    ServerHost = serverhost(Host),
+	    get_configure(Host, ServerHost, Node, From, Lang);
+	{set, #pubsub_owner{configure = {Node, XData}, _ = undefined}} ->
+	    case XData of
+		undefined ->
+		    {error, xmpp:err_bad_request(<<"No data form found">>, Lang)};
+		#xdata{type = cancel} ->
+		    {result, #pubsub{}};
+		#xdata{type = submit} ->
+		    Config = get_xdata_fields(XData),
+		    set_configure(Host, Node, From, Config, Lang);
+		#xdata{} ->
+		    {error, xmpp:err_bad_request(<<"Incorrect data form">>, Lang)}
 	    end;
-	Err -> Err
+	{get, #pubsub_owner{default = {Node, undefined}, _ = undefined}} ->
+	    get_default(Host, Node, From, Lang);
+	{set, #pubsub_owner{delete = {Node, _}, _ = undefined}} ->
+	    delete_node(Host, Node, From);
+	{set, #pubsub_owner{purge = Node, _ = undefined}} when Node /= undefined ->
+	    purge_node(Host, Node, From);
+	{get, #pubsub_owner{subscriptions = {Node, []}, _ = undefined}} ->
+	    get_subscriptions(Host, Node, From);
+	{set, #pubsub_owner{subscriptions = {Node, Subs}, _ = undefined}} ->
+	    set_subscriptions(Host, Node, From, Subs);
+	{get, #pubsub_owner{affiliations = {Node, []}, _ = undefined}} ->
+	    get_affiliations(Host, Node, From);
+	{set, #pubsub_owner{affiliations = {Node, Affs}, _ = undefined}} ->
+	    set_affiliations(Host, Node, From, Affs);
+	{_, #pubsub_owner{}} ->
+	    {error, xmpp:err_bad_request()};
+	_ ->
+	    {error, xmpp:err_feature_not_implemented()}
     end.
 
-%% @doc 

Processes an Ad Hoc Command.

+-spec adhoc_request(binary(), binary(), jid(), adhoc_command(), + atom(), [binary()]) -> adhoc_command() | {error, error()}. adhoc_request(Host, _ServerHost, Owner, - #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, - lang = Lang, action = <<"execute">>, - xdata = false}, - _Access, Plugins) -> + #adhoc_command{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, + action = execute, xdata = undefined}, + _Access, Plugins) -> send_pending_node_form(Host, Owner, Lang, Plugins); adhoc_request(Host, _ServerHost, Owner, - #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, - action = <<"execute">>, xdata = XData, lang = Lang}, - _Access, _Plugins) -> - ParseOptions = case XData of - #xmlel{name = <<"x">>} = XEl -> - case jlib:parse_xdata_submit(XEl) of - invalid -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - XData2 -> - case set_xoption(Host, XData2, []) of - NewOpts when is_list(NewOpts) -> {result, NewOpts}; - Err -> Err - end - end; - _ -> - Txt = <<"No data form found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} - end, - case ParseOptions of - {result, XForm} -> + #adhoc_command{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, + action = execute, xdata = #xdata{} = XData}, + _Access, _Plugins) -> + Config = get_xdata_fields(XData), + case set_xoption(Host, Config, []) of + XForm when is_list(XForm) -> case lists:keysearch(node, 1, XForm) of - {value, {_, Node}} -> send_pending_auth_events(Host, Node, Owner); - false -> {error, extended_error(?ERR_BAD_REQUEST, <<"bad-payload">>)} + {value, {_, Node}} -> + send_pending_auth_events(Host, Node, Owner, Lang); + false -> + {error, extended_error(xmpp:err_bad_request(), err_invalid_payload())} end; - Error -> Error + Err -> + Err end; adhoc_request(_Host, _ServerHost, _Owner, - #adhoc_request{action = <<"cancel">>}, _Access, - _Plugins) -> - #adhoc_response{status = canceled}; -adhoc_request(Host, ServerHost, Owner, - #adhoc_request{action = <<>>} = R, Access, Plugins) -> - adhoc_request(Host, ServerHost, Owner, - R#adhoc_request{action = <<"execute">>}, Access, - Plugins); + #adhoc_command{action = cancel}, _Access, _Plugins) -> + #adhoc_command{status = canceled}; adhoc_request(_Host, _ServerHost, _Owner, Other, _Access, _Plugins) -> ?DEBUG("Couldn't process ad hoc command:~n~p", [Other]), - {error, ?ERR_ITEM_NOT_FOUND}. + {error, xmpp:err_item_not_found()}. -%% @doc

Sends the process pending subscriptions XForm for Host to Owner.

+-spec send_pending_node_form(binary(), jid(), binary(), + [binary()]) -> adhoc_command() | {error, error()}. send_pending_node_form(Host, Owner, _Lang, Plugins) -> Filter = fun (Type) -> lists:member(<<"get-pending">>, plugin_features(Host, Type)) end, case lists:filter(Filter, Plugins) of [] -> - Err = extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, - unsupported, <<"get-pending">>), + Err = extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('get-pending')), {error, Err}; Ps -> - XOpts = [#xmlel{name = <<"option">>, attrs = [], - children = [#xmlel{name = <<"value">>, - attrs = [], - children = [{xmlcdata, Node}]}]} - || Node <- get_pending_nodes(Host, Owner, Ps)], - XForm = #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = [#xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"list-single">>}, - {<<"var">>, <<"pubsub#node">>}], - children = lists:usort(XOpts)}]}, - #adhoc_response{status = executing, - defaultaction = <<"execute">>, elements = [XForm]} + case get_pending_nodes(Host, Owner, Ps) of + {ok, Nodes} -> + XOpts = [#xdata_option{value = Node} || Node <- Nodes], + XForm = #xdata{type = form, + fields = [#xdata_field{ + type = 'list-single', + var = <<"pubsub#node">>, + options = lists:usort(XOpts)}]}, + #adhoc_command{status = executing, action = execute, + xdata = XForm}; + Err -> + Err + end end. +-spec get_pending_nodes(binary(), jid(), [binary()]) -> {ok, [binary()]} | + {error, error()}. get_pending_nodes(Host, Owner, Plugins) -> Tr = fun (Type) -> case node_call(Host, Type, get_pending_nodes, [Host, Owner]) of {result, Nodes} -> Nodes; _ -> [] end - end, + end, Action = fun() -> {result, lists:flatmap(Tr, Plugins)} end, case transaction(Host, Action, sync_dirty) of - {result, Res} -> Res; + {result, Res} -> {ok, Res}; Err -> Err end. %% @doc

Send a subscription approval form to Owner for all pending %% subscriptions on Host and Node.

-send_pending_auth_events(Host, Node, Owner) -> +-spec send_pending_auth_events(binary(), binary(), jid(), + binary()) -> adhoc_command() | {error, error()}. +send_pending_auth_events(Host, Node, Owner, Lang) -> ?DEBUG("Sending pending auth events for ~s on ~s:~s", - [jid:to_string(Owner), Host, Node]), - Action = fun (#pubsub_node{id = Nidx, type = Type}) -> - case lists:member(<<"get-pending">>, plugin_features(Host, Type)) of - true -> - case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of - {result, owner} -> node_call(Host, Type, get_node_subscriptions, [Nidx]); - _ -> {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)} - end; - false -> - {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, - unsupported, <<"get-pending">>)} - end - end, + [jid:to_string(Owner), Host, Node]), + Action = + fun(#pubsub_node{id = Nidx, type = Type}) -> + case lists:member(<<"get-pending">>, plugin_features(Host, Type)) of + true -> + case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of + {result, owner} -> + node_call(Host, Type, get_node_subscriptions, [Nidx]); + _ -> + {error, xmpp:err_forbidden( + <<"Owner privileges required">>, Lang)} + end; + false -> + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('get-pending'))} + end + end, case transaction(Host, Node, Action, sync_dirty) of {result, {N, Subs}} -> - lists:foreach(fun - ({J, pending, _SubId}) -> send_authorization_request(N, jid:make(J)); - ({J, pending}) -> send_authorization_request(N, jid:make(J)); - (_) -> ok - end, - Subs), - #adhoc_response{}; + lists:foreach( + fun({J, pending, _SubId}) -> send_authorization_request(N, jid:make(J)); + ({J, pending}) -> send_authorization_request(N, jid:make(J)); + (_) -> ok + end, Subs), + #adhoc_command{}; Err -> Err end. %%% authorization handling - -send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = Nidx, owners = O}, - Subscriber) -> +-spec send_authorization_request(#pubsub_node{}, jid()) -> ok. +send_authorization_request(#pubsub_node{nodeid = {Host, Node}, + type = Type, id = Nidx, owners = O}, + Subscriber) -> + %% TODO: pass lang to this function Lang = <<"en">>, - Stanza = #xmlel{name = <<"message">>, attrs = [], - children = - [#xmlel{name = <<"x">>, - attrs = - [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = - [#xmlel{name = <<"title">>, attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, <<"PubSub subscriber request">>)}]}, - #xmlel{name = <<"instructions">>, - attrs = [], - children = - [{xmlcdata, - translate:translate(Lang, - <<"Choose whether to approve this entity's " - "subscription.">>)}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, ?NS_PUBSUB_SUB_AUTH}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"pubsub#node">>}, - {<<"type">>, - <<"text-single">>}, - {<<"label">>, translate:translate(Lang, <<"Node ID">>)}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, Node}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, - <<"pubsub#subscriber_jid">>}, - {<<"type">>, <<"jid-single">>}, - {<<"label">>, - translate:translate(Lang, <<"Subscriber Address">>)}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, jid:to_string(Subscriber)}]}]}, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, - <<"pubsub#allow">>}, - {<<"type">>, <<"boolean">>}, - {<<"label">>, - translate:translate(Lang, - <<"Allow this Jabber ID to subscribe to " - "this pubsub node?">>)}], - children = - [#xmlel{name = <<"value">>, - attrs = [], - children = - [{xmlcdata, <<"false">>}]}]}]}]}, - lists:foreach(fun (Owner) -> - ejabberd_router:route(service_jid(Host), jid:make(Owner), Stanza) - end, - node_owners_action(Host, Type, Nidx, O)). + Fs = [#xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = [?NS_PUBSUB_SUB_AUTH]}, + #xdata_field{var = <<"pubsub#node">>, + type = 'text-single', + label = translate:translate(Lang, <<"Node ID">>), + values = [Node]}, + #xdata_field{var = <<"pubsub#subscriber_jid">>, + type = 'jid-single', + label = translate:translate(Lang, <<"Subscriber Address">>), + values = [jid:to_string(Subscriber)]}, + #xdata_field{var = <<"pubsub#allow">>, + type = boolean, + label = translate:translate( + Lang, + <<"Allow this Jabber ID to subscribe to " + "this pubsub node?">>), + values = [<<"false">>]}], + X = #xdata{type = form, + title = translate:translate( + Lang, <<"PubSub subscriber request">>), + instructions = [translate:translate( + Lang, + <<"Choose whether to approve this entity's " + "subscription.">>)], + fields = Fs}, + Stanza = #message{sub_els = [X]}, + lists:foreach( + fun (Owner) -> + ejabberd_router:route(service_jid(Host), jid:make(Owner), Stanza) + end, node_owners_action(Host, Type, Nidx, O)). +-spec find_authorization_response(message()) -> undefined | xdata(). find_authorization_response(Packet) -> - #xmlel{children = Els} = Packet, - XData1 = lists:map(fun - (#xmlel{name = <<"x">>, attrs = XAttrs} = XEl) -> - case fxml:get_attr_s(<<"xmlns">>, XAttrs) of - ?NS_XDATA -> - case fxml:get_attr_s(<<"type">>, XAttrs) of - <<"cancel">> -> none; - _ -> jlib:parse_xdata_submit(XEl) - end; - _ -> - none - end; - (_) -> - none - end, - fxml:remove_cdata(Els)), - XData = lists:filter(fun (E) -> E /= none end, XData1), - case XData of - [invalid] -> - invalid; - [] -> - none; - [XFields] when is_list(XFields) -> - ?DEBUG("XFields: ~p", [XFields]), - case lists:keysearch(<<"FORM_TYPE">>, 1, XFields) of - {value, {_, [?NS_PUBSUB_SUB_AUTH]}} -> XFields; - _ -> invalid - end + case xmpp:get_subtag(Packet, #xdata{}) of + #xdata{type = submit} = X -> + case xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X) of + [?NS_PUBSUB_SUB_AUTH] -> X; + _ -> undefined + end; + _ -> + undefined end. %% @doc Send a message to JID with the supplied Subscription +-spec send_authorization_approval(binary(), jid(), binary(), subscribed | none) -> ok. send_authorization_approval(Host, JID, SNode, Subscription) -> - SubAttrs = case Subscription of - %{S, SID} -> - % [{<<"subscription">>, subscription_to_string(S)}, - % {<<"subid">>, SID}]; - S -> - [{<<"subscription">>, subscription_to_string(S)}] - end, - Stanza = event_stanza(<<"subscription">>, - [{<<"jid">>, jid:to_string(JID)} - | nodeAttr(SNode)] - ++ SubAttrs), + Event = #ps_event{subscription = + #ps_subscription{jid = JID, + node = SNode, + type = Subscription}}, + Stanza = #message{sub_els = [Event]}, ejabberd_router:route(service_jid(Host), JID, Stanza). -handle_authorization_response(Host, From, To, Packet, XFields) -> - Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet), - case {lists:keysearch(<<"pubsub#node">>, 1, XFields), - lists:keysearch(<<"pubsub#subscriber_jid">>, 1, XFields), - lists:keysearch(<<"pubsub#allow">>, 1, XFields)} - of - {{value, {_, [Node]}}, - {value, {_, [SSubscriber]}}, - {value, {_, [SAllow]}}} -> +-spec handle_authorization_response(binary(), jid(), jid(), message(), xdata()) -> ok. +handle_authorization_response(Host, From, To, Packet, X) -> + Lang = xmpp:get_lang(Packet), + case {xmpp_util:get_xdata_values(<<"pubsub#node">>, X), + xmpp_util:get_xdata_values(<<"pubsub#subscriber_jid">>, X), + xmpp_util:get_xdata_values(<<"pubsub#allow">>, X)} of + {[Node], [SSubscriber], [SAllow]} -> FromLJID = jid:tolower(jid:remove_resource(From)), Subscriber = jid:from_string(SSubscriber), Allow = case SAllow of - <<"1">> -> true; - <<"true">> -> true; - _ -> false - end, - Action = fun (#pubsub_node{type = Type, id = Nidx, owners = O}) -> - Owners = node_owners_call(Host, Type, Nidx, O), - case lists:member(FromLJID, Owners) of - true -> - {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), - update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs); - false -> - {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)} - end - end, + <<"1">> -> true; + <<"true">> -> true; + _ -> false + end, + Action = + fun(#pubsub_node{type = Type, id = Nidx, owners = O}) -> + Owners = node_owners_call(Host, Type, Nidx, O), + case lists:member(FromLJID, Owners) of + true -> + {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), + update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs); + false -> + {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)} + end + end, case transaction(Host, Node, Action, sync_dirty) of {error, Error} -> - Err = jlib:make_error_reply(Packet, Error), - ejabberd_router:route(To, From, Err); + ejabberd_router:route_error(To, From, Packet, Error); {result, {_, _NewSubscription}} -> %% XXX: notify about subscription state change, section 12.11 ok; _ -> - Err = jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_internal_server_error(), + ejabberd_router:route_error(To, From, Packet, Err) end; _ -> - Txt = <<"Incorrect data form">>, - Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_not_acceptable(<<"Incorrect data form">>, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end. +-spec update_auth(binary(), binary(), _, _, jid() | error, boolean(), _) -> + {result, ok} | {error, error()}. update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> Sub= lists:filter(fun ({pending, _}) -> true; @@ -1661,67 +1529,47 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> {result, ok}; _ -> Txt = <<"No pending subscriptions found">>, - {error, ?ERRT_UNEXPECTED_REQUEST(?MYLANG, Txt)} + {error, xmpp:err_unexpected_request(Txt, ?MYLANG)} end. -define(XFIELD(Type, Label, Var, Val), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). + #xdata_field{type = Type, + label = translate:translate(Lang, Label), + var = Var, + values = [Val]}). -define(BOOLXFIELD(Label, Var, Val), - ?XFIELD(<<"boolean">>, Label, Var, - case Val of - true -> <<"1">>; - _ -> <<"0">> - end)). + ?XFIELD(boolean, Label, Var, + case Val of + true -> <<"1">>; + _ -> <<"0">> + end)). -define(STRINGXFIELD(Label, Var, Val), - ?XFIELD(<<"text-single">>, Label, Var, Val)). + ?XFIELD('text-single', Label, Var, Val)). -define(STRINGMXFIELD(Label, Var, Vals), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"text-multi">>}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, V}]} - || V <- Vals]}). + #xdata_field{type = 'text-multi', + label = translate:translate(Lang, Label), + var = Var, + values = Vals}). -define(XFIELDOPT(Type, Label, Var, Val, Opts), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = [#xmlel{name = <<"option">>, attrs = [], - children = [#xmlel{name = <<"value">>, - attrs = [], - children = [{xmlcdata, Opt}]}]} - || Opt <- Opts] - ++ - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]}]}). + #xdata_field{type = Type, + label = translate:translate(Lang, Label), + var = Var, + options = [#xdata_option{value = Opt} || Opt <- Opts], + values = [Val]}). -define(LISTXFIELD(Label, Var, Val, Opts), - ?XFIELDOPT(<<"list-single">>, Label, Var, Val, Opts)). + ?XFIELDOPT('list-single', Label, Var, Val, Opts)). -define(LISTMXFIELD(Label, Var, Vals, Opts), - #xmlel{name = <<"field">>, - attrs = [{<<"type">>, <<"list-multi">>}, - {<<"label">>, translate:translate(Lang, Label)}, - {<<"var">>, Var}], - children = [#xmlel{name = <<"option">>, attrs = [], - children = [#xmlel{name = <<"value">>, - attrs = [], - children = [{xmlcdata, Opt}]}]} - || Opt <- Opts] - ++ - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Val}]} - || Val <- Vals]}). + #xdata_field{type = 'list-multi', + label = translate:translate(Lang, Label), + var = Var, + options = [#xdata_option{value = Opt} || Opt <- Opts], + values = Vals}). %% @doc

Create new pubsub nodes

%%

In addition to method-specific error conditions, there are several general reasons why the node creation request might fail:

@@ -1740,97 +1588,69 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> %%
  • nodetree create_node checks if nodeid already exists
  • %%
  • node plugin create_node just sets default affiliation/subscription
  • %% --spec create_node(Host :: mod_pubsub:host(), ServerHost :: binary(), - Node :: <<>> | mod_pubsub:nodeId(), Owner :: jid(), - Type :: binary()) -> {result, [xmlel(),...]} | {error, xmlel()}. +-spec create_node(host(), binary(), binary(), jid(), + binary()) -> {result, pubsub()} | {error, error()}. create_node(Host, ServerHost, Node, Owner, Type) -> create_node(Host, ServerHost, Node, Owner, Type, all, []). --spec create_node(Host :: mod_pubsub:host(), ServerHost :: binary(), - Node :: <<>> | mod_pubsub:nodeId(), Owner :: jid(), - Type :: binary(), Access :: atom(), Configuration :: [xmlel()]) -> - {result, [xmlel(),...]} | {error, xmlel()}. - +-spec create_node(host(), binary(), binary(), jid(), binary(), + atom(), [{binary(), [binary()]}]) -> {result, pubsub()} | {error, error()}. create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) -> case lists:member(<<"instant-nodes">>, plugin_features(Host, Type)) of true -> Node = randoms:get_string(), case create_node(Host, ServerHost, Node, Owner, Type, Access, Configuration) of {result, _} -> - {result, [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"create">>, - attrs = nodeAttr(Node)}]}]}; + {result, #pubsub{create = Node}}; Error -> Error end; false -> - {error, extended_error(?ERR_NOT_ACCEPTABLE, <<"nodeid-required">>)} + {error, extended_error(xmpp:err_not_acceptable(), err_nodeid_required())} end; create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> Type = select_type(ServerHost, Host, Node, GivenType), - ParseOptions = case fxml:remove_cdata(Configuration) of - [] -> - {result, node_options(Host, Type)}; - [#xmlel{name = <<"x">>} = XEl] -> - case jlib:parse_xdata_submit(XEl) of - invalid -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}; - XData -> - case set_xoption(Host, XData, node_options(Host, Type)) of - NewOpts when is_list(NewOpts) -> {result, NewOpts}; - Err -> Err - end - end; - _ -> - ?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]), - Txt = <<"No data form found">>, - {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)} - end, - case ParseOptions of - {result, NodeOptions} -> - CreateNode = fun () -> - Parent = case node_call(Host, Type, node_to_path, [Node]) of - {result, [Node]} -> - <<>>; - {result, Path} -> - element(2, node_call(Host, Type, path_to_node, [lists:sublist(Path, length(Path)-1)])) - end, - Parents = case Parent of - <<>> -> []; - _ -> [Parent] - end, - case node_call(Host, Type, create_node_permission, - [Host, ServerHost, Node, Parent, Owner, Access]) - of - {result, true} -> - case tree_call(Host, create_node, - [Host, Node, Type, Owner, NodeOptions, Parents]) - of - {ok, Nidx} -> - SubsByDepth = get_node_subs_by_depth(Host, Node, Owner), - case node_call(Host, Type, create_node, [Nidx, Owner]) of - {result, Result} -> {result, {Nidx, SubsByDepth, Result}}; - Error -> Error - end; - {error, {virtual, Nidx}} -> - case node_call(Host, Type, create_node, [Nidx, Owner]) of - {result, Result} -> {result, {Nidx, [], Result}}; - Error -> Error - end; - Error -> - Error - end; - _ -> - Txt1 = <<"You're not allowed to create nodes">>, - {error, ?ERRT_FORBIDDEN(?MYLANG, Txt1)} - end - end, - Reply = [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"create">>, - attrs = nodeAttr(Node)}]}], + case set_xoption(Host, Configuration, node_options(Host, Type)) of + NodeOptions when is_list(NodeOptions) -> + CreateNode = + fun() -> + Parent = case node_call(Host, Type, node_to_path, [Node]) of + {result, [Node]} -> + <<>>; + {result, Path} -> + element(2, node_call(Host, Type, path_to_node, + [lists:sublist(Path, length(Path)-1)])) + end, + Parents = case Parent of + <<>> -> []; + _ -> [Parent] + end, + case node_call(Host, Type, create_node_permission, + [Host, ServerHost, Node, Parent, Owner, Access]) of + {result, true} -> + case tree_call(Host, create_node, + [Host, Node, Type, Owner, NodeOptions, Parents]) + of + {ok, Nidx} -> + SubsByDepth = get_node_subs_by_depth(Host, Node, Owner), + case node_call(Host, Type, create_node, [Nidx, Owner]) of + {result, Result} -> {result, {Nidx, SubsByDepth, Result}}; + Error -> Error + end; + {error, {virtual, Nidx}} -> + case node_call(Host, Type, create_node, [Nidx, Owner]) of + {result, Result} -> {result, {Nidx, [], Result}}; + Error -> Error + end; + Error -> + Error + end; + _ -> + Txt = <<"You're not allowed to create nodes">>, + {error, xmpp:err_forbidden(Txt, ?MYLANG)} + end + end, + Reply = #pubsub{create = Node}, case transaction(Host, CreateNode, transaction) of {result, {Nidx, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth), @@ -1864,10 +1684,9 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> %%
  • The node is the root collection node, which cannot be deleted.
  • %%
  • The specified node does not exist.
  • %% --spec delete_node(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - Owner :: jid()) -> {result, [xmlel(),...]} | {error, xmlel()}. +-spec delete_node(host(), binary(), jid()) -> {result, pubsub()} | {error, error()}. delete_node(_Host, <<>>, _Owner) -> - {error, ?ERRT_NOT_ALLOWED(?MYLANG, <<"No node specified">>)}; + {error, xmpp:err_not_allowed(<<"No node specified">>, ?MYLANG)}; delete_node(Host, Node, Owner) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of @@ -1879,7 +1698,7 @@ delete_node(Host, Node, Owner) -> Error -> Error end; _ -> - {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)} + {error, xmpp:err_forbidden(<<"Owner privileges required">>, ?MYLANG)} end end, Reply = [], @@ -1941,16 +1760,15 @@ delete_node(Host, Node, Owner) -> %%
  • The node does not support subscriptions.
  • %%
  • The node does not exist.
  • %% --spec subscribe_node(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - From :: jid(), JID :: binary(), Configuration :: [xmlel()]) -> - {result, [xmlel(),...]} | {error, xmlel()}. +-spec subscribe_node(host(), binary(), jid(), binary(), [{binary(), [binary()]}]) -> + {result, pubsub()} | {error, error()}. subscribe_node(Host, Node, From, JID, Configuration) -> SubModule = subscription_plugin(Host), SubOpts = case SubModule:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, - Subscriber = string_to_ljid(JID), + Subscriber = jid:tolower(JID), Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx, owners = O}) -> Features = plugin_features(Host, Type), SubscribeFeature = lists:member(<<"subscribe">>, Features), @@ -1976,21 +1794,21 @@ subscribe_node(Host, Node, From, JID, Configuration) -> true end, if not SubscribeFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"subscribe">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('subscribe'))}; not SubscribeConfig -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"subscribe">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('subscribe'))}; HasOptions andalso not OptionsFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"subscription-options">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('subscription-options'))}; SubOpts == invalid -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"invalid-options">>)}; + {error, extended_error(xmpp:err_bad_request(), + err_invalid_options())}; not CanSubscribe -> %% fallback to closest XEP compatible result, assume we are not allowed to subscribe - {error, - extended_error(?ERR_NOT_ALLOWED, <<"closed-node">>)}; + {error, extended_error(xmpp:err_not_allowed(), + err_closed_node())}; true -> Owners = node_owners_call(Host, Type, Nidx, O), {PS, RG} = get_presence_and_roster_permissions(Host, Subscriber, @@ -2001,19 +1819,13 @@ subscribe_node(Host, Node, From, JID, Configuration) -> end end, Reply = fun (Subscription) -> - SubAttrs = case Subscription of - {subscribed, SubId} -> - [{<<"subscription">>, subscription_to_string(subscribed)}, - {<<"subid">>, SubId}, {<<"node">>, Node}]; - Other -> - [{<<"subscription">>, subscription_to_string(Other)}, - {<<"node">>, Node}] - end, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"subscription">>, - attrs = [{<<"jid">>, jid:to_string(Subscriber)} - | SubAttrs]}]}] + Sub = case Subscription of + {subscribed, SubId} -> + #ps_subscription{type = subscribed, subid = SubId}; + Other -> + #ps_subscription{type = Other} + end, + #pubsub{subscription = Sub#ps_subscription{jid = Subscriber, node = Node}} end, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, subscribed, SubId, send_last}}} -> @@ -2052,14 +1864,10 @@ subscribe_node(Host, Node, From, JID, Configuration) -> %%
  • The node does not exist.
  • %%
  • The request specifies a subscription ID that is not valid or current.
  • %% --spec unsubscribe_node(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - From :: jid(), JID :: binary() | ljid(), - SubId :: mod_pubsub:subId()) -> - {result, []} | {error, xmlel()}. - -unsubscribe_node(Host, Node, From, JID, SubId) when is_binary(JID) -> - unsubscribe_node(Host, Node, From, string_to_ljid(JID), SubId); -unsubscribe_node(Host, Node, From, Subscriber, SubId) -> +-spec unsubscribe_node(host(), binary(), jid(), jid(), binary()) -> + {result, undefined} | {error, error()}. +unsubscribe_node(Host, Node, From, JID, SubId) -> + Subscriber = jid:tolower(JID), Action = fun (#pubsub_node{type = Type, id = Nidx}) -> node_call(Host, Type, unsubscribe_node, [Nidx, From, Subscriber, SubId]) end, @@ -2067,9 +1875,8 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) -> {result, {_, default}} -> ServerHost = serverhost(Host), ejabberd_hooks:run(pubsub_unsubscribe_node, ServerHost, - [ServerHost, Host, Node, Subscriber, SubId]), - {result, []}; - % {result, {_, Result}} -> {result, Result}; + [ServerHost, Host, Node, Subscriber, SubId]), + {result, undefined}; Error -> Error end. @@ -2084,12 +1891,8 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) -> %%
  • The item contains more than one payload element or the namespace of the root payload element does not match the configured namespace for the node.
  • %%
  • The request does not match the node configuration.
  • %% --spec publish_item(Host :: mod_pubsub:host(), ServerHost :: binary(), - Node :: mod_pubsub:nodeId(), Publisher :: jid(), - ItemId :: <<>> | mod_pubsub:itemId(), - Payload :: mod_pubsub:payload()) -> - {result, [xmlel(),...]} | {error, xmlel()}. - +-spec publish_item(host(), binary(), binary(), jid(), binary(), + [xmlel()]) -> {result, pubsub()} | {error, error()}. publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, [], all). publish_item(Host, ServerHost, Node, Publisher, <<>>, Payload, PubOpts, Access) -> @@ -2106,34 +1909,31 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access PayloadSize = byte_size(term_to_binary(Payload)) - 2, PayloadMaxSize = get_option(Options, max_payload_size), if not PublishFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"publish">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported(publish))}; PayloadSize > PayloadMaxSize -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"payload-too-big">>)}; + {error, extended_error(xmpp:err_not_acceptable(), + err_payload_too_big())}; (PayloadCount == 0) and (Payload == []) -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"payload-required">>)}; + {error, extended_error(xmpp:err_bad_request(), + err_payload_required())}; (PayloadCount > 1) or (PayloadCount == 0) -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"invalid-payload">>)}; + {error, extended_error(xmpp:err_bad_request(), + err_invalid_payload())}; (DeliverPayloads == false) and (PersistItems == false) and (PayloadSize > 0) -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"item-forbidden">>)}; + {error, extended_error(xmpp:err_bad_request(), + err_item_forbidden())}; ((DeliverPayloads == true) or (PersistItems == true)) and (PayloadSize == 0) -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"item-required">>)}; + {error, extended_error(xmpp:err_bad_request(), + err_item_required())}; true -> node_call(Host, Type, publish_item, [Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload, PubOpts]) end end, - Reply = [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"publish">>, attrs = nodeAttr(Node), - children = [#xmlel{name = <<"item">>, - attrs = itemAttr(ItemId)}]}]}], + Reply = #pubsub{publish = #ps_publish{node = Node, + items = [#ps_item{id = ItemId}]}}, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, Broadcast, Removed}}} -> Nidx = TNode#pubsub_node.id, @@ -2175,29 +1975,20 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access {result, Reply}; {result, {_, Result}} -> {result, Result}; - {error, _} = Error -> - case is_item_not_found(Error) of + {error, #error{reason = 'item-not-found'}} -> + Type = select_type(ServerHost, Host, Node), + case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of true -> - Type = select_type(ServerHost, Host, Node), - case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of - true -> - case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"create">>, - attrs = [{<<"node">>, NewNode}]}]}]} -> + case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of + {result, #pubsub{create = NewNode}} -> publish_item(Host, ServerHost, NewNode, Publisher, ItemId, - Payload, PubOpts, Access); - _ -> - {error, ?ERR_ITEM_NOT_FOUND} - end; - false -> - Txt = <<"Automatic node creation is not enabled">>, - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, Txt)} + Payload, PubOpts, Access); + _ -> + {error, xmpp:err_item_not_found()} end; false -> - Error + Txt = <<"Automatic node creation is not enabled">>, + {error, xmpp:err_item_not_found(Txt, ?MYLANG)} end; Error -> Error @@ -2214,14 +2005,12 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access %%
  • The node does not support persistent items.
  • %%
  • The service does not support the deletion of items.
  • %% --spec delete_item(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - Publisher :: jid(), ItemId :: mod_pubsub:itemId()) -> - {result, []} | {error, xmlel()}. - +-spec delete_item(host(), binary(), jid(), binary()) -> {result, undefined} | + {error, error()}. delete_item(Host, Node, Publisher, ItemId) -> delete_item(Host, Node, Publisher, ItemId, false). delete_item(_, <<>>, _, _, _) -> - {error, extended_error(?ERR_BAD_REQUEST, <<"node-required">>)}; + {error, extended_error(xmpp:err_bad_request(), err_nodeid_required())}; delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), @@ -2232,16 +2021,16 @@ delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> %% %% Request does not specify an item %% {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; not PersistentFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"persistent-items">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('persistent-items'))}; not DeleteFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"delete-items">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('delete-items'))}; true -> node_call(Host, Type, delete_item, [Nidx, Publisher, PublishModel, ItemId]) end end, - Reply = [], + Reply = undefined, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> Nidx = TNode#pubsub_node.id, @@ -2272,10 +2061,8 @@ delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> %%
  • The node is not configured to persist items.
  • %%
  • The specified node does not exist.
  • %% --spec purge_node(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - Owner :: jid()) -> - {result, []} | {error, xmlel()}. - +-spec purge_node(mod_pubsub:host(), binary(), jid()) -> {result, undefined} | + {error, error()}. purge_node(Host, Node, Owner) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), @@ -2283,18 +2070,18 @@ purge_node(Host, Node, Owner) -> PersistentFeature = lists:member(<<"persistent-items">>, Features), PersistentConfig = get_option(Options, persist_items), if not PurgeFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"purge-nodes">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('purge-nodes'))}; not PersistentFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"persistent-items">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('persistent-items'))}; not PersistentConfig -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"persistent-items">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('persistent-items'))}; true -> node_call(Host, Type, purge_node, [Nidx, Owner]) end end, - Reply = [], + Reply = undefined, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> Nidx = TNode#pubsub_node.id, @@ -2319,71 +2106,57 @@ purge_node(Host, Node, Owner) -> %%

    The permission are not checked in this function.

    %% @todo We probably need to check that the user doing the query has the right %% to read the items. --spec get_items(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - From :: jid(), SubId :: mod_pubsub:subId(), - SMaxItems :: binary(), ItemIds :: [mod_pubsub:itemId()], - Rsm :: none | rsm_in()) -> - {result, [xmlel(),...]} | {error, xmlel()}. - +-spec get_items(host(), binary(), jid(), binary(), + binary(), [binary()], undefined | rsm_set()) -> + {result, pubsub()} | {error, error()}. get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) -> - MaxItems = if SMaxItems == <<>> -> - case get_max_items_node(Host) of - undefined -> ?MAXITEMS; - Max -> Max - end; - true -> - case catch jlib:binary_to_integer(SMaxItems) of - {'EXIT', _} -> - Txt = <<"Value of 'max_items' should be integer">>, - {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}; - Val -> Val - end - end, - case MaxItems of - {error, Error} -> - {error, Error}; - _ -> - Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx, owners = O}) -> - Features = plugin_features(Host, Type), - RetreiveFeature = lists:member(<<"retrieve-items">>, Features), - PersistentFeature = lists:member(<<"persistent-items">>, Features), - AccessModel = get_option(Options, access_model), - AllowedGroups = get_option(Options, roster_groups_allowed, []), - if not RetreiveFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"retrieve-items">>)}; - not PersistentFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"persistent-items">>)}; - true -> - Owners = node_owners_call(Host, Type, Nidx, O), - {PS, RG} = get_presence_and_roster_permissions(Host, From, Owners, - AccessModel, AllowedGroups), - node_call(Host, Type, get_items, - [Nidx, From, AccessModel, PS, RG, SubId, RSM]) - end - end, - case transaction(Host, Node, Action, sync_dirty) of - {result, {_, {Items, RsmOut}}} -> - SendItems = case ItemIds of - [] -> - Items; - _ -> - lists:filter(fun (#pubsub_item{itemid = {ItemId, _}}) -> - lists:member(ItemId, ItemIds) - end, - Items) - end, - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = - [#xmlel{name = <<"items">>, attrs = nodeAttr(Node), - children = itemsEls(lists:sublist(SendItems, MaxItems))} - | jlib:rsm_encode(RsmOut)]}]}; - Error -> - Error - end + MaxItems = if SMaxItems == undefined -> + case get_max_items_node(Host) of + undefined -> ?MAXITEMS; + Max -> Max + end; + true -> + SMaxItems + end, + Action = + fun(#pubsub_node{options = Options, type = Type, + id = Nidx, owners = O}) -> + Features = plugin_features(Host, Type), + RetreiveFeature = lists:member(<<"retrieve-items">>, Features), + PersistentFeature = lists:member(<<"persistent-items">>, Features), + AccessModel = get_option(Options, access_model), + AllowedGroups = get_option(Options, roster_groups_allowed, []), + if not RetreiveFeature -> + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('retrieve-items'))}; + not PersistentFeature -> + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('persistent-items'))}; + true -> + Owners = node_owners_call(Host, Type, Nidx, O), + {PS, RG} = get_presence_and_roster_permissions( + Host, From, Owners, AccessModel, AllowedGroups), + node_call(Host, Type, get_items, + [Nidx, From, AccessModel, PS, RG, SubId, RSM]) + end + end, + case transaction(Host, Node, Action, sync_dirty) of + {result, {_, {Items, RsmOut}}} -> + SendItems = case ItemIds of + [] -> + Items; + _ -> + lists:filter( + fun(#pubsub_item{itemid = {ItemId, _}}) -> + lists:member(ItemId, ItemIds) + end, Items) + end, + {result, + #pubsub{items = #ps_items{node = Node, + items = itemsEls(lists:sublist(SendItems, MaxItems))}, + rsm = RsmOut}}; + Error -> + Error end. get_items(Host, Node) -> @@ -2487,227 +2260,200 @@ dispatch_items(From, To, _Node, Stanza) -> ejabberd_router:route(service_jid(From), jid:make(To), Stanza). %% @doc

    Return the list of affiliations as an XMPP response.

    --spec get_affiliations(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - JID :: jid(), Plugins :: [binary()]) -> - {result, [xmlel(),...]} | {error, xmlel()}. - +-spec get_affiliations(host(), binary(), jid(), [binary()]) -> + {result, pubsub()} | {error, error()}. get_affiliations(Host, Node, JID, Plugins) when is_list(Plugins) -> - Result = lists:foldl( fun (Type, {Status, Acc}) -> - Features = plugin_features(Host, Type), - RetrieveFeature = lists:member(<<"retrieve-affiliations">>, Features), - if not RetrieveFeature -> - {{error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, - unsupported, <<"retrieve-affiliations">>)}, - Acc}; - true -> - {result, Affs} = node_action(Host, Type, - get_entity_affiliations, - [Host, JID]), - {Status, [Affs | Acc]} - end - end, - {ok, []}, Plugins), + Result = + lists:foldl( + fun(Type, {Status, Acc}) -> + Features = plugin_features(Host, Type), + RetrieveFeature = lists:member(<<"retrieve-affiliations">>, Features), + if not RetrieveFeature -> + {{error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('retrieve-affiliations'))}, + Acc}; + true -> + {result, Affs} = node_action(Host, Type, + get_entity_affiliations, + [Host, JID]), + {Status, [Affs | Acc]} + end + end, + {ok, []}, Plugins), case Result of {ok, Affs} -> - Entities = lists:flatmap(fun - ({_, none}) -> - []; - ({#pubsub_node{nodeid = {_, NodeId}}, Aff}) -> - if (Node == <<>>) or (Node == NodeId) -> - [#xmlel{name = <<"affiliation">>, - attrs = [{<<"affiliation">>, affiliation_to_string(Aff)} - | nodeAttr(NodeId)]}]; - true -> - [] - end; - (_) -> - [] - end, - lists:usort(lists:flatten(Affs))), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"affiliations">>, attrs = [], - children = Entities}]}]}; + Entities = lists:flatmap( + fun({_, none}) -> + []; + ({#pubsub_node{nodeid = {_, NodeId}}, Aff}) -> + if (Node == <<>>) or (Node == NodeId) -> + [#ps_affiliation{node = NodeId, + type = Aff}]; + true -> + [] + end; + (_) -> + [] + end, lists:usort(lists:flatten(Affs))), + {result, #pubsub{affiliations = {<<>>, Entities}}}; {Error, _} -> Error end. --spec get_affiliations(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - JID :: jid()) -> - {result, [xmlel(),...]} | {error, xmlel()}. - +-spec get_affiliations(host(), binary(), jid()) -> + {result, pubsub_owner()} | {error, error()}. get_affiliations(Host, Node, JID) -> - Action = fun (#pubsub_node{type = Type, id = Nidx}) -> - Features = plugin_features(Host, Type), - RetrieveFeature = lists:member(<<"modify-affiliations">>, Features), - {result, Affiliation} = node_call(Host, Type, get_affiliation, [Nidx, JID]), - if not RetrieveFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"modify-affiliations">>)}; - Affiliation /= owner -> - {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}; - true -> - node_call(Host, Type, get_node_affiliations, [Nidx]) - end - end, + Action = + fun(#pubsub_node{type = Type, id = Nidx}) -> + Features = plugin_features(Host, Type), + RetrieveFeature = lists:member(<<"modify-affiliations">>, Features), + {result, Affiliation} = node_call(Host, Type, get_affiliation, [Nidx, JID]), + if not RetrieveFeature -> + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('modify-affiliations'))}; + Affiliation /= owner -> + {error, xmpp:err_forbidden(<<"Owner privileges required">>, ?MYLANG)}; + true -> + node_call(Host, Type, get_node_affiliations, [Nidx]) + end + end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, []}} -> - {error, ?ERR_ITEM_NOT_FOUND}; + {error, xmpp:err_item_not_found()}; {result, {_, Affs}} -> - Entities = lists:flatmap(fun - ({_, none}) -> - []; - ({AJID, Aff}) -> - [#xmlel{name = <<"affiliation">>, - attrs = [{<<"jid">>, jid:to_string(AJID)}, - {<<"affiliation">>, affiliation_to_string(Aff)}]}] - end, - Affs), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_OWNER}], - children = [#xmlel{name = <<"affiliations">>, - attrs = nodeAttr(Node), children = Entities}]}]}; + Entities = lists:flatmap( + fun({_, none}) -> + []; + ({AJID, Aff}) -> + [#ps_affiliation{jid = AJID, type = Aff}] + end, Affs), + {result, #pubsub_owner{affiliations = {Node, Entities}}}; Error -> Error end. --spec set_affiliations(Host :: mod_pubsub:host(), Node :: mod_pubsub:nodeId(), - From :: jid(), EntitiesEls :: [xmlel()]) -> - {result, []} | {error, xmlel()}. - -set_affiliations(Host, Node, From, EntitiesEls) -> +-spec set_affiliations(host(), binary(), jid(), [ps_affiliation()]) -> + {result, undefined} | {error, error()}. +set_affiliations(Host, Node, From, Affs) -> Owner = jid:tolower(jid:remove_resource(From)), - Entities = lists:foldl(fun - (_, error) -> - error; - (El, Acc) -> - case El of - #xmlel{name = <<"affiliation">>, attrs = Attrs} -> - JID = jid:from_string(fxml:get_attr_s(<<"jid">>, Attrs)), - Affiliation = string_to_affiliation(fxml:get_attr_s(<<"affiliation">>, Attrs)), - if (JID == error) or (Affiliation == false) -> error; - true -> [{jid:tolower(JID), Affiliation} | Acc] - end - end - end, - [], EntitiesEls), - case Entities of - error -> - {error, ?ERR_BAD_REQUEST}; - _ -> - Action = fun (#pubsub_node{type = Type, id = Nidx, owners = O} = N) -> - Owners = node_owners_call(Host, Type, Nidx, O), - case lists:member(Owner, Owners) of - true -> - OwnerJID = jid:make(Owner), - FilteredEntities = case Owners of - [Owner] -> [E || E <- Entities, element(1, E) =/= OwnerJID]; - _ -> Entities + Action = + fun(#pubsub_node{type = Type, id = Nidx, owners = O} = N) -> + Owners = node_owners_call(Host, Type, Nidx, O), + case lists:member(Owner, Owners) of + true -> + OwnerJID = jid:make(Owner), + FilteredAffs = + case Owners of + [Owner] -> + [Aff || Aff <- Affs, + Aff#ps_affiliation.jid /= OwnerJID]; + _ -> + Affs end, - lists:foreach(fun ({JID, Affiliation}) -> - node_call(Host, Type, set_affiliation, [Nidx, JID, Affiliation]), - case Affiliation of - owner -> - NewOwner = jid:tolower(jid:remove_resource(JID)), - NewOwners = [NewOwner | Owners], - tree_call(Host, + lists:foreach( + fun(#ps_affiliation{jid = JID, type = Affiliation}) -> + node_call(Host, Type, set_affiliation, [Nidx, JID, Affiliation]), + case Affiliation of + owner -> + NewOwner = jid:tolower(jid:remove_resource(JID)), + NewOwners = [NewOwner | Owners], + tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); - none -> - OldOwner = jid:tolower(jid:remove_resource(JID)), - case lists:member(OldOwner, Owners) of - true -> - NewOwners = Owners -- [OldOwner], - tree_call(Host, + none -> + OldOwner = jid:tolower(jid:remove_resource(JID)), + case lists:member(OldOwner, Owners) of + true -> + NewOwners = Owners -- [OldOwner], + tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); - _ -> - ok - end; - _ -> - ok - end - end, - FilteredEntities), - {result, []}; - _ -> - {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)} - end - end, - case transaction(Host, Node, Action, sync_dirty) of - {result, {_, Result}} -> {result, Result}; - Other -> Other - end + _ -> + ok + end; + _ -> + ok + end + end, FilteredAffs), + {result, undefined}; + _ -> + {error, xmpp:err_forbidden( + <<"Owner privileges required">>, ?MYLANG)} + end + end, + case transaction(Host, Node, Action, sync_dirty) of + {result, {_, Result}} -> {result, Result}; + Other -> Other end. +-spec get_options(binary(), binary(), jid(), binary(), binary()) -> + {result, xdata()} | {error, error()}. get_options(Host, Node, JID, SubId, Lang) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> case lists:member(<<"subscription-options">>, plugin_features(Host, Type)) of true -> get_options_helper(Host, JID, Lang, Node, Nidx, SubId, Type); false -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"subscription-options">>)} + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('subscription-options'))} end end, case transaction(Host, Node, Action, sync_dirty) of - {result, {_Node, XForm}} -> {result, [XForm]}; + {result, {_Node, XForm}} -> {result, XForm}; Error -> Error end. +-spec get_options_helper(binary(), jid(), binary(), binary(), _, binary(), + binary()) -> {result, pubsub()} | {error, error()}. get_options_helper(Host, JID, Lang, Node, Nidx, SubId, Type) -> - Subscriber = string_to_ljid(JID), + Subscriber = jid:tolower(JID), {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), SubIds = [Id || {Sub, Id} <- Subs, Sub == subscribed], case {SubId, SubIds} of {_, []} -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"not-subscribed">>)}; + {error, extended_error(xmpp:err_not_acceptable(), + err_not_subscribed())}; {<<>>, [SID]} -> read_sub(Host, Node, Nidx, Subscriber, SID, Lang); {<<>>, _} -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"subid-required">>)}; + {error, extended_error(xmpp:err_not_acceptable(), + err_subid_required())}; {_, _} -> ValidSubId = lists:member(SubId, SubIds), if ValidSubId -> read_sub(Host, Node, Nidx, Subscriber, SubId, Lang); true -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"invalid-subid">>)} + {error, extended_error(xmpp:err_not_acceptable(), + err_invalid_subid())} end end. +-spec read_sub(binary(), binary(), nodeIdx(), ljid(), binary(), binary()) -> {result, pubsub()}. read_sub(Host, Node, Nidx, Subscriber, SubId, Lang) -> SubModule = subscription_plugin(Host), - Children = case SubModule:get_subscription(Subscriber, Nidx, SubId) of - {error, notfound} -> - []; - {result, #pubsub_subscription{options = Options}} -> - {result, XdataEl} = SubModule:get_options_xform(Lang, Options), - [XdataEl] - end, - OptionsEl = #xmlel{name = <<"options">>, - attrs = [{<<"jid">>, jid:to_string(Subscriber)}, - {<<"subid">>, SubId} - | nodeAttr(Node)], - children = Children}, - PubsubEl = #xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [OptionsEl]}, - {result, PubsubEl}. - + XData = case SubModule:get_subscription(Subscriber, Nidx, SubId) of + {error, notfound} -> + undefined; + {result, #pubsub_subscription{options = Options}} -> + {result, X} = SubModule:get_options_xform(Lang, Options), + X + end, + {result, #pubsub{options = #ps_options{jid = jid:make(Subscriber), + subid = SubId, + node = Node, + xdata = XData}}}. + +-spec set_options(binary(), binary(), jid(), binary(), + [{binary(), [binary()]}]) -> + {result, undefined} | {error, error()}. set_options(Host, Node, JID, SubId, Configuration) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> case lists:member(<<"subscription-options">>, plugin_features(Host, Type)) of true -> set_options_helper(Host, Configuration, JID, Nidx, SubId, Type); false -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"subscription-options">>)} + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('subscription-options'))} end end, case transaction(Host, Node, Action, sync_dirty) of @@ -2715,56 +2461,53 @@ set_options(Host, Node, JID, SubId, Configuration) -> Error -> Error end. +-spec set_options_helper(binary(), [{binary(), [binary()]}], jid(), + nodeIdx(), binary(), binary()) -> + {result, undefined} | {error, error()}. set_options_helper(Host, Configuration, JID, Nidx, SubId, Type) -> SubModule = subscription_plugin(Host), SubOpts = case SubModule:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, - Subscriber = string_to_ljid(JID), + Subscriber = jid:tolower(JID), {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), SubIds = [Id || {Sub, Id} <- Subs, Sub == subscribed], case {SubId, SubIds} of {_, []} -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"not-subscribed">>)}; + {error, extended_error(xmpp:err_not_acceptable(), err_not_subscribed())}; {<<>>, [SID]} -> write_sub(Host, Nidx, Subscriber, SID, SubOpts); {<<>>, _} -> - {error, - extended_error(?ERR_NOT_ACCEPTABLE, <<"subid-required">>)}; + {error, extended_error(xmpp:err_not_acceptable(), err_subid_required())}; {_, _} -> write_sub(Host, Nidx, Subscriber, SubId, SubOpts) end. +-spec write_sub(binary(), nodeIdx(), ljid(), binary(), _) -> {result, undefined} | + {error, error()}. write_sub(_Host, _Nidx, _Subscriber, _SubId, invalid) -> - {error, - extended_error(?ERR_BAD_REQUEST, <<"invalid-options">>)}; + {error, extended_error(xmpp:err_bad_request(), err_invalid_options())}; write_sub(_Host, _Nidx, _Subscriber, _SubId, []) -> - {result, []}; + {result, undefined}; write_sub(Host, Nidx, Subscriber, SubId, Options) -> SubModule = subscription_plugin(Host), case SubModule:set_subscription(Subscriber, Nidx, SubId, Options) of - {result, _} -> {result, []}; - {error, _} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, <<"invalid-subid">>)} + {result, _} -> {result, undefined}; + {error, _} -> {error, extended_error(xmpp:err_not_acceptable(), + err_invalid_subid())} end. -%% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response} -%% Host = host() -%% Node = pubsubNode() -%% JID = jid() -%% Plugins = [Plugin::string()] -%% Reason = stanzaError() -%% Response = [pubsubIQResponse()] %% @doc

    Return the list of subscriptions as an XMPP response.

    +-spec get_subscriptions(host(), binary(), jid(), [binary()]) -> + {result, pubsub()} | {error, error()}. get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl(fun (Type, {Status, Acc}) -> Features = plugin_features(Host, Type), RetrieveFeature = lists:member(<<"retrieve-subscriptions">>, Features), if not RetrieveFeature -> - {{error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, - unsupported, <<"retrieve-subscriptions">>)}, + {{error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('retrieve-subscriptions'))}, Acc}; true -> Subscriber = jid:remove_resource(JID), @@ -2783,14 +2526,9 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> ({#pubsub_node{nodeid = {_, SubsNode}}, Sub}) -> case Node of <<>> -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"subscription">>, subscription_to_string(Sub)} - | nodeAttr(SubsNode)]}]; + [#ps_subscription{node = SubsNode, type = Sub}]; SubsNode -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"subscription">>, subscription_to_string(Sub)}]}]; + [#ps_subscription{type = Sub}]; _ -> [] end; @@ -2799,88 +2537,65 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> ({#pubsub_node{nodeid = {_, SubsNode}}, Sub, SubId, SubJID}) -> case Node of <<>> -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(SubJID)}, - {<<"subid">>, SubId}, - {<<"subscription">>, subscription_to_string(Sub)} - | nodeAttr(SubsNode)]}]; + [#ps_subscription{jid = SubJID, + subid = SubId, + type = Sub, + node = SubsNode}]; SubsNode -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(SubJID)}, - {<<"subid">>, SubId}, - {<<"subscription">>, subscription_to_string(Sub)}]}]; + [#ps_subscription{jid = SubJID, + subid = SubId, + type = Sub}]; _ -> [] end; ({#pubsub_node{nodeid = {_, SubsNode}}, Sub, SubJID}) -> case Node of <<>> -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(SubJID)}, - {<<"subscription">>, subscription_to_string(Sub)} - | nodeAttr(SubsNode)]}]; + [#ps_subscription{jid = SubJID, + type = Sub, + node = SubsNode}]; SubsNode -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(SubJID)}, - {<<"subscription">>, subscription_to_string(Sub)}]}]; + [#ps_subscription{jid = SubJID, type = Sub}]; _ -> [] end end, lists:usort(lists:flatten(Subs))), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = [#xmlel{name = <<"subscriptions">>, attrs = [], - children = Entities}]}]}; + {result, #pubsub{subscriptions = {<<>>, Entities}}}; {Error, _} -> Error end. +-spec get_subscriptions(binary(), binary(), jid()) -> {result, pubsub()} | + {error, error()}. get_subscriptions(Host, Node, JID) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), RetrieveFeature = lists:member(<<"manage-subscriptions">>, Features), {result, Affiliation} = node_call(Host, Type, get_affiliation, [Nidx, JID]), if not RetrieveFeature -> - {error, - extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"manage-subscriptions">>)}; + {error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('manage-subscriptions'))}; Affiliation /= owner -> - {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}; + {error, xmpp:err_forbidden(<<"Owner privileges required">>, ?MYLANG)}; true -> node_call(Host, Type, get_node_subscriptions, [Nidx]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Subs}} -> - Entities = lists:flatmap(fun - ({_, none}) -> - []; - ({_, pending, _}) -> - []; - ({AJID, Sub}) -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(AJID)}, - {<<"subscription">>, subscription_to_string(Sub)}]}]; + Entities = + lists:flatmap( + fun({_, none}) -> + []; + ({_, pending, _}) -> + []; + ({AJID, Sub}) -> + [#ps_subscription{jid = AJID, type = Sub}]; ({AJID, Sub, SubId}) -> - [#xmlel{name = <<"subscription">>, - attrs = - [{<<"jid">>, jid:to_string(AJID)}, - {<<"subscription">>, subscription_to_string(Sub)}, - {<<"subid">>, SubId}]}] - end, - Subs), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_OWNER}], - children = [#xmlel{name = <<"subscriptions">>, - attrs = nodeAttr(Node), - children = Entities}]}]}; + [#ps_subscription{jid = AJID, type = Sub, subid = SubId}] + end, Subs), + {result, #pubsub{subscriptions = {Node, Entities}}}; Error -> Error end. @@ -2908,78 +2623,55 @@ get_subscriptions_for_send_last(Host, PType, sql, JID, LJID, BJID) -> get_subscriptions_for_send_last(_Host, _PType, _, _JID, _LJID, _BJID) -> []. -set_subscriptions(Host, Node, From, EntitiesEls) -> +set_subscriptions(Host, Node, From, Entities) -> Owner = jid:tolower(jid:remove_resource(From)), - Entities = lists:foldl(fun - (_, error) -> - error; - (El, Acc) -> - case El of - #xmlel{name = <<"subscription">>, attrs = Attrs} -> - JID = jid:from_string(fxml:get_attr_s(<<"jid">>, Attrs)), - Sub = string_to_subscription(fxml:get_attr_s(<<"subscription">>, Attrs)), - SubId = fxml:get_attr_s(<<"subid">>, Attrs), - if (JID == error) or (Sub == false) -> error; - true -> [{jid:tolower(JID), Sub, SubId} | Acc] - end - end - end, - [], EntitiesEls), - case Entities of - error -> - {error, ?ERR_BAD_REQUEST}; - _ -> - Notify = fun (JID, Sub, _SubId) -> - Stanza = #xmlel{name = <<"message">>, attrs = [], - children = - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB}], - children = - [#xmlel{name = <<"subscription">>, - attrs = [{<<"jid">>, jid:to_string(JID)}, - {<<"subscription">>, subscription_to_string(Sub)} - | nodeAttr(Node)]}]}]}, - ejabberd_router:route(service_jid(Host), jid:make(JID), Stanza) - end, - Action = fun (#pubsub_node{type = Type, id = Nidx, owners = O}) -> - Owners = node_owners_call(Host, Type, Nidx, O), - case lists:member(Owner, Owners) of - true -> - Result = lists:foldl(fun ({JID, Sub, SubId}, Acc) -> - case - node_call(Host, Type, - set_subscriptions, - [Nidx, JID, Sub, SubId]) - of - {error, Err} -> - [{error, Err} | Acc]; - _ -> - Notify(JID, Sub, SubId), - Acc - end - end, - [], Entities), - case Result of - [] -> {result, []}; - [{error, E}|_] -> {error, E} - end; - _ -> - {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)} - end - end, - case transaction(Host, Node, Action, sync_dirty) of - {result, {_, Result}} -> {result, Result}; - Other -> Other - end + Notify = fun(#ps_subscription{jid = JID, type = Sub}) -> + Stanza = #message{ + sub_els = [#pubsub{ + subscription = #ps_subscription{ + jid = JID, + type = Sub, + node = Node}}]}, + ejabberd_router:route(service_jid(Host), JID, Stanza) + end, + Action = + fun(#pubsub_node{type = Type, id = Nidx, owners = O}) -> + Owners = node_owners_call(Host, Type, Nidx, O), + case lists:member(Owner, Owners) of + true -> + Result = + lists:foldl( + fun(_, {error, _} = Err) -> + Err; + (#ps_subscription{jid = JID, type = Sub, + subid = SubId} = Entity, _) -> + case node_call(Host, Type, + set_subscriptions, + [Nidx, JID, Sub, SubId]) of + {error, _} = Err -> + Err; + _ -> + Notify(Entity) + end + end, ok, Entities), + case Result of + ok -> {result, undefined}; + {error, _} = Err -> Err + end; + _ -> + {error, xmpp:err_forbidden( + <<"Owner privileges required">>, ?MYLANG)} + + end + end, + case transaction(Host, Node, Action, sync_dirty) of + {result, {_, Result}} -> {result, Result}; + Other -> Other end. --spec get_presence_and_roster_permissions(Host :: mod_pubsub:host(), - From :: ljid(), Owners :: [ljid(),...], - AccessModel :: mod_pubsub:accessModel(), - AllowedGroups :: [binary()]) -> - {PresenceSubscription::boolean(), - RosterGroup::boolean()}. - +-spec get_presence_and_roster_permissions( + host(), ljid(), [ljid()], accessModel(), + [binary()]) -> {boolean(), boolean()}. get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups) -> if (AccessModel == presence) or (AccessModel == roster) -> case Host of @@ -3037,10 +2729,10 @@ subscription_to_string(pending) -> <<"pending">>; subscription_to_string(unconfigured) -> <<"unconfigured">>; subscription_to_string(_) -> <<"none">>. --spec service_jid(Host :: mod_pubsub:host()) -> jid(). +-spec service_jid(jid() | ljid() | binary()) -> jid(). service_jid(#jid{} = Jid) -> Jid; service_jid({U, S, R}) -> jid:make(U, S, R); -service_jid(Host) -> jid:make(<<>>, Host, <<>>). +service_jid(Host) -> jid:make(Host). %% @spec (LJID, NotifyType, Depth, NodeOptions, SubOptions) -> boolean() %% LJID = jid() @@ -3071,7 +2763,7 @@ sub_option_can_deliver(_, _, {deliver, false}) -> false; sub_option_can_deliver(_, _, {expire, When}) -> p1_time_compat:timestamp() < When; sub_option_can_deliver(_, _, _) -> true. --spec presence_can_deliver(Entity :: ljid(), _ :: boolean()) -> boolean(). +-spec presence_can_deliver(ljid(), boolean()) -> boolean(). presence_can_deliver(_, false) -> true; presence_can_deliver({User, Server, Resource}, true) -> @@ -3092,10 +2784,7 @@ presence_can_deliver({User, Server, Resource}, true) -> false, Ss) end. --spec state_can_deliver(Entity::ljid(), - SubOptions :: mod_pubsub:subOptions() | []) -> - [ljid()]. - +-spec state_can_deliver(ljid(), subOptions() | []) -> [ljid()]. state_can_deliver({U, S, R}, []) -> [{U, S, R}]; state_can_deliver({U, S, R}, SubOptions) -> case lists:keysearch(show_values, 1, SubOptions) of @@ -3115,10 +2804,7 @@ state_can_deliver({U, S, R}, SubOptions) -> [], Resources) end. --spec get_resource_state(Entity :: ljid(), ShowValues :: [binary()], - JIDs :: [ljid()]) -> - [ljid()]. - +-spec get_resource_state(ljid(), [binary()], [ljid()]) -> [ljid()]. get_resource_state({U, S, R}, ShowValues, JIDs) -> case ejabberd_sm:get_session_pid(U, S, R) of none -> @@ -3137,8 +2823,7 @@ get_resource_state({U, S, R}, ShowValues, JIDs) -> end end. --spec payload_xmlelements(Payload :: mod_pubsub:payload()) -> - Count :: non_neg_integer(). +-spec payload_xmlelements([xmlel()]) -> non_neg_integer(). payload_xmlelements(Payload) -> payload_xmlelements(Payload, 0). @@ -3152,63 +2837,55 @@ items_event_stanza(Node, Options, Items) -> MoreEls = case Items of [LastItem] -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, - DateTime = calendar:now_to_datetime(ModifNow), - {T_string, Tz_string} = jlib:timestamp_to_iso(DateTime, utc), - [#xmlel{name = <<"delay">>, attrs = [{<<"xmlns">>, ?NS_DELAY}, - {<<"from">>, jid:to_string(ModifUSR)}, - {<<"stamp">>, <>}], - children = [{xmlcdata, <<>>}]}]; + [#delay{stamp = ModifNow, from = jid:make(ModifUSR)}]; _ -> [] end, - BaseStanza = event_stanza_with_els([#xmlel{name = <<"items">>, - attrs = nodeAttr(Node), - children = itemsEls(Items)}], - MoreEls), + BaseStanza = #message{ + sub_els = [#ps_event{items = #ps_items{ + node = Node, + items = itemsEls(Items)}} + | MoreEls]}, NotificationType = get_option(Options, notification_type, headline), add_message_type(BaseStanza, NotificationType). -event_stanza(Els) -> - event_stanza_with_els(Els, []). -event_stanza_with_els(Els, MoreEls) -> - #xmlel{name = <<"message">>, attrs = [], - children = [#xmlel{name = <<"event">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_EVENT}], - children = Els} - | MoreEls]}. - -event_stanza(Event, EvAttr) -> - event_stanza_with_els([#xmlel{name = Event, attrs = EvAttr}], []). - %%%%%% broadcast functions broadcast_publish_item(Host, Node, Nidx, Type, NodeOptions, ItemId, From, Payload, Removed) -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> - Content = case get_option(NodeOptions, deliver_payloads) of - true -> Payload; - false -> [] - end, - Attrs = case get_option(NodeOptions, itemreply, none) of - owner -> itemAttr(ItemId); %% owner not supported - publisher -> itemAttr(ItemId, {<<"publisher">>, jid:to_string(From)}); - none -> itemAttr(ItemId) - end, - Stanza = event_stanza( - [#xmlel{name = <<"items">>, attrs = nodeAttr(Node), - children = [#xmlel{name = <<"item">>, attrs = Attrs, - children = Content}]}]), + EventItem0 = case get_option(NodeOptions, deliver_payloads) of + true -> #ps_item{xml_els = Payload, id = ItemId}; + false -> #ps_item{id = ItemId} + end, + EventItem = case get_option(NodeOptions, itemreply, none) of + owner -> %% owner not supported + EventItem0; + publisher -> + EventItem0#ps_item{ + publisher = jid:to_string(From)}; + none -> + EventItem0 + end, + Stanza = #message{ + sub_els = + [#ps_event{items = + #ps_items{node = Node, + items = [EventItem]}}]}, broadcast_stanza(Host, From, Node, Nidx, Type, - NodeOptions, SubsByDepth, items, Stanza, true), + NodeOptions, SubsByDepth, items, Stanza, true), case Removed of [] -> ok; _ -> case get_option(NodeOptions, notify_retract) of true -> - RetractStanza = event_stanza( - [#xmlel{name = <<"items">>, attrs = nodeAttr(Node), - children = [#xmlel{name = <<"retract">>, attrs = itemAttr(RId)} || RId <- Removed]}]), + RetractStanza = #message{ + sub_els = + [#ps_event{ + items = #ps_items{ + node = Node, + retract = Removed}}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, items, RetractStanza, true); @@ -3230,9 +2907,12 @@ broadcast_retract_items(Host, Node, Nidx, Type, NodeOptions, ItemIds, ForceNotif true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> - Stanza = event_stanza( - [#xmlel{name = <<"items">>, attrs = nodeAttr(Node), - children = [#xmlel{name = <<"retract">>, attrs = itemAttr(ItemId)} || ItemId <- ItemIds]}]), + Stanza = #message{ + sub_els = + [#ps_event{ + items = #ps_items{ + node = Node, + retract = ItemIds}}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, items, Stanza, true), {result, true}; @@ -3248,8 +2928,7 @@ broadcast_purge_node(Host, Node, Nidx, Type, NodeOptions) -> true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> - Stanza = event_stanza( - [#xmlel{name = <<"purge">>, attrs = nodeAttr(Node)}]), + Stanza = #message{sub_els = [#ps_event{purge = Node}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; @@ -3267,8 +2946,7 @@ broadcast_removed_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth) -> [] -> {result, false}; _ -> - Stanza = event_stanza( - [#xmlel{name = <<"delete">>, attrs = nodeAttr(Node)}]), + Stanza = #message{sub_els = [#ps_event{delete = {Node, <<>>}}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true} @@ -3280,7 +2958,7 @@ broadcast_removed_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth) -> broadcast_created_node(_, _, _, _, _, []) -> {result, false}; broadcast_created_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth) -> - Stanza = event_stanza([#xmlel{name = <<"create">>, attrs = nodeAttr(Node)}]), + Stanza = #message{sub_els = [#ps_event{create = Node}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, nodes, Stanza, true), {result, true}. @@ -3291,13 +2969,15 @@ broadcast_config_notification(Host, Node, Nidx, Type, NodeOptions, Lang) -> SubsByDepth when is_list(SubsByDepth) -> Content = case get_option(NodeOptions, deliver_payloads) of true -> - [#xmlel{name = <<"x">>, attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}], - children = get_configure_xfields(Type, NodeOptions, Lang, [])}]; + #xdata{type = result, + fields = get_configure_xfields( + Type, NodeOptions, Lang, [])}; false -> - [] + undefined end, - Stanza = event_stanza( - [#xmlel{name = <<"configuration">>, attrs = nodeAttr(Node), children = Content}]), + Stanza = #message{ + sub_els = [#ps_event{ + configuration = {Node, Content}}]}, broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; @@ -3389,8 +3069,9 @@ broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, Nidx, Type, NodeO ejabberd_c2s:broadcast(C2SPid, {pep_message, <<((Node))/binary, "+notify">>}, _Sender = jid:make(LUser, LServer, <<"">>), - _StanzaToSend = add_extended_headers(Stanza, - _ReplyTo = extended_headers([jid:to_string(Publisher)]))); + _StanzaToSend = add_extended_headers( + Stanza, + _ReplyTo = extended_headers([Publisher]))); _ -> ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza]) end; @@ -3456,9 +3137,11 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> {_, JIDSubs} = lists:foldl(DepthsToDeliver, {[], []}, SubsByDepth), JIDSubs. +-spec user_resources(binary(), binary()) -> [binary()]. user_resources(User, Server) -> ejabberd_sm:get_user_resources(User, Server). +-spec user_resource(binary(), binary(), binary()) -> binary(). user_resource(User, Server, <<>>) -> case user_resources(User, Server) of [R | _] -> R; @@ -3468,26 +3151,19 @@ user_resource(_, _, Resource) -> Resource. %%%%%%% Configuration handling - +-spec get_configure(host(), binary(), binary(), jid(), + binary()) -> {error, error()} | {result, pubsub()}. get_configure(Host, ServerHost, Node, From, Lang) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> case node_call(Host, Type, get_affiliation, [Nidx, From]) of {result, owner} -> Groups = ejabberd_hooks:run_fold(roster_groups, ServerHost, [], [ServerHost]), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_OWNER}], - children = - [#xmlel{name = <<"configure">>, - attrs = nodeAttr(Node), - children = - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = - get_configure_xfields(Type, Options, Lang, Groups)}]}]}]}; + Fs = get_configure_xfields(Type, Options, Lang, Groups), + {result, #pubsub_owner{ + configure = + {Node, #xdata{type = form, fields = Fs}}}}; _ -> - {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)} + {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)} end end, case transaction(Host, Node, Action, sync_dirty) of @@ -3495,20 +3171,14 @@ get_configure(Host, ServerHost, Node, From, Lang) -> Other -> Other end. +-spec get_default(host(), binary(), jid(), binary()) -> {result, pubsub()}. get_default(Host, Node, _From, Lang) -> Type = select_type(Host, Host, Node), Options = node_options(Host, Type), - {result, - [#xmlel{name = <<"pubsub">>, - attrs = [{<<"xmlns">>, ?NS_PUBSUB_OWNER}], - children = - [#xmlel{name = <<"default">>, attrs = [], - children = - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"form">>}], - children = get_configure_xfields(Type, Options, Lang, [])}]}]}]}. + Fs = get_configure_xfields(Type, Options, Lang, []), + {result, #pubsub_owner{default = {<<>>, #xdata{type = form, fields = Fs}}}}. +-spec match_option(#pubsub_node{} | [{atom(), any()}], atom(), any()) -> boolean(). match_option(Node, Var, Val) when is_record(Node, pubsub_node) -> match_option(Node#pubsub_node.options, Var, Val); match_option(Options, Var, Val) when is_list(Options) -> @@ -3516,21 +3186,26 @@ match_option(Options, Var, Val) when is_list(Options) -> match_option(_, _, _) -> false. +-spec get_option([{atom(), any()}], atom()) -> any(). get_option([], _) -> false; get_option(Options, Var) -> get_option(Options, Var, false). +-spec get_option([{atom(), any()}], atom(), any()) -> any(). get_option(Options, Var, Def) -> case lists:keysearch(Var, 1, Options) of {value, {_Val, Ret}} -> Ret; _ -> Def end. +-spec node_options(host(), binary()) -> [{atom(), any()}]. node_options(Host, Type) -> case config(Host, default_node_config) of undefined -> node_plugin_options(Host, Type); [] -> node_plugin_options(Host, Type); Config -> Config end. + +-spec node_plugin_options(host(), binary()) -> [{atom(), any()}]. node_plugin_options(Host, Type) -> Module = plugin(Host, Type), case catch Module:options() of @@ -3540,12 +3215,15 @@ node_plugin_options(Host, Type) -> Result -> Result end. + +-spec filter_node_options([{atom(), any()}], [{atom(), any()}]) -> [{atom(), any()}]. filter_node_options(Options, BaseOptions) -> lists:foldl(fun({Key, Val}, Acc) -> DefaultValue = proplists:get_value(Key, Options, Val), [{Key, DefaultValue}|Acc] end, [], BaseOptions). +-spec node_owners_action(host(), binary(), nodeIdx(), [ljid()]) -> [ljid()]. node_owners_action(Host, Type, Nidx, []) -> case gen_mod:db_type(serverhost(Host), ?MODULE) of sql -> @@ -3559,6 +3237,7 @@ node_owners_action(Host, Type, Nidx, []) -> node_owners_action(_Host, _Type, _Nidx, Owners) -> Owners. +-spec node_owners_call(host(), binary(), nodeIdx(), [ljid()]) -> [ljid()]. node_owners_call(Host, Type, Nidx, []) -> case gen_mod:db_type(serverhost(Host), ?MODULE) of sql -> @@ -3583,6 +3262,7 @@ node_owners_call(_Host, _Type, _Nidx, Owners) -> %% @todo In practice, the current data structure means that we cannot manage %% millions of items on a given node. This should be addressed in a new %% version. +-spec max_items(host(), [{atom(), any()}]) -> non_neg_integer(). max_items(Host, Options) -> case get_option(Options, persist_items) of true -> @@ -3625,10 +3305,10 @@ max_items(Host, Options) -> [jid:to_string(O) || O <- Opts])). -define(ALIST_CONFIG_FIELD(Label, Var, Opts), - ?LISTXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (atom_to_binary(get_option(Options, Var), latin1)), - [atom_to_binary(O, latin1) || O <- Opts])). + ?LISTXFIELD(Label, + <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, + (atom_to_binary(get_option(Options, Var), latin1)), + [atom_to_binary(O, latin1) || O <- Opts])). -define(LISTM_CONFIG_FIELD(Label, Var, Opts), ?LISTMXFIELD(Label, @@ -3641,45 +3321,45 @@ max_items(Host, Options) -> get_option(Options, Var, []))). get_configure_xfields(_Type, Options, Lang, Groups) -> - [?XFIELD(<<"hidden">>, <<>>, <<"FORM_TYPE">>, (?NS_PUBSUB_NODE_CONFIG)), - ?BOOL_CONFIG_FIELD(<<"Deliver payloads with event notifications">>, - deliver_payloads), - ?BOOL_CONFIG_FIELD(<<"Deliver event notifications">>, - deliver_notifications), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node configuration changes">>, - notify_config), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node is deleted">>, - notify_delete), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when items are removed from the node">>, - notify_retract), - ?BOOL_CONFIG_FIELD(<<"Persist items to storage">>, - persist_items), - ?STRING_CONFIG_FIELD(<<"A friendly name for the node">>, - title), - ?INTEGER_CONFIG_FIELD(<<"Max # of items to persist">>, - max_items), - ?BOOL_CONFIG_FIELD(<<"Whether to allow subscriptions">>, - subscribe), - ?ALIST_CONFIG_FIELD(<<"Specify the access model">>, - access_model, [open, authorize, presence, roster, whitelist]), - ?LISTM_CONFIG_FIELD(<<"Roster groups allowed to subscribe">>, - roster_groups_allowed, Groups), - ?ALIST_CONFIG_FIELD(<<"Specify the publisher model">>, - publish_model, [publishers, subscribers, open]), - ?BOOL_CONFIG_FIELD(<<"Purge all items when the relevant publisher goes offline">>, - purge_offline), - ?ALIST_CONFIG_FIELD(<<"Specify the event message type">>, - notification_type, [headline, normal]), - ?INTEGER_CONFIG_FIELD(<<"Max payload size in bytes">>, - max_payload_size), - ?ALIST_CONFIG_FIELD(<<"When to send the last published item">>, - send_last_published_item, [never, on_sub, on_sub_and_presence]), - ?BOOL_CONFIG_FIELD(<<"Only deliver notifications to available users">>, - presence_based_delivery), - ?NLIST_CONFIG_FIELD(<<"The collections with which a node is affiliated">>, - collection), - ?ALIST_CONFIG_FIELD(<<"Whether owners or publisher should receive replies to items">>, - itemreply, [none, owner, publisher])]. + [?XFIELD(hidden, <<>>, <<"FORM_TYPE">>, ?NS_PUBSUB_NODE_CONFIG), + ?BOOL_CONFIG_FIELD(<<"Deliver payloads with event notifications">>, + deliver_payloads), + ?BOOL_CONFIG_FIELD(<<"Deliver event notifications">>, + deliver_notifications), + ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node configuration changes">>, + notify_config), + ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node is deleted">>, + notify_delete), + ?BOOL_CONFIG_FIELD(<<"Notify subscribers when items are removed from the node">>, + notify_retract), + ?BOOL_CONFIG_FIELD(<<"Persist items to storage">>, + persist_items), + ?STRING_CONFIG_FIELD(<<"A friendly name for the node">>, + title), + ?INTEGER_CONFIG_FIELD(<<"Max # of items to persist">>, + max_items), + ?BOOL_CONFIG_FIELD(<<"Whether to allow subscriptions">>, + subscribe), + ?ALIST_CONFIG_FIELD(<<"Specify the access model">>, + access_model, [open, authorize, presence, roster, whitelist]), + ?LISTM_CONFIG_FIELD(<<"Roster groups allowed to subscribe">>, + roster_groups_allowed, Groups), + ?ALIST_CONFIG_FIELD(<<"Specify the publisher model">>, + publish_model, [publishers, subscribers, open]), + ?BOOL_CONFIG_FIELD(<<"Purge all items when the relevant publisher goes offline">>, + purge_offline), + ?ALIST_CONFIG_FIELD(<<"Specify the event message type">>, + notification_type, [headline, normal]), + ?INTEGER_CONFIG_FIELD(<<"Max payload size in bytes">>, + max_payload_size), + ?ALIST_CONFIG_FIELD(<<"When to send the last published item">>, + send_last_published_item, [never, on_sub, on_sub_and_presence]), + ?BOOL_CONFIG_FIELD(<<"Only deliver notifications to available users">>, + presence_based_delivery), + ?NLIST_CONFIG_FIELD(<<"The collections with which a node is affiliated">>, + collection), + ?ALIST_CONFIG_FIELD(<<"Whether owners or publisher should receive replies to items">>, + itemreply, [none, owner, publisher])]. %%

    There are several reasons why the node configuration request might fail:

    %%
      @@ -3689,65 +3369,49 @@ get_configure_xfields(_Type, Options, Lang, Groups) -> %%
    • The node has no configuration options.
    • %%
    • The specified node does not exist.
    • %%
    -set_configure(Host, Node, From, Els, Lang) -> - case fxml:remove_cdata(Els) of - [#xmlel{name = <<"x">>} = XEl] -> - case {fxml:get_tag_attr_s(<<"xmlns">>, XEl), fxml:get_tag_attr_s(<<"type">>, XEl)} of - {?NS_XDATA, <<"cancel">>} -> - {result, []}; - {?NS_XDATA, <<"submit">>} -> - Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx} = N) -> - case node_call(Host, Type, get_affiliation, [Nidx, From]) of - {result, owner} -> - case jlib:parse_xdata_submit(XEl) of - invalid -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)}; - XData -> - OldOpts = case Options of - [] -> node_options(Host, Type); - _ -> Options - end, - case set_xoption(Host, XData, OldOpts) of - NewOpts when is_list(NewOpts) -> - case tree_call(Host, - set_node, - [N#pubsub_node{options = NewOpts}]) - of - {result, Nidx} -> {result, ok}; - ok -> {result, ok}; - Err -> Err - end; - Error -> - Error - end - end; - _ -> - Txt = <<"You're not an owner">>, - {error, ?ERRT_FORBIDDEN(Lang, Txt)} - end - end, - case transaction(Host, Node, Action, transaction) of - {result, {TNode, ok}} -> - Nidx = TNode#pubsub_node.id, - Type = TNode#pubsub_node.type, - Options = TNode#pubsub_node.options, - broadcast_config_notification(Host, Node, Nidx, Type, Options, Lang), - {result, []}; - Other -> - Other - end; - _ -> - Txt = <<"Incorrect data form">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} - end; - _ -> - Txt = <<"No data form found">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} +-spec set_configure(host(), binary(), jid(), [{binary(), [binary()]}], + binary()) -> {result, undefined} | {error, error()}. +set_configure(Host, Node, From, Config, Lang) -> + Action = + fun(#pubsub_node{options = Options, type = Type, id = Nidx} = N) -> + case node_call(Host, Type, get_affiliation, [Nidx, From]) of + {result, owner} -> + OldOpts = case Options of + [] -> node_options(Host, Type); + _ -> Options + end, + case set_xoption(Host, Config, OldOpts) of + NewOpts when is_list(NewOpts) -> + case tree_call(Host, + set_node, + [N#pubsub_node{options = NewOpts}]) + of + {result, Nidx} -> {result, ok}; + ok -> {result, ok}; + Err -> Err + end; + Error -> + Error + end; + _ -> + {error, xmpp:err_forbidden( + <<"Owner privileges required">>, Lang)} + end + end, + case transaction(Host, Node, Action, transaction) of + {result, {TNode, ok}} -> + Nidx = TNode#pubsub_node.id, + Type = TNode#pubsub_node.type, + Options = TNode#pubsub_node.options, + broadcast_config_notification(Host, Node, Nidx, Type, Options, Lang), + {result, undefined}; + Other -> + Other end. +-spec add_opt(atom(), any(), [{atom(), any()}]) -> [{atom(), any()}]. add_opt(Key, Value, Opts) -> - [{Key, Value} | lists:keydelete(Key, 1, Opts)]. + lists:keystore(Key, 1, Opts, {Key, Value}). -define(SET_BOOL_XOPT(Opt, Val), BoolVal = case Val of @@ -3761,7 +3425,7 @@ add_opt(Key, Value, Opts) -> error -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}; + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts)) end). @@ -3769,20 +3433,20 @@ add_opt(Key, Value, Opts) -> set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). -define(SET_INTEGER_XOPT(Opt, Val, Min, Max), - case catch jlib:binary_to_integer(Val) of - IVal when is_integer(IVal), IVal >= Min -> - if (Max =:= undefined) orelse (IVal =< Max) -> - set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); - true -> - Txt = <<"Incorrect value of '~s'">>, + case catch jlib:binary_to_integer(Val) of + IVal when is_integer(IVal), IVal >= Min -> + if (Max =:= undefined) orelse (IVal =< Max) -> + set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); + true -> + Txt = <<"Incorrect value of '~s'">>, + ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + end; + _ -> + Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} - end; - _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} - end). + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + end). -define(SET_ALIST_XOPT(Opt, Val, Vals), case lists:member(Val, [atom_to_binary(V, latin1) || V <- Vals]) of @@ -3791,12 +3455,13 @@ add_opt(Key, Value, Opts) -> false -> Txt = <<"Incorrect value of '~s'">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end). -define(SET_LIST_XOPT(Opt, Val), - set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). + set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). +-spec set_xoption(host(), [{binary(), [binary()]}], [{atom(), any()}]) -> [{atom(), any()}]. set_xoption(_Host, [], NewOpts) -> NewOpts; set_xoption(Host, [{<<"FORM_TYPE">>, _} | Opts], NewOpts) -> set_xoption(Host, Opts, NewOpts); @@ -3852,17 +3517,26 @@ set_xoption(Host, [{<<"pubsub#itemreply">>, [Val]} | Opts], NewOpts) -> set_xoption(Host, [_ | Opts], NewOpts) -> set_xoption(Host, Opts, NewOpts). +-spec get_xdata_fields(undefined | xdata()) -> [{binary(), [binary()]}]. +get_xdata_fields(undefined) -> + []; +get_xdata_fields(#xdata{fields = Fs}) -> + [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- Fs]. + +-spec get_max_items_node(host()) -> undefined | non_neg_integer(). get_max_items_node(Host) -> config(Host, max_items_node, undefined). +-spec get_max_subscriptions_node(host()) -> undefined | non_neg_integer(). get_max_subscriptions_node(Host) -> config(Host, max_subscriptions_node, undefined). %%%% last item cache handling - +-spec is_last_item_cache_enabled(host()) -> boolean(). is_last_item_cache_enabled(Host) -> config(Host, last_item_cache, false). +-spec set_cached_item(host(), nodeIdx(), binary(), binary(), [xmlel()]) -> ok. set_cached_item({_, ServerHost, _}, Nidx, ItemId, Publisher, Payload) -> set_cached_item(ServerHost, Nidx, ItemId, Publisher, Payload); set_cached_item(Host, Nidx, ItemId, Publisher, Payload) -> @@ -3873,6 +3547,7 @@ set_cached_item(Host, Nidx, ItemId, Publisher, Payload) -> _ -> ok end. +-spec unset_cached_item(host(), nodeIdx()) -> ok. unset_cached_item({_, ServerHost, _}, Nidx) -> unset_cached_item(ServerHost, Nidx); unset_cached_item(Host, Nidx) -> @@ -3881,9 +3556,7 @@ unset_cached_item(Host, Nidx) -> _ -> ok end. --spec get_cached_item(Host :: mod_pubsub:host(), Nidx :: mod_pubsub:nodeIdx()) -> - undefined | mod_pubsub:pubsubItem(). - +-spec get_cached_item(host(), nodeIdx()) -> undefined | pubsubItem(). get_cached_item({_, ServerHost, _}, Nidx) -> get_cached_item(ServerHost, Nidx); get_cached_item(Host, Nidx) -> @@ -3904,21 +3577,24 @@ get_cached_item(Host, Nidx) -> end. %%%% plugin handling - +-spec host(binary()) -> binary(). host(ServerHost) -> config(ServerHost, host, <<"pubsub.", ServerHost/binary>>). +-spec serverhost(host()) -> binary(). serverhost({_U, ServerHost, _R})-> serverhost(ServerHost); serverhost(Host) -> ejabberd_router:host_of_route(Host). +-spec tree(host()) -> atom(). tree(Host) -> case config(Host, nodetree) of undefined -> tree(Host, ?STDTREE); Tree -> Tree end. +-spec tree(host(), binary() | atom()) -> atom(). tree(_Host, <<"virtual">>) -> nodetree_virtual; % special case, virtual does not use any backend tree(Host, Name) -> @@ -3928,6 +3604,7 @@ tree(Host, Name) -> _ -> Name end. +-spec plugin(host(), binary() | atom()) -> atom(). plugin(Host, Name) -> case gen_mod:db_type(serverhost(Host), ?MODULE) of mnesia -> jlib:binary_to_atom(<<"node_", Name/binary>>); @@ -3935,6 +3612,7 @@ plugin(Host, Name) -> _ -> Name end. +-spec plugins(host()) -> [binary()]. plugins(Host) -> case config(Host, plugins) of undefined -> [?STDNODE]; @@ -3942,6 +3620,9 @@ plugins(Host) -> Plugins -> Plugins end. +-spec subscription_plugin(host()) -> pubsub_subscription | + pubsub_subscription_sql | + none. subscription_plugin(Host) -> case gen_mod:db_type(serverhost(Host), ?MODULE) of mnesia -> pubsub_subscription; @@ -3949,9 +3630,11 @@ subscription_plugin(Host) -> _ -> none end. +-spec config(binary(), any()) -> any(). config(ServerHost, Key) -> config(ServerHost, Key, undefined). +-spec config(host(), any(), any()) -> any(). config({_User, Host, _Resource}, Key, Default) -> config(Host, Key, Default); config(ServerHost, Key, Default) -> @@ -3960,6 +3643,7 @@ config(ServerHost, Key, Default) -> _ -> Default end. +-spec select_type(binary(), host(), binary(), binary()) -> binary(). select_type(ServerHost, Host, Node, Type) -> SelectedType = case Host of {_User, _Server, _Resource} -> @@ -3976,6 +3660,7 @@ select_type(ServerHost, Host, Node, Type) -> false -> hd(ConfiguredTypes) end. +-spec select_type(binary(), host(), binary()) -> binary(). select_type(ServerHost, Host, Node) -> select_type(ServerHost, Host, Node, hd(plugins(Host))). @@ -4005,7 +3690,7 @@ features() -> % see plugin "subscribe", % REQUIRED % see plugin "subscription-options", % OPTIONAL % see plugin "subscription-notifications" % OPTIONAL - +-spec plugin_features(binary(), binary()) -> [binary()]. plugin_features(Host, Type) -> Module = plugin(Host, Type), case catch Module:features() of @@ -4013,6 +3698,7 @@ plugin_features(Host, Type) -> Result -> Result end. +-spec features(binary(), binary()) -> [binary()]. features(Host, <<>>) -> lists:usort(lists:foldl(fun (Plugin, Acc) -> Acc ++ plugin_features(Host, Plugin) @@ -4048,11 +3734,13 @@ tree_action(Host, Function, Args) -> Result; {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), - {error, ?ERR_INTERNAL_SERVER_ERROR} + ErrTxt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(ErrTxt, ?MYLANG)} end; Other -> ?ERROR_MSG("unsupported backend: ~p~n", [Other]), - {error, ?ERR_INTERNAL_SERVER_ERROR} + ErrTxt = <<"Database failure">>, + {error, xmpp:err_internal_server_error(ErrTxt, ?MYLANG)} end. %% @doc

    node plugin call.

    @@ -4108,7 +3796,7 @@ transaction(Host, Fun, Trans) -> transaction_retry(Host, ServerHost, Fun, Trans, DBType, Retry). transaction_retry(_Host, _ServerHost, _Fun, _Trans, _DBType, 0) -> - {error, ?ERR_INTERNAL_SERVER_ERROR}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}; transaction_retry(Host, ServerHost, Fun, Trans, DBType, Count) -> Res = case DBType of mnesia -> @@ -4133,75 +3821,126 @@ transaction_retry(Host, ServerHost, Fun, Trans, DBType, Count) -> {error, Error}; {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), - {error, ?ERR_INTERNAL_SERVER_ERROR}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}; {'EXIT', {timeout, _} = Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [Reason]), transaction_retry(Host, ServerHost, Fun, Trans, DBType, Count - 1); {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), - {error, ?ERR_INTERNAL_SERVER_ERROR}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}; Other -> ?ERROR_MSG("transaction return internal error: ~p~n", [Other]), - {error, ?ERR_INTERNAL_SERVER_ERROR} + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)} end. %%%% helpers %% Add pubsub-specific error element -extended_error(Error, Ext) -> - extended_error(Error, Ext, [{<<"xmlns">>, ?NS_PUBSUB_ERRORS}]). - -extended_error(Error, unsupported, Feature) -> - %% Give a uniq identifier - extended_error(Error, <<"unsupported">>, - [{<<"xmlns">>, ?NS_PUBSUB_ERRORS}, - {<<"feature">>, Feature}]); -extended_error(#xmlel{name = Error, attrs = Attrs, children = SubEls}, Ext, ExtAttrs) -> - #xmlel{name = Error, attrs = Attrs, - children = lists:reverse([#xmlel{name = Ext, attrs = ExtAttrs} | SubEls])}. - -is_item_not_found({error, ErrEl}) -> - case fxml:get_subtag_with_xmlns( - ErrEl, <<"item-not-found">>, ?NS_STANZAS) of - #xmlel{} -> true; - _ -> false - end. +-spec extended_error(error(), ps_error()) -> error(). +extended_error(StanzaErr, PubSubErr) -> + StanzaErr#error{sub_els = [PubSubErr]}. -string_to_ljid(JID) -> - case jid:from_string(JID) of - error -> - {<<>>, <<>>, <<>>}; - J -> - case jid:tolower(J) of - error -> {<<>>, <<>>, <<>>}; - J1 -> J1 - end - end. +-spec err_closed_node() -> ps_error(). +err_closed_node() -> + #ps_error{type = 'closed-node'}. + +-spec err_configuration_required() -> ps_error(). +err_configuration_required() -> + #ps_error{type = 'configuration-required'}. + +-spec err_invalid_jid() -> ps_error(). +err_invalid_jid() -> + #ps_error{type = 'invalid-jid'}. + +-spec err_invalid_options() -> ps_error(). +err_invalid_options() -> + #ps_error{type = 'invalid-options'}. + +-spec err_invalid_payload() -> ps_error(). +err_invalid_payload() -> + #ps_error{type = 'invalid-payload'}. + +-spec err_invalid_subid() -> ps_error(). +err_invalid_subid() -> + #ps_error{type = 'invalid-subid'}. + +-spec err_item_forbidden() -> ps_error(). +err_item_forbidden() -> + #ps_error{type = 'item-forbidden'}. + +-spec err_item_required() -> ps_error(). +err_item_required() -> + #ps_error{type = 'item-required'}. + +-spec err_jid_required() -> ps_error(). +err_jid_required() -> + #ps_error{type = 'jid-required'}. + +-spec err_max_items_exceeded() -> ps_error(). +err_max_items_exceeded() -> + #ps_error{type = 'max-items-exceeded'}. + +-spec err_max_nodes_exceeded() -> ps_error(). +err_max_nodes_exceeded() -> + #ps_error{type = 'max-nodes-exceeded'}. + +-spec err_nodeid_required() -> ps_error(). +err_nodeid_required() -> + #ps_error{type = 'nodeid-required'}. + +-spec err_not_in_roster_group() -> ps_error(). +err_not_in_roster_group() -> + #ps_error{type = 'not-in-roster-group'}. + +-spec err_not_subscribed() -> ps_error(). +err_not_subscribed() -> + #ps_error{type = 'not-subscribed'}. + +-spec err_payload_too_big() -> ps_error(). +err_payload_too_big() -> + #ps_error{type = 'payload-too-big'}. + +-spec err_payload_required() -> ps_error(). +err_payload_required() -> + #ps_error{type = 'payload-required'}. + +-spec err_pending_subscription() -> ps_error(). +err_pending_subscription() -> + #ps_error{type = 'pending-subscription'}. + +-spec err_presence_subscription_required() -> ps_error(). +err_presence_subscription_required() -> + #ps_error{type = 'presence-subscription-required'}. + +-spec err_subid_required() -> ps_error(). +err_subid_required() -> + #ps_error{type = 'subid-required'}. + +-spec err_too_many_subscriptions() -> ps_error(). +err_too_many_subscriptions() -> + #ps_error{type = 'too-many-subscriptions'}. + +-spec err_unsupported(ps_error_feature()) -> ps_error(). +err_unsupported(Feature) -> + #ps_error{type = 'unsupported', feature = Feature}. + +-spec err_unsupported_access_model() -> ps_error(). +err_unsupported_access_model() -> + #ps_error{type = 'unsupported-access-model'}. -spec uniqid() -> mod_pubsub:itemId(). uniqid() -> {T1, T2, T3} = p1_time_compat:timestamp(), iolist_to_binary(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). -nodeAttr(Node) -> [{<<"node">>, Node}]. - -itemAttr([]) -> []; -itemAttr(ItemId) -> [{<<"id">>, ItemId}]. -itemAttr(ItemId, From) -> [{<<"id">>, ItemId}, From]. - +-spec itemsEls([#pubsub_item{}]) -> [ps_item()]. itemsEls(Items) -> - [#xmlel{name = <<"item">>, attrs = itemAttr(ItemId), children = Payload} - || #pubsub_item{itemid = {ItemId, _}, payload = Payload} <- Items]. + [#ps_item{id = ItemId, xml_els = Payload} + || #pubsub_item{itemid = {ItemId, _}, payload = Payload} <- Items]. --spec add_message_type(Message :: xmlel(), Type :: atom()) -> xmlel(). - -add_message_type(Message, normal) -> Message; -add_message_type(#xmlel{name = <<"message">>, attrs = Attrs, children = Els}, Type) -> - #xmlel{name = <<"message">>, - attrs = [{<<"type">>, jlib:atom_to_binary(Type)} | Attrs], - children = Els}; -add_message_type(XmlEl, _Type) -> - XmlEl. +-spec add_message_type(message(), message_type()) -> message(). +add_message_type(#message{} = Message, Type) -> + Message#message{type = Type}. %% Place of changed at the bottom of the stanza %% cf. http://xmpp.org/extensions/xep-0060.html#publisher-publish-success-subid @@ -4209,32 +3948,24 @@ add_message_type(XmlEl, _Type) -> %% "[SHIM Headers] SHOULD be included after the event notification information %% (i.e., as the last child of the stanza)". -add_shim_headers(Stanza, HeaderEls) -> - add_headers(Stanza, <<"headers">>, ?NS_SHIM, HeaderEls). - -add_extended_headers(Stanza, HeaderEls) -> - add_headers(Stanza, <<"addresses">>, ?NS_ADDRESS, HeaderEls). +-spec add_shim_headers(stanza(), [{binary(), binary()}]) -> stanza(). +add_shim_headers(Stanza, Headers) -> + xmpp:set_subtag(Stanza, #shim{headers = Headers}). -add_headers(#xmlel{name = Name, attrs = Attrs, children = Els}, HeaderName, HeaderNS, HeaderEls) -> - HeaderEl = #xmlel{name = HeaderName, - attrs = [{<<"xmlns">>, HeaderNS}], - children = HeaderEls}, - #xmlel{name = Name, attrs = Attrs, - children = lists:append(Els, [HeaderEl])}. +-spec add_extended_headers(stanza(), [address()]) -> stanza(). +add_extended_headers(Stanza, Addrs) -> + xmpp:set_subtag(Stanza, #addresses{list = Addrs}). +-spec subid_shim([binary()]) -> [{binary(), binary()}]. subid_shim(SubIds) -> - [#xmlel{name = <<"header">>, - attrs = [{<<"name">>, <<"SubId">>}], - children = [{xmlcdata, SubId}]} - || SubId <- SubIds]. + [{<<"SubId">>, SubId} || SubId <- SubIds]. %% The argument is a list of Jids because this function could be used %% with the 'pubsub#replyto' (type=jid-multi) node configuration. +-spec extended_headers([jid()]) -> [address()]. extended_headers(Jids) -> - [#xmlel{name = <<"address">>, - attrs = [{<<"type">>, <<"replyto">>}, {<<"jid">>, Jid}]} - || Jid <- Jids]. + [#address{type = replyto, jid = Jid} || Jid <- Jids]. -spec on_user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok. on_user_offline(_, JID, _) -> @@ -4244,6 +3975,7 @@ on_user_offline(_, JID, _) -> _ -> ok end. +-spec purge_offline(ljid()) -> ok. purge_offline(LJID) -> Host = host(element(2, LJID)), Plugins = plugins(Host), @@ -4251,8 +3983,8 @@ purge_offline(LJID) -> Features = plugin_features(Host, Type), case lists:member(<<"retrieve-affiliations">>, plugin_features(Host, Type)) of false -> - {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, - unsupported, <<"retrieve-affiliations">>)}, + {{error, extended_error(xmpp:err_feature_not_implemented(), + err_unsupported('retrieve-affiliations'))}, Acc}; true -> Items = lists:member(<<"retract-items">>, Features) @@ -4286,6 +4018,7 @@ purge_offline(LJID) -> ?DEBUG("on_user_offline ~p", [Error]) end. +-spec purge_offline(host(), ljid(), binary()) -> ok | {error, error()}. purge_offline(Host, LJID, Node) -> Nidx = Node#pubsub_node.id, Type = Node#pubsub_node.type, diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index fa4af4d57..2a468c69a 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -36,7 +36,7 @@ -compile([{parse_transform, ejabberd_sql_pt}]). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_sql_pt.hrl"). -export([init/3, terminate/2, options/0, features/0, @@ -81,27 +81,27 @@ create_node(Nidx, Owner) -> J = encode_jid(OwnerKey), A = encode_affiliation(owner), S = encode_subscriptions([]), - catch ejabberd_sql:sql_query_t( - ?SQL("insert into pubsub_state(" - "nodeid, jid, affiliation, subscriptions) " - "values (%(Nidx)d, %(J)s, %(A)s, %(S)s)")), + ejabberd_sql:sql_query_t( + ?SQL("insert into pubsub_state(" + "nodeid, jid, affiliation, subscriptions) " + "values (%(Nidx)d, %(J)s, %(A)s, %(S)s)")), {result, {default, broadcast}}. delete_node(Nodes) -> - Reply = lists:map(fun (#pubsub_node{id = Nidx} = PubsubNode) -> - Subscriptions = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(jid)s, @(subscriptions)s " - "from pubsub_state where nodeid=%(Nidx)d")) - of - {selected, RItems} -> - [{decode_jid(SJID), decode_subscriptions(Subs)} || - {SJID, Subs} <- RItems]; - _ -> - [] - end, - {PubsubNode, Subscriptions} - end, Nodes), + Reply = lists:map( + fun(#pubsub_node{id = Nidx} = PubsubNode) -> + Subscriptions = + case ejabberd_sql:sql_query_t( + ?SQL("select @(jid)s, @(subscriptions)s " + "from pubsub_state where nodeid=%(Nidx)d")) of + {selected, RItems} -> + [{decode_jid(SJID), decode_subscriptions(Subs)} + || {SJID, Subs} <- RItems]; + _ -> + [] + end, + {PubsubNode, Subscriptions} + end, Nodes), {result, {default, broadcast, Reply}}. subscribe_node(Nidx, Sender, Subscriber, AccessModel, @@ -118,22 +118,25 @@ subscribe_node(Nidx, Sender, Subscriber, AccessModel, Subscriptions), Owner = Affiliation == owner, if not Authorized -> - {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"invalid-jid">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_bad_request(), mod_pubsub:err_invalid_jid())}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; PendingSubscription -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"pending-subscription">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_pending_subscription())}; (AccessModel == presence) and (not PresenceSubscription) and (not Owner) -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and (not RosterGroup) and (not Owner) -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and (not Whitelisted) and (not Owner) -> - {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_allowed(), mod_pubsub:err_closed_node())}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; @@ -177,7 +180,7 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> if %% Requesting entity is prohibited from unsubscribing entity not Authorized -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %% Entity did not specify SubId %%SubId == "", ?? -> %% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; @@ -186,8 +189,9 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; %% Requesting entity is not a subscriber Subscriptions == [] -> - {error, - ?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_unexpected_request(), + mod_pubsub:err_not_subscribed())}; %% Subid supplied, so use that. SubIdExists -> Sub = first_in_list(fun @@ -200,8 +204,9 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> delete_subscription(SubKey, Nidx, S, Affiliation, Subscriptions), {result, default}; false -> - {error, - ?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)} + {error, mod_pubsub:extended_error( + xmpp:err_unexpected_request(), + mod_pubsub:err_not_subscribed())} end; %% Asking to remove all subscriptions to the given node SubId == all -> @@ -214,8 +219,8 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> {result, default}; %% No subid and more than one possible subscription match. true -> - {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)} + {error, mod_pubsub:extended_error( + xmpp:err_bad_request(), mod_pubsub:err_subid_required())} end. delete_subscription(SubKey, Nidx, {Subscription, SubId}, Affiliation, Subscriptions) -> @@ -241,7 +246,7 @@ publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload, or (Affiliation == publisher) or (Affiliation == publish_only)) or (Subscribed == true)) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; true -> if MaxItems > 0 -> PubId = {p1_time_compat:timestamp(), SubKey}, @@ -277,11 +282,11 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> _ -> false end, if not Allowed -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; true -> case del_item(Nidx, ItemId) of {updated, 1} -> {result, {default, broadcast}}; - _ -> {error, ?ERR_ITEM_NOT_FOUND} + _ -> {error, xmpp:err_item_not_found()} end end. @@ -299,7 +304,7 @@ purge_node(Nidx, Owner) -> States), {result, {default, broadcast}}; _ -> - {error, ?ERR_FORBIDDEN} + {error, xmpp:err_forbidden()} end. get_entity_affiliations(Host, Owner) -> @@ -307,48 +312,42 @@ get_entity_affiliations(Host, Owner) -> GenKey = jid:remove_resource(SubKey), H = encode_host(Host), J = encode_jid(GenKey), - Reply = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(node)s, @(type)s, @(i.nodeid)d, @(affiliation)s " - "from pubsub_state i, pubsub_node n where " - "i.nodeid = n.nodeid and jid=%(J)s and host=%(H)s")) - of - {selected, RItems} -> - [{nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), decode_affiliation(A)} - || {N, T, I, A} <- RItems]; - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t( + ?SQL("select @(node)s, @(type)s, @(i.nodeid)d, @(affiliation)s " + "from pubsub_state i, pubsub_node n where " + "i.nodeid = n.nodeid and jid=%(J)s and host=%(H)s")) of + {selected, RItems} -> + [{nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), + decode_affiliation(A)} || {N, T, I, A} <- RItems]; + _ -> + [] + end}. get_node_affiliations(Nidx) -> - Reply = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(jid)s, @(affiliation)s from pubsub_state " - "where nodeid=%(Nidx)d")) - of - {selected, RItems} -> - [{decode_jid(J), decode_affiliation(A)} || {J, A} <- RItems]; - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t( + ?SQL("select @(jid)s, @(affiliation)s from pubsub_state " + "where nodeid=%(Nidx)d")) of + {selected, RItems} -> + [{decode_jid(J), decode_affiliation(A)} || {J, A} <- RItems]; + _ -> + [] + end}. get_affiliation(Nidx, Owner) -> SubKey = jid:tolower(Owner), GenKey = jid:remove_resource(SubKey), J = encode_jid(GenKey), - Reply = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(affiliation)s from pubsub_state " - "where nodeid=%(Nidx)d and jid=%(J)s")) - of - {selected, [{A}]} -> - decode_affiliation(A); - _ -> - none - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t( + ?SQL("select @(affiliation)s from pubsub_state " + "where nodeid=%(Nidx)d and jid=%(J)s")) of + {selected, [{A}]} -> + decode_affiliation(A); + _ -> + none + end}. set_affiliation(Nidx, Owner, Affiliation) -> SubKey = jid:tolower(Owner), @@ -382,26 +381,26 @@ get_entity_subscriptions(Host, Owner) -> "where i.nodeid = n.nodeid and" " jid in (%(SJ)s, %(GJ)s) and host=%(H)s") end, - Reply = case catch ejabberd_sql:sql_query_t(Query) of - {selected, RItems} -> - lists:foldl(fun ({N, T, I, J, S}, Acc) -> - Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), - Jid = decode_jid(J), - case decode_subscriptions(S) of - [] -> - [{Node, none, Jid} | Acc]; - Subs -> - lists:foldl(fun ({Sub, SubId}, Acc2) -> - [{Node, Sub, SubId, Jid} | Acc2] - end, - Acc, Subs) - end - end, - [], RItems); - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t(Query) of + {selected, RItems} -> + lists:foldl( + fun({N, T, I, J, S}, Acc) -> + Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), + Jid = decode_jid(J), + case decode_subscriptions(S) of + [] -> + [{Node, none, Jid} | Acc]; + Subs -> + lists:foldl( + fun({Sub, SubId}, Acc2) -> + [{Node, Sub, SubId, Jid} | Acc2] + end, Acc, Subs) + end + end, [], RItems); + _ -> + [] + end}. -spec get_entity_subscriptions_for_send_last(Host :: mod_pubsub:hostPubsub(), Owner :: jid()) -> @@ -435,66 +434,62 @@ get_entity_subscriptions_for_send_last(Host, Owner) -> "and val='on_sub_and_presence' and" " jid in (%(SJ)s, %(GJ)s) and host=%(H)s") end, - Reply = case catch ejabberd_sql:sql_query_t(Query) of - {selected, RItems} -> - lists:foldl(fun ({N, T, I, J, S}, Acc) -> - Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), - Jid = decode_jid(J), - case decode_subscriptions(S) of - [] -> - [{Node, none, Jid} | Acc]; - Subs -> - lists:foldl(fun ({Sub, SubId}, Acc2) -> - [{Node, Sub, SubId, Jid}| Acc2] - end, - Acc, Subs) - end - end, - [], RItems); - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t(Query) of + {selected, RItems} -> + lists:foldl( + fun ({N, T, I, J, S}, Acc) -> + Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), + Jid = decode_jid(J), + case decode_subscriptions(S) of + [] -> + [{Node, none, Jid} | Acc]; + Subs -> + lists:foldl( + fun ({Sub, SubId}, Acc2) -> + [{Node, Sub, SubId, Jid}| Acc2] + end, Acc, Subs) + end + end, [], RItems); + _ -> + [] + end}. get_node_subscriptions(Nidx) -> - Reply = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(jid)s, @(subscriptions)s from pubsub_state " - "where nodeid=%(Nidx)d")) - of - {selected, RItems} -> - lists:foldl(fun ({J, S}, Acc) -> - Jid = decode_jid(J), - case decode_subscriptions(S) of - [] -> - [{Jid, none} | Acc]; - Subs -> - lists:foldl(fun ({Sub, SubId}, Acc2) -> - [{Jid, Sub, SubId} | Acc2] - end, - Acc, Subs) - end - end, - [], RItems); - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t( + ?SQL("select @(jid)s, @(subscriptions)s from pubsub_state " + "where nodeid=%(Nidx)d")) of + {selected, RItems} -> + lists:foldl( + fun ({J, S}, Acc) -> + Jid = decode_jid(J), + case decode_subscriptions(S) of + [] -> + [{Jid, none} | Acc]; + Subs -> + lists:foldl( + fun ({Sub, SubId}, Acc2) -> + [{Jid, Sub, SubId} | Acc2] + end, Acc, Subs) + end + end, [], RItems); + _ -> + [] + end}. get_subscriptions(Nidx, Owner) -> SubKey = jid:tolower(Owner), J = encode_jid(SubKey), - Reply = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(subscriptions)s from pubsub_state" - " where nodeid=%(Nidx)d and jid=%(J)s")) - of - {selected, [{S}]} -> - decode_subscriptions(S); - _ -> - [] - end, - {result, Reply}. + {result, + case ejabberd_sql:sql_query_t( + ?SQL("select @(subscriptions)s from pubsub_state" + " where nodeid=%(Nidx)d and jid=%(J)s")) of + {selected, [{S}]} -> + decode_subscriptions(S); + _ -> + [] + end}. set_subscriptions(Nidx, Owner, Subscription, SubId) -> SubKey = jid:tolower(Owner), @@ -503,8 +498,9 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) -> {_, []} -> case Subscription of none -> - {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"not-subscribed">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_bad_request(), + mod_pubsub:err_not_subscribed())}; _ -> new_subscription(Nidx, Owner, Subscription, SubState) end; @@ -514,8 +510,9 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) -> _ -> replace_subscription({Subscription, SID}, SubState) end; {<<>>, [_ | _]} -> - {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_bad_request(), + mod_pubsub:err_subid_required())}; _ -> case Subscription of none -> unsub_with_subid(Nidx, SubId, SubState); @@ -585,21 +582,19 @@ get_nodes_helper(NodeTree, #pubsub_state{stateid = {_, N}, subscriptions = Subs} end. get_states(Nidx) -> - case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s " - "from pubsub_state where nodeid=%(Nidx)d")) - of + case ejabberd_sql:sql_query_t( + ?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s " + "from pubsub_state where nodeid=%(Nidx)d")) of {selected, RItems} -> {result, - lists:map(fun ({SJID, Aff, Subs}) -> - JID = decode_jid(SJID), - #pubsub_state{stateid = {JID, Nidx}, - items = itemids(Nidx, JID), - affiliation = decode_affiliation(Aff), - subscriptions = decode_subscriptions(Subs)} - end, - RItems)}; + lists:map( + fun({SJID, Aff, Subs}) -> + JID = decode_jid(SJID), + #pubsub_state{stateid = {JID, Nidx}, + items = itemids(Nidx, JID), + affiliation = decode_affiliation(Aff), + subscriptions = decode_subscriptions(Subs)} + end, RItems)}; _ -> {result, []} end. @@ -614,16 +609,14 @@ get_state(Nidx, JID) -> get_state_without_itemids(Nidx, JID) -> J = encode_jid(JID), - case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s " - "from pubsub_state " - "where nodeid=%(Nidx)d and jid=%(J)s")) - of + case ejabberd_sql:sql_query_t( + ?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s " + "from pubsub_state " + "where nodeid=%(Nidx)d and jid=%(J)s")) of {selected, [{SJID, Aff, Subs}]} -> #pubsub_state{stateid = {decode_jid(SJID), Nidx}, - affiliation = decode_affiliation(Aff), - subscriptions = decode_subscriptions(Subs)}; + affiliation = decode_affiliation(Aff), + subscriptions = decode_subscriptions(Subs)}; _ -> #pubsub_state{stateid = {JID, Nidx}} end. @@ -653,73 +646,60 @@ del_state(Nidx, JID) -> " where jid=%(J)s and nodeid=%(Nidx)d")), ok. -%get_items(Nidx, _From) -> -% case catch -% ejabberd_sql:sql_query_t([<<"select itemid, publisher, creation, modification, payload " -% "from pubsub_item where nodeid='">>, Nidx, -% <<"' order by modification desc;">>]) -% of -% {selected, -% [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} -> -% {result, [raw_to_item(Nidx, RItem) || RItem <- RItems]}; -% _ -> -% {result, []} -% end. - -get_items(Nidx, From, none) -> - MaxItems = case catch - ejabberd_sql:sql_query_t( - ?SQL("select @(val)s from pubsub_node_option " - "where nodeid=%(Nidx)d and name='max_items'")) - of - {selected, [{Value}]} -> - jlib:expr_to_term(Value); - _ -> - ?MAXITEMS - end, - get_items(Nidx, From, #rsm_in{max = MaxItems}); -get_items(Nidx, _From, - #rsm_in{max = M, direction = Direction, id = I, index = IncIndex}) -> - Max = ejabberd_sql:escape(jlib:i2l(M)), - {Way, Order} = case Direction of - aft when I == <<>> -> {<<"is not">>, <<"desc">>}; - aft -> {<<"<">>, <<"desc">>}; - before when I == <<>> -> {<<"is not">>, <<"asc">>}; - before -> {<<">">>, <<"asc">>}; - _ -> {<<"is not">>, <<"desc">>} - end, +get_items(Nidx, From, undefined) -> + MaxItems = case ejabberd_sql:sql_query_t( + ?SQL("select @(val)s from pubsub_node_option " + "where nodeid=%(Nidx)d and name='max_items'")) of + {selected, [{Value}]} -> + jlib:expr_to_term(Value); + _ -> + ?MAXITEMS + end, + get_items(Nidx, From, #rsm_set{max = MaxItems}); +get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex, + 'after' = After, before = Before}) -> + {Way, Order} = if After == <<>> -> {<<"is not">>, <<"desc">>}; + After /= undefined -> {<<"<">>, <<"desc">>}; + Before == <<>> -> {<<"is not">>, <<"asc">>}; + Before /= undefined -> {<<">">>, <<"asc">>}; + true -> {<<"is not">>, <<"desc">>} + end, SNidx = integer_to_binary(Nidx), - [AttrName, Id] = case I of - undefined when IncIndex =/= undefined -> - case catch - ejabberd_sql:sql_query_t([<<"select modification from pubsub_item pi " - "where exists ( select count(*) as count1 " - "from pubsub_item where nodeid='">>, SNidx, + I = if After /= undefined -> After; + Before /= undefined -> Before; + true -> undefined + end, + [AttrName, Id] = + case I of + undefined when IncIndex =/= undefined -> + case ejabberd_sql:sql_query_t( + [<<"select modification from pubsub_item pi " + "where exists ( select count(*) as count1 " + "from pubsub_item where nodeid='">>, SNidx, <<"' and modification > pi.modification having count1 = ">>, - ejabberd_sql:escape(jlib:i2l(IncIndex)), <<" );">>]) - of - {selected, [_], [[O]]} -> - [<<"modification">>, <<"'", O/binary, "'">>]; - _ -> - [<<"modification">>, <<"null">>] - end; - undefined -> - [<<"modification">>, <<"null">>]; - <<>> -> - [<<"modification">>, <<"null">>]; - I -> - [A, B] = str:tokens(ejabberd_sql:escape(jlib:i2l(I)), <<"@">>), - [A, <<"'", B/binary, "'">>] - end, - Count = case catch - ejabberd_sql:sql_query_t([<<"select count(*) from pubsub_item where nodeid='">>, SNidx, <<"';">>]) - of - {selected, [_], [[C]]} -> C; - _ -> <<"0">> - end, + IncIndex, <<" );">>]) of + {selected, [_], [[O]]} -> + [<<"modification">>, <<"'", O/binary, "'">>]; + _ -> + [<<"modification">>, <<"null">>] + end; + undefined -> + [<<"modification">>, <<"null">>]; + <<>> -> + [<<"modification">>, <<"null">>]; + I -> + [A, B] = str:tokens(ejabberd_sql:escape(I), <<"@">>), + [A, <<"'", B/binary, "'">>] + end, + Count = case ejabberd_sql:sql_query_t( + [<<"select count(*) from pubsub_item where nodeid='">>, + SNidx, <<"';">>]) of + {selected, [_], [[C]]} -> binary_to_integer(C); + _ -> 0 + end, Query = fun(mssql, _) -> ejabberd_sql:sql_query_t( - [<<"select top ">>, jlib:i2l(Max), + [<<"select top ">>, Max, <<" itemid, publisher, creation, modification, payload " "from pubsub_item where nodeid='">>, SNidx, <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>, @@ -729,32 +709,33 @@ get_items(Nidx, _From, [<<"select itemid, publisher, creation, modification, payload " "from pubsub_item where nodeid='">>, SNidx, <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>, - AttrName, <<" ">>, Order, <<" limit ">>, jlib:i2l(Max), <<" ;">>]) + AttrName, <<" ">>, Order, <<" limit ">>, Max, <<" ;">>]) end, - case catch ejabberd_sql:sql_query_t(Query) of - {selected, - [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} -> + case ejabberd_sql:sql_query_t(Query) of + {selected, [<<"itemid">>, <<"publisher">>, <<"creation">>, + <<"modification">>, <<"payload">>], RItems} -> case RItems of [[_, _, _, F, _]|_] -> - Index = case catch - ejabberd_sql:sql_query_t([<<"select count(*) from pubsub_item " - "where nodeid='">>, SNidx, <<"' and ">>, - AttrName, <<" > '">>, F, <<"';">>]) - of - %{selected, [_], [{C}, {In}]} -> [string:strip(C, both, $"), string:strip(In, both, $")]; - {selected, [_], [[In]]} -> In; - _ -> <<"0">> - end, + Index = case catch ejabberd_sql:sql_query_t( + [<<"select count(*) from pubsub_item " + "where nodeid='">>, SNidx, <<"' and ">>, + AttrName, <<" > '">>, F, <<"';">>]) of + {selected, [_], [[In]]} -> binary_to_integer(In); + _ -> 0 + end, [_, _, _, L, _] = lists:last(RItems), - RsmOut = #rsm_out{count = Count, index = Index, - first = <<"modification@", F/binary>>, - last = <<"modification@", (jlib:i2l(L))/binary>>}, + RsmOut = #rsm_set{count = Count, + index = Index, + first = #rsm_first{ + index = Index, + data = <<"modification@", F/binary>>}, + last = <<"modification@", L/binary>>}, {result, {[raw_to_item(Nidx, RItem) || RItem <- RItems], RsmOut}}; [] -> - {result, {[], #rsm_out{count = Count}}} + {result, {[], #rsm_set{count = Count}}} end; _ -> - {result, {[], none}} + {result, {[], undefined}} end. get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) -> @@ -769,18 +750,20 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; (AccessModel == presence) and not PresenceSubscription -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and not RosterGroup -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and not Whitelisted -> - {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_allowed(), mod_pubsub:err_closed_node())}; (AccessModel == authorize) and not Whitelisted -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; @@ -820,9 +803,9 @@ get_item(Nidx, ItemId) -> {selected, [RItem]} -> {result, raw_to_item(Nidx, RItem)}; {selected, []} -> - {error, ?ERR_ITEM_NOT_FOUND}; + {error, xmpp:err_item_not_found()}; {'EXIT', _} -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)} + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)} end. get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> @@ -837,18 +820,20 @@ get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _Sub %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; (AccessModel == presence) and not PresenceSubscription -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and not RosterGroup -> - {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_authorized(), + mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and not Whitelisted -> - {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_allowed(), mod_pubsub:err_closed_node())}; (AccessModel == authorize) and not Whitelisted -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; diff --git a/src/xmpp.erl b/src/xmpp.erl index 8dbc49532..10872b341 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -10,7 +10,7 @@ %% API -export([make_iq_result/1, make_iq_result/2, make_error/2, - decode/1, decode/2, decode_tags_by_ns/2, encode/1, + decode/1, decode/2, encode/1, get_type/1, get_to/1, get_from/1, get_id/1, get_lang/1, get_error/1, get_els/1, get_ns/1, set_type/2, set_to/2, set_from/2, set_id/2, @@ -252,6 +252,10 @@ decode(Pkt, _Opts) -> decode_els(Stanza) -> decode_els(Stanza, fun xmpp_codec:is_known_tag/1). +-type match_fun() :: fun((xmlel()) -> boolean()). +-spec decode_els(iq(), match_fun()) -> iq(); + (message(), match_fun()) -> message(); + (presence(), match_fun()) -> presence(). decode_els(Stanza, MatchFun) -> Els = lists:map( fun(#xmlel{} = El) -> @@ -268,10 +272,6 @@ decode_els(Stanza, MatchFun) -> encode(Pkt) -> xmpp_codec:encode(Pkt). --spec decode_tags_by_ns([xmpp_element() | xmlel()], [binary()]) -> [xmpp_element()]. -decode_tags_by_ns(Els, NSList) -> - [xmpp_codec:decode(El) || El <- Els, lists:member(get_ns(El), NSList)]. - format_error(Reason) -> xmpp_codec:format_error(Reason). diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index afe6ff1ad..135a2acbb 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -520,10 +520,166 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> decode_shim_header(<<"http://jabber.org/protocol/shim">>, IgnoreEls, _el); + {<<"unsupported-access-model">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_unsupported_access_model(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"unsupported">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_unsupported(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"too-many-subscriptions">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_too_many_subscriptions(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"subid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_subid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"presence-subscription-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_presence_subscription_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"pending-subscription">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_pending_subscription(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"payload-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_payload_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"payload-too-big">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_payload_too_big(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"not-subscribed">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_not_subscribed(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"not-in-roster-group">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_not_in_roster_group(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"nodeid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_nodeid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"max-nodes-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_max_nodes_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"max-items-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_max_items_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"jid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_jid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"item-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_item_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"item-forbidden">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_item_forbidden(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-subid">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_invalid_subid(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-payload">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_invalid_payload(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-options">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_invalid_options(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-jid">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_invalid_jid(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"configuration-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_configuration_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"closed-node">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + decode_pubsub_error_closed_node(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_owner(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"default">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"default">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"publish-options">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"configure">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"configure">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"create">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"create">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, @@ -544,6 +700,10 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); + {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); {<<"affiliations">>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, @@ -552,29 +712,41 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); + {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); {<<"event">>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); + {<<"items">>, + <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); {<<"items">>, <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_event_items(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); {<<"item">>, <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_event_item(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); + decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); {<<"retract">>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"items">>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); + {<<"configuration">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); {<<"affiliation">>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, @@ -583,6 +755,14 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); {<<"x">>, <<"jabber:x:data">>} -> decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); {<<"item">>, <<"jabber:x:data">>} -> @@ -1654,9 +1834,126 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> true; {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> true; + {<<"unsupported-access-model">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"unsupported">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"too-many-subscriptions">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"subid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"presence-subscription-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"pending-subscription">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"payload-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"payload-too-big">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"not-subscribed">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"not-in-roster-group">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"nodeid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"max-nodes-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"max-items-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"jid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"item-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"item-forbidden">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"invalid-subid">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"invalid-payload">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"invalid-options">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"invalid-jid">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"configuration-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"closed-node">>, + <<"http://jabber.org/protocol/pubsub#errors">>} -> + true; + {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>} -> true; + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; + {<<"default">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"default">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"publish-options">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"configure">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"configure">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"create">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; + {<<"create">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>} -> true; @@ -1672,28 +1969,40 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"subscribe">>, <<"http://jabber.org/protocol/pubsub">>} -> true; + {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; {<<"affiliations">>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscriptions">>, <<"http://jabber.org/protocol/pubsub">>} -> true; + {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; {<<"event">>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; + {<<"items">>, + <<"http://jabber.org/protocol/pubsub">>} -> + true; {<<"items">>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + true; {<<"item">>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; {<<"retract">>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"items">>, - <<"http://jabber.org/protocol/pubsub">>} -> + {<<"configuration">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"affiliation">>, <<"http://jabber.org/protocol/pubsub">>} -> @@ -1701,6 +2010,12 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"subscription">>, <<"http://jabber.org/protocol/pubsub">>} -> true; + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#owner">>} -> + true; + {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#event">>} -> + true; {<<"x">>, <<"jabber:x:data">>} -> true; {<<"item">>, <<"jabber:x:data">>} -> true; {<<"reported">>, <<"jabber:x:data">>} -> true; @@ -2410,59 +2725,162 @@ encode({xdata_field, _, _, _, _, _, _, _, _} = Field) -> [{<<"xmlns">>, <<"jabber:x:data">>}]); encode({xdata, _, _, _, _, _, _} = X) -> encode_xdata(X, [{<<"xmlns">>, <<"jabber:x:data">>}]); -encode({pubsub_subscription, _, _, _, _} = +encode({ps_subscription, _, _, _, _, _, _} = Subscription) -> - encode_pubsub_subscription(Subscription, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_affiliation, _, _} = Affiliation) -> - encode_pubsub_affiliation(Affiliation, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_item, _, _} = Item) -> - encode_pubsub_item(Item, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_items, _, _, _, _} = Items) -> - encode_pubsub_items(Items, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_event_item, _, _, _, _} = Item) -> - encode_pubsub_event_item(Item, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#event">>}]); -encode({pubsub_event_items, _, _, _} = Items) -> - encode_pubsub_event_items(Items, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#event">>}]); -encode({pubsub_event, _} = Event) -> + encode_pubsub_subscription(Subscription, []); +encode({ps_affiliation, + <<"http://jabber.org/protocol/pubsub">>, _, _, _} = + Affiliation) -> + encode_pubsub_affiliation(Affiliation, []); +encode({ps_affiliation, + <<"http://jabber.org/protocol/pubsub#owner">>, _, _, + _} = + Affiliation) -> + encode_pubsub_owner_affiliation(Affiliation, []); +encode({ps_item, _, _, _, _, _} = Item) -> + encode_pubsub_item(Item, []); +encode({ps_items, _, _, _, _, _, _} = Items) -> + encode_pubsub_items(Items, []); +encode({ps_event, _, _, _, _, _, _} = Event) -> encode_pubsub_event(Event, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub#event">>}]); -encode({pubsub_subscribe, _, _} = Subscribe) -> +encode({ps_subscribe, _, _} = Subscribe) -> encode_pubsub_subscribe(Subscribe, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_unsubscribe, _, _, _} = Unsubscribe) -> +encode({ps_unsubscribe, _, _, _} = Unsubscribe) -> encode_pubsub_unsubscribe(Unsubscribe, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_publish, _, _} = Publish) -> +encode({ps_publish, _, _} = Publish) -> encode_pubsub_publish(Publish, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_options, _, _, _, _} = Options) -> +encode({ps_options, _, _, _, _} = Options) -> encode_pubsub_options(Options, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_retract, _, _, _} = Retract) -> +encode({ps_retract, _, _, _} = Retract) -> encode_pubsub_retract(Retract, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub, _, _, _, _, _, _, _, _} = Pubsub) -> +encode({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _} = + Pubsub) -> encode_pubsub(Pubsub, [{<<"xmlns">>, <<"http://jabber.org/protocol/pubsub">>}]); +encode({pubsub_owner, _, _, _, _, _, _} = Pubsub) -> + encode_pubsub_owner(Pubsub, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#owner">>}]); +encode({ps_error, 'closed-node', _} = Closed_node) -> + encode_pubsub_error_closed_node(Closed_node, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'configuration-required', _} = + Configuration_required) -> + encode_pubsub_error_configuration_required(Configuration_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'invalid-jid', _} = Invalid_jid) -> + encode_pubsub_error_invalid_jid(Invalid_jid, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'invalid-options', _} = + Invalid_options) -> + encode_pubsub_error_invalid_options(Invalid_options, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'invalid-payload', _} = + Invalid_payload) -> + encode_pubsub_error_invalid_payload(Invalid_payload, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'invalid-subid', _} = + Invalid_subid) -> + encode_pubsub_error_invalid_subid(Invalid_subid, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'item-forbidden', _} = + Item_forbidden) -> + encode_pubsub_error_item_forbidden(Item_forbidden, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'item-required', _} = + Item_required) -> + encode_pubsub_error_item_required(Item_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'jid-required', _} = Jid_required) -> + encode_pubsub_error_jid_required(Jid_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'max-items-exceeded', _} = + Max_items_exceeded) -> + encode_pubsub_error_max_items_exceeded(Max_items_exceeded, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'max-nodes-exceeded', _} = + Max_nodes_exceeded) -> + encode_pubsub_error_max_nodes_exceeded(Max_nodes_exceeded, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'nodeid-required', _} = + Nodeid_required) -> + encode_pubsub_error_nodeid_required(Nodeid_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'not-in-roster-group', _} = + Not_in_roster_group) -> + encode_pubsub_error_not_in_roster_group(Not_in_roster_group, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'not-subscribed', _} = + Not_subscribed) -> + encode_pubsub_error_not_subscribed(Not_subscribed, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'payload-too-big', _} = + Payload_too_big) -> + encode_pubsub_error_payload_too_big(Payload_too_big, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'payload-required', _} = + Payload_required) -> + encode_pubsub_error_payload_required(Payload_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'pending-subscription', _} = + Pending_subscription) -> + encode_pubsub_error_pending_subscription(Pending_subscription, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'presence-subscription-required', _} = + Presence_subscription_required) -> + encode_pubsub_error_presence_subscription_required(Presence_subscription_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'subid-required', _} = + Subid_required) -> + encode_pubsub_error_subid_required(Subid_required, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'too-many-subscriptions', _} = + Too_many_subscriptions) -> + encode_pubsub_error_too_many_subscriptions(Too_many_subscriptions, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, unsupported, _} = Unsupported) -> + encode_pubsub_error_unsupported(Unsupported, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); +encode({ps_error, 'unsupported-access-model', _} = + Unsupported_access_model) -> + encode_pubsub_error_unsupported_access_model(Unsupported_access_model, + [{<<"xmlns">>, + <<"http://jabber.org/protocol/pubsub#errors">>}]); encode({shim, _} = Headers) -> encode_shim_headers(Headers, [{<<"xmlns">>, <<"http://jabber.org/protocol/shim">>}]); @@ -2581,7 +2999,7 @@ encode({carbons_received, _} = Received) -> encode({carbons_sent, _} = Sent) -> encode_carbons_sent(Sent, [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({feature_csi, _} = Csi) -> +encode({feature_csi, <<"urn:xmpp:csi:0">>} = Csi) -> encode_feature_csi(Csi, []); encode({csi, active} = Active) -> encode_csi_active(Active, @@ -2717,478 +3135,565 @@ encode({thumbnail, _, _, _, _} = Thumbnail) -> encode_thumbnail(Thumbnail, [{<<"xmlns">>, <<"urn:xmpp:thumbs:1">>}]). -get_name({last, _, _}) -> <<"query">>; -get_name({version, _, _, _}) -> <<"query">>; -get_name({roster_item, _, _, _, _, _}) -> <<"item">>; -get_name({roster_query, _, _}) -> <<"query">>; -get_name({rosterver_feature}) -> <<"ver">>; -get_name({privacy_item, _, _, _, _, _, _, _, _}) -> - <<"item">>; -get_name({privacy_list, _, _}) -> <<"list">>; -get_name({privacy_query, _, _, _}) -> <<"query">>; +get_name({address, _, _, _, _, _}) -> <<"address">>; +get_name({addresses, _}) -> <<"addresses">>; +get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>; +get_name({adhoc_command, _, _, _, _, _, _, _, _}) -> + <<"command">>; +get_name({adhoc_note, _, _}) -> <<"note">>; +get_name({bind, _, _}) -> <<"bind">>; get_name({block, _}) -> <<"block">>; -get_name({unblock, _}) -> <<"unblock">>; get_name({block_list, _}) -> <<"blocklist">>; -get_name({identity, _, _, _, _}) -> <<"identity">>; -get_name({disco_info, _, _, _, _}) -> <<"query">>; -get_name({disco_item, _, _, _}) -> <<"item">>; -get_name({disco_items, _, _, _}) -> <<"query">>; -get_name({private, _}) -> <<"query">>; +get_name({bob_data, _, _, _, _}) -> <<"data">>; get_name({bookmark_conference, _, _, _, _, _}) -> <<"conference">>; -get_name({bookmark_url, _, _}) -> <<"url">>; get_name({bookmark_storage, _, _}) -> <<"storage">>; -get_name({stat_error, _, _}) -> <<"error">>; -get_name({stat, _, _, _, _}) -> <<"stat">>; -get_name({stats, _, _}) -> <<"query">>; -get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; -get_name({message, _, _, _, _, _, _, _, _, _}) -> - <<"message">>; -get_name({presence, _, _, _, _, _, _, _, _, _}) -> - <<"presence">>; -get_name({gone, _}) -> <<"gone">>; -get_name({redirect, _}) -> <<"redirect">>; -get_name({error, _, _, _, _, _, _}) -> <<"error">>; -get_name({bind, _, _}) -> <<"bind">>; -get_name({legacy_auth, _, _, _, _}) -> <<"query">>; -get_name({sasl_auth, _, _}) -> <<"auth">>; -get_name({sasl_abort}) -> <<"abort">>; -get_name({sasl_challenge, _}) -> <<"challenge">>; -get_name({sasl_response, _}) -> <<"response">>; -get_name({sasl_success, _}) -> <<"success">>; -get_name({sasl_failure, _, _}) -> <<"failure">>; -get_name({sasl_mechanisms, _}) -> <<"mechanisms">>; -get_name({starttls, _}) -> <<"starttls">>; -get_name({starttls_proceed}) -> <<"proceed">>; -get_name({starttls_failure}) -> <<"failure">>; -get_name({compress_failure, _}) -> <<"failure">>; +get_name({bookmark_url, _, _}) -> <<"url">>; +get_name({bytestreams, _, _, _, _, _, _}) -> + <<"query">>; +get_name({caps, _, _, _, _}) -> <<"c">>; +get_name({carbons_disable}) -> <<"disable">>; +get_name({carbons_enable}) -> <<"enable">>; +get_name({carbons_private}) -> <<"private">>; +get_name({carbons_received, _}) -> <<"received">>; +get_name({carbons_sent, _}) -> <<"sent">>; +get_name({chatstate, active}) -> <<"active">>; +get_name({chatstate, composing}) -> <<"composing">>; +get_name({chatstate, gone}) -> <<"gone">>; +get_name({chatstate, inactive}) -> <<"inactive">>; +get_name({chatstate, paused}) -> <<"paused">>; +get_name({client_id, _}) -> <<"client-id">>; get_name({compress, _}) -> <<"compress">>; +get_name({compress_failure, _}) -> <<"failure">>; get_name({compressed}) -> <<"compressed">>; get_name({compression, _}) -> <<"compression">>; -get_name({stream_features, _}) -> <<"stream:features">>; -get_name({p1_push}) -> <<"push">>; -get_name({p1_rebind}) -> <<"rebind">>; -get_name({p1_ack}) -> <<"ack">>; -get_name({caps, _, _, _, _}) -> <<"c">>; +get_name({csi, active}) -> <<"active">>; +get_name({csi, inactive}) -> <<"inactive">>; +get_name({db_result, _, _, _, _, _}) -> <<"db:result">>; +get_name({db_verify, _, _, _, _, _, _}) -> + <<"db:verify">>; +get_name({delay, _, _, _}) -> <<"delay">>; +get_name({disco_info, _, _, _, _}) -> <<"query">>; +get_name({disco_item, _, _, _}) -> <<"item">>; +get_name({disco_items, _, _, _}) -> <<"query">>; +get_name({error, _, _, _, _, _, _}) -> <<"error">>; +get_name({expire, _, _}) -> <<"x">>; +get_name({feature_csi, _}) -> <<"csi">>; get_name({feature_register}) -> <<"register">>; +get_name({feature_sm, _}) -> <<"sm">>; +get_name({forwarded, _, _}) -> <<"forwarded">>; +get_name({gone, _}) -> <<"gone">>; +get_name({handshake, _}) -> <<"handshake">>; +get_name({hint, 'no-copy'}) -> <<"no-copy">>; +get_name({hint, 'no-permanent-storage'}) -> + <<"no-permanent-storage">>; +get_name({hint, 'no-permanent-store'}) -> + <<"no-permanent-store">>; +get_name({hint, 'no-storage'}) -> <<"no-storage">>; +get_name({hint, 'no-store'}) -> <<"no-store">>; +get_name({hint, store}) -> <<"store">>; +get_name({identity, _, _, _, _}) -> <<"identity">>; +get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; +get_name({last, _, _}) -> <<"query">>; +get_name({legacy_auth, _, _, _, _}) -> <<"query">>; +get_name({mam_archived, _, _}) -> <<"archived">>; +get_name({mam_fin, _, _, _, _}) -> <<"fin">>; +get_name({mam_prefs, _, _, _, _}) -> <<"prefs">>; +get_name({mam_query, _, _, _, _, _, _, _, _}) -> + <<"query">>; +get_name({mam_result, _, _, _, _}) -> <<"result">>; +get_name({media, _, _, _}) -> <<"media">>; +get_name({media_uri, _, _}) -> <<"uri">>; +get_name({message, _, _, _, _, _, _, _, _, _}) -> + <<"message">>; +get_name({mix_join, _, _}) -> <<"join">>; +get_name({mix_leave}) -> <<"leave">>; +get_name({mix_participant, _, _}) -> <<"participant">>; +get_name({muc, _, _}) -> <<"x">>; +get_name({muc_actor, _, _}) -> <<"actor">>; +get_name({muc_admin, _}) -> <<"query">>; +get_name({muc_decline, _, _, _}) -> <<"decline">>; +get_name({muc_destroy, _, _, _, _}) -> <<"destroy">>; +get_name({muc_history, _, _, _, _}) -> <<"history">>; +get_name({muc_invite, _, _, _, _}) -> <<"invite">>; +get_name({muc_item, _, _, _, _, _, _, _}) -> <<"item">>; +get_name({muc_owner, _, _, _}) -> <<"query">>; +get_name({muc_subscribe, _, _}) -> <<"subscribe">>; +get_name({muc_subscriptions, _}) -> <<"subscriptions">>; +get_name({muc_unique, _}) -> <<"unique">>; +get_name({muc_unsubscribe}) -> <<"unsubscribe">>; +get_name({muc_user, _, _, _, _, _, _}) -> <<"x">>; +get_name({nick, _}) -> <<"nick">>; +get_name({offline, _, _, _}) -> <<"offline">>; +get_name({offline_item, _, _}) -> <<"item">>; +get_name({oob_x, _, _, _}) -> <<"x">>; +get_name({p1_ack}) -> <<"ack">>; +get_name({p1_push}) -> <<"push">>; +get_name({p1_rebind}) -> <<"rebind">>; +get_name({ping}) -> <<"ping">>; +get_name({presence, _, _, _, _, _, _, _, _, _}) -> + <<"presence">>; +get_name({privacy_item, _, _, _, _, _, _, _, _}) -> + <<"item">>; +get_name({privacy_list, _, _}) -> <<"list">>; +get_name({privacy_query, _, _, _}) -> <<"query">>; +get_name({private, _}) -> <<"query">>; +get_name({ps_affiliation, _, _, _, _}) -> + <<"affiliation">>; +get_name({ps_error, 'closed-node', _}) -> + <<"closed-node">>; +get_name({ps_error, 'configuration-required', _}) -> + <<"configuration-required">>; +get_name({ps_error, 'invalid-jid', _}) -> + <<"invalid-jid">>; +get_name({ps_error, 'invalid-options', _}) -> + <<"invalid-options">>; +get_name({ps_error, 'invalid-payload', _}) -> + <<"invalid-payload">>; +get_name({ps_error, 'invalid-subid', _}) -> + <<"invalid-subid">>; +get_name({ps_error, 'item-forbidden', _}) -> + <<"item-forbidden">>; +get_name({ps_error, 'item-required', _}) -> + <<"item-required">>; +get_name({ps_error, 'jid-required', _}) -> + <<"jid-required">>; +get_name({ps_error, 'max-items-exceeded', _}) -> + <<"max-items-exceeded">>; +get_name({ps_error, 'max-nodes-exceeded', _}) -> + <<"max-nodes-exceeded">>; +get_name({ps_error, 'nodeid-required', _}) -> + <<"nodeid-required">>; +get_name({ps_error, 'not-in-roster-group', _}) -> + <<"not-in-roster-group">>; +get_name({ps_error, 'not-subscribed', _}) -> + <<"not-subscribed">>; +get_name({ps_error, 'payload-required', _}) -> + <<"payload-required">>; +get_name({ps_error, 'payload-too-big', _}) -> + <<"payload-too-big">>; +get_name({ps_error, 'pending-subscription', _}) -> + <<"pending-subscription">>; +get_name({ps_error, 'presence-subscription-required', + _}) -> + <<"presence-subscription-required">>; +get_name({ps_error, 'subid-required', _}) -> + <<"subid-required">>; +get_name({ps_error, 'too-many-subscriptions', _}) -> + <<"too-many-subscriptions">>; +get_name({ps_error, unsupported, _}) -> + <<"unsupported">>; +get_name({ps_error, 'unsupported-access-model', _}) -> + <<"unsupported-access-model">>; +get_name({ps_event, _, _, _, _, _, _}) -> <<"event">>; +get_name({ps_item, _, _, _, _, _}) -> <<"item">>; +get_name({ps_items, _, _, _, _, _, _}) -> <<"items">>; +get_name({ps_options, _, _, _, _}) -> <<"options">>; +get_name({ps_publish, _, _}) -> <<"publish">>; +get_name({ps_retract, _, _, _}) -> <<"retract">>; +get_name({ps_subscribe, _, _}) -> <<"subscribe">>; +get_name({ps_subscription, _, _, _, _, _, _}) -> + <<"subscription">>; +get_name({ps_unsubscribe, _, _, _}) -> + <<"unsubscribe">>; +get_name({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _}) -> + <<"pubsub">>; +get_name({pubsub_owner, _, _, _, _, _, _}) -> + <<"pubsub">>; +get_name({redirect, _}) -> <<"redirect">>; get_name({register, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"query">>; -get_name({xmpp_session, _}) -> <<"session">>; -get_name({ping}) -> <<"ping">>; -get_name({time, _, _}) -> <<"time">>; -get_name({text, _, _}) -> <<"text">>; +get_name({roster_item, _, _, _, _, _}) -> <<"item">>; +get_name({roster_query, _, _}) -> <<"query">>; +get_name({rosterver_feature}) -> <<"ver">>; +get_name({rsm_first, _, _}) -> <<"first">>; +get_name({rsm_set, _, _, _, _, _, _, _}) -> <<"set">>; +get_name({sasl_abort}) -> <<"abort">>; +get_name({sasl_auth, _, _}) -> <<"auth">>; +get_name({sasl_challenge, _}) -> <<"challenge">>; +get_name({sasl_failure, _, _}) -> <<"failure">>; +get_name({sasl_mechanisms, _}) -> <<"mechanisms">>; +get_name({sasl_response, _}) -> <<"response">>; +get_name({sasl_success, _}) -> <<"success">>; +get_name({search, _, _, _, _, _, _, _}) -> <<"query">>; +get_name({search_item, _, _, _, _, _}) -> <<"item">>; get_name({'see-other-host', _}) -> <<"see-other-host">>; +get_name({shim, _}) -> <<"headers">>; +get_name({sic, _, _, _}) -> <<"address">>; +get_name({sm_a, _, _}) -> <<"a">>; +get_name({sm_enable, _, _, _}) -> <<"enable">>; +get_name({sm_enabled, _, _, _, _, _}) -> <<"enabled">>; +get_name({sm_failed, _, _, _}) -> <<"failed">>; +get_name({sm_r, _}) -> <<"r">>; +get_name({sm_resume, _, _, _}) -> <<"resume">>; +get_name({sm_resumed, _, _, _}) -> <<"resumed">>; +get_name({stanza_id, _, _}) -> <<"stanza-id">>; +get_name({starttls, _}) -> <<"starttls">>; +get_name({starttls_failure}) -> <<"failure">>; +get_name({starttls_proceed}) -> <<"proceed">>; +get_name({stat, _, _, _, _}) -> <<"stat">>; +get_name({stat_error, _, _}) -> <<"error">>; +get_name({stats, _, _}) -> <<"query">>; get_name({stream_error, _, _}) -> <<"stream:error">>; -get_name({vcard_name, _, _, _, _, _}) -> <<"N">>; +get_name({stream_features, _}) -> <<"stream:features">>; +get_name({stream_start, _, _, _, _, _, _, _, _}) -> + <<"stream:stream">>; +get_name({streamhost, _, _, _}) -> <<"streamhost">>; +get_name({text, _, _}) -> <<"text">>; +get_name({thumbnail, _, _, _, _}) -> <<"thumbnail">>; +get_name({time, _, _}) -> <<"time">>; +get_name({unblock, _}) -> <<"unblock">>; +get_name({upload_request, _, _, _, _}) -> <<"request">>; +get_name({upload_slot, _, _, _}) -> <<"slot">>; get_name({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"ADR">>; -get_name({vcard_label, _, _, _, _, _, _, _, _}) -> - <<"LABEL">>; -get_name({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"TEL">>; get_name({vcard_email, _, _, _, _, _, _}) -> <<"EMAIL">>; get_name({vcard_geo, _, _}) -> <<"GEO">>; +get_name({vcard_key, _, _}) -> <<"KEY">>; +get_name({vcard_label, _, _, _, _, _, _, _, _}) -> + <<"LABEL">>; get_name({vcard_logo, _, _, _}) -> <<"LOGO">>; -get_name({vcard_photo, _, _, _}) -> <<"PHOTO">>; +get_name({vcard_name, _, _, _, _, _}) -> <<"N">>; get_name({vcard_org, _, _}) -> <<"ORG">>; +get_name({vcard_photo, _, _, _}) -> <<"PHOTO">>; get_name({vcard_sound, _, _, _}) -> <<"SOUND">>; -get_name({vcard_key, _, _}) -> <<"KEY">>; +get_name({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"TEL">>; get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"vCard">>; get_name({vcard_xupdate, _, _}) -> <<"x">>; -get_name({xdata_option, _, _}) -> <<"option">>; +get_name({version, _, _, _}) -> <<"query">>; +get_name({x_conference, _, _, _, _, _}) -> <<"x">>; +get_name({xcaptcha, _}) -> <<"captcha">>; +get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; get_name({xdata_field, _, _, _, _, _, _, _, _}) -> <<"field">>; -get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; -get_name({pubsub_subscription, _, _, _, _}) -> - <<"subscription">>; -get_name({pubsub_affiliation, _, _}) -> - <<"affiliation">>; -get_name({pubsub_item, _, _}) -> <<"item">>; -get_name({pubsub_items, _, _, _, _}) -> <<"items">>; -get_name({pubsub_event_item, _, _, _, _}) -> <<"item">>; -get_name({pubsub_event_items, _, _, _}) -> <<"items">>; -get_name({pubsub_event, _}) -> <<"event">>; -get_name({pubsub_subscribe, _, _}) -> <<"subscribe">>; -get_name({pubsub_unsubscribe, _, _, _}) -> - <<"unsubscribe">>; -get_name({pubsub_publish, _, _}) -> <<"publish">>; -get_name({pubsub_options, _, _, _, _}) -> <<"options">>; -get_name({pubsub_retract, _, _, _}) -> <<"retract">>; -get_name({pubsub, _, _, _, _, _, _, _, _}) -> - <<"pubsub">>; -get_name({shim, _}) -> <<"headers">>; -get_name({chatstate, active}) -> <<"active">>; -get_name({chatstate, composing}) -> <<"composing">>; -get_name({chatstate, gone}) -> <<"gone">>; -get_name({chatstate, inactive}) -> <<"inactive">>; -get_name({chatstate, paused}) -> <<"paused">>; -get_name({delay, _, _, _}) -> <<"delay">>; -get_name({streamhost, _, _, _}) -> <<"streamhost">>; -get_name({bytestreams, _, _, _, _, _, _}) -> - <<"query">>; -get_name({muc_history, _, _, _, _}) -> <<"history">>; -get_name({muc_decline, _, _, _}) -> <<"decline">>; -get_name({muc_destroy, _, _, _, _}) -> <<"destroy">>; -get_name({muc_invite, _, _, _, _}) -> <<"invite">>; -get_name({muc_user, _, _, _, _, _, _}) -> <<"x">>; -get_name({muc_owner, _, _, _}) -> <<"query">>; -get_name({muc_item, _, _, _, _, _, _, _}) -> <<"item">>; -get_name({muc_actor, _, _}) -> <<"actor">>; -get_name({muc_admin, _}) -> <<"query">>; -get_name({muc, _, _}) -> <<"x">>; -get_name({muc_unique, _}) -> <<"unique">>; -get_name({x_conference, _, _, _, _, _}) -> <<"x">>; -get_name({muc_subscriptions, _}) -> <<"subscriptions">>; -get_name({muc_subscribe, _, _}) -> <<"subscribe">>; -get_name({muc_unsubscribe}) -> <<"unsubscribe">>; -get_name({rsm_first, _, _}) -> <<"first">>; -get_name({rsm_set, _, _, _, _, _, _, _}) -> <<"set">>; -get_name({mam_query, _, _, _, _, _, _, _, _}) -> - <<"query">>; -get_name({mam_archived, _, _}) -> <<"archived">>; -get_name({mam_result, _, _, _, _}) -> <<"result">>; -get_name({mam_prefs, _, _, _, _}) -> <<"prefs">>; -get_name({mam_fin, _, _, _, _}) -> <<"fin">>; -get_name({forwarded, _, _}) -> <<"forwarded">>; -get_name({carbons_disable}) -> <<"disable">>; -get_name({carbons_enable}) -> <<"enable">>; -get_name({carbons_private}) -> <<"private">>; -get_name({carbons_received, _}) -> <<"received">>; -get_name({carbons_sent, _}) -> <<"sent">>; -get_name({feature_csi, _}) -> <<"csi">>; -get_name({csi, active}) -> <<"active">>; -get_name({csi, inactive}) -> <<"inactive">>; -get_name({feature_sm, _}) -> <<"sm">>; -get_name({sm_enable, _, _, _}) -> <<"enable">>; -get_name({sm_enabled, _, _, _, _, _}) -> <<"enabled">>; -get_name({sm_resume, _, _, _}) -> <<"resume">>; -get_name({sm_resumed, _, _, _}) -> <<"resumed">>; -get_name({sm_r, _}) -> <<"r">>; -get_name({sm_a, _, _}) -> <<"a">>; -get_name({sm_failed, _, _, _}) -> <<"failed">>; -get_name({offline_item, _, _}) -> <<"item">>; -get_name({offline, _, _, _}) -> <<"offline">>; -get_name({mix_join, _, _}) -> <<"join">>; -get_name({mix_leave}) -> <<"leave">>; -get_name({mix_participant, _, _}) -> <<"participant">>; -get_name({hint, 'no-copy'}) -> <<"no-copy">>; -get_name({hint, 'no-store'}) -> <<"no-store">>; -get_name({hint, 'no-storage'}) -> <<"no-storage">>; -get_name({hint, store}) -> <<"store">>; -get_name({hint, 'no-permanent-store'}) -> - <<"no-permanent-store">>; -get_name({hint, 'no-permanent-storage'}) -> - <<"no-permanent-storage">>; -get_name({search_item, _, _, _, _, _}) -> <<"item">>; -get_name({search, _, _, _, _, _, _, _}) -> <<"query">>; +get_name({xdata_option, _, _}) -> <<"option">>; get_name({xevent, _, _, _, _, _}) -> <<"x">>; -get_name({expire, _, _}) -> <<"x">>; -get_name({nick, _}) -> <<"nick">>; -get_name({address, _, _, _, _, _}) -> <<"address">>; -get_name({addresses, _}) -> <<"addresses">>; -get_name({stanza_id, _, _}) -> <<"stanza-id">>; -get_name({client_id, _}) -> <<"client-id">>; -get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>; -get_name({adhoc_note, _, _}) -> <<"note">>; -get_name({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"command">>; -get_name({db_result, _, _, _, _, _}) -> <<"db:result">>; -get_name({db_verify, _, _, _, _, _, _}) -> - <<"db:verify">>; -get_name({handshake, _}) -> <<"handshake">>; -get_name({stream_start, _, _, _, _, _, _, _, _}) -> - <<"stream:stream">>; -get_name({bob_data, _, _, _, _}) -> <<"data">>; -get_name({xcaptcha, _}) -> <<"captcha">>; -get_name({media_uri, _, _}) -> <<"uri">>; -get_name({media, _, _, _}) -> <<"media">>; -get_name({oob_x, _, _, _}) -> <<"x">>; -get_name({sic, _, _, _}) -> <<"address">>; -get_name({upload_request, _, _, _, _}) -> <<"request">>; -get_name({upload_slot, _, _, _}) -> <<"slot">>; -get_name({thumbnail, _, _, _, _}) -> <<"thumbnail">>. +get_name({xmpp_session, _}) -> <<"session">>. -get_ns({last, _, _}) -> <<"jabber:iq:last">>; -get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; -get_ns({roster_item, _, _, _, _, _}) -> - <<"jabber:iq:roster">>; -get_ns({roster_query, _, _}) -> <<"jabber:iq:roster">>; -get_ns({rosterver_feature}) -> - <<"urn:xmpp:features:rosterver">>; -get_ns({privacy_item, _, _, _, _, _, _, _, _}) -> - <<"jabber:iq:privacy">>; -get_ns({privacy_list, _, _}) -> <<"jabber:iq:privacy">>; -get_ns({privacy_query, _, _, _}) -> - <<"jabber:iq:privacy">>; +get_ns({address, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/address">>; +get_ns({addresses, _}) -> + <<"http://jabber.org/protocol/address">>; +get_ns({adhoc_actions, _, _, _, _}) -> + <<"http://jabber.org/protocol/commands">>; +get_ns({adhoc_command, _, _, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/commands">>; +get_ns({adhoc_note, _, _}) -> + <<"http://jabber.org/protocol/commands">>; +get_ns({bind, _, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-bind">>; get_ns({block, _}) -> <<"urn:xmpp:blocking">>; -get_ns({unblock, _}) -> <<"urn:xmpp:blocking">>; get_ns({block_list, _}) -> <<"urn:xmpp:blocking">>; -get_ns({identity, _, _, _, _}) -> - <<"http://jabber.org/protocol/disco#info">>; +get_ns({bob_data, _, _, _, _}) -> <<"urn:xmpp:bob">>; +get_ns({bookmark_conference, _, _, _, _, _}) -> + <<"storage:bookmarks">>; +get_ns({bookmark_storage, _, _}) -> + <<"storage:bookmarks">>; +get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>; +get_ns({bytestreams, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/bytestreams">>; +get_ns({caps, _, _, _, _}) -> + <<"http://jabber.org/protocol/caps">>; +get_ns({carbons_disable}) -> <<"urn:xmpp:carbons:2">>; +get_ns({carbons_enable}) -> <<"urn:xmpp:carbons:2">>; +get_ns({carbons_private}) -> <<"urn:xmpp:carbons:2">>; +get_ns({carbons_received, _}) -> + <<"urn:xmpp:carbons:2">>; +get_ns({carbons_sent, _}) -> <<"urn:xmpp:carbons:2">>; +get_ns({chatstate, active}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, composing}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, gone}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, inactive}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({chatstate, paused}) -> + <<"http://jabber.org/protocol/chatstates">>; +get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>; +get_ns({compress, _}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compress_failure, _}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compressed}) -> + <<"http://jabber.org/protocol/compress">>; +get_ns({compression, _}) -> + <<"http://jabber.org/features/compress">>; +get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>; +get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>; +get_ns({db_result, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({db_verify, _, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({delay, _, _, _}) -> <<"urn:xmpp:delay">>; get_ns({disco_info, _, _, _, _}) -> <<"http://jabber.org/protocol/disco#info">>; get_ns({disco_item, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; get_ns({disco_items, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; -get_ns({private, _}) -> <<"jabber:iq:private">>; -get_ns({bookmark_conference, _, _, _, _, _}) -> - <<"storage:bookmarks">>; -get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>; -get_ns({bookmark_storage, _, _}) -> - <<"storage:bookmarks">>; -get_ns({stat_error, _, _}) -> - <<"http://jabber.org/protocol/stats">>; -get_ns({stat, _, _, _, _}) -> - <<"http://jabber.org/protocol/stats">>; -get_ns({stats, _, _}) -> - <<"http://jabber.org/protocol/stats">>; +get_ns({error, _, _, _, _, _, _}) -> + <<"jabber:client">>; +get_ns({expire, _, _}) -> <<"jabber:x:expire">>; +get_ns({feature_csi, Xmlns}) -> Xmlns; +get_ns({feature_register}) -> + <<"http://jabber.org/features/iq-register">>; +get_ns({feature_sm, Xmlns}) -> Xmlns; +get_ns({forwarded, _, _}) -> <<"urn:xmpp:forward:0">>; +get_ns({gone, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; +get_ns({handshake, _}) -> <<"jabber:client">>; +get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-permanent-storage'}) -> + <<"urn:xmpp:hints">>; +get_ns({hint, 'no-permanent-store'}) -> + <<"urn:xmpp:hints">>; +get_ns({hint, 'no-storage'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, 'no-store'}) -> <<"urn:xmpp:hints">>; +get_ns({hint, store}) -> <<"urn:xmpp:hints">>; +get_ns({identity, _, _, _, _}) -> + <<"http://jabber.org/protocol/disco#info">>; get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>; +get_ns({last, _, _}) -> <<"jabber:iq:last">>; +get_ns({legacy_auth, _, _, _, _}) -> + <<"jabber:iq:auth">>; +get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; +get_ns({mam_fin, _, _, _, _}) -> <<"urn:xmpp:mam:0">>; +get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; +get_ns({mam_query, Xmlns, _, _, _, _, _, _, _}) -> + Xmlns; +get_ns({mam_result, Xmlns, _, _, _}) -> Xmlns; +get_ns({media, _, _, _}) -> + <<"urn:xmpp:media-element">>; +get_ns({media_uri, _, _}) -> + <<"urn:xmpp:media-element">>; get_ns({message, _, _, _, _, _, _, _, _, _}) -> <<"jabber:client">>; +get_ns({mix_join, _, _}) -> <<"urn:xmpp:mix:0">>; +get_ns({mix_leave}) -> <<"urn:xmpp:mix:0">>; +get_ns({mix_participant, _, _}) -> <<"urn:xmpp:mix:0">>; +get_ns({muc, _, _}) -> + <<"http://jabber.org/protocol/muc">>; +get_ns({muc_admin, _}) -> + <<"http://jabber.org/protocol/muc#admin">>; +get_ns({muc_decline, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_destroy, Xmlns, _, _, _}) -> Xmlns; +get_ns({muc_history, _, _, _, _}) -> + <<"http://jabber.org/protocol/muc">>; +get_ns({muc_invite, _, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({muc_owner, _, _, _}) -> + <<"http://jabber.org/protocol/muc#owner">>; +get_ns({muc_subscribe, _, _}) -> + <<"urn:xmpp:mucsub:0">>; +get_ns({muc_subscriptions, _}) -> + <<"urn:xmpp:mucsub:0">>; +get_ns({muc_unique, _}) -> + <<"http://jabber.org/protocol/muc#unique">>; +get_ns({muc_unsubscribe}) -> <<"urn:xmpp:mucsub:0">>; +get_ns({muc_user, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/muc#user">>; +get_ns({nick, _}) -> + <<"http://jabber.org/protocol/nick">>; +get_ns({offline, _, _, _}) -> + <<"http://jabber.org/protocol/offline">>; +get_ns({offline_item, _, _}) -> + <<"http://jabber.org/protocol/offline">>; +get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>; +get_ns({p1_ack}) -> <<"p1:ack">>; +get_ns({p1_push}) -> <<"p1:push">>; +get_ns({p1_rebind}) -> <<"p1:rebind">>; +get_ns({ping}) -> <<"urn:xmpp:ping">>; get_ns({presence, _, _, _, _, _, _, _, _, _}) -> <<"jabber:client">>; -get_ns({gone, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; +get_ns({privacy_item, _, _, _, _, _, _, _, _}) -> + <<"jabber:iq:privacy">>; +get_ns({privacy_list, _, _}) -> <<"jabber:iq:privacy">>; +get_ns({privacy_query, _, _, _}) -> + <<"jabber:iq:privacy">>; +get_ns({private, _}) -> <<"jabber:iq:private">>; +get_ns({ps_affiliation, Xmlns, _, _, _}) -> Xmlns; +get_ns({ps_error, 'closed-node', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'configuration-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'invalid-jid', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'invalid-options', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'invalid-payload', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'invalid-subid', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'item-forbidden', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'item-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'jid-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'max-items-exceeded', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'max-nodes-exceeded', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'nodeid-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'not-in-roster-group', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'not-subscribed', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'payload-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'payload-too-big', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'pending-subscription', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'presence-subscription-required', + _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'subid-required', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'too-many-subscriptions', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, unsupported, _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_error, 'unsupported-access-model', _}) -> + <<"http://jabber.org/protocol/pubsub#errors">>; +get_ns({ps_event, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub#event">>; +get_ns({ps_item, Xmlns, _, _, _, _}) -> Xmlns; +get_ns({ps_items, Xmlns, _, _, _, _, _}) -> Xmlns; +get_ns({ps_options, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({ps_publish, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({ps_retract, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({ps_subscribe, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({ps_subscription, Xmlns, _, _, _, _, _}) -> + Xmlns; +get_ns({ps_unsubscribe, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _}) -> + <<"http://jabber.org/protocol/pubsub">>; +get_ns({pubsub_owner, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/pubsub#owner">>; get_ns({redirect, _}) -> <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; -get_ns({error, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({bind, _, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-bind">>; -get_ns({legacy_auth, _, _, _, _}) -> - <<"jabber:iq:auth">>; -get_ns({sasl_auth, _, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({register, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _}) -> + <<"jabber:iq:register">>; +get_ns({roster_item, _, _, _, _, _}) -> + <<"jabber:iq:roster">>; +get_ns({roster_query, _, _}) -> <<"jabber:iq:roster">>; +get_ns({rosterver_feature}) -> + <<"urn:xmpp:features:rosterver">>; +get_ns({rsm_first, _, _}) -> + <<"http://jabber.org/protocol/rsm">>; +get_ns({rsm_set, _, _, _, _, _, _, _}) -> + <<"http://jabber.org/protocol/rsm">>; get_ns({sasl_abort}) -> <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_challenge, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_response, _}) -> +get_ns({sasl_auth, _, _}) -> <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_success, _}) -> +get_ns({sasl_challenge, _}) -> <<"urn:ietf:params:xml:ns:xmpp-sasl">>; get_ns({sasl_failure, _, _}) -> <<"urn:ietf:params:xml:ns:xmpp-sasl">>; get_ns({sasl_mechanisms, _}) -> <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_response, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({sasl_success, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-sasl">>; +get_ns({search, _, _, _, _, _, _, _}) -> + <<"jabber:iq:search">>; +get_ns({search_item, _, _, _, _, _}) -> + <<"jabber:iq:search">>; +get_ns({'see-other-host', _}) -> + <<"urn:ietf:params:xml:ns:xmpp-streams">>; +get_ns({shim, _}) -> + <<"http://jabber.org/protocol/shim">>; +get_ns({sic, _, _, Xmlns}) -> Xmlns; +get_ns({sm_a, _, Xmlns}) -> Xmlns; +get_ns({sm_enable, _, _, Xmlns}) -> Xmlns; +get_ns({sm_enabled, _, _, _, _, Xmlns}) -> Xmlns; +get_ns({sm_failed, _, _, Xmlns}) -> Xmlns; +get_ns({sm_r, Xmlns}) -> Xmlns; +get_ns({sm_resume, _, _, Xmlns}) -> Xmlns; +get_ns({sm_resumed, _, _, Xmlns}) -> Xmlns; +get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; get_ns({starttls, _}) -> <<"urn:ietf:params:xml:ns:xmpp-tls">>; -get_ns({starttls_proceed}) -> - <<"urn:ietf:params:xml:ns:xmpp-tls">>; get_ns({starttls_failure}) -> <<"urn:ietf:params:xml:ns:xmpp-tls">>; -get_ns({compress_failure, _}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compress, _}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compressed}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compression, _}) -> - <<"http://jabber.org/features/compress">>; +get_ns({starttls_proceed}) -> + <<"urn:ietf:params:xml:ns:xmpp-tls">>; +get_ns({stat, _, _, _, _}) -> + <<"http://jabber.org/protocol/stats">>; +get_ns({stat_error, _, _}) -> + <<"http://jabber.org/protocol/stats">>; +get_ns({stats, _, _}) -> + <<"http://jabber.org/protocol/stats">>; +get_ns({stream_error, _, _}) -> + <<"http://etherx.jabber.org/streams">>; get_ns({stream_features, _}) -> <<"http://etherx.jabber.org/streams">>; -get_ns({p1_push}) -> <<"p1:push">>; -get_ns({p1_rebind}) -> <<"p1:rebind">>; -get_ns({p1_ack}) -> <<"p1:ack">>; -get_ns({caps, _, _, _, _}) -> - <<"http://jabber.org/protocol/caps">>; -get_ns({feature_register}) -> - <<"http://jabber.org/features/iq-register">>; -get_ns({register, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _}) -> - <<"jabber:iq:register">>; -get_ns({xmpp_session, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-session">>; -get_ns({ping}) -> <<"urn:xmpp:ping">>; +get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> + Xmlns; +get_ns({streamhost, _, _, _}) -> + <<"http://jabber.org/protocol/bytestreams">>; +get_ns({thumbnail, _, _, _, _}) -> + <<"urn:xmpp:thumbs:1">>; get_ns({time, _, _}) -> <<"urn:xmpp:time">>; -get_ns({'see-other-host', _}) -> - <<"urn:ietf:params:xml:ns:xmpp-streams">>; -get_ns({stream_error, _, _}) -> - <<"http://etherx.jabber.org/streams">>; -get_ns({vcard_name, _, _, _, _, _}) -> <<"vcard-temp">>; +get_ns({unblock, _}) -> <<"urn:xmpp:blocking">>; +get_ns({upload_request, _, _, _, Xmlns}) -> Xmlns; +get_ns({upload_slot, _, _, Xmlns}) -> Xmlns; get_ns({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_label, _, _, _, _, _, _, _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"vcard-temp">>; get_ns({vcard_email, _, _, _, _, _, _}) -> <<"vcard-temp">>; get_ns({vcard_geo, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_key, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_label, _, _, _, _, _, _, _, _}) -> + <<"vcard-temp">>; get_ns({vcard_logo, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_photo, _, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_name, _, _, _, _, _}) -> <<"vcard-temp">>; get_ns({vcard_org, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_photo, _, _, _}) -> <<"vcard-temp">>; get_ns({vcard_sound, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_key, _, _}) -> <<"vcard-temp">>; +get_ns({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, + _, _}) -> + <<"vcard-temp">>; get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> <<"vcard-temp">>; get_ns({vcard_xupdate, _, _}) -> <<"vcard-temp:x:update">>; -get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>; -get_ns({xdata_field, _, _, _, _, _, _, _, _}) -> - <<"jabber:x:data">>; -get_ns({xdata, _, _, _, _, _, _}) -> - <<"jabber:x:data">>; -get_ns({pubsub_subscription, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_affiliation, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_item, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_items, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_event_item, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub#event">>; -get_ns({pubsub_event_items, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub#event">>; -get_ns({pubsub_event, _}) -> - <<"http://jabber.org/protocol/pubsub#event">>; -get_ns({pubsub_subscribe, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_unsubscribe, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_publish, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_options, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_retract, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub, _, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({shim, _}) -> - <<"http://jabber.org/protocol/shim">>; -get_ns({chatstate, active}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, composing}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, gone}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, inactive}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, paused}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({delay, _, _, _}) -> <<"urn:xmpp:delay">>; -get_ns({streamhost, _, _, _}) -> - <<"http://jabber.org/protocol/bytestreams">>; -get_ns({bytestreams, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/bytestreams">>; -get_ns({muc_history, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc">>; -get_ns({muc_decline, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_destroy, Xmlns, _, _, _}) -> Xmlns; -get_ns({muc_invite, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_user, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_owner, _, _, _}) -> - <<"http://jabber.org/protocol/muc#owner">>; -get_ns({muc_admin, _}) -> - <<"http://jabber.org/protocol/muc#admin">>; -get_ns({muc, _, _}) -> - <<"http://jabber.org/protocol/muc">>; -get_ns({muc_unique, _}) -> - <<"http://jabber.org/protocol/muc#unique">>; +get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; get_ns({x_conference, _, _, _, _, _}) -> <<"jabber:x:conference">>; -get_ns({muc_subscriptions, _}) -> - <<"urn:xmpp:mucsub:0">>; -get_ns({muc_subscribe, _, _}) -> - <<"urn:xmpp:mucsub:0">>; -get_ns({muc_unsubscribe}) -> <<"urn:xmpp:mucsub:0">>; -get_ns({rsm_first, _, _}) -> - <<"http://jabber.org/protocol/rsm">>; -get_ns({rsm_set, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/rsm">>; -get_ns({mam_query, Xmlns, _, _, _, _, _, _, _}) -> - Xmlns; -get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; -get_ns({mam_result, Xmlns, _, _, _}) -> Xmlns; -get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; -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">>; -get_ns({carbons_private}) -> <<"urn:xmpp:carbons:2">>; -get_ns({carbons_received, _}) -> - <<"urn:xmpp:carbons:2">>; -get_ns({carbons_sent, _}) -> <<"urn:xmpp:carbons:2">>; -get_ns({feature_csi, Xmlns}) -> Xmlns; -get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>; -get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>; -get_ns({feature_sm, Xmlns}) -> Xmlns; -get_ns({sm_enable, _, _, Xmlns}) -> Xmlns; -get_ns({sm_enabled, _, _, _, _, Xmlns}) -> Xmlns; -get_ns({sm_resume, _, _, Xmlns}) -> Xmlns; -get_ns({sm_resumed, _, _, Xmlns}) -> Xmlns; -get_ns({sm_r, Xmlns}) -> Xmlns; -get_ns({sm_a, _, Xmlns}) -> Xmlns; -get_ns({sm_failed, _, _, Xmlns}) -> Xmlns; -get_ns({offline_item, _, _}) -> - <<"http://jabber.org/protocol/offline">>; -get_ns({offline, _, _, _}) -> - <<"http://jabber.org/protocol/offline">>; -get_ns({mix_join, _, _}) -> <<"urn:xmpp:mix:0">>; -get_ns({mix_leave}) -> <<"urn:xmpp:mix:0">>; -get_ns({mix_participant, _, _}) -> <<"urn:xmpp:mix:0">>; -get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, 'no-store'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, 'no-storage'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, store}) -> <<"urn:xmpp:hints">>; -get_ns({hint, 'no-permanent-store'}) -> - <<"urn:xmpp:hints">>; -get_ns({hint, 'no-permanent-storage'}) -> - <<"urn:xmpp:hints">>; -get_ns({search_item, _, _, _, _, _}) -> - <<"jabber:iq:search">>; -get_ns({search, _, _, _, _, _, _, _}) -> - <<"jabber:iq:search">>; -get_ns({xevent, _, _, _, _, _}) -> <<"jabber:x:event">>; -get_ns({expire, _, _}) -> <<"jabber:x:expire">>; -get_ns({nick, _}) -> - <<"http://jabber.org/protocol/nick">>; -get_ns({address, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/address">>; -get_ns({addresses, _}) -> - <<"http://jabber.org/protocol/address">>; -get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; -get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>; -get_ns({adhoc_actions, _, _, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({adhoc_note, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({db_result, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({db_verify, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({handshake, _}) -> <<"jabber:client">>; -get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> - Xmlns; -get_ns({bob_data, _, _, _, _}) -> <<"urn:xmpp:bob">>; -get_ns({xcaptcha, _}) -> <<"urn:xmpp:captcha">>; -get_ns({media_uri, _, _}) -> - <<"urn:xmpp:media-element">>; -get_ns({media, _, _, _}) -> - <<"urn:xmpp:media-element">>; -get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>; -get_ns({sic, _, _, Xmlns}) -> Xmlns; -get_ns({upload_request, _, _, _, Xmlns}) -> Xmlns; -get_ns({upload_slot, _, _, Xmlns}) -> Xmlns; -get_ns({thumbnail, _, _, _, _}) -> - <<"urn:xmpp:thumbs:1">>. +get_ns({xcaptcha, _}) -> <<"urn:xmpp:captcha">>; +get_ns({xdata, _, _, _, _, _, _}) -> + <<"jabber:x:data">>; +get_ns({xdata_field, _, _, _, _, _, _, _, _}) -> + <<"jabber:x:data">>; +get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>; +get_ns({xevent, _, _, _, _, _}) -> <<"jabber:x:event">>; +get_ns({xmpp_session, _}) -> + <<"urn:ietf:params:xml:ns:xmpp-session">>. dec_int(Val) -> dec_int(Val, infinity, infinity). @@ -3337,22 +3842,27 @@ pp(xdata_field, 8) -> sub_els]; pp(xdata, 6) -> [type, instructions, title, reported, items, fields]; -pp(pubsub_subscription, 4) -> [jid, node, subid, type]; -pp(pubsub_affiliation, 2) -> [node, type]; -pp(pubsub_item, 2) -> [id, xml_els]; -pp(pubsub_items, 4) -> [node, max_items, subid, items]; -pp(pubsub_event_item, 4) -> - [id, node, publisher, xml_els]; -pp(pubsub_event_items, 3) -> [node, retract, items]; -pp(pubsub_event, 1) -> [items]; -pp(pubsub_subscribe, 2) -> [node, jid]; -pp(pubsub_unsubscribe, 3) -> [node, jid, subid]; -pp(pubsub_publish, 2) -> [node, items]; -pp(pubsub_options, 4) -> [node, jid, subid, xdata]; -pp(pubsub_retract, 3) -> [node, notify, items]; -pp(pubsub, 8) -> - [subscriptions, affiliations, publish, subscribe, - unsubscribe, options, items, retract]; +pp(ps_subscription, 6) -> + [xmlns, jid, type, node, subid, expiry]; +pp(ps_item, 5) -> [xmlns, id, xml_els, node, publisher]; +pp(ps_items, 6) -> + [xmlns, node, items, max_items, subid, retract]; +pp(ps_event, 6) -> + [items, purge, subscription, delete, create, + configuration]; +pp(ps_subscribe, 2) -> [node, jid]; +pp(ps_unsubscribe, 3) -> [node, jid, subid]; +pp(ps_publish, 2) -> [node, items]; +pp(ps_options, 4) -> [node, jid, subid, xdata]; +pp(ps_retract, 3) -> [node, notify, items]; +pp(pubsub, 16) -> + [subscriptions, subscription, affiliations, publish, + publish_options, subscribe, unsubscribe, options, items, + retract, create, configure, default, delete, purge, + rsm]; +pp(pubsub_owner, 6) -> + [affiliations, configure, default, delete, purge, + subscriptions]; pp(shim, 1) -> [headers]; pp(delay, 3) -> [stamp, from, desc]; pp(streamhost, 3) -> [jid, host, port]; @@ -12074,381 +12584,1749 @@ decode_chatstate_composing(__TopXMLNS, __IgnoreEls, {xmlel, <<"composing">>, _attrs, _els}) -> {chatstate, composing}. -encode_chatstate_composing({chatstate, composing}, - _xmlns_attrs) -> +encode_chatstate_composing({chatstate, composing}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"composing">>, _attrs, _els}. + +decode_chatstate_active(__TopXMLNS, __IgnoreEls, + {xmlel, <<"active">>, _attrs, _els}) -> + {chatstate, active}. + +encode_chatstate_active({chatstate, active}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"active">>, _attrs, _els}. + +decode_shim_headers(__TopXMLNS, __IgnoreEls, + {xmlel, <<"headers">>, _attrs, _els}) -> + Headers = decode_shim_headers_els(__TopXMLNS, + __IgnoreEls, _els, []), + {shim, Headers}. + +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, [], + Headers) -> + lists:reverse(Headers); +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"header">>, _attrs, _} = _el | _els], + Headers) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/shim">> -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + [decode_shim_header(__TopXMLNS, __IgnoreEls, + _el) + | Headers]); + <<"http://jabber.org/protocol/shim">> -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + [decode_shim_header(<<"http://jabber.org/protocol/shim">>, + __IgnoreEls, _el) + | Headers]); + _ -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + Headers) + end; +decode_shim_headers_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Headers) -> + decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, + Headers). + +encode_shim_headers({shim, Headers}, _xmlns_attrs) -> + _els = + lists:reverse('encode_shim_headers_$headers'(Headers, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"headers">>, _attrs, _els}. + +'encode_shim_headers_$headers'([], _acc) -> _acc; +'encode_shim_headers_$headers'([Headers | _els], + _acc) -> + 'encode_shim_headers_$headers'(_els, + [encode_shim_header(Headers, []) | _acc]). + +decode_shim_header(__TopXMLNS, __IgnoreEls, + {xmlel, <<"header">>, _attrs, _els}) -> + Cdata = decode_shim_header_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Name = decode_shim_header_attrs(__TopXMLNS, _attrs, + undefined), + {Name, Cdata}. + +decode_shim_header_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_shim_header_cdata(__TopXMLNS, Cdata); +decode_shim_header_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, + <>); +decode_shim_header_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +decode_shim_header_attrs(__TopXMLNS, + [{<<"name">>, _val} | _attrs], _Name) -> + decode_shim_header_attrs(__TopXMLNS, _attrs, _val); +decode_shim_header_attrs(__TopXMLNS, [_ | _attrs], + Name) -> + decode_shim_header_attrs(__TopXMLNS, _attrs, Name); +decode_shim_header_attrs(__TopXMLNS, [], Name) -> + decode_shim_header_attr_name(__TopXMLNS, Name). + +encode_shim_header({Name, Cdata}, _xmlns_attrs) -> + _els = encode_shim_header_cdata(Cdata, []), + _attrs = encode_shim_header_attr_name(Name, + _xmlns_attrs), + {xmlel, <<"header">>, _attrs, _els}. + +decode_shim_header_attr_name(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"name">>, <<"header">>, __TopXMLNS}}); +decode_shim_header_attr_name(__TopXMLNS, _val) -> _val. + +encode_shim_header_attr_name(_val, _acc) -> + [{<<"name">>, _val} | _acc]. + +decode_shim_header_cdata(__TopXMLNS, <<>>) -> <<>>; +decode_shim_header_cdata(__TopXMLNS, _val) -> _val. + +encode_shim_header_cdata(<<>>, _acc) -> _acc; +encode_shim_header_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_pubsub_error_unsupported_access_model(__TopXMLNS, + __IgnoreEls, + {xmlel, + <<"unsupported-access-model">>, + _attrs, _els}) -> + {ps_error, 'unsupported-access-model', undefined}. + +encode_pubsub_error_unsupported_access_model({ps_error, + 'unsupported-access-model', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"unsupported-access-model">>, _attrs, _els}. + +decode_pubsub_error_unsupported(__TopXMLNS, __IgnoreEls, + {xmlel, <<"unsupported">>, _attrs, _els}) -> + Feature = + decode_pubsub_error_unsupported_attrs(__TopXMLNS, + _attrs, undefined), + {ps_error, unsupported, Feature}. + +decode_pubsub_error_unsupported_attrs(__TopXMLNS, + [{<<"feature">>, _val} | _attrs], + _Feature) -> + decode_pubsub_error_unsupported_attrs(__TopXMLNS, + _attrs, _val); +decode_pubsub_error_unsupported_attrs(__TopXMLNS, + [_ | _attrs], Feature) -> + decode_pubsub_error_unsupported_attrs(__TopXMLNS, + _attrs, Feature); +decode_pubsub_error_unsupported_attrs(__TopXMLNS, [], + Feature) -> + decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, + Feature). + +encode_pubsub_error_unsupported({ps_error, unsupported, + Feature}, + _xmlns_attrs) -> + _els = [], + _attrs = + encode_pubsub_error_unsupported_attr_feature(Feature, + _xmlns_attrs), + {xmlel, <<"unsupported">>, _attrs, _els}. + +decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"feature">>, <<"unsupported">>, + __TopXMLNS}}); +decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + ['access-authorize', 'access-open', 'access-presence', + 'access-roster', 'access-whitelist', 'auto-create', + 'auto-subscribe', collections, 'config-node', + 'create-and-configure', 'create-nodes', 'delete-items', + 'delete-nodes', 'filtered-notifications', + 'get-pending', 'instant-nodes', 'item-ids', + 'last-published', 'leased-subscription', + 'manage-subscriptions', 'member-affiliation', + 'meta-data', 'modify-affiliations', 'multi-collection', + 'multi-subscribe', 'outcast-affiliation', + 'persistent-items', 'presence-notifications', + 'presence-subscribe', publish, 'publish-options', + 'publish-only-affiliation', 'publisher-affiliation', + 'purge-nodes', 'retract-items', + 'retrieve-affiliations', 'retrieve-default', + 'retrieve-items', 'retrieve-subscriptions', subscribe, + 'subscription-options', 'subscription-notifications']) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"feature">>, <<"unsupported">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_error_unsupported_attr_feature(_val, + _acc) -> + [{<<"feature">>, enc_enum(_val)} | _acc]. + +decode_pubsub_error_too_many_subscriptions(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"too-many-subscriptions">>, + _attrs, _els}) -> + {ps_error, 'too-many-subscriptions', undefined}. + +encode_pubsub_error_too_many_subscriptions({ps_error, + 'too-many-subscriptions', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"too-many-subscriptions">>, _attrs, _els}. + +decode_pubsub_error_subid_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"subid-required">>, _attrs, + _els}) -> + {ps_error, 'subid-required', undefined}. + +encode_pubsub_error_subid_required({ps_error, + 'subid-required', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"subid-required">>, _attrs, _els}. + +decode_pubsub_error_presence_subscription_required(__TopXMLNS, + __IgnoreEls, + {xmlel, + <<"presence-subscription-required">>, + _attrs, _els}) -> + {ps_error, 'presence-subscription-required', undefined}. + +encode_pubsub_error_presence_subscription_required({ps_error, + 'presence-subscription-required', + _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"presence-subscription-required">>, _attrs, + _els}. + +decode_pubsub_error_pending_subscription(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"pending-subscription">>, + _attrs, _els}) -> + {ps_error, 'pending-subscription', undefined}. + +encode_pubsub_error_pending_subscription({ps_error, + 'pending-subscription', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"pending-subscription">>, _attrs, _els}. + +decode_pubsub_error_payload_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"payload-required">>, _attrs, + _els}) -> + {ps_error, 'payload-required', undefined}. + +encode_pubsub_error_payload_required({ps_error, + 'payload-required', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"payload-required">>, _attrs, _els}. + +decode_pubsub_error_payload_too_big(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"payload-too-big">>, _attrs, + _els}) -> + {ps_error, 'payload-too-big', undefined}. + +encode_pubsub_error_payload_too_big({ps_error, + 'payload-too-big', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"payload-too-big">>, _attrs, _els}. + +decode_pubsub_error_not_subscribed(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"not-subscribed">>, _attrs, + _els}) -> + {ps_error, 'not-subscribed', undefined}. + +encode_pubsub_error_not_subscribed({ps_error, + 'not-subscribed', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-subscribed">>, _attrs, _els}. + +decode_pubsub_error_not_in_roster_group(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"not-in-roster-group">>, + _attrs, _els}) -> + {ps_error, 'not-in-roster-group', undefined}. + +encode_pubsub_error_not_in_roster_group({ps_error, + 'not-in-roster-group', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"not-in-roster-group">>, _attrs, _els}. + +decode_pubsub_error_nodeid_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"nodeid-required">>, _attrs, + _els}) -> + {ps_error, 'nodeid-required', undefined}. + +encode_pubsub_error_nodeid_required({ps_error, + 'nodeid-required', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"nodeid-required">>, _attrs, _els}. + +decode_pubsub_error_max_nodes_exceeded(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"max-nodes-exceeded">>, _attrs, + _els}) -> + {ps_error, 'max-nodes-exceeded', undefined}. + +encode_pubsub_error_max_nodes_exceeded({ps_error, + 'max-nodes-exceeded', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"max-nodes-exceeded">>, _attrs, _els}. + +decode_pubsub_error_max_items_exceeded(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"max-items-exceeded">>, _attrs, + _els}) -> + {ps_error, 'max-items-exceeded', undefined}. + +encode_pubsub_error_max_items_exceeded({ps_error, + 'max-items-exceeded', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"max-items-exceeded">>, _attrs, _els}. + +decode_pubsub_error_jid_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"jid-required">>, _attrs, _els}) -> + {ps_error, 'jid-required', undefined}. + +encode_pubsub_error_jid_required({ps_error, + 'jid-required', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"jid-required">>, _attrs, _els}. + +decode_pubsub_error_item_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"item-required">>, _attrs, _els}) -> + {ps_error, 'item-required', undefined}. + +encode_pubsub_error_item_required({ps_error, + 'item-required', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"item-required">>, _attrs, _els}. + +decode_pubsub_error_item_forbidden(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"item-forbidden">>, _attrs, + _els}) -> + {ps_error, 'item-forbidden', undefined}. + +encode_pubsub_error_item_forbidden({ps_error, + 'item-forbidden', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"item-forbidden">>, _attrs, _els}. + +decode_pubsub_error_invalid_subid(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-subid">>, _attrs, _els}) -> + {ps_error, 'invalid-subid', undefined}. + +encode_pubsub_error_invalid_subid({ps_error, + 'invalid-subid', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-subid">>, _attrs, _els}. + +decode_pubsub_error_invalid_payload(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-payload">>, _attrs, + _els}) -> + {ps_error, 'invalid-payload', undefined}. + +encode_pubsub_error_invalid_payload({ps_error, + 'invalid-payload', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-payload">>, _attrs, _els}. + +decode_pubsub_error_invalid_options(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"invalid-options">>, _attrs, + _els}) -> + {ps_error, 'invalid-options', undefined}. + +encode_pubsub_error_invalid_options({ps_error, + 'invalid-options', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"invalid-options">>, _attrs, _els}. + +decode_pubsub_error_invalid_jid(__TopXMLNS, __IgnoreEls, + {xmlel, <<"invalid-jid">>, _attrs, _els}) -> + {ps_error, 'invalid-jid', undefined}. + +encode_pubsub_error_invalid_jid({ps_error, + 'invalid-jid', _}, + _xmlns_attrs) -> _els = [], _attrs = _xmlns_attrs, - {xmlel, <<"composing">>, _attrs, _els}. + {xmlel, <<"invalid-jid">>, _attrs, _els}. -decode_chatstate_active(__TopXMLNS, __IgnoreEls, - {xmlel, <<"active">>, _attrs, _els}) -> - {chatstate, active}. +decode_pubsub_error_configuration_required(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"configuration-required">>, + _attrs, _els}) -> + {ps_error, 'configuration-required', undefined}. -encode_chatstate_active({chatstate, active}, - _xmlns_attrs) -> +encode_pubsub_error_configuration_required({ps_error, + 'configuration-required', _}, + _xmlns_attrs) -> _els = [], _attrs = _xmlns_attrs, - {xmlel, <<"active">>, _attrs, _els}. + {xmlel, <<"configuration-required">>, _attrs, _els}. -decode_shim_headers(__TopXMLNS, __IgnoreEls, - {xmlel, <<"headers">>, _attrs, _els}) -> - Headers = decode_shim_headers_els(__TopXMLNS, - __IgnoreEls, _els, []), - {shim, Headers}. +decode_pubsub_error_closed_node(__TopXMLNS, __IgnoreEls, + {xmlel, <<"closed-node">>, _attrs, _els}) -> + {ps_error, 'closed-node', undefined}. -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, [], - Headers) -> - lists:reverse(Headers); -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"header">>, _attrs, _} = _el | _els], - Headers) -> +encode_pubsub_error_closed_node({ps_error, + 'closed-node', _}, + _xmlns_attrs) -> + _els = [], + _attrs = _xmlns_attrs, + {xmlel, <<"closed-node">>, _attrs, _els}. + +decode_pubsub_owner(__TopXMLNS, __IgnoreEls, + {xmlel, <<"pubsub">>, _attrs, _els}) -> + {Subscriptions, Affiliations, Default, Purge, Delete, + Configure} = + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined, undefined), + {pubsub_owner, Affiliations, Configure, Default, Delete, + Purge, Subscriptions}. + +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, [], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + {Subscriptions, Affiliations, Default, Purge, Delete, + Configure}; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == - <<"http://jabber.org/protocol/shim">> -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - [decode_shim_header(__TopXMLNS, __IgnoreEls, - _el) - | Headers]); - <<"http://jabber.org/protocol/shim">> -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - [decode_shim_header(<<"http://jabber.org/protocol/shim">>, - __IgnoreEls, _el) - | Headers]); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, + decode_pubsub_owner_affiliations(__TopXMLNS, + __IgnoreEls, + _el), + Default, Purge, Delete, Configure); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, + decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, + _el), + Default, Purge, Delete, Configure); _ -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - Headers) + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) end; -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Headers) -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - Headers). - -encode_shim_headers({shim, Headers}, _xmlns_attrs) -> +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"configure">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, + decode_pubsub_configure(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) + end; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"default">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, + decode_pubsub_default(__TopXMLNS, __IgnoreEls, + _el), + Purge, Delete, Configure); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Purge, Delete, Configure); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Purge, Delete, Configure); + _ -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) + end; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"delete">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + decode_pubsub_delete(__TopXMLNS, __IgnoreEls, + _el), + Configure); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Configure); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Configure); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Configure); + _ -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) + end; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"purge">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, + decode_pubsub_purge(__TopXMLNS, __IgnoreEls, + _el), + Delete, Configure); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Delete, Configure); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Delete, Configure); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Delete, Configure); + _ -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) + end; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], + Subscriptions, Affiliations, Default, Purge, Delete, + Configure) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_subscriptions(__TopXMLNS, + __IgnoreEls, _el), + Affiliations, Default, Purge, Delete, + Configure); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Affiliations, Default, Purge, Delete, + Configure); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Affiliations, Default, Purge, Delete, + Configure); + _ -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, + Delete, Configure) + end; +decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Subscriptions, Affiliations, Default, Purge, + Delete, Configure) -> + decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, + Subscriptions, Affiliations, Default, Purge, Delete, + Configure). + +encode_pubsub_owner({pubsub_owner, Affiliations, + Configure, Default, Delete, Purge, Subscriptions}, + _xmlns_attrs) -> _els = - lists:reverse('encode_shim_headers_$headers'(Headers, - [])), + lists:reverse('encode_pubsub_owner_$subscriptions'(Subscriptions, + 'encode_pubsub_owner_$affiliations'(Affiliations, + 'encode_pubsub_owner_$default'(Default, + 'encode_pubsub_owner_$purge'(Purge, + 'encode_pubsub_owner_$delete'(Delete, + 'encode_pubsub_owner_$configure'(Configure, + []))))))), _attrs = _xmlns_attrs, - {xmlel, <<"headers">>, _attrs, _els}. - -'encode_shim_headers_$headers'([], _acc) -> _acc; -'encode_shim_headers_$headers'([Headers | _els], - _acc) -> - 'encode_shim_headers_$headers'(_els, - [encode_shim_header(Headers, []) | _acc]). - -decode_shim_header(__TopXMLNS, __IgnoreEls, - {xmlel, <<"header">>, _attrs, _els}) -> - Cdata = decode_shim_header_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Name = decode_shim_header_attrs(__TopXMLNS, _attrs, - undefined), - {Name, Cdata}. - -decode_shim_header_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_shim_header_cdata(__TopXMLNS, Cdata); -decode_shim_header_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_shim_header_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). + {xmlel, <<"pubsub">>, _attrs, _els}. -decode_shim_header_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_shim_header_attrs(__TopXMLNS, _attrs, _val); -decode_shim_header_attrs(__TopXMLNS, [_ | _attrs], - Name) -> - decode_shim_header_attrs(__TopXMLNS, _attrs, Name); -decode_shim_header_attrs(__TopXMLNS, [], Name) -> - decode_shim_header_attr_name(__TopXMLNS, Name). +'encode_pubsub_owner_$subscriptions'(undefined, _acc) -> + _acc; +'encode_pubsub_owner_$subscriptions'(Subscriptions, + _acc) -> + [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. -encode_shim_header({Name, Cdata}, _xmlns_attrs) -> - _els = encode_shim_header_cdata(Cdata, []), - _attrs = encode_shim_header_attr_name(Name, - _xmlns_attrs), - {xmlel, <<"header">>, _attrs, _els}. +'encode_pubsub_owner_$affiliations'(undefined, _acc) -> + _acc; +'encode_pubsub_owner_$affiliations'(Affiliations, + _acc) -> + [encode_pubsub_owner_affiliations(Affiliations, []) + | _acc]. -decode_shim_header_attr_name(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"header">>, __TopXMLNS}}); -decode_shim_header_attr_name(__TopXMLNS, _val) -> _val. +'encode_pubsub_owner_$default'(undefined, _acc) -> _acc; +'encode_pubsub_owner_$default'(Default, _acc) -> + [encode_pubsub_default(Default, []) | _acc]. -encode_shim_header_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. +'encode_pubsub_owner_$purge'(undefined, _acc) -> _acc; +'encode_pubsub_owner_$purge'(Purge, _acc) -> + [encode_pubsub_purge(Purge, []) | _acc]. -decode_shim_header_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_shim_header_cdata(__TopXMLNS, _val) -> _val. +'encode_pubsub_owner_$delete'(undefined, _acc) -> _acc; +'encode_pubsub_owner_$delete'(Delete, _acc) -> + [encode_pubsub_delete(Delete, []) | _acc]. -encode_shim_header_cdata(<<>>, _acc) -> _acc; -encode_shim_header_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. +'encode_pubsub_owner_$configure'(undefined, _acc) -> + _acc; +'encode_pubsub_owner_$configure'(Configure, _acc) -> + [encode_pubsub_configure(Configure, []) | _acc]. decode_pubsub(__TopXMLNS, __IgnoreEls, {xmlel, <<"pubsub">>, _attrs, _els}) -> - {Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish} = + {Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription} = decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined), - {pubsub, Subscriptions, Affiliations, Publish, - Subscribe, Unsubscribe, Options, Items, Retract}. - -decode_pubsub_els(__TopXMLNS, __IgnoreEls, [], Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> - {Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish}; + undefined, undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, undefined, + undefined), + {pubsub, Subscriptions, Subscription, Affiliations, + Publish, Publish_options, Subscribe, Unsubscribe, + Options, Items, Retract, Create, Configure, Default, + Delete, Purge, Rsm}. + +decode_pubsub_els(__TopXMLNS, __IgnoreEls, [], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + {Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription}; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, + _el), + Default, Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Default, Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Default, Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, + decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, + _el), + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, + decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, + decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, + _el), + Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, + decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Publish, Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"unsubscribe">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, + decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, + _el), + Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, + decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Subscribe, Publish, Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"options">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, + decode_pubsub_options(__TopXMLNS, __IgnoreEls, _el), + Affiliations, Subscriptions, Default, Retract, + Purge, Delete, Configure, Create, Unsubscribe, + Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, + decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Affiliations, Subscriptions, Default, Retract, + Purge, Delete, Configure, Create, Unsubscribe, + Subscribe, Publish, Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"items">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, + decode_pubsub_items(__TopXMLNS, __IgnoreEls, _el), + Options, Affiliations, Subscriptions, Default, + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Options, Affiliations, Subscriptions, Default, + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Options, Affiliations, Subscriptions, Default, + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], - Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"retract">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, - decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, - _el), - Retract, Unsubscribe, Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, + decode_pubsub_retract(__TopXMLNS, __IgnoreEls, _el), + Purge, Delete, Configure, Create, Unsubscribe, + Subscribe, Publish, Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Retract, Unsubscribe, Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, + decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Purge, Delete, Configure, Create, Unsubscribe, + Subscribe, Publish, Rsm, Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], - Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"create">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, - decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, - _el), - Subscriptions, Retract, Unsubscribe, Subscribe, - Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, + decode_pubsub_create(__TopXMLNS, __IgnoreEls, _el), + Unsubscribe, Subscribe, Publish, Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, - decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Subscriptions, Retract, Unsubscribe, Subscribe, - Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Unsubscribe, Subscribe, Publish, Rsm, Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], - Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"configure">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, - decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + decode_pubsub_configure(__TopXMLNS, __IgnoreEls, _el), - Publish); + Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, - decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, __IgnoreEls, _el), - Publish); + Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsubscribe">>, _attrs, _} = _el | _els], - Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"publish-options">>, _attrs, _} = _el + | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, - _el), - Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_publish_options(__TopXMLNS, + __IgnoreEls, _el), + Items, Options, Affiliations, Subscriptions, + Default, Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Items, Options, Affiliations, Subscriptions, + Default, Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"options">>, _attrs, _} = _el | _els], Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"default">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - decode_pubsub_options(__TopXMLNS, __IgnoreEls, _el), - Affiliations, Subscriptions, Retract, Unsubscribe, - Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, + decode_pubsub_default(__TopXMLNS, __IgnoreEls, _el), + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, __IgnoreEls, _el), - Affiliations, Subscriptions, Retract, Unsubscribe, - Subscribe, Publish); + Retract, Purge, Delete, Configure, Create, + Unsubscribe, Subscribe, Publish, Rsm, Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"items">>, _attrs, _} = _el | _els], Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"delete">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_items(__TopXMLNS, __IgnoreEls, _el), - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish); + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, + decode_pubsub_delete(__TopXMLNS, __IgnoreEls, _el), + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"purge">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, + decode_pubsub_purge(__TopXMLNS, __IgnoreEls, _el), + Delete, Configure, Create, Unsubscribe, Subscribe, + Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Delete, Configure, Create, Unsubscribe, Subscribe, + Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Delete, Configure, Create, Unsubscribe, Subscribe, + Publish, Rsm, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, __IgnoreEls, _el), - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish); + Delete, Configure, Create, Unsubscribe, Subscribe, + Publish, Rsm, Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"retract">>, _attrs, _} = _el | _els], Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"subscription">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, - decode_pubsub_retract(__TopXMLNS, __IgnoreEls, _el), - Unsubscribe, Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, + decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, + _el)); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, - decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Unsubscribe, Subscribe, Publish); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"set">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"http://jabber.org/protocol/rsm">> -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, + __IgnoreEls, _el), + Subscription); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) end; decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"publish">>, _attrs, _} = _el | _els], Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> + [{xmlel, <<"publish">>, _attrs, _} = _el | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, - decode_pubsub_publish(__TopXMLNS, __IgnoreEls, - _el)); + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, + decode_pubsub_publish(__TopXMLNS, __IgnoreEls, _el), + Rsm, Subscription); <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + Rsm, Subscription); + _ -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, + Rsm, Subscription) + end; +decode_pubsub_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription) -> + decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, + Publish_options, Items, Options, Affiliations, + Subscriptions, Default, Retract, Purge, Delete, + Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, + Subscription). + +encode_pubsub({pubsub, Subscriptions, Subscription, + Affiliations, Publish, Publish_options, Subscribe, + Unsubscribe, Options, Items, Retract, Create, Configure, + Default, Delete, Purge, Rsm}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_$publish_options'(Publish_options, + 'encode_pubsub_$items'(Items, + 'encode_pubsub_$options'(Options, + 'encode_pubsub_$affiliations'(Affiliations, + 'encode_pubsub_$subscriptions'(Subscriptions, + 'encode_pubsub_$default'(Default, + 'encode_pubsub_$retract'(Retract, + 'encode_pubsub_$purge'(Purge, + 'encode_pubsub_$delete'(Delete, + 'encode_pubsub_$configure'(Configure, + 'encode_pubsub_$create'(Create, + 'encode_pubsub_$unsubscribe'(Unsubscribe, + 'encode_pubsub_$subscribe'(Subscribe, + 'encode_pubsub_$publish'(Publish, + 'encode_pubsub_$rsm'(Rsm, + 'encode_pubsub_$subscription'(Subscription, + []))))))))))))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"pubsub">>, _attrs, _els}. + +'encode_pubsub_$publish_options'(undefined, _acc) -> + _acc; +'encode_pubsub_$publish_options'(Publish_options, + _acc) -> + [encode_pubsub_publish_options(Publish_options, []) + | _acc]. + +'encode_pubsub_$items'(undefined, _acc) -> _acc; +'encode_pubsub_$items'(Items, _acc) -> + [encode_pubsub_items(Items, []) | _acc]. + +'encode_pubsub_$options'(undefined, _acc) -> _acc; +'encode_pubsub_$options'(Options, _acc) -> + [encode_pubsub_options(Options, []) | _acc]. + +'encode_pubsub_$affiliations'(undefined, _acc) -> _acc; +'encode_pubsub_$affiliations'(Affiliations, _acc) -> + [encode_pubsub_affiliations(Affiliations, []) | _acc]. + +'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc; +'encode_pubsub_$subscriptions'(Subscriptions, _acc) -> + [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. + +'encode_pubsub_$default'(undefined, _acc) -> _acc; +'encode_pubsub_$default'(Default, _acc) -> + [encode_pubsub_default(Default, []) | _acc]. + +'encode_pubsub_$retract'(undefined, _acc) -> _acc; +'encode_pubsub_$retract'(Retract, _acc) -> + [encode_pubsub_retract(Retract, []) | _acc]. + +'encode_pubsub_$purge'(undefined, _acc) -> _acc; +'encode_pubsub_$purge'(Purge, _acc) -> + [encode_pubsub_purge(Purge, []) | _acc]. + +'encode_pubsub_$delete'(undefined, _acc) -> _acc; +'encode_pubsub_$delete'(Delete, _acc) -> + [encode_pubsub_delete(Delete, []) | _acc]. + +'encode_pubsub_$configure'(undefined, _acc) -> _acc; +'encode_pubsub_$configure'(Configure, _acc) -> + [encode_pubsub_configure(Configure, []) | _acc]. + +'encode_pubsub_$create'(undefined, _acc) -> _acc; +'encode_pubsub_$create'(Create, _acc) -> + [encode_pubsub_create(Create, []) | _acc]. + +'encode_pubsub_$unsubscribe'(undefined, _acc) -> _acc; +'encode_pubsub_$unsubscribe'(Unsubscribe, _acc) -> + [encode_pubsub_unsubscribe(Unsubscribe, []) | _acc]. + +'encode_pubsub_$subscribe'(undefined, _acc) -> _acc; +'encode_pubsub_$subscribe'(Subscribe, _acc) -> + [encode_pubsub_subscribe(Subscribe, []) | _acc]. + +'encode_pubsub_$publish'(undefined, _acc) -> _acc; +'encode_pubsub_$publish'(Publish, _acc) -> + [encode_pubsub_publish(Publish, []) | _acc]. + +'encode_pubsub_$rsm'(undefined, _acc) -> _acc; +'encode_pubsub_$rsm'(Rsm, _acc) -> + [encode_rsm_set(Rsm, + [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]) + | _acc]. + +'encode_pubsub_$subscription'(undefined, _acc) -> _acc; +'encode_pubsub_$subscription'(Subscription, _acc) -> + [encode_pubsub_subscription(Subscription, []) | _acc]. + +decode_pubsub_purge(__TopXMLNS, __IgnoreEls, + {xmlel, <<"purge">>, _attrs, _els}) -> + Node = decode_pubsub_purge_attrs(__TopXMLNS, _attrs, + undefined), + Node. + +decode_pubsub_purge_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_purge_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_purge_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_purge_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_purge_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_purge_attr_node(__TopXMLNS, Node). + +encode_pubsub_purge(Node, _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_purge_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"purge">>, _attrs, _els}. + +decode_pubsub_purge_attr_node(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"purge">>, __TopXMLNS}}); +decode_pubsub_purge_attr_node(__TopXMLNS, _val) -> _val. + +encode_pubsub_purge_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_delete(__TopXMLNS, __IgnoreEls, + {xmlel, <<"delete">>, _attrs, _els}) -> + Uri = decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Node = decode_pubsub_delete_attrs(__TopXMLNS, _attrs, + undefined), + {Node, Uri}. + +decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, [], + Uri) -> + Uri; +decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], + Uri) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">>; + __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">>; + __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_redirect(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + Uri) + end; +decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Uri) -> + decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, + Uri). + +decode_pubsub_delete_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_delete_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_delete_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_delete_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_delete_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_delete_attr_node(__TopXMLNS, Node). + +encode_pubsub_delete({Node, Uri}, _xmlns_attrs) -> + _els = lists:reverse('encode_pubsub_delete_$uri'(Uri, + [])), + _attrs = encode_pubsub_delete_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"delete">>, _attrs, _els}. + +'encode_pubsub_delete_$uri'(<<>>, _acc) -> _acc; +'encode_pubsub_delete_$uri'(Uri, _acc) -> + [encode_pubsub_redirect(Uri, []) | _acc]. + +decode_pubsub_delete_attr_node(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"delete">>, __TopXMLNS}}); +decode_pubsub_delete_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_delete_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_redirect(__TopXMLNS, __IgnoreEls, + {xmlel, <<"redirect">>, _attrs, _els}) -> + Uri = decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, + undefined), + Uri. + +decode_pubsub_redirect_attrs(__TopXMLNS, + [{<<"uri">>, _val} | _attrs], _Uri) -> + decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_redirect_attrs(__TopXMLNS, [_ | _attrs], + Uri) -> + decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, Uri); +decode_pubsub_redirect_attrs(__TopXMLNS, [], Uri) -> + decode_pubsub_redirect_attr_uri(__TopXMLNS, Uri). + +encode_pubsub_redirect(Uri, _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_redirect_attr_uri(Uri, + _xmlns_attrs), + {xmlel, <<"redirect">>, _attrs, _els}. + +decode_pubsub_redirect_attr_uri(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"uri">>, <<"redirect">>, __TopXMLNS}}); +decode_pubsub_redirect_attr_uri(__TopXMLNS, _val) -> + _val. + +encode_pubsub_redirect_attr_uri(_val, _acc) -> + [{<<"uri">>, _val} | _acc]. + +decode_pubsub_default(__TopXMLNS, __IgnoreEls, + {xmlel, <<"default">>, _attrs, _els}) -> + Xdata = decode_pubsub_default_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + Node = decode_pubsub_default_attrs(__TopXMLNS, _attrs, + undefined), + {Node, Xdata}. + +decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, [], + Xdata) -> + Xdata; +decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, + Xdata) + end; +decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Xdata) -> + decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, + Xdata). + +decode_pubsub_default_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_default_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_default_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_default_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_default_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_default_attr_node(__TopXMLNS, Node). + +encode_pubsub_default({Node, Xdata}, _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_default_$xdata'(Xdata, + [])), + _attrs = encode_pubsub_default_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"default">>, _attrs, _els}. + +'encode_pubsub_default_$xdata'(undefined, _acc) -> _acc; +'encode_pubsub_default_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +decode_pubsub_default_attr_node(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_default_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_default_attr_node(<<>>, _acc) -> _acc; +encode_pubsub_default_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_publish_options(__TopXMLNS, __IgnoreEls, + {xmlel, <<"publish-options">>, _attrs, _els}) -> + Xdata = decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + Xdata. + +decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, [], Xdata) -> + Xdata; +decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], + Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, _els, Xdata) + end; +decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Xdata) -> + decode_pubsub_publish_options_els(__TopXMLNS, + __IgnoreEls, _els, Xdata). + +encode_pubsub_publish_options(Xdata, _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_publish_options_$xdata'(Xdata, + [])), + _attrs = _xmlns_attrs, + {xmlel, <<"publish-options">>, _attrs, _els}. + +'encode_pubsub_publish_options_$xdata'(undefined, + _acc) -> + _acc; +'encode_pubsub_publish_options_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +decode_pubsub_configure(__TopXMLNS, __IgnoreEls, + {xmlel, <<"configure">>, _attrs, _els}) -> + Xdata = decode_pubsub_configure_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + Node = decode_pubsub_configure_attrs(__TopXMLNS, _attrs, + undefined), + {Node, Xdata}. + +decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, [], + Xdata) -> + Xdata; +decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el | _els], + Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, + _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el)); _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) + decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, + _els, Xdata) end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Items, Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish) -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, Items, - Options, Affiliations, Subscriptions, Retract, - Unsubscribe, Subscribe, Publish). - -encode_pubsub({pubsub, Subscriptions, Affiliations, - Publish, Subscribe, Unsubscribe, Options, Items, - Retract}, - _xmlns_attrs) -> - _els = lists:reverse('encode_pubsub_$items'(Items, - 'encode_pubsub_$options'(Options, - 'encode_pubsub_$affiliations'(Affiliations, - 'encode_pubsub_$subscriptions'(Subscriptions, - 'encode_pubsub_$retract'(Retract, - 'encode_pubsub_$unsubscribe'(Unsubscribe, - 'encode_pubsub_$subscribe'(Subscribe, - 'encode_pubsub_$publish'(Publish, - []))))))))), - _attrs = _xmlns_attrs, - {xmlel, <<"pubsub">>, _attrs, _els}. +decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Xdata) -> + decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, + _els, Xdata). -'encode_pubsub_$items'(undefined, _acc) -> _acc; -'encode_pubsub_$items'(Items, _acc) -> - [encode_pubsub_items(Items, []) | _acc]. +decode_pubsub_configure_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_configure_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_configure_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_configure_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_configure_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_configure_attr_node(__TopXMLNS, Node). -'encode_pubsub_$options'(undefined, _acc) -> _acc; -'encode_pubsub_$options'(Options, _acc) -> - [encode_pubsub_options(Options, []) | _acc]. +encode_pubsub_configure({Node, Xdata}, _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_configure_$xdata'(Xdata, + [])), + _attrs = encode_pubsub_configure_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"configure">>, _attrs, _els}. -'encode_pubsub_$affiliations'(undefined, _acc) -> _acc; -'encode_pubsub_$affiliations'(Affiliations, _acc) -> - [encode_pubsub_affiliations(Affiliations, []) | _acc]. +'encode_pubsub_configure_$xdata'(undefined, _acc) -> + _acc; +'encode_pubsub_configure_$xdata'(Xdata, _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. -'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc; -'encode_pubsub_$subscriptions'(Subscriptions, _acc) -> - [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. +decode_pubsub_configure_attr_node(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_configure_attr_node(__TopXMLNS, _val) -> + _val. -'encode_pubsub_$retract'(undefined, _acc) -> _acc; -'encode_pubsub_$retract'(Retract, _acc) -> - [encode_pubsub_retract(Retract, []) | _acc]. +encode_pubsub_configure_attr_node(<<>>, _acc) -> _acc; +encode_pubsub_configure_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. -'encode_pubsub_$unsubscribe'(undefined, _acc) -> _acc; -'encode_pubsub_$unsubscribe'(Unsubscribe, _acc) -> - [encode_pubsub_unsubscribe(Unsubscribe, []) | _acc]. +decode_pubsub_create(__TopXMLNS, __IgnoreEls, + {xmlel, <<"create">>, _attrs, _els}) -> + Node = decode_pubsub_create_attrs(__TopXMLNS, _attrs, + undefined), + Node. -'encode_pubsub_$subscribe'(undefined, _acc) -> _acc; -'encode_pubsub_$subscribe'(Subscribe, _acc) -> - [encode_pubsub_subscribe(Subscribe, []) | _acc]. +decode_pubsub_create_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_create_attrs(__TopXMLNS, _attrs, _val); +decode_pubsub_create_attrs(__TopXMLNS, [_ | _attrs], + Node) -> + decode_pubsub_create_attrs(__TopXMLNS, _attrs, Node); +decode_pubsub_create_attrs(__TopXMLNS, [], Node) -> + decode_pubsub_create_attr_node(__TopXMLNS, Node). -'encode_pubsub_$publish'(undefined, _acc) -> _acc; -'encode_pubsub_$publish'(Publish, _acc) -> - [encode_pubsub_publish(Publish, []) | _acc]. +encode_pubsub_create(Node, _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_create_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"create">>, _attrs, _els}. + +decode_pubsub_create_attr_node(__TopXMLNS, undefined) -> + <<>>; +decode_pubsub_create_attr_node(__TopXMLNS, _val) -> + _val. + +encode_pubsub_create_attr_node(<<>>, _acc) -> _acc; +encode_pubsub_create_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. decode_pubsub_retract(__TopXMLNS, __IgnoreEls, {xmlel, <<"retract">>, _attrs, _els}) -> @@ -12456,7 +14334,7 @@ decode_pubsub_retract(__TopXMLNS, __IgnoreEls, __IgnoreEls, _els, []), {Node, Notify} = decode_pubsub_retract_attrs(__TopXMLNS, _attrs, undefined, undefined), - {pubsub_retract, Node, Notify, Items}. + {ps_retract, Node, Notify, Items}. decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, [], Items) -> @@ -12477,6 +14355,11 @@ decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, __IgnoreEls, _el) | Items]); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el) + | Items]); _ -> decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, Items) @@ -12503,8 +14386,7 @@ decode_pubsub_retract_attrs(__TopXMLNS, [], Node, {decode_pubsub_retract_attr_node(__TopXMLNS, Node), decode_pubsub_retract_attr_notify(__TopXMLNS, Notify)}. -encode_pubsub_retract({pubsub_retract, Node, Notify, - Items}, +encode_pubsub_retract({ps_retract, Node, Notify, Items}, _xmlns_attrs) -> _els = lists:reverse('encode_pubsub_retract_$items'(Items, @@ -12552,7 +14434,7 @@ decode_pubsub_options(__TopXMLNS, __IgnoreEls, {Node, Subid, Jid} = decode_pubsub_options_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), - {pubsub_options, Node, Jid, Subid, Xdata}. + {ps_options, Node, Jid, Subid, Xdata}. decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, [], Xdata) -> @@ -12596,7 +14478,7 @@ decode_pubsub_options_attrs(__TopXMLNS, [], Node, Subid, decode_pubsub_options_attr_subid(__TopXMLNS, Subid), decode_pubsub_options_attr_jid(__TopXMLNS, Jid)}. -encode_pubsub_options({pubsub_options, Node, Jid, Subid, +encode_pubsub_options({ps_options, Node, Jid, Subid, Xdata}, _xmlns_attrs) -> _els = @@ -12655,7 +14537,7 @@ decode_pubsub_publish(__TopXMLNS, __IgnoreEls, __IgnoreEls, _els, []), Node = decode_pubsub_publish_attrs(__TopXMLNS, _attrs, undefined), - {pubsub_publish, Node, Items}. + {ps_publish, Node, Items}. decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, [], Items) -> @@ -12676,6 +14558,11 @@ decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, __IgnoreEls, _el) | Items]); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el) + | Items]); _ -> decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, Items) @@ -12694,7 +14581,7 @@ decode_pubsub_publish_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_publish_attrs(__TopXMLNS, [], Node) -> decode_pubsub_publish_attr_node(__TopXMLNS, Node). -encode_pubsub_publish({pubsub_publish, Node, Items}, +encode_pubsub_publish({ps_publish, Node, Items}, _xmlns_attrs) -> _els = lists:reverse('encode_pubsub_publish_$items'(Items, @@ -12723,7 +14610,7 @@ decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, {Node, Subid, Jid} = decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), - {pubsub_unsubscribe, Node, Jid, Subid}. + {ps_unsubscribe, Node, Jid, Subid}. decode_pubsub_unsubscribe_attrs(__TopXMLNS, [{<<"node">>, _val} | _attrs], _Node, Subid, @@ -12750,8 +14637,8 @@ decode_pubsub_unsubscribe_attrs(__TopXMLNS, [], Node, decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, Subid), decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, Jid)}. -encode_pubsub_unsubscribe({pubsub_unsubscribe, Node, - Jid, Subid}, +encode_pubsub_unsubscribe({ps_unsubscribe, Node, Jid, + Subid}, _xmlns_attrs) -> _els = [], _attrs = encode_pubsub_unsubscribe_attr_jid(Jid, @@ -12803,7 +14690,7 @@ decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, {xmlel, <<"subscribe">>, _attrs, _els}) -> {Node, Jid} = decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, undefined, undefined), - {pubsub_subscribe, Node, Jid}. + {ps_subscribe, Node, Jid}. decode_pubsub_subscribe_attrs(__TopXMLNS, [{<<"node">>, _val} | _attrs], _Node, Jid) -> @@ -12822,7 +14709,7 @@ decode_pubsub_subscribe_attrs(__TopXMLNS, [], Node, {decode_pubsub_subscribe_attr_node(__TopXMLNS, Node), decode_pubsub_subscribe_attr_jid(__TopXMLNS, Jid)}. -encode_pubsub_subscribe({pubsub_subscribe, Node, Jid}, +encode_pubsub_subscribe({ps_subscribe, Node, Jid}, _xmlns_attrs) -> _els = [], _attrs = encode_pubsub_subscribe_attr_jid(Jid, @@ -12857,12 +14744,108 @@ decode_pubsub_subscribe_attr_jid(__TopXMLNS, _val) -> encode_pubsub_subscribe_attr_jid(_val, _acc) -> [{<<"jid">>, enc_jid(_val)} | _acc]. +decode_pubsub_owner_affiliations(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"affiliations">>, _attrs, _els}) -> + Affiliations = + decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, _els, []), + Node = + decode_pubsub_owner_affiliations_attrs(__TopXMLNS, + _attrs, undefined), + {Node, Affiliations}. + +decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, [], Affiliations) -> + lists:reverse(Affiliations); +decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"affiliation">>, _attrs, _} = + _el + | _els], + Affiliations) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, _els, + [decode_pubsub_owner_affiliation(__TopXMLNS, + __IgnoreEls, + _el) + | Affiliations]); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, _els, + [decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, + _el) + | Affiliations]); + _ -> + decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, _els, Affiliations) + end; +decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Affiliations) -> + decode_pubsub_owner_affiliations_els(__TopXMLNS, + __IgnoreEls, _els, Affiliations). + +decode_pubsub_owner_affiliations_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_owner_affiliations_attrs(__TopXMLNS, + _attrs, _val); +decode_pubsub_owner_affiliations_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_pubsub_owner_affiliations_attrs(__TopXMLNS, + _attrs, Node); +decode_pubsub_owner_affiliations_attrs(__TopXMLNS, [], + Node) -> + decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, + Node). + +encode_pubsub_owner_affiliations({Node, Affiliations}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_owner_affiliations_$affiliations'(Affiliations, + [])), + _attrs = + encode_pubsub_owner_affiliations_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"affiliations">>, _attrs, _els}. + +'encode_pubsub_owner_affiliations_$affiliations'([], + _acc) -> + _acc; +'encode_pubsub_owner_affiliations_$affiliations'([Affiliations + | _els], + _acc) -> + 'encode_pubsub_owner_affiliations_$affiliations'(_els, + [encode_pubsub_owner_affiliation(Affiliations, + []) + | _acc]). + +decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_owner_affiliations_attr_node(<<>>, + _acc) -> + _acc; +encode_pubsub_owner_affiliations_attr_node(_val, + _acc) -> + [{<<"node">>, _val} | _acc]. + decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, {xmlel, <<"affiliations">>, _attrs, _els}) -> Affiliations = decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, _els, []), - Affiliations. + Node = decode_pubsub_affiliations_attrs(__TopXMLNS, + _attrs, undefined), + {Node, Affiliations}. decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, [], Affiliations) -> @@ -12897,12 +14880,25 @@ decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, _els, Affiliations). -encode_pubsub_affiliations(Affiliations, +decode_pubsub_affiliations_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_affiliations_attrs(__TopXMLNS, _attrs, + _val); +decode_pubsub_affiliations_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_pubsub_affiliations_attrs(__TopXMLNS, _attrs, + Node); +decode_pubsub_affiliations_attrs(__TopXMLNS, [], + Node) -> + decode_pubsub_affiliations_attr_node(__TopXMLNS, Node). + +encode_pubsub_affiliations({Node, Affiliations}, _xmlns_attrs) -> _els = lists:reverse('encode_pubsub_affiliations_$affiliations'(Affiliations, [])), - _attrs = _xmlns_attrs, + _attrs = encode_pubsub_affiliations_attr_node(Node, + _xmlns_attrs), {xmlel, <<"affiliations">>, _attrs, _els}. 'encode_pubsub_affiliations_$affiliations'([], _acc) -> @@ -12915,6 +14911,18 @@ encode_pubsub_affiliations(Affiliations, []) | _acc]). +decode_pubsub_affiliations_attr_node(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_affiliations_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_affiliations_attr_node(<<>>, _acc) -> + _acc; +encode_pubsub_affiliations_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, {xmlel, <<"subscriptions">>, _attrs, _els}) -> Subscriptions = @@ -12934,7 +14942,9 @@ decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> + <<"http://jabber.org/protocol/pubsub">>; + __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#owner">> -> decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, _els, [decode_pubsub_subscription(__TopXMLNS, @@ -12948,6 +14958,20 @@ decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el) | Subscriptions]); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, + _el) + | Subscriptions]); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, + _els, + [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, + _el) + | Subscriptions]); _ -> decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, _els, Subscriptions) @@ -13003,358 +15027,368 @@ encode_pubsub_subscriptions_attr_node(_val, _acc) -> decode_pubsub_event(__TopXMLNS, __IgnoreEls, {xmlel, <<"event">>, _attrs, _els}) -> - Items = decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - _els, []), - {pubsub_event, Items}. + {Items, Create, Delete, Purge, Configuration, + Subscription} = + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined, undefined), + {ps_event, Items, Purge, Subscription, Delete, Create, + Configuration}. decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); + Items, Create, Delete, Purge, Configuration, + Subscription) -> + {Items, Create, Delete, Purge, Configuration, + Subscription}; decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"items">>, _attrs, _} = _el | _els], - Items) -> + [{xmlel, <<"items">>, _attrs, _} = _el | _els], Items, + Create, Delete, Purge, Configuration, Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub#event">> -> decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_event_items(__TopXMLNS, - __IgnoreEls, _el) - | Items]); + decode_pubsub_items(__TopXMLNS, __IgnoreEls, + _el), + Create, Delete, Purge, Configuration, + Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Create, Delete, Purge, Configuration, + Subscription); <<"http://jabber.org/protocol/pubsub#event">> -> decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_event_items(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el) - | Items]); + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Create, Delete, Purge, Configuration, + Subscription); _ -> decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items) + Items, Create, Delete, Purge, Configuration, + Subscription) end; decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -encode_pubsub_event({pubsub_event, Items}, - _xmlns_attrs) -> - _els = lists:reverse('encode_pubsub_event_$items'(Items, - [])), - _attrs = _xmlns_attrs, - {xmlel, <<"event">>, _attrs, _els}. - -'encode_pubsub_event_$items'([], _acc) -> _acc; -'encode_pubsub_event_$items'([Items | _els], _acc) -> - 'encode_pubsub_event_$items'(_els, - [encode_pubsub_event_items(Items, []) | _acc]). - -decode_pubsub_event_items(__TopXMLNS, __IgnoreEls, - {xmlel, <<"items">>, _attrs, _els}) -> - {Items, Retract} = - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, [], []), - Node = decode_pubsub_event_items_attrs(__TopXMLNS, - _attrs, undefined), - {pubsub_event_items, Node, Retract, Items}. - -decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - [], Items, Retract) -> - {lists:reverse(Items), lists:reverse(Retract)}; -decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"retract">>, _attrs, _} = _el | _els], - Items, Retract) -> + [{xmlel, <<"subscription">>, _attrs, _} = _el | _els], + Items, Create, Delete, Purge, Configuration, + Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, Items, - [decode_pubsub_event_retract(__TopXMLNS, - __IgnoreEls, - _el) - | Retract]); + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + decode_pubsub_subscription(__TopXMLNS, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el)); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el)); <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, Items, - [decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, - _el) - | Retract]); + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el)); _ -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, Items, Retract) + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription) end; -decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], - Items, Retract) -> +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"purge">>, _attrs, _} = _el | _els], Items, + Create, Delete, Purge, Configuration, Subscription) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_event_item(__TopXMLNS, - __IgnoreEls, - _el) - | Items], - Retract); + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, + decode_pubsub_purge(__TopXMLNS, __IgnoreEls, + _el), + Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Configuration, Subscription); <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_event_item(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, - _el) - | Items], - Retract); + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Configuration, Subscription); _ -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, Items, Retract) + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription) end; -decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items, Retract) -> - decode_pubsub_event_items_els(__TopXMLNS, __IgnoreEls, - _els, Items, Retract). - -decode_pubsub_event_items_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_event_items_attrs(__TopXMLNS, _attrs, - _val); -decode_pubsub_event_items_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_pubsub_event_items_attrs(__TopXMLNS, _attrs, - Node); -decode_pubsub_event_items_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_event_items_attr_node(__TopXMLNS, Node). - -encode_pubsub_event_items({pubsub_event_items, Node, - Retract, Items}, - _xmlns_attrs) -> - _els = - lists:reverse('encode_pubsub_event_items_$items'(Items, - 'encode_pubsub_event_items_$retract'(Retract, - []))), - _attrs = encode_pubsub_event_items_attr_node(Node, - _xmlns_attrs), - {xmlel, <<"items">>, _attrs, _els}. - -'encode_pubsub_event_items_$items'([], _acc) -> _acc; -'encode_pubsub_event_items_$items'([Items | _els], - _acc) -> - 'encode_pubsub_event_items_$items'(_els, - [encode_pubsub_event_item(Items, []) - | _acc]). - -'encode_pubsub_event_items_$retract'([], _acc) -> _acc; -'encode_pubsub_event_items_$retract'([Retract | _els], - _acc) -> - 'encode_pubsub_event_items_$retract'(_els, - [encode_pubsub_event_retract(Retract, - []) - | _acc]). - -decode_pubsub_event_items_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"items">>, __TopXMLNS}}); -decode_pubsub_event_items_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_event_items_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_event_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - __Xmls = decode_pubsub_event_item_els(__TopXMLNS, - __IgnoreEls, _els, []), - {Id, Node, Publisher} = - decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {pubsub_event_item, Id, Node, Publisher, __Xmls}. - -decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, - [], __Xmls) -> - lists:reverse(__Xmls); -decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], __Xmls) -> - decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, - _els, [_el | __Xmls]); -decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], __Xmls) -> - decode_pubsub_event_item_els(__TopXMLNS, __IgnoreEls, - _els, __Xmls). - -decode_pubsub_event_item_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, Node, - Publisher) -> - decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, _val, - Node, Publisher); -decode_pubsub_event_item_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Id, _Node, - Publisher) -> - decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, - _val, Publisher); -decode_pubsub_event_item_attrs(__TopXMLNS, - [{<<"publisher">>, _val} | _attrs], Id, Node, - _Publisher) -> - decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, - Node, _val); -decode_pubsub_event_item_attrs(__TopXMLNS, [_ | _attrs], - Id, Node, Publisher) -> - decode_pubsub_event_item_attrs(__TopXMLNS, _attrs, Id, - Node, Publisher); -decode_pubsub_event_item_attrs(__TopXMLNS, [], Id, Node, - Publisher) -> - {decode_pubsub_event_item_attr_id(__TopXMLNS, Id), - decode_pubsub_event_item_attr_node(__TopXMLNS, Node), - decode_pubsub_event_item_attr_publisher(__TopXMLNS, - Publisher)}. - -encode_pubsub_event_item({pubsub_event_item, Id, Node, - Publisher, __Xmls}, - _xmlns_attrs) -> - _els = __Xmls, - _attrs = - encode_pubsub_event_item_attr_publisher(Publisher, - encode_pubsub_event_item_attr_node(Node, - encode_pubsub_event_item_attr_id(Id, - _xmlns_attrs))), - {xmlel, <<"item">>, _attrs, _els}. - -decode_pubsub_event_item_attr_id(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_event_item_attr_id(__TopXMLNS, _val) -> - _val. - -encode_pubsub_event_item_attr_id(<<>>, _acc) -> _acc; -encode_pubsub_event_item_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_pubsub_event_item_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_event_item_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_event_item_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_event_item_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"delete">>, _attrs, _} = _el | _els], Items, + Create, Delete, Purge, Configuration, Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, + decode_pubsub_delete(__TopXMLNS, __IgnoreEls, + _el), + Purge, Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Purge, Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub#owner">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, + __IgnoreEls, _el), + Purge, Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Purge, Configuration, Subscription); + _ -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription) + end; +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"create">>, _attrs, _} = _el | _els], Items, + Create, Delete, Purge, Configuration, Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_pubsub_create(__TopXMLNS, __IgnoreEls, + _el), + Delete, Purge, Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, + __IgnoreEls, _el), + Delete, Purge, Configuration, Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el), + Delete, Purge, Configuration, Subscription); + _ -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription) + end; +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"configuration">>, _attrs, _} = _el | _els], + Items, Create, Delete, Purge, Configuration, + Subscription) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, + decode_pubsub_event_configuration(__TopXMLNS, + __IgnoreEls, + _el), + Subscription); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, + decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, + _el), + Subscription); + _ -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription) + end; +decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Items, Create, Delete, Purge, Configuration, + Subscription) -> + decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, + Items, Create, Delete, Purge, Configuration, + Subscription). -decode_pubsub_event_item_attr_publisher(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_event_item_attr_publisher(__TopXMLNS, - _val) -> - _val. +encode_pubsub_event({ps_event, Items, Purge, + Subscription, Delete, Create, Configuration}, + _xmlns_attrs) -> + _els = lists:reverse('encode_pubsub_event_$items'(Items, + 'encode_pubsub_event_$create'(Create, + 'encode_pubsub_event_$delete'(Delete, + 'encode_pubsub_event_$purge'(Purge, + 'encode_pubsub_event_$configuration'(Configuration, + 'encode_pubsub_event_$subscription'(Subscription, + []))))))), + _attrs = _xmlns_attrs, + {xmlel, <<"event">>, _attrs, _els}. -encode_pubsub_event_item_attr_publisher(<<>>, _acc) -> - _acc; -encode_pubsub_event_item_attr_publisher(_val, _acc) -> - [{<<"publisher">>, _val} | _acc]. +'encode_pubsub_event_$items'(undefined, _acc) -> _acc; +'encode_pubsub_event_$items'(Items, _acc) -> + [encode_pubsub_items(Items, []) | _acc]. -decode_pubsub_event_retract(__TopXMLNS, __IgnoreEls, - {xmlel, <<"retract">>, _attrs, _els}) -> - Id = decode_pubsub_event_retract_attrs(__TopXMLNS, - _attrs, undefined), - Id. +'encode_pubsub_event_$create'(undefined, _acc) -> _acc; +'encode_pubsub_event_$create'(Create, _acc) -> + [encode_pubsub_create(Create, []) | _acc]. -decode_pubsub_event_retract_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id) -> - decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, - _val); -decode_pubsub_event_retract_attrs(__TopXMLNS, - [_ | _attrs], Id) -> - decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, - Id); -decode_pubsub_event_retract_attrs(__TopXMLNS, [], Id) -> - decode_pubsub_event_retract_attr_id(__TopXMLNS, Id). +'encode_pubsub_event_$delete'(undefined, _acc) -> _acc; +'encode_pubsub_event_$delete'(Delete, _acc) -> + [encode_pubsub_delete(Delete, []) | _acc]. -encode_pubsub_event_retract(Id, _xmlns_attrs) -> - _els = [], - _attrs = encode_pubsub_event_retract_attr_id(Id, - _xmlns_attrs), - {xmlel, <<"retract">>, _attrs, _els}. +'encode_pubsub_event_$purge'(undefined, _acc) -> _acc; +'encode_pubsub_event_$purge'(Purge, _acc) -> + [encode_pubsub_purge(Purge, []) | _acc]. -decode_pubsub_event_retract_attr_id(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"retract">>, __TopXMLNS}}); -decode_pubsub_event_retract_attr_id(__TopXMLNS, _val) -> - _val. +'encode_pubsub_event_$configuration'(undefined, _acc) -> + _acc; +'encode_pubsub_event_$configuration'(Configuration, + _acc) -> + [encode_pubsub_event_configuration(Configuration, []) + | _acc]. -encode_pubsub_event_retract_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. +'encode_pubsub_event_$subscription'(undefined, _acc) -> + _acc; +'encode_pubsub_event_$subscription'(Subscription, + _acc) -> + [encode_pubsub_subscription(Subscription, []) | _acc]. decode_pubsub_items(__TopXMLNS, __IgnoreEls, {xmlel, <<"items">>, _attrs, _els}) -> - Items = decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - _els, []), - {Max_items, Node, Subid} = + {Items, Retract} = decode_pubsub_items_els(__TopXMLNS, + __IgnoreEls, _els, [], + undefined), + {Xmlns, Max_items, Node, Subid} = decode_pubsub_items_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined), - {pubsub_items, Node, Max_items, Subid, Items}. + undefined, undefined, undefined), + {ps_items, Xmlns, Node, Items, Max_items, Subid, + Retract}. decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); + Items, Retract) -> + {lists:reverse(Items), Retract}; decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> + [{xmlel, <<"retract">>, _attrs, _} = _el | _els], Items, + Retract) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_pubsub_event_retract(__TopXMLNS, + __IgnoreEls, + _el)); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + Items, + decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, + _el)); + _ -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + Items, Retract) + end; +decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, + Retract) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"">> + when __TopXMLNS == + <<"http://jabber.org/protocol/pubsub">>; + __TopXMLNS == + <<"http://jabber.org/protocol/pubsub#event">> -> decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, [decode_pubsub_item(__TopXMLNS, __IgnoreEls, _el) - | Items]); + | Items], + Retract); <<"http://jabber.org/protocol/pubsub">> -> decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, __IgnoreEls, _el) - | Items]); + | Items], + Retract); + <<"http://jabber.org/protocol/pubsub#event">> -> + decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, + [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, + __IgnoreEls, _el) + | Items], + Retract); _ -> decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items) + Items, Retract) end; decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> + [_ | _els], Items, Retract) -> decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items). + Items, Retract). decode_pubsub_items_attrs(__TopXMLNS, - [{<<"max_items">>, _val} | _attrs], _Max_items, Node, - Subid) -> + [{<<"xmlns">>, _val} | _attrs], _Xmlns, Max_items, + Node, Subid) -> decode_pubsub_items_attrs(__TopXMLNS, _attrs, _val, - Node, Subid); + Max_items, Node, Subid); +decode_pubsub_items_attrs(__TopXMLNS, + [{<<"max_items">>, _val} | _attrs], Xmlns, _Max_items, + Node, Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, + _val, Node, Subid); decode_pubsub_items_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Max_items, _Node, - Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, - _val, Subid); + [{<<"node">>, _val} | _attrs], Xmlns, Max_items, + _Node, Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, + Max_items, _val, Subid); decode_pubsub_items_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Max_items, Node, - _Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, - Node, _val); + [{<<"subid">>, _val} | _attrs], Xmlns, Max_items, + Node, _Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, + Max_items, Node, _val); decode_pubsub_items_attrs(__TopXMLNS, [_ | _attrs], + Xmlns, Max_items, Node, Subid) -> + decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, + Max_items, Node, Subid); +decode_pubsub_items_attrs(__TopXMLNS, [], Xmlns, Max_items, Node, Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Max_items, - Node, Subid); -decode_pubsub_items_attrs(__TopXMLNS, [], Max_items, - Node, Subid) -> - {decode_pubsub_items_attr_max_items(__TopXMLNS, + {decode_pubsub_items_attr_xmlns(__TopXMLNS, Xmlns), + decode_pubsub_items_attr_max_items(__TopXMLNS, Max_items), decode_pubsub_items_attr_node(__TopXMLNS, Node), decode_pubsub_items_attr_subid(__TopXMLNS, Subid)}. -encode_pubsub_items({pubsub_items, Node, Max_items, - Subid, Items}, +encode_pubsub_items({ps_items, Xmlns, Node, Items, + Max_items, Subid, Retract}, _xmlns_attrs) -> _els = lists:reverse('encode_pubsub_items_$items'(Items, - [])), + 'encode_pubsub_items_$retract'(Retract, + []))), _attrs = encode_pubsub_items_attr_subid(Subid, encode_pubsub_items_attr_node(Node, encode_pubsub_items_attr_max_items(Max_items, - _xmlns_attrs))), + encode_pubsub_items_attr_xmlns(Xmlns, + _xmlns_attrs)))), {xmlel, <<"items">>, _attrs, _els}. 'encode_pubsub_items_$items'([], _acc) -> _acc; @@ -13362,6 +15396,19 @@ encode_pubsub_items({pubsub_items, Node, Max_items, 'encode_pubsub_items_$items'(_els, [encode_pubsub_item(Items, []) | _acc]). +'encode_pubsub_items_$retract'(undefined, _acc) -> _acc; +'encode_pubsub_items_$retract'(Retract, _acc) -> + [encode_pubsub_event_retract(Retract, []) | _acc]. + +decode_pubsub_items_attr_xmlns(__TopXMLNS, undefined) -> + <<>>; +decode_pubsub_items_attr_xmlns(__TopXMLNS, _val) -> + _val. + +encode_pubsub_items_attr_xmlns(<<>>, _acc) -> _acc; +encode_pubsub_items_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + decode_pubsub_items_attr_max_items(__TopXMLNS, undefined) -> undefined; @@ -13400,9 +15447,10 @@ decode_pubsub_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> __Xmls = decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, _els, []), - Id = decode_pubsub_item_attrs(__TopXMLNS, _attrs, - undefined), - {pubsub_item, Id, __Xmls}. + {Id, Xmlns, Node, Publisher} = + decode_pubsub_item_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined, undefined), + {ps_item, Xmlns, Id, __Xmls, Node, Publisher}. decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, [], __Xmls) -> @@ -13417,18 +15465,46 @@ decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, __Xmls). decode_pubsub_item_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_item_attrs(__TopXMLNS, [_ | _attrs], - Id) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id); -decode_pubsub_item_attrs(__TopXMLNS, [], Id) -> - decode_pubsub_item_attr_id(__TopXMLNS, Id). - -encode_pubsub_item({pubsub_item, Id, __Xmls}, + [{<<"id">>, _val} | _attrs], _Id, Xmlns, Node, + Publisher) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, _val, + Xmlns, Node, Publisher); +decode_pubsub_item_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Id, _Xmlns, Node, + Publisher) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, _val, + Node, Publisher); +decode_pubsub_item_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], Id, Xmlns, _Node, + Publisher) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, + _val, Publisher); +decode_pubsub_item_attrs(__TopXMLNS, + [{<<"publisher">>, _val} | _attrs], Id, Xmlns, Node, + _Publisher) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, + Node, _val); +decode_pubsub_item_attrs(__TopXMLNS, [_ | _attrs], Id, + Xmlns, Node, Publisher) -> + decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, + Node, Publisher); +decode_pubsub_item_attrs(__TopXMLNS, [], Id, Xmlns, + Node, Publisher) -> + {decode_pubsub_item_attr_id(__TopXMLNS, Id), + decode_pubsub_item_attr_xmlns(__TopXMLNS, Xmlns), + decode_pubsub_item_attr_node(__TopXMLNS, Node), + decode_pubsub_item_attr_publisher(__TopXMLNS, + Publisher)}. + +encode_pubsub_item({ps_item, Xmlns, Id, __Xmls, Node, + Publisher}, _xmlns_attrs) -> _els = __Xmls, - _attrs = encode_pubsub_item_attr_id(Id, _xmlns_attrs), + _attrs = encode_pubsub_item_attr_publisher(Publisher, + encode_pubsub_item_attr_node(Node, + encode_pubsub_item_attr_xmlns(Xmlns, + encode_pubsub_item_attr_id(Id, + _xmlns_attrs)))), {xmlel, <<"item">>, _attrs, _els}. decode_pubsub_item_attr_id(__TopXMLNS, undefined) -> @@ -13439,40 +15515,287 @@ encode_pubsub_item_attr_id(<<>>, _acc) -> _acc; encode_pubsub_item_attr_id(_val, _acc) -> [{<<"id">>, _val} | _acc]. +decode_pubsub_item_attr_xmlns(__TopXMLNS, undefined) -> + <<>>; +decode_pubsub_item_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_pubsub_item_attr_xmlns(<<>>, _acc) -> _acc; +encode_pubsub_item_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_pubsub_item_attr_node(__TopXMLNS, undefined) -> + <<>>; +decode_pubsub_item_attr_node(__TopXMLNS, _val) -> _val. + +encode_pubsub_item_attr_node(<<>>, _acc) -> _acc; +encode_pubsub_item_attr_node(_val, _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_item_attr_publisher(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_item_attr_publisher(__TopXMLNS, _val) -> + _val. + +encode_pubsub_item_attr_publisher(<<>>, _acc) -> _acc; +encode_pubsub_item_attr_publisher(_val, _acc) -> + [{<<"publisher">>, _val} | _acc]. + +decode_pubsub_event_retract(__TopXMLNS, __IgnoreEls, + {xmlel, <<"retract">>, _attrs, _els}) -> + Id = decode_pubsub_event_retract_attrs(__TopXMLNS, + _attrs, undefined), + Id. + +decode_pubsub_event_retract_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id) -> + decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, + _val); +decode_pubsub_event_retract_attrs(__TopXMLNS, + [_ | _attrs], Id) -> + decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, + Id); +decode_pubsub_event_retract_attrs(__TopXMLNS, [], Id) -> + decode_pubsub_event_retract_attr_id(__TopXMLNS, Id). + +encode_pubsub_event_retract(Id, _xmlns_attrs) -> + _els = [], + _attrs = encode_pubsub_event_retract_attr_id(Id, + _xmlns_attrs), + {xmlel, <<"retract">>, _attrs, _els}. + +decode_pubsub_event_retract_attr_id(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"id">>, <<"retract">>, __TopXMLNS}}); +decode_pubsub_event_retract_attr_id(__TopXMLNS, _val) -> + _val. + +encode_pubsub_event_retract_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_pubsub_event_configuration(__TopXMLNS, + __IgnoreEls, + {xmlel, <<"configuration">>, _attrs, _els}) -> + Xdata = + decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, _els, undefined), + Node = + decode_pubsub_event_configuration_attrs(__TopXMLNS, + _attrs, undefined), + {Node, Xdata}. + +decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, [], Xdata) -> + Xdata; +decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, + [{xmlel, <<"x">>, _attrs, _} = _el + | _els], + Xdata) -> + case get_attr(<<"xmlns">>, _attrs) of + <<"jabber:x:data">> -> + decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, _els, + decode_xdata(<<"jabber:x:data">>, + __IgnoreEls, _el)); + _ -> + decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, _els, Xdata) + end; +decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, [_ | _els], Xdata) -> + decode_pubsub_event_configuration_els(__TopXMLNS, + __IgnoreEls, _els, Xdata). + +decode_pubsub_event_configuration_attrs(__TopXMLNS, + [{<<"node">>, _val} | _attrs], _Node) -> + decode_pubsub_event_configuration_attrs(__TopXMLNS, + _attrs, _val); +decode_pubsub_event_configuration_attrs(__TopXMLNS, + [_ | _attrs], Node) -> + decode_pubsub_event_configuration_attrs(__TopXMLNS, + _attrs, Node); +decode_pubsub_event_configuration_attrs(__TopXMLNS, [], + Node) -> + decode_pubsub_event_configuration_attr_node(__TopXMLNS, + Node). + +encode_pubsub_event_configuration({Node, Xdata}, + _xmlns_attrs) -> + _els = + lists:reverse('encode_pubsub_event_configuration_$xdata'(Xdata, + [])), + _attrs = + encode_pubsub_event_configuration_attr_node(Node, + _xmlns_attrs), + {xmlel, <<"configuration">>, _attrs, _els}. + +'encode_pubsub_event_configuration_$xdata'(undefined, + _acc) -> + _acc; +'encode_pubsub_event_configuration_$xdata'(Xdata, + _acc) -> + [encode_xdata(Xdata, + [{<<"xmlns">>, <<"jabber:x:data">>}]) + | _acc]. + +decode_pubsub_event_configuration_attr_node(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"node">>, <<"configuration">>, + __TopXMLNS}}); +decode_pubsub_event_configuration_attr_node(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_event_configuration_attr_node(_val, + _acc) -> + [{<<"node">>, _val} | _acc]. + +decode_pubsub_owner_affiliation(__TopXMLNS, __IgnoreEls, + {xmlel, <<"affiliation">>, _attrs, _els}) -> + {Jid, Xmlns, Type} = + decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + _attrs, undefined, undefined, + undefined), + {ps_affiliation, Xmlns, <<>>, Type, Jid}. + +decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], _Jid, Xmlns, + Type) -> + decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + _attrs, _val, Xmlns, Type); +decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Jid, + _Xmlns, Type) -> + decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + _attrs, Jid, _val, Type); +decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + [{<<"affiliation">>, _val} | _attrs], Jid, + Xmlns, _Type) -> + decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + _attrs, Jid, Xmlns, _val); +decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + [_ | _attrs], Jid, Xmlns, Type) -> + decode_pubsub_owner_affiliation_attrs(__TopXMLNS, + _attrs, Jid, Xmlns, Type); +decode_pubsub_owner_affiliation_attrs(__TopXMLNS, [], + Jid, Xmlns, Type) -> + {decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, + Jid), + decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, + Xmlns), + decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, + Type)}. + +encode_pubsub_owner_affiliation({ps_affiliation, Xmlns, + _, Type, Jid}, + _xmlns_attrs) -> + _els = [], + _attrs = + encode_pubsub_owner_affiliation_attr_affiliation(Type, + encode_pubsub_owner_affiliation_attr_xmlns(Xmlns, + encode_pubsub_owner_affiliation_attr_jid(Jid, + _xmlns_attrs))), + {xmlel, <<"affiliation">>, _attrs, _els}. + +decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"jid">>, <<"affiliation">>, + __TopXMLNS}}); +decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, + _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"jid">>, <<"affiliation">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_owner_affiliation_attr_jid(_val, _acc) -> + [{<<"jid">>, enc_jid(_val)} | _acc]. + +decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_owner_affiliation_attr_xmlns(<<>>, + _acc) -> + _acc; +encode_pubsub_owner_affiliation_attr_xmlns(_val, + _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, + undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"affiliation">>, <<"affiliation">>, + __TopXMLNS}}); +decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, + _val) -> + case catch dec_enum(_val, + [member, none, outcast, owner, publisher, + 'publish-only']) + of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"affiliation">>, <<"affiliation">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_owner_affiliation_attr_affiliation(_val, + _acc) -> + [{<<"affiliation">>, enc_enum(_val)} | _acc]. + decode_pubsub_affiliation(__TopXMLNS, __IgnoreEls, {xmlel, <<"affiliation">>, _attrs, _els}) -> - {Node, Type} = + {Node, Xmlns, Type} = decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {pubsub_affiliation, Node, Type}. + undefined, undefined, undefined), + {ps_affiliation, Xmlns, Node, Type, undefined}. decode_pubsub_affiliation_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Type) -> + [{<<"node">>, _val} | _attrs], _Node, Xmlns, + Type) -> + decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, + _val, Xmlns, Type); +decode_pubsub_affiliation_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Node, _Xmlns, + Type) -> decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - _val, Type); + Node, _val, Type); decode_pubsub_affiliation_attrs(__TopXMLNS, [{<<"affiliation">>, _val} | _attrs], Node, - _Type) -> + Xmlns, _Type) -> decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - Node, _val); + Node, Xmlns, _val); decode_pubsub_affiliation_attrs(__TopXMLNS, - [_ | _attrs], Node, Type) -> + [_ | _attrs], Node, Xmlns, Type) -> decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - Node, Type); + Node, Xmlns, Type); decode_pubsub_affiliation_attrs(__TopXMLNS, [], Node, - Type) -> + Xmlns, Type) -> {decode_pubsub_affiliation_attr_node(__TopXMLNS, Node), + decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, Xmlns), decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, Type)}. -encode_pubsub_affiliation({pubsub_affiliation, Node, - Type}, +encode_pubsub_affiliation({ps_affiliation, Xmlns, Node, + Type, _}, _xmlns_attrs) -> _els = [], _attrs = encode_pubsub_affiliation_attr_affiliation(Type, - encode_pubsub_affiliation_attr_node(Node, - _xmlns_attrs)), + encode_pubsub_affiliation_attr_xmlns(Xmlns, + encode_pubsub_affiliation_attr_node(Node, + _xmlns_attrs))), {xmlel, <<"affiliation">>, _attrs, _els}. decode_pubsub_affiliation_attr_node(__TopXMLNS, @@ -13486,6 +15809,18 @@ decode_pubsub_affiliation_attr_node(__TopXMLNS, _val) -> encode_pubsub_affiliation_attr_node(_val, _acc) -> [{<<"node">>, _val} | _acc]. +decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_affiliation_attr_xmlns(<<>>, _acc) -> + _acc; +encode_pubsub_affiliation_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -13510,57 +15845,86 @@ encode_pubsub_affiliation_attr_affiliation(_val, decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, {xmlel, <<"subscription">>, _attrs, _els}) -> - {Jid, Node, Subid, Type} = + {Xmlns, Jid, Node, Subid, Type, Expiry} = decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, - undefined), - {pubsub_subscription, Jid, Node, Subid, Type}. + undefined, undefined, undefined), + {ps_subscription, Xmlns, Jid, Type, Node, Subid, + Expiry}. decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Node, - Subid, Type) -> + [{<<"xmlns">>, _val} | _attrs], _Xmlns, Jid, + Node, Subid, Type, Expiry) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + _val, Jid, Node, Subid, Type, Expiry); +decode_pubsub_subscription_attrs(__TopXMLNS, + [{<<"jid">>, _val} | _attrs], Xmlns, _Jid, + Node, Subid, Type, Expiry) -> decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - _val, Node, Subid, Type); + Xmlns, _val, Node, Subid, Type, Expiry); decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Jid, _Node, - Subid, Type) -> + [{<<"node">>, _val} | _attrs], Xmlns, Jid, + _Node, Subid, Type, Expiry) -> decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Jid, _val, Subid, Type); + Xmlns, Jid, _val, Subid, Type, Expiry); decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Jid, Node, - _Subid, Type) -> + [{<<"subid">>, _val} | _attrs], Xmlns, Jid, + Node, _Subid, Type, Expiry) -> decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Jid, Node, _val, Type); + Xmlns, Jid, Node, _val, Type, Expiry); decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"subscription">>, _val} | _attrs], Jid, - Node, Subid, _Type) -> + [{<<"subscription">>, _val} | _attrs], Xmlns, + Jid, Node, Subid, _Type, Expiry) -> decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Jid, Node, Subid, _val); + Xmlns, Jid, Node, Subid, _val, Expiry); decode_pubsub_subscription_attrs(__TopXMLNS, - [_ | _attrs], Jid, Node, Subid, Type) -> + [{<<"expiry">>, _val} | _attrs], Xmlns, Jid, + Node, Subid, Type, _Expiry) -> decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Jid, Node, Subid, Type); -decode_pubsub_subscription_attrs(__TopXMLNS, [], Jid, - Node, Subid, Type) -> - {decode_pubsub_subscription_attr_jid(__TopXMLNS, Jid), + Xmlns, Jid, Node, Subid, Type, _val); +decode_pubsub_subscription_attrs(__TopXMLNS, + [_ | _attrs], Xmlns, Jid, Node, Subid, Type, + Expiry) -> + decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, + Xmlns, Jid, Node, Subid, Type, Expiry); +decode_pubsub_subscription_attrs(__TopXMLNS, [], Xmlns, + Jid, Node, Subid, Type, Expiry) -> + {decode_pubsub_subscription_attr_xmlns(__TopXMLNS, + Xmlns), + decode_pubsub_subscription_attr_jid(__TopXMLNS, Jid), decode_pubsub_subscription_attr_node(__TopXMLNS, Node), decode_pubsub_subscription_attr_subid(__TopXMLNS, Subid), decode_pubsub_subscription_attr_subscription(__TopXMLNS, - Type)}. + Type), + decode_pubsub_subscription_attr_expiry(__TopXMLNS, + Expiry)}. -encode_pubsub_subscription({pubsub_subscription, Jid, - Node, Subid, Type}, +encode_pubsub_subscription({ps_subscription, Xmlns, Jid, + Type, Node, Subid, Expiry}, _xmlns_attrs) -> _els = [], - _attrs = - encode_pubsub_subscription_attr_subscription(Type, - encode_pubsub_subscription_attr_subid(Subid, - encode_pubsub_subscription_attr_node(Node, - encode_pubsub_subscription_attr_jid(Jid, - _xmlns_attrs)))), + _attrs = encode_pubsub_subscription_attr_expiry(Expiry, + encode_pubsub_subscription_attr_subscription(Type, + encode_pubsub_subscription_attr_subid(Subid, + encode_pubsub_subscription_attr_node(Node, + encode_pubsub_subscription_attr_jid(Jid, + encode_pubsub_subscription_attr_xmlns(Xmlns, + _xmlns_attrs)))))), {xmlel, <<"subscription">>, _attrs, _els}. +decode_pubsub_subscription_attr_xmlns(__TopXMLNS, + undefined) -> + <<>>; +decode_pubsub_subscription_attr_xmlns(__TopXMLNS, + _val) -> + _val. + +encode_pubsub_subscription_attr_xmlns(<<>>, _acc) -> + _acc; +encode_pubsub_subscription_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + decode_pubsub_subscription_attr_jid(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -13624,6 +15988,25 @@ encode_pubsub_subscription_attr_subscription(_val, _acc) -> [{<<"subscription">>, enc_enum(_val)} | _acc]. +decode_pubsub_subscription_attr_expiry(__TopXMLNS, + undefined) -> + undefined; +decode_pubsub_subscription_attr_expiry(__TopXMLNS, + _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"expiry">>, <<"subscription">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_pubsub_subscription_attr_expiry(undefined, + _acc) -> + _acc; +encode_pubsub_subscription_attr_expiry(_val, _acc) -> + [{<<"expiry">>, enc_utc(_val)} | _acc]. + decode_xdata(__TopXMLNS, __IgnoreEls, {xmlel, <<"x">>, _attrs, _els}) -> {Fields, Items, Instructions, Reported, Title} = -- cgit v1.2.3 From 5ec972b00f2f140594eebfe1569e203cfb4f741c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 8 Sep 2016 15:49:27 +0300 Subject: Improve pubsub code --- src/adhoc.erl | 149 ---------------------------------------- src/mod_pubsub.erl | 75 ++++++++++++-------- src/node_dag.erl | 7 +- src/node_dispatch.erl | 14 ++-- src/node_flat.erl | 74 ++++++++++---------- src/node_flat_sql.erl | 7 +- src/nodetree_dag.erl | 18 ++--- src/nodetree_tree.erl | 10 +-- src/nodetree_tree_sql.erl | 18 ++--- src/pubsub_db_sql.erl | 16 ++--- src/pubsub_subscription.erl | 95 ++++++++++--------------- src/pubsub_subscription_sql.erl | 114 +++++++++++++----------------- 12 files changed, 215 insertions(+), 382 deletions(-) delete mode 100644 src/adhoc.erl (limited to 'src') diff --git a/src/adhoc.erl b/src/adhoc.erl deleted file mode 100644 index 6970584f9..000000000 --- a/src/adhoc.erl +++ /dev/null @@ -1,149 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : adhoc.erl -%%% Author : Magnus Henoch -%%% Purpose : Provide helper functions for ad-hoc commands (XEP-0050) -%%% Created : 31 Oct 2005 by Magnus Henoch -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%---------------------------------------------------------------------- - --module(adhoc). - --author('henoch@dtek.chalmers.se'). - --export([ - parse_request/1, - produce_response/2, - produce_response/1 -]). - --include("ejabberd.hrl"). --include("logger.hrl"). --include("jlib.hrl"). --include("adhoc.hrl"). - -%% Parse an ad-hoc request. Return either an adhoc_request record or -%% an {error, ErrorType} tuple. -%% --spec parse_request(IQ :: iq_request()) -> adhoc_response() | {error, _}. - -parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) -> - ?DEBUG("entering parse_request...", []), - Node = fxml:get_tag_attr_s(<<"node">>, SubEl), - SessionID = fxml:get_tag_attr_s(<<"sessionid">>, SubEl), - Action = fxml:get_tag_attr_s(<<"action">>, SubEl), - XData = find_xdata_el(SubEl), - #xmlel{children = AllEls} = SubEl, - Others = case XData of - false -> AllEls; - _ -> lists:delete(XData, AllEls) - end, - #adhoc_request{ - lang = Lang, - node = Node, - sessionid = SessionID, - action = Action, - xdata = XData, - others = Others - }; -parse_request(#iq{lang = Lang}) -> - Text = <<"Failed to parse ad-hoc command request">>, - {error, ?ERRT_BAD_REQUEST(Lang, Text)}. - -%% Borrowed from mod_vcard.erl -find_xdata_el(#xmlel{children = SubEls}) -> - find_xdata_el1(SubEls). - -find_xdata_el1([]) -> false; -find_xdata_el1([El | Els]) when is_record(El, xmlel) -> - case fxml:get_tag_attr_s(<<"xmlns">>, El) of - ?NS_XDATA -> El; - _ -> find_xdata_el1(Els) - end; -find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). - -%% Produce a node to use as response from an adhoc_response -%% record, filling in values for language, node and session id from -%% the request. -%% --spec produce_response(Adhoc_Request :: adhoc_request(), - Adhoc_Response :: adhoc_response()) -> - Xmlel::xmlel(). - -%% Produce a node to use as response from an adhoc_response -%% record. -produce_response(#adhoc_request{lang = Lang, node = Node, sessionid = SessionID}, - Adhoc_Response) -> - produce_response(Adhoc_Response#adhoc_response{ - lang = Lang, node = Node, sessionid = SessionID - }). - -%% --spec produce_response(Adhoc_Response::adhoc_response()) -> Xmlel::xmlel(). - -produce_response( - #adhoc_response{ - %lang = _Lang, - node = Node, - sessionid = ProvidedSessionID, - status = Status, - defaultaction = DefaultAction, - actions = Actions, - notes = Notes, - elements = Elements - }) -> - SessionID = if is_binary(ProvidedSessionID), - ProvidedSessionID /= <<"">> -> ProvidedSessionID; - true -> jlib:now_to_utc_string(p1_time_compat:timestamp()) - end, - case Actions of - [] -> - ActionsEls = []; - _ -> - case DefaultAction of - <<"">> -> ActionsElAttrs = []; - _ -> ActionsElAttrs = [{<<"execute">>, DefaultAction}] - end, - ActionsEls = [ - #xmlel{ - name = <<"actions">>, - attrs = ActionsElAttrs, - children = [ - #xmlel{name = Action, attrs = [], children = []} - || Action <- Actions] - } - ] - end, - NotesEls = lists:map(fun({Type, Text}) -> - #xmlel{ - name = <<"note">>, - attrs = [{<<"type">>, Type}], - children = [{xmlcdata, Text}] - } - end, Notes), - #xmlel{ - name = <<"command">>, - attrs = [ - {<<"xmlns">>, ?NS_COMMANDS}, - {<<"sessionid">>, SessionID}, - {<<"node">>, Node}, - {<<"status">>, iolist_to_binary(atom_to_list(Status))} - ], - children = ActionsEls ++ NotesEls ++ Elements - }. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index c84fb5fe8..a7a0e2d88 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -41,8 +41,6 @@ -include("ejabberd.hrl"). -include("logger.hrl"). -%%-include("adhoc.hrl"). -%%-include("jlib.hrl"). -include("xmpp.hrl"). -include("pubsub.hrl"). @@ -1199,11 +1197,14 @@ iq_get_vcard(Lang) -> iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, sub_els = [SubEl]}) -> case {IQType, SubEl} of - {set, #pubsub{create = Node, configure = {_, XData}, + {set, #pubsub{create = Node, configure = Configure, _ = undefined}} when is_binary(Node) -> ServerHost = serverhost(Host), Plugins = config(ServerHost, plugins), - Config = get_xdata_fields(XData), + Config = case Configure of + {_, XData} -> get_xdata_fields(XData); + undefined -> [] + end, Type = hd(Plugins), create_node(Host, ServerHost, Node, From, Type, Access, Config); {set, #pubsub{publish = #ps_publish{node = Node, items = Items}, @@ -1223,7 +1224,12 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, _ = undefined}} -> case Items of [#ps_item{id = ItemId}] -> - delete_item(Host, Node, From, ItemId, Notify); + if ItemId /= <<>> -> + delete_item(Host, Node, From, ItemId, Notify); + true -> + {error, extended_error(xmpp:err_bad_request(), + err_item_required())} + end; [] -> {error, extended_error(xmpp:err_bad_request(), err_item_required())}; _ -> @@ -1259,11 +1265,14 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, jid = JID, xdata = XData}, _ = undefined}} -> set_options(Host, Node, JID, SubId, get_xdata_fields(XData)); + {set, #pubsub{}} -> + {error, xmpp:err_bad_request()}; _ -> {error, xmpp:err_feature_not_implemented()} end. --spec iq_pubsub_owner(binary() | ljid(), iq()) -> {result, pubsub()} | {error, error()}. +-spec iq_pubsub_owner(binary() | ljid(), iq()) -> {result, pubsub_owner() | undefined} | + {error, error()}. iq_pubsub_owner(Host, #iq{type = IQType, from = From, lang = Lang, sub_els = [SubEl]}) -> case {IQType, SubEl} of @@ -1275,7 +1284,7 @@ iq_pubsub_owner(Host, #iq{type = IQType, from = From, undefined -> {error, xmpp:err_bad_request(<<"No data form found">>, Lang)}; #xdata{type = cancel} -> - {result, #pubsub{}}; + {result, #pubsub_owner{}}; #xdata{type = submit} -> Config = get_xdata_fields(XData), set_configure(Host, Node, From, Config, Lang); @@ -1684,7 +1693,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> %%
  • The node is the root collection node, which cannot be deleted.
  • %%
  • The specified node does not exist.
  • %% --spec delete_node(host(), binary(), jid()) -> {result, pubsub()} | {error, error()}. +-spec delete_node(host(), binary(), jid()) -> {result, pubsub_owner()} | {error, error()}. delete_node(_Host, <<>>, _Owner) -> {error, xmpp:err_not_allowed(<<"No node specified">>, ?MYLANG)}; delete_node(Host, Node, Owner) -> @@ -1701,7 +1710,7 @@ delete_node(Host, Node, Owner) -> {error, xmpp:err_forbidden(<<"Owner privileges required">>, ?MYLANG)} end end, - Reply = [], + Reply = undefined, ServerHost = serverhost(Host), case transaction(Host, Node, Action, transaction) of {result, {_, {SubsByDepth, {Result, broadcast, Removed}}}} -> @@ -2566,8 +2575,8 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> Error end. --spec get_subscriptions(binary(), binary(), jid()) -> {result, pubsub()} | - {error, error()}. +-spec get_subscriptions(host(), binary(), jid()) -> {result, pubsub_owner()} | + {error, error()}. get_subscriptions(Host, Node, JID) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), @@ -2595,7 +2604,7 @@ get_subscriptions(Host, Node, JID) -> ({AJID, Sub, SubId}) -> [#ps_subscription{jid = AJID, type = Sub, subid = SubId}] end, Subs), - {result, #pubsub{subscriptions = {Node, Entities}}}; + {result, #pubsub_owner{subscriptions = {Node, Entities}}}; Error -> Error end. @@ -2623,6 +2632,8 @@ get_subscriptions_for_send_last(Host, PType, sql, JID, LJID, BJID) -> get_subscriptions_for_send_last(_Host, _PType, _, _JID, _LJID, _BJID) -> []. +-spec set_subscriptions(host(), binary(), jid(), [ps_subscription()]) -> + {result, undefined} | {error, error()}. set_subscriptions(Host, Node, From, Entities) -> Owner = jid:tolower(jid:remove_resource(From)), Notify = fun(#ps_subscription{jid = JID, type = Sub}) -> @@ -3152,7 +3163,7 @@ user_resource(_, _, Resource) -> %%%%%%% Configuration handling -spec get_configure(host(), binary(), binary(), jid(), - binary()) -> {error, error()} | {result, pubsub()}. + binary()) -> {error, error()} | {result, pubsub_owner()}. get_configure(Host, ServerHost, Node, From, Lang) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> case node_call(Host, Type, get_affiliation, [Nidx, From]) of @@ -3171,7 +3182,7 @@ get_configure(Host, ServerHost, Node, From, Lang) -> Other -> Other end. --spec get_default(host(), binary(), jid(), binary()) -> {result, pubsub()}. +-spec get_default(host(), binary(), jid(), binary()) -> {result, pubsub_owner()}. get_default(Host, Node, _From, Lang) -> Type = select_type(Host, Host, Node), Options = node_options(Host, Type), @@ -3371,6 +3382,8 @@ get_configure_xfields(_Type, Options, Lang, Groups) -> %% -spec set_configure(host(), binary(), jid(), [{binary(), [binary()]}], binary()) -> {result, undefined} | {error, error()}. +set_configure(_Host, <<>>, _From, _Config, _Lang) -> + {error, extended_error(xmpp:err_bad_request(), err_nodeid_required())}; set_configure(Host, Node, From, Config, Lang) -> Action = fun(#pubsub_node{options = Options, type = Type, id = Nidx} = N) -> @@ -3664,26 +3677,28 @@ select_type(ServerHost, Host, Node, Type) -> select_type(ServerHost, Host, Node) -> select_type(ServerHost, Host, Node, hd(plugins(Host))). +-spec feature(binary()) -> binary(). feature(<<"rsm">>) -> ?NS_RSM; feature(Feature) -> <<(?NS_PUBSUB)/binary, "#", Feature/binary>>. +-spec features() -> [binary()]. features() -> [% see plugin "access-authorize", % OPTIONAL - <<"access-open">>, % OPTIONAL this relates to access_model option in node_hometree - <<"access-presence">>, % OPTIONAL this relates to access_model option in node_pep - <<"access-whitelist">>, % OPTIONAL - <<"collections">>, % RECOMMENDED - <<"config-node">>, % RECOMMENDED - <<"create-and-configure">>, % RECOMMENDED - <<"item-ids">>, % RECOMMENDED - <<"last-published">>, % RECOMMENDED - <<"member-affiliation">>, % RECOMMENDED - <<"presence-notifications">>, % OPTIONAL - <<"presence-subscribe">>, % RECOMMENDED - <<"publisher-affiliation">>, % RECOMMENDED - <<"publish-only-affiliation">>, % OPTIONAL - <<"retrieve-default">>, - <<"shim">>]. % RECOMMENDED + <<"access-open">>, % OPTIONAL this relates to access_model option in node_hometree + <<"access-presence">>, % OPTIONAL this relates to access_model option in node_pep + <<"access-whitelist">>, % OPTIONAL + <<"collections">>, % RECOMMENDED + <<"config-node">>, % RECOMMENDED + <<"create-and-configure">>, % RECOMMENDED + <<"item-ids">>, % RECOMMENDED + <<"last-published">>, % RECOMMENDED + <<"member-affiliation">>, % RECOMMENDED + <<"presence-notifications">>, % OPTIONAL + <<"presence-subscribe">>, % RECOMMENDED + <<"publisher-affiliation">>, % RECOMMENDED + <<"publish-only-affiliation">>, % OPTIONAL + <<"retrieve-default">>, + <<"shim">>]. % RECOMMENDED % see plugin "retrieve-items", % RECOMMENDED % see plugin "retrieve-subscriptions", % RECOMMENDED @@ -3920,7 +3935,7 @@ err_subid_required() -> err_too_many_subscriptions() -> #ps_error{type = 'too-many-subscriptions'}. --spec err_unsupported(ps_error_feature()) -> ps_error(). +-spec err_unsupported(ps_feature()) -> ps_error(). err_unsupported(Feature) -> #ps_error{type = 'unsupported', feature = Feature}. diff --git a/src/node_dag.erl b/src/node_dag.erl index afb610ca7..45f8ade63 100644 --- a/src/node_dag.erl +++ b/src/node_dag.erl @@ -28,7 +28,7 @@ -author('bjc@kublai.com'). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, @@ -78,8 +78,9 @@ publish_item(Nidx, Publisher, Model, MaxItems, ItemId, Payload, PubOpts) -> case find_opt(node_type, Options) of collection -> Txt = <<"Publishing items to collection node is not allowed">>, - {error, - ?ERR_EXTENDED(?ERRT_NOT_ALLOWED(?MYLANG, Txt), <<"publish">>)}; + {error, mod_pubsub:extended_error( + xmpp:err_not_allowed(Txt, ?MYLANG), + mod_pubsub:err_unsupported('publish'))}; _ -> node_hometree:publish_item(Nidx, Publisher, Model, MaxItems, ItemId, Payload, PubOpts) diff --git a/src/node_dispatch.erl b/src/node_dispatch.erl index b3af69cd1..0a72b18d5 100644 --- a/src/node_dispatch.erl +++ b/src/node_dispatch.erl @@ -34,7 +34,7 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, @@ -94,10 +94,12 @@ delete_node(Nodes) -> subscribe_node(_Nidx, _Sender, _Subscriber, _AccessModel, _SendLast, _PresenceSubscription, _RosterGroup, _Options) -> - {error, ?ERR_FORBIDDEN}. + {error, mod_pubsub:extended_error(xmpp:err_feature_not_implemented(), + mod_pubsub:err_unsupported('subscribe'))}. unsubscribe_node(_Nidx, _Sender, _Subscriber, _SubId) -> - {error, ?ERR_FORBIDDEN}. + {error, mod_pubsub:extended_error(xmpp:err_feature_not_implemented(), + mod_pubsub:err_unsupported('subscribe'))}. publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload, PubOpts) -> @@ -118,10 +120,12 @@ remove_extra_items(_Nidx, _MaxItems, ItemIds) -> {result, {ItemIds, []}}. delete_item(_Nidx, _Publisher, _PublishModel, _ItemId) -> - {error, ?ERR_ITEM_NOT_FOUND}. + {error, mod_pubsub:extended_error(xmpp:err_feature_not_implemented(), + mod_pubsub:err_unsupported('delete-items'))}. purge_node(_Nidx, _Owner) -> - {error, ?ERR_FORBIDDEN}. + {error, mod_pubsub:extended_error(xmpp:err_feature_not_implemented(), + mod_pubsub:err_unsupported('purge-nodes'))}. get_entity_affiliations(_Host, _Owner) -> {result, []}. diff --git a/src/node_flat.erl b/src/node_flat.erl index 2fb24ee69..2ec9afe54 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -34,7 +34,7 @@ -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, @@ -107,8 +107,8 @@ features() -> <<"retrieve-items">>, <<"retrieve-subscriptions">>, <<"subscribe">>, + %%<<"subscription-options">>, <<"subscription-notifications">>]. -%%<<"subscription-options">> %% @doc Checks if the current user has the permission to create the requested node %%

    In flat node, any unused node name is allowed. The access parameter is also @@ -196,27 +196,27 @@ subscribe_node(Nidx, Sender, Subscriber, AccessModel, Owner = Affiliation == owner, if not Authorized -> {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"invalid-jid">>)}; + mod_pubsub:extended_error((xmpp:err_bad_request()), mod_pubsub:err_invalid_jid())}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; PendingSubscription -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"pending-subscription">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_pending_subscription())}; (AccessModel == presence) and (not PresenceSubscription) and (not Owner) -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and (not RosterGroup) and (not Owner) -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and (not Whitelisted) and (not Owner) -> {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + mod_pubsub:extended_error((xmpp:err_not_allowed()), mod_pubsub:err_closed_node())}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; %%ForbiddenAnonymous -> %% % Requesting entity is anonymous - %% {error, ?ERR_FORBIDDEN}; + %% {error, xmpp:err_forbidden()}; true -> %%SubId = pubsub_subscription:add_subscription(Subscriber, Nidx, Options), {NewSub, SubId} = case Subscriptions of @@ -265,17 +265,17 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> if %% Requesting entity is prohibited from unsubscribing entity not Authorized -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %% Entity did not specify SubId %%SubId == "", ?? -> - %% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; + %% {error, mod_pubsub:extended_error(xmpp:err_bad_request(), "subid-required")}; %% Invalid subscription identifier %%InvalidSubId -> - %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; + %% {error, mod_pubsub:extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; %% Requesting entity is not a subscriber Subscriptions == [] -> {error, - ?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)}; + mod_pubsub:extended_error(xmpp:err_unexpected_request(), mod_pubsub:err_not_subscribed())}; %% Subid supplied, so use that. SubIdExists -> Sub = first_in_list(fun @@ -289,7 +289,7 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> {result, default}; false -> {error, - ?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)} + mod_pubsub:extended_error(xmpp:err_unexpected_request(), mod_pubsub:err_not_subscribed())} end; %% Asking to remove all subscriptions to the given node SubId == all -> @@ -302,7 +302,7 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) -> %% No subid and more than one possible subscription match. true -> {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)} + mod_pubsub:extended_error((xmpp:err_bad_request()), mod_pubsub:err_subid_required())} end. delete_subscriptions(SubKey, Nidx, Subscriptions, SubState) -> @@ -366,7 +366,7 @@ publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload, or (Affiliation == publisher) or (Affiliation == publish_only)) or (Subscribed == true)) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; true -> if MaxItems > 0 -> Now = p1_time_compat:timestamp(), @@ -425,7 +425,7 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> _ -> false end, if not Allowed -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; true -> case lists:member(ItemId, Items) of true -> @@ -450,9 +450,9 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> (_, Res) -> Res end, - {error, ?ERR_ITEM_NOT_FOUND}, States); + {error, xmpp:err_item_not_found()}, States); _ -> - {error, ?ERR_ITEM_NOT_FOUND} + {error, xmpp:err_item_not_found()} end end end. @@ -474,7 +474,7 @@ purge_node(Nidx, Owner) -> States), {result, {default, broadcast}}; _ -> - {error, ?ERR_FORBIDDEN} + {error, xmpp:err_forbidden()} end. %% @doc

    Return the current affiliations for the given user

    @@ -581,7 +581,7 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) -> case Subscription of none -> {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"not-subscribed">>)}; + mod_pubsub:extended_error((xmpp:err_bad_request()), mod_pubsub:err_not_subscribed())}; _ -> new_subscription(Nidx, Owner, Subscription, SubState) end; @@ -592,7 +592,7 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) -> end; {<<>>, [_ | _]} -> {error, - ?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)}; + mod_pubsub:extended_error((xmpp:err_bad_request()), mod_pubsub:err_subid_required())}; _ -> case Subscription of none -> unsub_with_subid(Nidx, SubId, SubState); @@ -721,23 +721,23 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM can_fetch_item(Affiliation, FullSubscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID - %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; + %{error, mod_pubsub:extended_error(xmpp:err_bad_request(), "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID - %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; + %{error, mod_pubsub:extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; (AccessModel == presence) and not PresenceSubscription -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and not RosterGroup -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and not Whitelisted -> {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + mod_pubsub:extended_error((xmpp:err_not_allowed()), mod_pubsub:err_closed_node())}; (AccessModel == authorize) and not Whitelisted -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; @@ -750,7 +750,7 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM get_item(Nidx, ItemId) -> case mnesia:read({pubsub_item, {ItemId, Nidx}}) of [Item] when is_record(Item, pubsub_item) -> {result, Item}; - _ -> {error, ?ERR_ITEM_NOT_FOUND} + _ -> {error, xmpp:err_item_not_found()} end. get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> @@ -762,23 +762,23 @@ get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _Sub Whitelisted = can_fetch_item(Affiliation, Subscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID - %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; + %{error, mod_pubsub:extended_error(xmpp:err_bad_request(), "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID - %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; + %{error, mod_pubsub:extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; (Affiliation == outcast) or (Affiliation == publish_only) -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; (AccessModel == presence) and not PresenceSubscription -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_presence_subscription_required())}; (AccessModel == roster) and not RosterGroup -> {error, - ?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)}; + mod_pubsub:extended_error((xmpp:err_not_authorized()), mod_pubsub:err_not_in_roster_group())}; (AccessModel == whitelist) and not Whitelisted -> {error, - ?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)}; + mod_pubsub:extended_error((xmpp:err_not_allowed()), mod_pubsub:err_closed_node())}; (AccessModel == authorize) and not Whitelisted -> - {error, ?ERR_FORBIDDEN}; + {error, xmpp:err_forbidden()}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index 2a468c69a..025f6caa8 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -677,7 +677,7 @@ get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex, "where exists ( select count(*) as count1 " "from pubsub_item where nodeid='">>, SNidx, <<"' and modification > pi.modification having count1 = ">>, - IncIndex, <<" );">>]) of + integer_to_binary(IncIndex), <<" );">>]) of {selected, [_], [[O]]} -> [<<"modification">>, <<"'", O/binary, "'">>]; _ -> @@ -699,7 +699,7 @@ get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex, end, Query = fun(mssql, _) -> ejabberd_sql:sql_query_t( - [<<"select top ">>, Max, + [<<"select top ">>, integer_to_binary(Max), <<" itemid, publisher, creation, modification, payload " "from pubsub_item where nodeid='">>, SNidx, <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>, @@ -709,7 +709,8 @@ get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex, [<<"select itemid, publisher, creation, modification, payload " "from pubsub_item where nodeid='">>, SNidx, <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>, - AttrName, <<" ">>, Order, <<" limit ">>, Max, <<" ;">>]) + AttrName, <<" ">>, Order, <<" limit ">>, + integer_to_binary(Max), <<" ;">>]) end, case ejabberd_sql:sql_query_t(Query) of {selected, [<<"itemid">>, <<"publisher">>, <<"creation">>, diff --git a/src/nodetree_dag.erl b/src/nodetree_dag.erl index 387d98413..f17f2846d 100644 --- a/src/nodetree_dag.erl +++ b/src/nodetree_dag.erl @@ -30,7 +30,7 @@ -include_lib("stdlib/include/qlc.hrl"). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, @@ -69,13 +69,13 @@ create_node(Key, Node, Type, Owner, Options, Parents) -> Other -> Other end; _ -> - {error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)} + {error, xmpp:err_conflict(<<"Node already exists">>, ?MYLANG)} end. delete_node(Key, Node) -> case find_node(Key, Node) of false -> - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}; + {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)}; Record -> lists:foreach(fun (#pubsub_node{options = Opts} = Child) -> NewOpts = remove_config_parent(Node, Opts), @@ -99,7 +99,7 @@ get_node(Host, Node, _From) -> get_node(Host, Node) -> case find_node(Host, Node) of - false -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}; + false -> {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)}; Record -> Record end. @@ -115,7 +115,7 @@ get_nodes(Key) -> get_parentnodes(Host, Node, _From) -> case find_node(Host, Node) of false -> - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}; + {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)}; #pubsub_node{parents = Parents} -> Q = qlc:q([N || #pubsub_node{nodeid = {NHost, NNode}} = N @@ -139,7 +139,7 @@ get_subnodes(Host, <<>>) -> get_subnodes_helper(Host, <<>>); get_subnodes(Host, Node) -> case find_node(Host, Node) of - false -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}; + false -> {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)}; _ -> get_subnodes_helper(Host, Node) end. @@ -226,13 +226,13 @@ validate_parentage(Key, Owners, [<<>> | T]) -> validate_parentage(Key, Owners, [ParentID | T]) -> case find_node(Key, ParentID) of false -> - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}; + {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)}; #pubsub_node{owners = POwners, options = POptions} -> NodeType = find_opt(node_type, ?DEFAULT_NODETYPE, POptions), MutualOwners = [O || O <- Owners, PO <- POwners, O == PO], case {MutualOwners, NodeType} of - {[], _} -> {error, ?ERR_FORBIDDEN}; + {[], _} -> {error, xmpp:err_forbidden()}; {_, collection} -> validate_parentage(Key, Owners, T); - {_, _} -> {error, ?ERR_NOT_ALLOWED} + {_, _} -> {error, xmpp:err_not_allowed()} end end. diff --git a/src/nodetree_tree.erl b/src/nodetree_tree.erl index 69b50ff9f..81972ca3c 100644 --- a/src/nodetree_tree.erl +++ b/src/nodetree_tree.erl @@ -40,7 +40,7 @@ -include_lib("stdlib/include/qlc.hrl"). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, @@ -76,13 +76,13 @@ get_node(Host, Node, _From) -> get_node(Host, Node) -> case mnesia:read({pubsub_node, {Host, Node}}) of [Record] when is_record(Record, pubsub_node) -> Record; - _ -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)} + _ -> {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)} end. get_node(Nidx) -> case mnesia:index_read(pubsub_node, Nidx, #pubsub_node.id) of [Record] when is_record(Record, pubsub_node) -> Record; - _ -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)} + _ -> {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)} end. get_nodes(Host, _From) -> @@ -180,10 +180,10 @@ create_node(Host, Node, Type, Owner, Options, Parents) -> options = Options}), {ok, Nidx}; false -> - {error, ?ERR_FORBIDDEN} + {error, xmpp:err_forbidden()} end; _ -> - {error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)} + {error, xmpp:err_conflict(<<"Node already exists">>, ?MYLANG)} end. delete_node(Host, Node) -> diff --git a/src/nodetree_tree_sql.erl b/src/nodetree_tree_sql.erl index edfdbc1d5..c292c7755 100644 --- a/src/nodetree_tree_sql.erl +++ b/src/nodetree_tree_sql.erl @@ -40,7 +40,7 @@ -compile([{parse_transform, ejabberd_sql_pt}]). -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("ejabberd_sql_pt.hrl"). -export([init/3, terminate/2, options/0, set_node/1, @@ -97,7 +97,7 @@ set_node(Record) when is_record(Record, pubsub_node) -> case Nidx of none -> Txt = <<"Node index not found">>, - {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, Txt)}; + {error, xmpp:err_internal_server_error(Txt, ?MYLANG)}; _ -> lists:foreach(fun ({Key, Value}) -> SKey = iolist_to_binary(atom_to_list(Key)), @@ -125,9 +125,9 @@ get_node(Host, Node) -> {selected, [RItem]} -> raw_to_node(Host, RItem); {'EXIT', _Reason} -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}; _ -> - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)} + {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)} end. get_node(Nidx) -> @@ -139,9 +139,9 @@ get_node(Nidx) -> {selected, [{Host, Node, Parent, Type}]} -> raw_to_node(Host, {Node, Parent, Type, Nidx}); {'EXIT', _Reason} -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}; + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}; _ -> - {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)} + {error, xmpp:err_item_not_found(<<"Node not found">>, ?MYLANG)} end. get_nodes(Host, _From) -> @@ -249,12 +249,12 @@ create_node(Host, Node, Type, Owner, Options, Parents) -> Other -> Other end; false -> - {error, ?ERR_FORBIDDEN} + {error, xmpp:err_forbidden()} end; {result, _} -> - {error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)}; + {error, xmpp:err_conflict(<<"Node already exists">>, ?MYLANG)}; {error, db_fail} -> - {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)} + {error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)} end. delete_node(Host, Node) -> diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index b910a5e7d..a6f8888a9 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -75,27 +75,27 @@ add_subscription(#pubsub_subscription{subid = SubId, options = Opts}) -> Opts), ok. -subscription_opt_from_sql({<<"DELIVER">>, Value}) -> +subscription_opt_from_sql([<<"DELIVER">>, Value]) -> {deliver, sql_to_boolean(Value)}; -subscription_opt_from_sql({<<"DIGEST">>, Value}) -> +subscription_opt_from_sql([<<"DIGEST">>, Value]) -> {digest, sql_to_boolean(Value)}; -subscription_opt_from_sql({<<"DIGEST_FREQUENCY">>, Value}) -> +subscription_opt_from_sql([<<"DIGEST_FREQUENCY">>, Value]) -> {digest_frequency, sql_to_integer(Value)}; -subscription_opt_from_sql({<<"EXPIRE">>, Value}) -> +subscription_opt_from_sql([<<"EXPIRE">>, Value]) -> {expire, sql_to_timestamp(Value)}; -subscription_opt_from_sql({<<"INCLUDE_BODY">>, Value}) -> +subscription_opt_from_sql([<<"INCLUDE_BODY">>, Value]) -> {include_body, sql_to_boolean(Value)}; %%TODO: might be > than 1 show_values value??. %% need to use compact all in only 1 opt. -subscription_opt_from_sql({<<"SHOW_VALUES">>, Value}) -> +subscription_opt_from_sql([<<"SHOW_VALUES">>, Value]) -> {show_values, Value}; -subscription_opt_from_sql({<<"SUBSCRIPTION_TYPE">>, Value}) -> +subscription_opt_from_sql([<<"SUBSCRIPTION_TYPE">>, Value]) -> {subscription_type, case Value of <<"items">> -> items; <<"nodes">> -> nodes end}; -subscription_opt_from_sql({<<"SUBSCRIPTION_DEPTH">>, Value}) -> +subscription_opt_from_sql([<<"SUBSCRIPTION_DEPTH">>, Value]) -> {subscription_depth, case Value of <<"all">> -> all; diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index 3ab502184..33c884afb 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -39,7 +39,7 @@ -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PUBSUB_DELIVER, <<"pubsub#deliver">>). -define(PUBSUB_DIGEST, <<"pubsub#digest">>). @@ -112,30 +112,15 @@ get_options_xform(Lang, Options) -> Keys = [deliver, show_values, subscription_type, subscription_depth], XFields = [get_option_xfield(Lang, Key, Options) || Key <- Keys], {result, - #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}], - children = - [#xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, ?NS_PUBSUB_SUB_OPTIONS}]}]}] - ++ XFields}}. + #xdata{type = form, + fields = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [?NS_PUBSUB_SUB_OPTIONS]}| + XFields]}}. parse_options_xform(XFields) -> - case fxml:remove_cdata(XFields) of - [#xmlel{name = <<"x">>} = XEl] -> - case jlib:parse_xdata_submit(XEl) of - XData when is_list(XData) -> - Opts = set_xoption(XData, []), - {result, Opts}; - Other -> Other - end; - _ -> {result, []} - end. + Opts = set_xoption(XFields, []), + {result, Opts}. %%==================================================================== %% Internal functions @@ -223,9 +208,17 @@ val_xfield(digest_frequency = Opt, [Val]) -> _ -> Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + end; +val_xfield(expire = Opt, [Val]) -> + case jlib:datetime_string_to_timestamp(Val) of + undefined -> + Txt = <<"Value of '~s' should be datetime string">>, + ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; + Timestamp -> + Timestamp end; -val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val); val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; val_xfield(subscription_type, [<<"items">>]) -> items; @@ -237,7 +230,7 @@ val_xfield(subscription_depth = Opt, [Depth]) -> _ -> Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end. %% Convert XForm booleans to Erlang booleans. @@ -248,10 +241,7 @@ xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}. - --spec get_option_xfield(Lang :: binary(), Key :: atom(), - Options :: mod_pubsub:subOptions()) -> xmlel(). + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. @@ -261,33 +251,22 @@ get_option_xfield(Lang, Key, Options) -> {Type, OptEls} = type_and_options(xfield_type(Key), Lang), Vals = case lists:keysearch(Key, 1, Options) of {value, {_, Val}} -> - [tr_xfield_values(Vals) - || Vals <- xfield_val(Key, Val)]; - false -> [] + [xfield_val(Key, Val)]; + false -> + [] end, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, Var}, {<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}], - children = OptEls ++ Vals}. + #xdata_field{type = Type, var = Var, + label = translate:translate(Lang, Label), + values = Vals, + options = OptEls}. type_and_options({Type, Options}, Lang) -> {Type, [tr_xfield_options(O, Lang) || O <- Options]}; type_and_options(Type, _Lang) -> {Type, []}. tr_xfield_options({Value, Label}, Lang) -> - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, translate:translate(Lang, Label)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Value}]}]}. - -tr_xfield_values(Value) -> - %% Return the XForm variable name for a subscription option key. - %% Return the XForm variable type for a subscription option key. - #xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Value}]}. + #xdata_option{label = translate:translate(Lang, Label), + value = Value}. xfield_var(deliver) -> ?PUBSUB_DELIVER; %xfield_var(digest) -> ?PUBSUB_DIGEST; @@ -298,24 +277,24 @@ xfield_var(show_values) -> ?PUBSUB_SHOW_VALUES; xfield_var(subscription_type) -> ?PUBSUB_SUBSCRIPTION_TYPE; xfield_var(subscription_depth) -> ?PUBSUB_SUBSCRIPTION_DEPTH. -xfield_type(deliver) -> <<"boolean">>; -%xfield_type(digest) -> <<"boolean">>; -%xfield_type(digest_frequency) -> <<"text-single">>; -%xfield_type(expire) -> <<"text-single">>; -%xfield_type(include_body) -> <<"boolean">>; +xfield_type(deliver) -> boolean; +%xfield_type(digest) -> boolean; +%xfield_type(digest_frequency) -> 'text-single'; +%xfield_type(expire) -> 'text-single'; +%xfield_type(include_body) -> boolean; xfield_type(show_values) -> - {<<"list-multi">>, + {'list-multi', [{<<"away">>, ?SHOW_VALUE_AWAY_LABEL}, {<<"chat">>, ?SHOW_VALUE_CHAT_LABEL}, {<<"dnd">>, ?SHOW_VALUE_DND_LABEL}, {<<"online">>, ?SHOW_VALUE_ONLINE_LABEL}, {<<"xa">>, ?SHOW_VALUE_XA_LABEL}]}; xfield_type(subscription_type) -> - {<<"list-single">>, + {'list-single', [{<<"items">>, ?SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL}, {<<"nodes">>, ?SUBSCRIPTION_TYPE_VALUE_NODES_LABEL}]}; xfield_type(subscription_depth) -> - {<<"list-single">>, + {'list-single', [{<<"1">>, ?SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL}, {<<"all">>, ?SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL}]}. diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index 6e598320c..7c0670957 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -35,7 +35,7 @@ -include("pubsub.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). -define(PUBSUB_DELIVER, <<"pubsub#deliver">>). -define(PUBSUB_DIGEST, <<"pubsub#digest">>). @@ -117,30 +117,15 @@ get_options_xform(Lang, Options) -> Keys = [deliver, show_values, subscription_type, subscription_depth], XFields = [get_option_xfield(Lang, Key, Options) || Key <- Keys], {result, - #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}], - children = - [#xmlel{name = <<"field">>, - attrs = - [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = - [{xmlcdata, ?NS_PUBSUB_SUB_OPTIONS}]}]}] - ++ XFields}}. + #xdata{type = form, + fields = [#xdata_field{type = hidden, + var = <<"FORM_TYPE">>, + values = [?NS_PUBSUB_SUB_OPTIONS]}| + XFields]}}. parse_options_xform(XFields) -> - case fxml:remove_cdata(XFields) of - [#xmlel{name = <<"x">>} = XEl] -> - case jlib:parse_xdata_submit(XEl) of - XData when is_list(XData) -> - Opts = set_xoption(XData, []), - {result, Opts}; - Other -> Other - end; - _ -> {result, []} - end. + Opts = set_xoption(XFields, []), + {result, Opts}. %%==================================================================== %% Internal functions @@ -188,9 +173,17 @@ val_xfield(digest_frequency = Opt, [Val]) -> _ -> Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + end; +val_xfield(expire = Opt, [Val]) -> + case jlib:datetime_string_to_timestamp(Val) of + undefined -> + Txt = <<"Value of '~s' should be datetime string">>, + ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; + Timestamp -> + Timestamp end; -val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val); val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; val_xfield(subscription_type, [<<"items">>]) -> items; @@ -202,7 +195,7 @@ val_xfield(subscription_depth = Opt, [Depth]) -> _ -> Txt = <<"Value of '~s' should be integer">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)} + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end. %% Convert XForm booleans to Erlang booleans. @@ -213,7 +206,7 @@ xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> Txt = <<"Value of '~s' should be boolean">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])), - {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}. + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. @@ -222,34 +215,23 @@ get_option_xfield(Lang, Key, Options) -> Label = xfield_label(Key), {Type, OptEls} = type_and_options(xfield_type(Key), Lang), Vals = case lists:keysearch(Key, 1, Options) of - {value, {_, Val}} -> - [tr_xfield_values(Vals) - || Vals <- xfield_val(Key, Val)]; - false -> [] - end, - #xmlel{name = <<"field">>, - attrs = - [{<<"var">>, Var}, {<<"type">>, Type}, - {<<"label">>, translate:translate(Lang, Label)}], - children = OptEls ++ Vals}. + {value, {_, Val}} -> + [xfield_val(Key, Val)]; + false -> + [] + end, + #xdata_field{type = Type, var = Var, + label = translate:translate(Lang, Label), + values = Vals, + options = OptEls}. type_and_options({Type, Options}, Lang) -> {Type, [tr_xfield_options(O, Lang) || O <- Options]}; type_and_options(Type, _Lang) -> {Type, []}. tr_xfield_options({Value, Label}, Lang) -> - #xmlel{name = <<"option">>, - attrs = - [{<<"label">>, translate:translate(Lang, Label)}], - children = - [#xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Value}]}]}. - -tr_xfield_values(Value) -> - %% Return the XForm variable name for a subscription option key. - %% Return the XForm variable type for a subscription option key. - #xmlel{name = <<"value">>, attrs = [], - children = [{xmlcdata, Value}]}. + #xdata_option{label = translate:translate(Lang, Label), + value = Value}. xfield_var(deliver) -> ?PUBSUB_DELIVER; %xfield_var(digest) -> ?PUBSUB_DIGEST; @@ -260,26 +242,26 @@ xfield_var(show_values) -> ?PUBSUB_SHOW_VALUES; xfield_var(subscription_type) -> ?PUBSUB_SUBSCRIPTION_TYPE; xfield_var(subscription_depth) -> ?PUBSUB_SUBSCRIPTION_DEPTH. -xfield_type(deliver) -> <<"boolean">>; -%xfield_type(digest) -> <<"boolean">>; -%xfield_type(digest_frequency) -> <<"text-single">>; -%xfield_type(expire) -> <<"text-single">>; -%xfield_type(include_body) -> <<"boolean">>; +xfield_type(deliver) -> boolean; +%xfield_type(digest) -> boolean; +%xfield_type(digest_frequency) -> 'text-single'; +%xfield_type(expire) -> 'text-single'; +%xfield_type(include_body) -> boolean; xfield_type(show_values) -> - {<<"list-multi">>, - [{<<"away">>, ?SHOW_VALUE_AWAY_LABEL}, - {<<"chat">>, ?SHOW_VALUE_CHAT_LABEL}, - {<<"dnd">>, ?SHOW_VALUE_DND_LABEL}, - {<<"online">>, ?SHOW_VALUE_ONLINE_LABEL}, - {<<"xa">>, ?SHOW_VALUE_XA_LABEL}]}; + {'list-multi', + [{<<"away">>, ?SHOW_VALUE_AWAY_LABEL}, + {<<"chat">>, ?SHOW_VALUE_CHAT_LABEL}, + {<<"dnd">>, ?SHOW_VALUE_DND_LABEL}, + {<<"online">>, ?SHOW_VALUE_ONLINE_LABEL}, + {<<"xa">>, ?SHOW_VALUE_XA_LABEL}]}; xfield_type(subscription_type) -> - {<<"list-single">>, - [{<<"items">>, ?SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL}, - {<<"nodes">>, ?SUBSCRIPTION_TYPE_VALUE_NODES_LABEL}]}; + {'list-single', + [{<<"items">>, ?SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL}, + {<<"nodes">>, ?SUBSCRIPTION_TYPE_VALUE_NODES_LABEL}]}; xfield_type(subscription_depth) -> - {<<"list-single">>, - [{<<"1">>, ?SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL}, - {<<"all">>, ?SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL}]}. + {'list-single', + [{<<"1">>, ?SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL}, + {<<"all">>, ?SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL}]}. %% Return the XForm variable label for a subscription option key. xfield_label(deliver) -> ?DELIVER_LABEL; -- cgit v1.2.3 From c29a48695d3d46e556aea2ea3c5fb8b558d43f7c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 8 Sep 2016 17:08:48 +0300 Subject: Rename #error{} record to #stanza_error{} --- src/ejabberd_c2s.erl | 4 +- src/ejabberd_piefxis.erl | 2 +- src/ejabberd_router.erl | 4 +- src/ejabberd_s2s_in.erl | 2 +- src/ejabberd_s2s_out.erl | 6 +-- src/ejabberd_service.erl | 2 +- src/gen_pubsub_node.erl | 2 +- src/mod_adhoc.erl | 8 ++-- src/mod_announce.erl | 6 +-- src/mod_blocking.erl | 16 +++---- src/mod_caps.erl | 4 +- src/mod_configure.erl | 10 ++-- src/mod_disco.erl | 16 +++---- src/mod_http_upload.erl | 2 +- src/mod_irc.erl | 2 +- src/mod_mix.erl | 2 +- src/mod_muc_room.erl | 32 ++++++------- src/mod_multicast.erl | 2 +- src/mod_privacy.erl | 18 +++---- src/mod_pubsub.erl | 90 +++++++++++++++++----------------- src/mod_vcard.erl | 12 ++--- src/xmpp.erl | 122 +++++++++++++++++++++++------------------------ src/xmpp_codec.erl | 18 +++---- 23 files changed, 192 insertions(+), 190 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 9c1d99091..e658536ab 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -961,7 +961,7 @@ wait_for_bind(Pkt, StateData) -> end, fsm_next_state(wait_for_bind, StateData). --spec open_session(state()) -> {ok, state()} | {error, error()}. +-spec open_session(state()) -> {ok, state()} | {error, stanza_error()}. open_session(StateData) -> U = StateData#state.user, R = StateData#state.resource, @@ -1568,7 +1568,7 @@ send_element(StateData, #xmlel{} = El) -> send_element(StateData, Pkt) -> send_element(StateData, xmpp:encode(Pkt)). --spec send_error(state(), xmlel() | stanza(), error()) -> ok. +-spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. send_error(StateData, Stanza, Error) -> Type = xmpp:get_type(Stanza), if Type == error; Type == result; diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index 6a2b5e644..7d7d01060 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -487,7 +487,7 @@ process_privacy(#privacy_query{lists = Lists, Txt = <<"No module is handling this query">>, Error = {error, xmpp:err_feature_not_implemented(Txt, ?MYLANG)}, case mod_privacy:process_iq_set(Error, IQ) of - {error, #error{reason = Reason}} = Err -> + {error, #stanza_error{reason = Reason}} = Err -> if Reason == 'item-not-found', Lists == [], Active == undefined, Default /= undefined -> %% Failed to set default list because there is no diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index d65edc6e3..db82f67ea 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -86,7 +86,7 @@ route(From, To, Packet) -> %% Route the error packet only if the originating packet is not an error itself. %% RFC3920 9.3.1 -spec route_error(jid(), jid(), xmlel(), xmlel()) -> ok; - (jid(), jid(), stanza(), error()) -> ok. + (jid(), jid(), stanza(), stanza_error()) -> ok. route_error(From, To, #xmlel{} = ErrPacket, #xmlel{} = OrigPacket) -> #xmlel{attrs = Attrs} = OrigPacket, @@ -94,7 +94,7 @@ route_error(From, To, #xmlel{} = ErrPacket, #xmlel{} = OrigPacket) -> false -> route(From, To, ErrPacket); true -> ok end; -route_error(From, To, Packet, #error{} = Err) -> +route_error(From, To, Packet, #stanza_error{} = Err) -> Type = xmpp:get_type(Packet), if Type == error; Type == result -> ok; diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 7be4906fb..fd560a451 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -541,7 +541,7 @@ send_element(StateData, El) -> El1 = fix_ns(xmpp:encode(El)), send_text(StateData, fxml:element_to_binary(El1)). --spec send_error(state(), xmlel() | stanza(), error()) -> ok. +-spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. send_error(StateData, Stanza, Error) -> Type = xmpp:get_type(Stanza), if Type == error; Type == result; diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 4284f7f7b..dd37445d7 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -785,13 +785,13 @@ fix_ns(El) -> El. %% Bounce a single message (xmlelement) --spec bounce_element(stanza(), error()) -> ok. +-spec bounce_element(stanza(), stanza_error()) -> ok. bounce_element(El, Error) -> From = xmpp:get_from(El), To = xmpp:get_to(El), ejabberd_router:route_error(To, From, El, Error). --spec bounce_queue(queue:queue(), error()) -> ok. +-spec bounce_queue(queue:queue(), stanza_error()) -> ok. bounce_queue(Q, Error) -> case queue:out(Q) of {{value, El}, Q1} -> @@ -807,7 +807,7 @@ cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. --spec bounce_messages(error()) -> ok. +-spec bounce_messages(stanza_error()) -> ok. bounce_messages(Error) -> receive {send_element, El} -> diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 3df39438a..002d74949 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -308,7 +308,7 @@ send_element(StateData, El) -> El1 = fix_ns(xmpp:encode(El)), send_text(StateData, fxml:element_to_binary(El1)). --spec send_error(state(), xmlel() | stanza(), error()) -> ok. +-spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. send_error(StateData, Stanza, Error) -> Type = xmpp:get_type(Stanza), if Type == error; Type == result; diff --git a/src/gen_pubsub_node.erl b/src/gen_pubsub_node.erl index cc94ea147..5690c8a1d 100644 --- a/src/gen_pubsub_node.erl +++ b/src/gen_pubsub_node.erl @@ -178,7 +178,7 @@ -callback get_items(nodeIdx(), jid(), accessModel(), boolean(), boolean(), binary(), undefined | rsm_set()) -> - {result, {[pubsubItem()], undefined | rsm_set()}} | {error, error()}. + {result, {[pubsubItem()], undefined | rsm_set()}} | {error, stanza_error()}. -callback get_items(nodeIdx(), jid(), undefined | rsm_set()) -> {result, {[pubsubItem()], undefined | rsm_set()}}. diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index e6d94e40a..5b582d82b 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -173,9 +173,9 @@ get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- --spec get_local_features({error, error()} | {result, [binary()]} | empty, +-spec get_local_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]} | empty. + {error, stanza_error()} | {result, [binary()]} | empty. get_local_features(Acc, _From, _To, <<"">>, _Lang) -> Feats = case Acc of {result, I} -> I; @@ -238,7 +238,7 @@ process_adhoc_request(#iq{from = From, to = To, process_adhoc_request(#iq{} = IQ, _Hooks) -> xmpp:make_error(IQ, xmpp:err_bad_request()). --spec ping_item(empty | {error, error()} | {result, [disco_item()]}, +-spec ping_item(empty | {error, stanza_error()} | {result, [disco_item()]}, jid(), jid(), binary()) -> {result, [disco_item()]}. ping_item(Acc, _From, #jid{server = Server} = _To, Lang) -> @@ -252,7 +252,7 @@ ping_item(Acc, _From, #jid{server = Server} = _To, {result, Items ++ Nodes}. -spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) -> - adhoc_command() | {error, error()}. + adhoc_command() | {error, stanza_error()}. ping_command(_Acc, _From, _To, #adhoc_command{lang = Lang, node = <<"ping">>, action = Action} = Request) -> diff --git a/src/mod_announce.erl b/src/mod_announce.erl index eb201fc88..d9209f418 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -336,8 +336,8 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) -> end. %%------------------------------------------------------------------------- --spec announce_items(empty | {error, error()} | {result, [disco_item()]}, - jid(), jid(), binary()) -> {error, error()} | +-spec announce_items(empty | {error, stanza_error()} | {result, [disco_item()]}, + jid(), jid(), binary()) -> {error, stanza_error()} | {result, [disco_item()]} | empty. announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) -> @@ -386,7 +386,7 @@ commands_result(Allow, From, To, Request) -> end. -spec announce_commands(adhoc_command(), jid(), jid(), adhoc_command()) -> - adhoc_command() | {error, error()}. + adhoc_command() | {error, stanza_error()}. announce_commands(Acc, From, #jid{lserver = LServer} = To, #adhoc_command{node = Node} = Request) -> LNode = tokenize(Node), diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 98fb1e441..55e3ca151 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -72,19 +72,19 @@ depends(_Host, _Opts) -> process_iq(IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed()). --spec process_iq_get({error, error()} | {result, xmpp_element() | undefined}, +-spec process_iq_get({error, stanza_error()} | {result, xmpp_element() | undefined}, iq(), userlist()) -> - {error, error()} | {result, block_list()}. + {error, stanza_error()} | {result, block_list()}. process_iq_get(_, #iq{lang = Lang, from = From, sub_els = [#block_list{}]}, _) -> #jid{luser = LUser, lserver = LServer} = From, {stop, process_blocklist_get(LUser, LServer, Lang)}; process_iq_get(Acc, _, _) -> Acc. --spec process_iq_set({error, error()} | +-spec process_iq_set({error, stanza_error()} | {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, - iq()) -> {error, error()} | + iq()) -> {error, stanza_error()} | {result, undefined} | {result, undefined, userlist()}. process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> @@ -136,7 +136,7 @@ list_to_blocklist_jids([_ | Items], JIDs) -> -spec process_blocklist_block(binary(), binary(), [ljid()], binary()) -> - {error, error()} | + {error, stanza_error()} | {result, undefined, userlist()}. process_blocklist_block(LUser, LServer, JIDs, Lang) -> Filter = fun (List) -> @@ -171,7 +171,7 @@ process_blocklist_block(LUser, LServer, JIDs, Lang) -> end. -spec process_blocklist_unblock_all(binary(), binary(), binary()) -> - {error, error()} | + {error, stanza_error()} | {result, undefined} | {result, undefined, userlist()}. process_blocklist_unblock_all(LUser, LServer, Lang) -> @@ -195,7 +195,7 @@ process_blocklist_unblock_all(LUser, LServer, Lang) -> end. -spec process_blocklist_unblock(binary(), binary(), [ljid()], binary()) -> - {error, error()} | + {error, stanza_error()} | {result, undefined} | {result, undefined, userlist()}. process_blocklist_unblock(LUser, LServer, JIDs, Lang) -> @@ -240,7 +240,7 @@ broadcast_blocklist_event(LUser, LServer, Event) -> {broadcast, {blocking, Event}}). -spec process_blocklist_get(binary(), binary(), binary()) -> - {error, error()} | {result, block_list()}. + {error, stanza_error()} | {result, block_list()}. process_blocklist_get(LUser, LServer, Lang) -> Mod = db_mod(LServer), case Mod:process_blocklist_get(LUser, LServer) of diff --git a/src/mod_caps.erl b/src/mod_caps.erl index a388b085f..ae11ab651 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -158,10 +158,10 @@ caps_stream_features(Acc, MyHost) -> [#caps{hash = <<"sha-1">>, node = ?EJABBERD_URI, version = Hash}|Acc] end. --spec disco_features({error, error()} | {result, [binary()]} | empty, +-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]} | empty. + {error, stanza_error()} | {result, [binary()]} | empty. disco_features(Acc, From, To, Node, Lang) -> case is_valid_node(Node) of true -> diff --git a/src/mod_configure.erl b/src/mod_configure.erl index a798d010f..dd361028b 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -270,8 +270,8 @@ get_local_features(Acc, From, end. %%%----------------------------------------------------------------------- --spec adhoc_sm_items(empty | {error, error()} | {result, [disco_item()]}, - jid(), jid(), binary()) -> {error, error()} | +-spec adhoc_sm_items(empty | {error, stanza_error()} | {result, [disco_item()]}, + jid(), jid(), binary()) -> {error, stanza_error()} | {result, [disco_item()]} | empty. adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To, @@ -325,8 +325,8 @@ get_user_resources(User, Server) -> %%%----------------------------------------------------------------------- --spec adhoc_local_items(empty | {error, error()} | {result, [disco_item()]}, - jid(), jid(), binary()) -> {error, error()} | +-spec adhoc_local_items(empty | {error, stanza_error()} | {result, [disco_item()]}, + jid(), jid(), binary()) -> {error, stanza_error()} | {result, [disco_item()]} | empty. adhoc_local_items(Acc, From, @@ -773,7 +773,7 @@ get_stopped_nodes(_Lang) -> end). -spec adhoc_local_commands(adhoc_command(), jid(), jid(), adhoc_command()) -> - adhoc_command() | {error, error()}. + adhoc_command() | {error, stanza_error()}. adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To, #adhoc_command{node = Node, lang = Lang} = Request) -> diff --git a/src/mod_disco.erl b/src/mod_disco.erl index e33241928..953d1da10 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -198,9 +198,9 @@ get_local_identity(Acc, _From, _To, <<"">>, _Lang) -> get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. --spec get_local_features({error, error()} | {result, [binary()]} | empty, +-spec get_local_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]}. + {error, stanza_error()} | {result, [binary()]}. get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; @@ -222,10 +222,10 @@ get_local_features(Acc, _From, _To, _Node, Lang) -> {error, xmpp:err_item_not_found(Txt, Lang)} end. --spec get_local_services({error, error()} | {result, [disco_item()]} | empty, +-spec get_local_services({error, stanza_error()} | {result, [disco_item()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [disco_item()]}. + {error, stanza_error()} | {result, [disco_item()]}. get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; @@ -296,10 +296,10 @@ process_sm_iq_items(#iq{type = get, lang = Lang, xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang)) end. --spec get_sm_items({error, error()} | {result, [disco_item()]} | empty, +-spec get_sm_items({error, stanza_error()} | {result, [disco_item()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [disco_item()]}. + {error, stanza_error()} | {result, [disco_item()]}. get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; @@ -383,9 +383,9 @@ get_sm_identity(Acc, _From, _ -> [] end. --spec get_sm_features({error, error()} | {result, [binary()]} | empty, +-spec get_sm_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]}. + {error, stanza_error()} | {result, [binary()]}. get_sm_features(empty, From, To, _Node, Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index babdbb7b6..f1f5d8173 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -601,7 +601,7 @@ create_slot(#state{service_url = undefined, {ok, [UserStr, RandStr, FileStr]}; deny -> {error, xmpp:err_service_unavailable()}; - #error{} = Error -> + #stanza_error{} = Error -> {error, Error} end; create_slot(#state{service_url = ServiceURL}, diff --git a/src/mod_irc.erl b/src/mod_irc.erl index a833287c8..fefebcfa3 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -679,7 +679,7 @@ adhoc_join(From, To, #adhoc_command{lang = Lang, xdata = X} = Request) -> end. -spec adhoc_register(binary(), jid(), jid(), adhoc_command()) -> - adhoc_command() | {error, error()}. + adhoc_command() | {error, stanza_error()}. adhoc_register(_ServerHost, _From, _To, #adhoc_command{action = cancel} = Request) -> xmpp_util:make_adhoc_response(Request, #adhoc_command{status = canceled}); diff --git a/src/mod_mix.erl b/src/mod_mix.erl index 52a3c8ed8..f39408210 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -52,7 +52,7 @@ stop(Host) -> supervisor:delete_child(ejabberd_sup, Proc), ok. --spec disco_features({error, error()} | {result, [binary()]} | empty, +-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> {result, [binary()]}. disco_features(_Acc, _From, _To, _Node, _Lang) -> {result, [?NS_MIX_0]}. diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 2f2962b97..c32551091 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -1136,8 +1136,8 @@ decide_fate_message(_, _, _) -> continue_delivery. %% Check if the elements of this error stanza indicate %% that the sender is a dead participant. %% If so, return true to kick the participant. --spec check_error_kick(error()) -> boolean(). -check_error_kick(#error{reason = Reason}) -> +-spec check_error_kick(stanza_error()) -> boolean(). +check_error_kick(#stanza_error{reason = Reason}) -> case Reason of #gone{} -> true; 'internal-server-error' -> true; @@ -1153,8 +1153,8 @@ check_error_kick(#error{reason = Reason}) -> check_error_kick(undefined) -> false. --spec get_error_condition(error()) -> string(). -get_error_condition(#error{reason = Reason}) -> +-spec get_error_condition(stanza_error()) -> string(). +get_error_condition(#stanza_error{reason = Reason}) -> case Reason of #gone{} -> "gone"; #redirect{} -> "redirect"; @@ -1673,7 +1673,7 @@ nick_collision(User, Nick, StateData) -> -spec add_new_user(jid(), binary(), presence() | iq(), state()) -> state() | - {error, error()} | + {error, stanza_error()} | {ignore, state()} | {result, xmpp_element(), state()}. add_new_user(From, Nick, Packet, StateData) -> @@ -2467,7 +2467,7 @@ can_change_subject(Role, StateData) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Admin stuff --spec process_iq_admin(jid(), iq(), #state{}) -> {error, error()} | +-spec process_iq_admin(jid(), iq(), #state{}) -> {error, stanza_error()} | {result, undefined, #state{}} | {result, muc_admin()}. process_iq_admin(_From, #iq{lang = Lang, sub_els = [#muc_admin{items = []}]}, @@ -2557,7 +2557,7 @@ search_affiliation(Affiliation, StateData) -> -spec process_admin_items_set(jid(), [muc_item()], binary(), #state{}) -> {result, undefined, #state{}} | - {error, error()}. + {error, stanza_error()}. process_admin_items_set(UJID, Items, Lang, StateData) -> UAffiliation = get_affiliation(UJID, StateData), URole = get_role(UJID, StateData), @@ -2939,7 +2939,7 @@ get_actor_nick(MJID, StateData) -> -spec process_iq_owner(jid(), iq(), state()) -> {result, undefined | muc_owner()} | {result, undefined | muc_owner(), state() | stop} | - {error, error()}. + {error, stanza_error()}. process_iq_owner(From, #iq{type = set, lang = Lang, sub_els = [#muc_owner{destroy = Destroy, config = Config, @@ -3294,7 +3294,7 @@ get_config(Lang, StateData, From) -> [StateData, From, Lang]), #xdata{type = form, title = Title, fields = Fields}. --spec set_config(xdata(), state(), binary()) -> {error, error()} | +-spec set_config(xdata(), state(), binary()) -> {error, stanza_error()} | {result, undefined, state()}. set_config(#xdata{fields = Fields}, StateData, Lang) -> Options = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- Fields], @@ -3377,7 +3377,7 @@ get_config_opt_name(Pos) -> end). -spec set_xoption([{binary(), [binary()]}], #config{}, - binary(), binary()) -> #config{} | {error, error()}. + binary(), binary()) -> #config{} | {error, stanza_error()}. set_xoption([], Config, _ServerHost, _Lang) -> Config; set_xoption([{<<"muc#roomconfig_roomname">>, Vals} | Opts], @@ -3836,7 +3836,7 @@ destroy_room(DEl, StateData) -> end). -spec process_iq_disco_info(jid(), iq(), state()) -> - {result, disco_info()} | {error, error()}. + {result, disco_info()} | {error, stanza_error()}. process_iq_disco_info(_From, #iq{type = set, lang = Lang}, _StateData) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, {error, xmpp:err_not_allowed(Txt, Lang)}; @@ -3901,7 +3901,7 @@ iq_disco_info_extras(Lang, StateData) -> integer_to_binary(Len), Lang)]}. -spec process_iq_disco_items(jid(), iq(), state()) -> - {error, error()} | {result, disco_items()}. + {error, stanza_error()} | {result, disco_items()}. process_iq_disco_items(_From, #iq{type = set, lang = Lang}, _StateData) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, {error, xmpp:err_not_allowed(Txt, Lang)}; @@ -3919,7 +3919,7 @@ process_iq_disco_items(From, #iq{type = get, lang = Lang}, StateData) -> end end. --spec process_iq_captcha(jid(), iq(), state()) -> {error, error()} | +-spec process_iq_captcha(jid(), iq(), state()) -> {error, stanza_error()} | {result, undefined}. process_iq_captcha(_From, #iq{type = get, lang = Lang}, _StateData) -> Txt = <<"Value 'get' of 'type' attribute is not allowed">>, @@ -3939,7 +3939,7 @@ process_iq_captcha(_From, #iq{type = set, lang = Lang, sub_els = [SubEl]}, -spec process_iq_vcard(jid(), iq(), state()) -> {result, vcard_temp() | xmlel()} | {result, undefined, state()} | - {error, error()}. + {error, stanza_error()}. process_iq_vcard(_From, #iq{type = get}, StateData) -> #state{config = #config{vcard = VCardRaw}} = StateData, case fxml_stream:parse_element(VCardRaw) of @@ -3962,7 +3962,7 @@ process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [SubEl]}, end. -spec process_iq_mucsub(jid(), iq(), state()) -> - {error, error()} | + {error, stanza_error()} | {result, undefined | muc_subscribe(), state()} | {ignore, state()}. process_iq_mucsub(_From, #iq{type = set, lang = Lang, @@ -4205,7 +4205,7 @@ is_invitation(Packet) -> (_) -> false end, Els). --spec check_invitation(jid(), message(), state()) -> {error, error()} | jid(). +-spec check_invitation(jid(), message(), state()) -> {error, stanza_error()} | jid(). check_invitation(From, Packet, StateData) -> Lang = xmpp:get_lang(Packet), FAffiliation = get_affiliation(From, StateData), diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index f1c090ae4..72046491f 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -243,7 +243,7 @@ handle_iq(From, To, Packet, State) -> end. -spec process_iq(jid(), iq(), state()) -> {result, xmpp_element()} | - {error, error()} | reply. + {error, stanza_error()} | reply. process_iq(From, #iq{type = get, lang = Lang, sub_els = [#disco_info{}]}, State) -> {result, iq_disco_info(From, Lang, State)}; diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index f94c422b3..3be3f2d3b 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -100,8 +100,8 @@ stop(Host) -> process_iq(IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed()). --spec process_iq_get({error, error()} | {result, xmpp_element() | undefined}, - iq(), userlist()) -> {error, error()} | {result, privacy_query()}. +-spec process_iq_get({error, stanza_error()} | {result, xmpp_element() | undefined}, + iq(), userlist()) -> {error, stanza_error()} | {result, privacy_query()}. process_iq_get(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{lists = Lists}]}, #userlist{name = Active}) -> @@ -117,7 +117,7 @@ process_iq_get(_, #iq{from = From, lang = Lang, end. -spec process_lists_get(binary(), binary(), binary(), binary()) -> - {error, error()} | {result, privacy_query()}. + {error, stanza_error()} | {result, privacy_query()}. process_lists_get(LUser, LServer, Active, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_lists_get(LUser, LServer) of @@ -135,7 +135,7 @@ process_lists_get(LUser, LServer, Active, Lang) -> end. -spec process_list_get(binary(), binary(), binary(), binary()) -> - {error, error()} | {result, privacy_query()}. + {error, stanza_error()} | {result, privacy_query()}. process_list_get(LUser, LServer, Name, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_list_get(LUser, LServer, Name) of @@ -214,10 +214,10 @@ decode_value(Type, Value) -> undefined -> none end. --spec process_iq_set({error, error()} | +-spec process_iq_set({error, stanza_error()} | {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, - iq()) -> {error, error()} | + iq()) -> {error, stanza_error()} | {result, undefined, userlist()}. process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{default = Default, @@ -239,7 +239,7 @@ process_iq_set(_, #iq{from = From, lang = Lang, end. -spec process_default_set(binary(), binary(), none | binary(), - binary()) -> {error, error()} | {result, undefined}. + binary()) -> {error, stanza_error()} | {result, undefined}. process_default_set(LUser, LServer, Value, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:process_default_set(LUser, LServer, Value) of @@ -258,7 +258,7 @@ process_default_set(LUser, LServer, Value, Lang) -> end. -spec process_active_set(binary(), binary(), none | binary(), binary()) -> - {error, error()} | + {error, stanza_error()} | {result, undefined, userlist()}. process_active_set(_LUser, _LServer, none, _Lang) -> {result, undefined, #userlist{}}; @@ -280,7 +280,7 @@ set_privacy_list(#privacy{us = {_, LServer}} = Privacy) -> Mod:set_privacy_list(Privacy). -spec process_lists_set(binary(), binary(), binary(), [privacy_item()], - binary()) -> {error, error()} | {result, undefined}. + binary()) -> {error, stanza_error()} | {result, undefined}. process_lists_set(LUser, LServer, Name, [], Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:remove_privacy_list(LUser, LServer, Name) of diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index a7a0e2d88..b470d83d9 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -525,9 +525,9 @@ disco_local_identity(Acc, _From, To, <<>>, _Lang) -> disco_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. --spec disco_local_features({error, error()} | {result, [binary()]} | empty, +-spec disco_local_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]} | empty. + {error, stanza_error()} | {result, [binary()]} | empty. disco_local_features(Acc, _From, To, <<>>, _Lang) -> Host = host(To#jid.lserver), Feats = case Acc of @@ -538,9 +538,9 @@ disco_local_features(Acc, _From, To, <<>>, _Lang) -> disco_local_features(Acc, _From, _To, _Node, _Lang) -> Acc. --spec disco_local_items({error, error()} | {result, [disco_item()]} | empty, +-spec disco_local_items({error, stanza_error()} | {result, [disco_item()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [disco_item()]} | empty. + {error, stanza_error()} | {result, [disco_item()]} | empty. disco_local_items(Acc, _From, _To, <<>>, _Lang) -> Acc; disco_local_items(Acc, _From, _To, _Node, _Lang) -> Acc. @@ -578,9 +578,9 @@ disco_identity(Host, Node, From) -> _ -> [] end. --spec disco_sm_features({error, error()} | {result, [binary()]} | empty, +-spec disco_sm_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]}. + {error, stanza_error()} | {result, [binary()]}. disco_sm_features(empty, From, To, Node, Lang) -> disco_sm_features({result, []}, From, To, Node, Lang); disco_sm_features({result, OtherFeatures} = _Acc, From, To, Node, _Lang) -> @@ -612,9 +612,9 @@ disco_features(Host, Node, From) -> _ -> [] end. --spec disco_sm_items({error, error()} | {result, [disco_item()]} | empty, +-spec disco_sm_items({error, stanza_error()} | {result, [disco_item()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [disco_item()]}. + {error, stanza_error()} | {result, [disco_item()]}. disco_sm_items(empty, From, To, Node, Lang) -> disco_sm_items({result, []}, From, To, Node, Lang); disco_sm_items({result, OtherItems}, From, To, Node, _Lang) -> @@ -1052,12 +1052,12 @@ command_disco_info(_Host, ?NS_PUBSUB_GET_PENDING, _From) -> features = [?NS_COMMANDS]}}. -spec node_disco_info(binary(), binary(), jid()) -> {result, disco_info()} | - {error, error()}. + {error, stanza_error()}. node_disco_info(Host, Node, From) -> node_disco_info(Host, Node, From, true, true). -spec node_disco_info(binary(), binary(), jid(), boolean(), boolean()) -> - {result, disco_info()} | {error, error()}. + {result, disco_info()} | {error, stanza_error()}. node_disco_info(Host, Node, _From, _Identity, _Features) -> Action = fun(#pubsub_node{type = Type, options = Options}) -> @@ -1075,7 +1075,7 @@ node_disco_info(Host, Node, _From, _Identity, _Features) -> end. -spec iq_disco_info(binary(), binary(), jid(), binary()) - -> {result, disco_info()} | {error, error()}. + -> {result, disco_info()} | {error, stanza_error()}. iq_disco_info(Host, SNode, From, Lang) -> [Node | _] = case SNode of <<>> -> [<<>>]; @@ -1105,7 +1105,7 @@ iq_disco_info(Host, SNode, From, Lang) -> end. -spec iq_disco_items(host(), binary(), jid(), undefined | rsm_set()) -> - {result, disco_items()} | {error, error()}. + {result, disco_items()} | {error, stanza_error()}. iq_disco_items(Host, <<>>, From, _RSM) -> Items = lists:map( @@ -1193,7 +1193,7 @@ iq_get_vcard(Lang) -> desc = <>}. -spec iq_pubsub(binary() | ljid(), atom(), iq()) -> - {result, pubsub()} | {error, error()}. + {result, pubsub()} | {error, stanza_error()}. iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, sub_els = [SubEl]}) -> case {IQType, SubEl} of @@ -1272,7 +1272,7 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, end. -spec iq_pubsub_owner(binary() | ljid(), iq()) -> {result, pubsub_owner() | undefined} | - {error, error()}. + {error, stanza_error()}. iq_pubsub_owner(Host, #iq{type = IQType, from = From, lang = Lang, sub_els = [SubEl]}) -> case {IQType, SubEl} of @@ -1312,7 +1312,7 @@ iq_pubsub_owner(Host, #iq{type = IQType, from = From, end. -spec adhoc_request(binary(), binary(), jid(), adhoc_command(), - atom(), [binary()]) -> adhoc_command() | {error, error()}. + atom(), [binary()]) -> adhoc_command() | {error, stanza_error()}. adhoc_request(Host, _ServerHost, Owner, #adhoc_command{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, action = execute, xdata = undefined}, @@ -1342,7 +1342,7 @@ adhoc_request(_Host, _ServerHost, _Owner, Other, _Access, _Plugins) -> {error, xmpp:err_item_not_found()}. -spec send_pending_node_form(binary(), jid(), binary(), - [binary()]) -> adhoc_command() | {error, error()}. + [binary()]) -> adhoc_command() | {error, stanza_error()}. send_pending_node_form(Host, Owner, _Lang, Plugins) -> Filter = fun (Type) -> lists:member(<<"get-pending">>, plugin_features(Host, Type)) @@ -1369,7 +1369,7 @@ send_pending_node_form(Host, Owner, _Lang, Plugins) -> end. -spec get_pending_nodes(binary(), jid(), [binary()]) -> {ok, [binary()]} | - {error, error()}. + {error, stanza_error()}. get_pending_nodes(Host, Owner, Plugins) -> Tr = fun (Type) -> case node_call(Host, Type, get_pending_nodes, [Host, Owner]) of @@ -1386,7 +1386,7 @@ get_pending_nodes(Host, Owner, Plugins) -> %% @doc

    Send a subscription approval form to Owner for all pending %% subscriptions on Host and Node.

    -spec send_pending_auth_events(binary(), binary(), jid(), - binary()) -> adhoc_command() | {error, error()}. + binary()) -> adhoc_command() | {error, stanza_error()}. send_pending_auth_events(Host, Node, Owner, Lang) -> ?DEBUG("Sending pending auth events for ~s on ~s:~s", [jid:to_string(Owner), Host, Node]), @@ -1520,7 +1520,7 @@ handle_authorization_response(Host, From, To, Packet, X) -> end. -spec update_auth(binary(), binary(), _, _, jid() | error, boolean(), _) -> - {result, ok} | {error, error()}. + {result, ok} | {error, stanza_error()}. update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> Sub= lists:filter(fun ({pending, _}) -> true; @@ -1598,12 +1598,12 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> %%
  • node plugin create_node just sets default affiliation/subscription
  • %% -spec create_node(host(), binary(), binary(), jid(), - binary()) -> {result, pubsub()} | {error, error()}. + binary()) -> {result, pubsub()} | {error, stanza_error()}. create_node(Host, ServerHost, Node, Owner, Type) -> create_node(Host, ServerHost, Node, Owner, Type, all, []). -spec create_node(host(), binary(), binary(), jid(), binary(), - atom(), [{binary(), [binary()]}]) -> {result, pubsub()} | {error, error()}. + atom(), [{binary(), [binary()]}]) -> {result, pubsub()} | {error, stanza_error()}. create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) -> case lists:member(<<"instant-nodes">>, plugin_features(Host, Type)) of true -> @@ -1693,7 +1693,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> %%
  • The node is the root collection node, which cannot be deleted.
  • %%
  • The specified node does not exist.
  • %% --spec delete_node(host(), binary(), jid()) -> {result, pubsub_owner()} | {error, error()}. +-spec delete_node(host(), binary(), jid()) -> {result, pubsub_owner()} | {error, stanza_error()}. delete_node(_Host, <<>>, _Owner) -> {error, xmpp:err_not_allowed(<<"No node specified">>, ?MYLANG)}; delete_node(Host, Node, Owner) -> @@ -1770,7 +1770,7 @@ delete_node(Host, Node, Owner) -> %%
  • The node does not exist.
  • %% -spec subscribe_node(host(), binary(), jid(), binary(), [{binary(), [binary()]}]) -> - {result, pubsub()} | {error, error()}. + {result, pubsub()} | {error, stanza_error()}. subscribe_node(Host, Node, From, JID, Configuration) -> SubModule = subscription_plugin(Host), SubOpts = case SubModule:parse_options_xform(Configuration) of @@ -1874,7 +1874,7 @@ subscribe_node(Host, Node, From, JID, Configuration) -> %%
  • The request specifies a subscription ID that is not valid or current.
  • %% -spec unsubscribe_node(host(), binary(), jid(), jid(), binary()) -> - {result, undefined} | {error, error()}. + {result, undefined} | {error, stanza_error()}. unsubscribe_node(Host, Node, From, JID, SubId) -> Subscriber = jid:tolower(JID), Action = fun (#pubsub_node{type = Type, id = Nidx}) -> @@ -1901,7 +1901,7 @@ unsubscribe_node(Host, Node, From, JID, SubId) -> %%
  • The request does not match the node configuration.
  • %% -spec publish_item(host(), binary(), binary(), jid(), binary(), - [xmlel()]) -> {result, pubsub()} | {error, error()}. + [xmlel()]) -> {result, pubsub()} | {error, stanza_error()}. publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, [], all). publish_item(Host, ServerHost, Node, Publisher, <<>>, Payload, PubOpts, Access) -> @@ -1984,7 +1984,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access {result, Reply}; {result, {_, Result}} -> {result, Result}; - {error, #error{reason = 'item-not-found'}} -> + {error, #stanza_error{reason = 'item-not-found'}} -> Type = select_type(ServerHost, Host, Node), case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of true -> @@ -2015,7 +2015,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access %%
  • The service does not support the deletion of items.
  • %% -spec delete_item(host(), binary(), jid(), binary()) -> {result, undefined} | - {error, error()}. + {error, stanza_error()}. delete_item(Host, Node, Publisher, ItemId) -> delete_item(Host, Node, Publisher, ItemId, false). delete_item(_, <<>>, _, _, _) -> @@ -2071,7 +2071,7 @@ delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> %%
  • The specified node does not exist.
  • %% -spec purge_node(mod_pubsub:host(), binary(), jid()) -> {result, undefined} | - {error, error()}. + {error, stanza_error()}. purge_node(Host, Node, Owner) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), @@ -2117,7 +2117,7 @@ purge_node(Host, Node, Owner) -> %% to read the items. -spec get_items(host(), binary(), jid(), binary(), binary(), [binary()], undefined | rsm_set()) -> - {result, pubsub()} | {error, error()}. + {result, pubsub()} | {error, stanza_error()}. get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) -> MaxItems = if SMaxItems == undefined -> case get_max_items_node(Host) of @@ -2270,7 +2270,7 @@ dispatch_items(From, To, _Node, Stanza) -> %% @doc

    Return the list of affiliations as an XMPP response.

    -spec get_affiliations(host(), binary(), jid(), [binary()]) -> - {result, pubsub()} | {error, error()}. + {result, pubsub()} | {error, stanza_error()}. get_affiliations(Host, Node, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( @@ -2310,7 +2310,7 @@ get_affiliations(Host, Node, JID, Plugins) when is_list(Plugins) -> end. -spec get_affiliations(host(), binary(), jid()) -> - {result, pubsub_owner()} | {error, error()}. + {result, pubsub_owner()} | {error, stanza_error()}. get_affiliations(Host, Node, JID) -> Action = fun(#pubsub_node{type = Type, id = Nidx}) -> @@ -2342,7 +2342,7 @@ get_affiliations(Host, Node, JID) -> end. -spec set_affiliations(host(), binary(), jid(), [ps_affiliation()]) -> - {result, undefined} | {error, error()}. + {result, undefined} | {error, stanza_error()}. set_affiliations(Host, Node, From, Affs) -> Owner = jid:tolower(jid:remove_resource(From)), Action = @@ -2396,7 +2396,7 @@ set_affiliations(Host, Node, From, Affs) -> end. -spec get_options(binary(), binary(), jid(), binary(), binary()) -> - {result, xdata()} | {error, error()}. + {result, xdata()} | {error, stanza_error()}. get_options(Host, Node, JID, SubId, Lang) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> case lists:member(<<"subscription-options">>, plugin_features(Host, Type)) of @@ -2413,7 +2413,7 @@ get_options(Host, Node, JID, SubId, Lang) -> end. -spec get_options_helper(binary(), jid(), binary(), binary(), _, binary(), - binary()) -> {result, pubsub()} | {error, error()}. + binary()) -> {result, pubsub()} | {error, stanza_error()}. get_options_helper(Host, JID, Lang, Node, Nidx, SubId, Type) -> Subscriber = jid:tolower(JID), {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), @@ -2454,7 +2454,7 @@ read_sub(Host, Node, Nidx, Subscriber, SubId, Lang) -> -spec set_options(binary(), binary(), jid(), binary(), [{binary(), [binary()]}]) -> - {result, undefined} | {error, error()}. + {result, undefined} | {error, stanza_error()}. set_options(Host, Node, JID, SubId, Configuration) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> case lists:member(<<"subscription-options">>, plugin_features(Host, Type)) of @@ -2472,7 +2472,7 @@ set_options(Host, Node, JID, SubId, Configuration) -> -spec set_options_helper(binary(), [{binary(), [binary()]}], jid(), nodeIdx(), binary(), binary()) -> - {result, undefined} | {error, error()}. + {result, undefined} | {error, stanza_error()}. set_options_helper(Host, Configuration, JID, Nidx, SubId, Type) -> SubModule = subscription_plugin(Host), SubOpts = case SubModule:parse_options_xform(Configuration) of @@ -2494,7 +2494,7 @@ set_options_helper(Host, Configuration, JID, Nidx, SubId, Type) -> end. -spec write_sub(binary(), nodeIdx(), ljid(), binary(), _) -> {result, undefined} | - {error, error()}. + {error, stanza_error()}. write_sub(_Host, _Nidx, _Subscriber, _SubId, invalid) -> {error, extended_error(xmpp:err_bad_request(), err_invalid_options())}; write_sub(_Host, _Nidx, _Subscriber, _SubId, []) -> @@ -2509,7 +2509,7 @@ write_sub(Host, Nidx, Subscriber, SubId, Options) -> %% @doc

    Return the list of subscriptions as an XMPP response.

    -spec get_subscriptions(host(), binary(), jid(), [binary()]) -> - {result, pubsub()} | {error, error()}. + {result, pubsub()} | {error, stanza_error()}. get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl(fun (Type, {Status, Acc}) -> Features = plugin_features(Host, Type), @@ -2576,7 +2576,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> end. -spec get_subscriptions(host(), binary(), jid()) -> {result, pubsub_owner()} | - {error, error()}. + {error, stanza_error()}. get_subscriptions(Host, Node, JID) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> Features = plugin_features(Host, Type), @@ -2633,7 +2633,7 @@ get_subscriptions_for_send_last(_Host, _PType, _, _JID, _LJID, _BJID) -> []. -spec set_subscriptions(host(), binary(), jid(), [ps_subscription()]) -> - {result, undefined} | {error, error()}. + {result, undefined} | {error, stanza_error()}. set_subscriptions(Host, Node, From, Entities) -> Owner = jid:tolower(jid:remove_resource(From)), Notify = fun(#ps_subscription{jid = JID, type = Sub}) -> @@ -3163,7 +3163,7 @@ user_resource(_, _, Resource) -> %%%%%%% Configuration handling -spec get_configure(host(), binary(), binary(), jid(), - binary()) -> {error, error()} | {result, pubsub_owner()}. + binary()) -> {error, stanza_error()} | {result, pubsub_owner()}. get_configure(Host, ServerHost, Node, From, Lang) -> Action = fun (#pubsub_node{options = Options, type = Type, id = Nidx}) -> case node_call(Host, Type, get_affiliation, [Nidx, From]) of @@ -3381,7 +3381,7 @@ get_configure_xfields(_Type, Options, Lang, Groups) -> %%
  • The specified node does not exist.
  • %% -spec set_configure(host(), binary(), jid(), [{binary(), [binary()]}], - binary()) -> {result, undefined} | {error, error()}. + binary()) -> {result, undefined} | {error, stanza_error()}. set_configure(_Host, <<>>, _From, _Config, _Lang) -> {error, extended_error(xmpp:err_bad_request(), err_nodeid_required())}; set_configure(Host, Node, From, Config, Lang) -> @@ -3851,9 +3851,9 @@ transaction_retry(Host, ServerHost, Fun, Trans, DBType, Count) -> %%%% helpers %% Add pubsub-specific error element --spec extended_error(error(), ps_error()) -> error(). +-spec extended_error(stanza_error(), ps_error()) -> stanza_error(). extended_error(StanzaErr, PubSubErr) -> - StanzaErr#error{sub_els = [PubSubErr]}. + StanzaErr#stanza_error{sub_els = [PubSubErr]}. -spec err_closed_node() -> ps_error(). err_closed_node() -> @@ -4033,7 +4033,7 @@ purge_offline(LJID) -> ?DEBUG("on_user_offline ~p", [Error]) end. --spec purge_offline(host(), ljid(), binary()) -> ok | {error, error()}. +-spec purge_offline(host(), ljid(), binary()) -> ok | {error, stanza_error()}. purge_offline(Host, LJID, Node) -> Nidx = Node#pubsub_node.id, Type = Node#pubsub_node.type, diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index f0fb556ba..1f6edb460 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -150,9 +150,9 @@ do_route(From, To, #iq{} = IQ) -> do_route(_, _, _) -> ok. --spec get_sm_features({error, error()} | empty | {result, [binary()]}, +-spec get_sm_features({error, stanza_error()} | empty | {result, [binary()]}, jid(), jid(), binary(), binary()) -> - {error, error()} | empty | {result, [binary()]}. + {error, stanza_error()} | empty | {result, [binary()]}. get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; @@ -230,9 +230,9 @@ process_search(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Incorrect data form">>, xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)). --spec disco_items({error, error()} | {result, [disco_item()]} | empty, +-spec disco_items({error, stanza_error()} | {result, [disco_item()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [disco_item()]}. + {error, stanza_error()} | {result, [disco_item()]}. disco_items(empty, _From, _To, <<"">>, _Lang) -> {result, []}; disco_items(empty, _From, _To, _Node, Lang) -> @@ -240,9 +240,9 @@ disco_items(empty, _From, _To, _Node, Lang) -> disco_items(Acc, _From, _To, _Node, _Lang) -> Acc. --spec disco_features({error, error()} | {result, [binary()]} | empty, +-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty, jid(), jid(), binary(), binary()) -> - {error, error()} | {result, [binary()]}. + {error, stanza_error()} | {result, [binary()]}. disco_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; disco_features(Acc, _From, _To, <<"">>, _Lang) -> diff --git a/src/xmpp.erl b/src/xmpp.erl index 10872b341..49d824af2 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() | xmlel()) -> message(); - (presence(), error() | xmlel()) -> presence(); - (iq(), error() | xmlel()) -> iq(); - (xmlel(), error() | xmlel()) -> xmlel(). +-spec make_error(message(), stanza_error() | xmlel()) -> message(); + (presence(), stanza_error() | xmlel()) -> presence(); + (iq(), stanza_error() | xmlel()) -> iq(); + (xmlel(), stanza_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]}; @@ -150,9 +150,9 @@ get_to(#iq{to = J}) -> J; get_to(#message{to = J}) -> J; get_to(#presence{to = J}) -> J. --spec get_error(iq() | message() | presence()) -> undefined | error(). +-spec get_error(iq() | message() | presence()) -> undefined | stanza_error(). get_error(Stanza) -> - case get_subtag(Stanza, #error{}) of + case get_subtag(Stanza, #stanza_error{}) of false -> undefined; Error -> Error end. @@ -206,9 +206,9 @@ set_from_to(#iq{} = IQ, F, T) -> IQ#iq{from = F, to = T}; set_from_to(#message{} = Msg, F, T) -> Msg#message{from = F, to = T}; 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(). +-spec set_error(iq(), stanza_error()) -> iq(); + (message(), stanza_error()) -> message(); + (presence(), stanza_error()) -> presence(). set_error(Stanza, E) -> set_subtag(Stanza, E). -spec set_els(iq(), [xmpp_element() | xmlel()]) -> iq(); @@ -383,199 +383,199 @@ pp(Term) -> %%%=================================================================== %%% Functions to construct general XMPP errors %%%=================================================================== --spec err_bad_request() -> error(). +-spec err_bad_request() -> stanza_error(). err_bad_request() -> err(modify, 'bad-request', 400). --spec err_bad_request(binary(), binary()) -> error(). +-spec err_bad_request(binary(), binary()) -> stanza_error(). err_bad_request(Text, Lang) -> err(modify, 'bad-request', 400, Text, Lang). --spec err_conflict() -> error(). +-spec err_conflict() -> stanza_error(). err_conflict() -> err(cancel, 'conflict', 409). --spec err_conflict(binary(), binary()) -> error(). +-spec err_conflict(binary(), binary()) -> stanza_error(). err_conflict(Text, Lang) -> err(cancel, 'conflict', 409, Text, Lang). --spec err_feature_not_implemented() -> error(). +-spec err_feature_not_implemented() -> stanza_error(). err_feature_not_implemented() -> err(cancel, 'feature-not-implemented', 501). --spec err_feature_not_implemented(binary(), binary()) -> error(). +-spec err_feature_not_implemented(binary(), binary()) -> stanza_error(). err_feature_not_implemented(Text, Lang) -> err(cancel, 'feature-not-implemented', 501, Text, Lang). --spec err_forbidden() -> error(). +-spec err_forbidden() -> stanza_error(). err_forbidden() -> err(auth, 'forbidden', 403). --spec err_forbidden(binary(), binary()) -> error(). +-spec err_forbidden(binary(), binary()) -> stanza_error(). err_forbidden(Text, Lang) -> err(auth, 'forbidden', 403, Text, Lang). %% RFC 6120 says error type SHOULD be "cancel". %% RFC 3920 and XEP-0082 says it SHOULD be "modify". --spec err_gone() -> error(). +-spec err_gone() -> stanza_error(). err_gone() -> err(modify, 'gone', 302). --spec err_gone(binary(), binary()) -> error(). +-spec err_gone(binary(), binary()) -> stanza_error(). err_gone(Text, Lang) -> err(modify, 'gone', 302, Text, Lang). %% RFC 6120 sasy error type SHOULD be "cancel". %% RFC 3920 and XEP-0082 says it SHOULD be "wait". --spec err_internal_server_error() -> error(). +-spec err_internal_server_error() -> stanza_error(). err_internal_server_error() -> err(wait, 'internal-server-error', 500). --spec err_internal_server_error(binary(), binary()) -> error(). +-spec err_internal_server_error(binary(), binary()) -> stanza_error(). err_internal_server_error(Text, Lang) -> err(wait, 'internal-server-error', 500, Text, Lang). --spec err_item_not_found() -> error(). +-spec err_item_not_found() -> stanza_error(). err_item_not_found() -> err(cancel, 'item-not-found', 404). --spec err_item_not_found(binary(), binary()) -> error(). +-spec err_item_not_found(binary(), binary()) -> stanza_error(). err_item_not_found(Text, Lang) -> err(cancel, 'item-not-found', 404, Text, Lang). --spec err_jid_malformed() -> error(). +-spec err_jid_malformed() -> stanza_error(). err_jid_malformed() -> err(modify, 'jid-malformed', 400). --spec err_jid_malformed(binary(), binary()) -> error(). +-spec err_jid_malformed(binary(), binary()) -> stanza_error(). err_jid_malformed(Text, Lang) -> err(modify, 'jid-malformed', 400, Text, Lang). --spec err_not_acceptable() -> error(). +-spec err_not_acceptable() -> stanza_error(). err_not_acceptable() -> err(modify, 'not-acceptable', 406). --spec err_not_acceptable(binary(), binary()) -> error(). +-spec err_not_acceptable(binary(), binary()) -> stanza_error(). err_not_acceptable(Text, Lang) -> err(modify, 'not-acceptable', 406, Text, Lang). --spec err_not_allowed() -> error(). +-spec err_not_allowed() -> stanza_error(). err_not_allowed() -> err(cancel, 'not-allowed', 405). --spec err_not_allowed(binary(), binary()) -> error(). +-spec err_not_allowed(binary(), binary()) -> stanza_error(). err_not_allowed(Text, Lang) -> err(cancel, 'not-allowed', 405, Text, Lang). --spec err_not_authorized() -> error(). +-spec err_not_authorized() -> stanza_error(). err_not_authorized() -> err(auth, 'not-authorized', 401). --spec err_not_authorized(binary(), binary()) -> error(). +-spec err_not_authorized(binary(), binary()) -> stanza_error(). err_not_authorized(Text, Lang) -> err(auth, 'not-authorized', 401, Text, Lang). --spec err_payment_required() -> error(). +-spec err_payment_required() -> stanza_error(). err_payment_required() -> err(auth, 'not-authorized', 402). --spec err_payment_required(binary(), binary()) -> error(). +-spec err_payment_required(binary(), binary()) -> stanza_error(). err_payment_required(Text, Lang) -> err(auth, 'not-authorized', 402, Text, Lang). %% is defined in neither RFC 3920 nor XEP-0086. %% We choose '403' error code (as in ). --spec err_policy_violation() -> error(). +-spec err_policy_violation() -> stanza_error(). err_policy_violation() -> err(modify, 'policy-violation', 403). --spec err_policy_violation(binary(), binary()) -> error(). +-spec err_policy_violation(binary(), binary()) -> stanza_error(). err_policy_violation(Text, Lang) -> err(modify, 'policy-violation', 403, Text, Lang). --spec err_recipient_unavailable() -> error(). +-spec err_recipient_unavailable() -> stanza_error(). err_recipient_unavailable() -> err(wait, 'recipient-unavailable', 404). --spec err_recipient_unavailable(binary(), binary()) -> error(). +-spec err_recipient_unavailable(binary(), binary()) -> stanza_error(). err_recipient_unavailable(Text, Lang) -> err(wait, 'recipient-unavailable', 404, Text, Lang). --spec err_redirect() -> error(). +-spec err_redirect() -> stanza_error(). err_redirect() -> err(modify, 'redirect', 302). --spec err_redirect(binary(), binary()) -> error(). +-spec err_redirect(binary(), binary()) -> stanza_error(). err_redirect(Text, Lang) -> err(modify, 'redirect', 302, Text, Lang). --spec err_registration_required() -> error(). +-spec err_registration_required() -> stanza_error(). err_registration_required() -> err(auth, 'registration-required', 407). --spec err_registration_required(binary(), binary()) -> error(). +-spec err_registration_required(binary(), binary()) -> stanza_error(). err_registration_required(Text, Lang) -> err(auth, 'registration-required', 407, Text, Lang). --spec err_remote_server_not_found() -> error(). +-spec err_remote_server_not_found() -> stanza_error(). err_remote_server_not_found() -> err(cancel, 'remote-server-not-found', 404). --spec err_remote_server_not_found(binary(), binary()) -> error(). +-spec err_remote_server_not_found(binary(), binary()) -> stanza_error(). err_remote_server_not_found(Text, Lang) -> err(cancel, 'remote-server-not-found', 404, Text, Lang). --spec err_remote_server_timeout() -> error(). +-spec err_remote_server_timeout() -> stanza_error(). err_remote_server_timeout() -> err(wait, 'remote-server-timeout', 504). --spec err_remote_server_timeout(binary(), binary()) -> error(). +-spec err_remote_server_timeout(binary(), binary()) -> stanza_error(). err_remote_server_timeout(Text, Lang) -> err(wait, 'remote-server-timeout', 504, Text, Lang). --spec err_resource_constraint() -> error(). +-spec err_resource_constraint() -> stanza_error(). err_resource_constraint() -> err(wait, 'resource-constraint', 500). --spec err_resource_constraint(binary(), binary()) -> error(). +-spec err_resource_constraint(binary(), binary()) -> stanza_error(). err_resource_constraint(Text, Lang) -> err(wait, 'resource-constraint', 500, Text, Lang). --spec err_service_unavailable() -> error(). +-spec err_service_unavailable() -> stanza_error(). err_service_unavailable() -> err(cancel, 'service-unavailable', 503). --spec err_service_unavailable(binary(), binary()) -> error(). +-spec err_service_unavailable(binary(), binary()) -> stanza_error(). err_service_unavailable(Text, Lang) -> err(cancel, 'service-unavailable', 503, Text, Lang). --spec err_subscription_required() -> error(). +-spec err_subscription_required() -> stanza_error(). err_subscription_required() -> err(auth, 'subscription-required', 407). --spec err_subscription_required(binary(), binary()) -> error(). +-spec err_subscription_required(binary(), binary()) -> stanza_error(). err_subscription_required(Text, Lang) -> err(auth, 'subscription-required', 407, Text, Lang). %% No error type is defined for . %% Let user provide the type. -spec err_undefined_condition('auth' | 'cancel' | 'continue' | - 'modify' | 'wait') -> error(). + 'modify' | 'wait') -> stanza_error(). err_undefined_condition(Type) -> err(Type, 'undefined-condition', 500). -spec err_undefined_condition('auth' | 'cancel' | 'continue' | 'modify' | 'wait', - binary(), binary()) -> error(). + binary(), binary()) -> stanza_error(). err_undefined_condition(Type, Text, Lang) -> err(Type, 'undefined-condition', 500, Text, Lang). %% RFC 6120 says error type SHOULD be "wait" or "modify". %% RFC 3920 and XEP-0082 says it SHOULD be "wait". --spec err_unexpected_request() -> error(). +-spec err_unexpected_request() -> stanza_error(). err_unexpected_request() -> err(wait, 'unexpected-request', 400). --spec err_unexpected_request(binary(), binary()) -> error(). +-spec err_unexpected_request(binary(), binary()) -> stanza_error(). err_unexpected_request(Text, Lang) -> err(wait, 'unexpected-request', 400, Text, Lang). @@ -786,17 +786,17 @@ serr_unsupported_version(Text, Lang) -> %%% Internal functions %%%=================================================================== -spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', - atom() | gone() | redirect(), non_neg_integer()) -> error(). + atom() | gone() | redirect(), non_neg_integer()) -> stanza_error(). err(Type, Reason, Code) -> - #error{type = Type, reason = Reason, code = Code}. + #stanza_error{type = Type, reason = Reason, code = Code}. -spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', atom() | gone() | redirect(), non_neg_integer(), - binary(), binary()) -> error(). + binary(), binary()) -> stanza_error(). err(Type, Reason, Code, Text, Lang) -> - #error{type = Type, reason = Reason, code = Code, - text = #text{lang = Lang, - data = translate:translate(Lang, Text)}}. + #stanza_error{type = Type, reason = Reason, code = Code, + text = #text{lang = Lang, + data = translate:translate(Lang, Text)}}. -spec serr(atom() | 'see-other-host'()) -> stream_error(). serr(Reason) -> diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 135a2acbb..8653d591c 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -2567,7 +2567,7 @@ encode({redirect, _} = Redirect) -> encode_error_redirect(Redirect, [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); -encode({error, _, _, _, _, _, _} = Error) -> +encode({stanza_error, _, _, _, _, _, _} = Error) -> encode_error(Error, [{<<"xmlns">>, <<"jabber:client">>}]); encode({bind, _, _} = Bind) -> @@ -3176,7 +3176,6 @@ get_name({delay, _, _, _}) -> <<"delay">>; get_name({disco_info, _, _, _, _}) -> <<"query">>; get_name({disco_item, _, _, _}) -> <<"item">>; get_name({disco_items, _, _, _}) -> <<"query">>; -get_name({error, _, _, _, _, _, _}) -> <<"error">>; get_name({expire, _, _}) -> <<"x">>; get_name({feature_csi, _}) -> <<"csi">>; get_name({feature_register}) -> <<"register">>; @@ -3329,6 +3328,8 @@ get_name({sm_failed, _, _, _}) -> <<"failed">>; get_name({sm_r, _}) -> <<"r">>; get_name({sm_resume, _, _, _}) -> <<"resume">>; get_name({sm_resumed, _, _, _}) -> <<"resumed">>; +get_name({stanza_error, _, _, _, _, _, _}) -> + <<"error">>; get_name({stanza_id, _, _}) -> <<"stanza-id">>; get_name({starttls, _}) -> <<"starttls">>; get_name({starttls_failure}) -> <<"failure">>; @@ -3441,8 +3442,6 @@ get_ns({disco_item, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; get_ns({disco_items, _, _, _}) -> <<"http://jabber.org/protocol/disco#items">>; -get_ns({error, _, _, _, _, _, _}) -> - <<"jabber:client">>; get_ns({expire, _, _}) -> <<"jabber:x:expire">>; get_ns({feature_csi, Xmlns}) -> Xmlns; get_ns({feature_register}) -> @@ -3633,6 +3632,8 @@ get_ns({sm_failed, _, _, Xmlns}) -> Xmlns; get_ns({sm_r, Xmlns}) -> Xmlns; get_ns({sm_resume, _, _, Xmlns}) -> Xmlns; get_ns({sm_resumed, _, _, Xmlns}) -> Xmlns; +get_ns({stanza_error, _, _, _, _, _, _}) -> + <<"jabber:client">>; get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; get_ns({starttls, _}) -> <<"urn:ietf:params:xml:ns:xmpp-tls">>; @@ -3778,7 +3779,8 @@ pp(presence, 9) -> sub_els]; pp(gone, 1) -> [uri]; pp(redirect, 1) -> [uri]; -pp(error, 6) -> [type, code, by, reason, text, sub_els]; +pp(stanza_error, 6) -> + [type, code, by, reason, text, sub_els]; pp(bind, 2) -> [jid, resource]; pp(legacy_auth, 4) -> [username, password, digest, resource]; @@ -25595,7 +25597,7 @@ decode_error(__TopXMLNS, __IgnoreEls, {Type, Code, By} = decode_error_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), - {error, Type, Code, By, Reason, Text, __Els}. + {stanza_error, Type, Code, By, Reason, Text, __Els}. decode_error_els(__TopXMLNS, __IgnoreEls, [], Text, Reason, __Els) -> @@ -25965,8 +25967,8 @@ 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, - __Els}, +encode_error({stanza_error, Type, Code, By, Reason, + Text, __Els}, _xmlns_attrs) -> _els = [encode(_el) || _el <- __Els] ++ lists:reverse('encode_error_$text'(Text, -- cgit v1.2.3 From e987b888481e3e68f6259e96e7c54af84d168c3c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 13 Sep 2016 12:30:05 +0300 Subject: Make common tests working again --- src/ejabberd_c2s.erl | 2 +- src/mod_announce.erl | 55 ++++++++++++++++++----------------- src/mod_blocking.erl | 44 ++++++++++++++-------------- src/mod_client_state.erl | 2 +- src/mod_mam.erl | 9 +++++- src/mod_mam_mnesia.erl | 8 +++++- src/mod_mix.erl | 31 +++++++++----------- src/mod_muc.erl | 10 +++---- src/mod_offline.erl | 2 +- src/mod_privacy.erl | 14 ++++++--- src/mod_pubsub.erl | 38 ++++-------------------- src/mod_register.erl | 8 ++---- src/mod_roster.erl | 73 ++++++++++++++++++++++++----------------------- src/mod_vcard.erl | 2 +- src/mod_vcard_ldap.erl | 8 +++--- src/mod_vcard_xupdate.erl | 2 +- src/node_flat.erl | 2 +- src/xmpp_codec.erl | 66 ++++++++++++++++++++++++++---------------- src/xmpp_util.erl | 2 +- 19 files changed, 192 insertions(+), 186 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index e658536ab..186f7e9a5 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -2663,7 +2663,7 @@ make_resume_id(StateData) -> add_resent_delay_info(_State, #iq{} = El, _Time) -> El; add_resent_delay_info(#state{server = From}, El, Time) -> - xmpp_util:add_delay_info(El, From, Time, <<"Resent">>). + xmpp_util:add_delay_info(El, jid:make(From), Time, <<"Resent">>). %%%---------------------------------------------------------------------- %%% XEP-0352 diff --git a/src/mod_announce.erl b/src/mod_announce.erl index d9209f418..8d2fbebff 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -130,34 +130,37 @@ stop(Host) -> {wait, Proc}. %% Announcing via messages to a custom resource --spec announce(jid(), jid(), stanza()) -> ok. +-spec announce(jid(), jid(), stanza()) -> ok | stop. announce(From, #jid{luser = <<>>} = To, #message{} = Packet) -> Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME), - case To#jid.lresource of - <<"announce/all">> -> - Proc ! {announce_all, From, To, Packet}; - <<"announce/all-hosts/all">> -> - Proc ! {announce_all_hosts_all, From, To, Packet}; - <<"announce/online">> -> - Proc ! {announce_online, From, To, Packet}; - <<"announce/all-hosts/online">> -> - Proc ! {announce_all_hosts_online, From, To, Packet}; - <<"announce/motd">> -> - Proc ! {announce_motd, From, To, Packet}; - <<"announce/all-hosts/motd">> -> - Proc ! {announce_all_hosts_motd, From, To, Packet}; - <<"announce/motd/update">> -> - Proc ! {announce_motd_update, From, To, Packet}; - <<"announce/all-hosts/motd/update">> -> - Proc ! {announce_all_hosts_motd_update, From, To, Packet}; - <<"announce/motd/delete">> -> - Proc ! {announce_motd_delete, From, To, Packet}; - <<"announce/all-hosts/motd/delete">> -> - Proc ! {announce_all_hosts_motd_delete, From, To, Packet}; - _ -> - ok - end, - ok; + Res = case To#jid.lresource of + <<"announce/all">> -> + Proc ! {announce_all, From, To, Packet}; + <<"announce/all-hosts/all">> -> + Proc ! {announce_all_hosts_all, From, To, Packet}; + <<"announce/online">> -> + Proc ! {announce_online, From, To, Packet}; + <<"announce/all-hosts/online">> -> + Proc ! {announce_all_hosts_online, From, To, Packet}; + <<"announce/motd">> -> + Proc ! {announce_motd, From, To, Packet}; + <<"announce/all-hosts/motd">> -> + Proc ! {announce_all_hosts_motd, From, To, Packet}; + <<"announce/motd/update">> -> + Proc ! {announce_motd_update, From, To, Packet}; + <<"announce/all-hosts/motd/update">> -> + Proc ! {announce_all_hosts_motd_update, From, To, Packet}; + <<"announce/motd/delete">> -> + Proc ! {announce_motd_delete, From, To, Packet}; + <<"announce/all-hosts/motd/delete">> -> + Proc ! {announce_all_hosts_motd_delete, From, To, Packet}; + _ -> + ok + end, + case Res of + ok -> ok; + _ -> stop + end; announce(_From, _To, _Packet) -> ok. diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 55e3ca151..b3bbff96e 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -74,39 +74,37 @@ process_iq(IQ) -> -spec process_iq_get({error, stanza_error()} | {result, xmpp_element() | undefined}, iq(), userlist()) -> - {error, stanza_error()} | {result, block_list()}. + {error, stanza_error()} | + {result, xmpp_element() | undefined}. process_iq_get(_, #iq{lang = Lang, from = From, sub_els = [#block_list{}]}, _) -> #jid{luser = LUser, lserver = LServer} = From, - {stop, process_blocklist_get(LUser, LServer, Lang)}; + process_blocklist_get(LUser, LServer, Lang); process_iq_get(Acc, _, _) -> Acc. -spec process_iq_set({error, stanza_error()} | {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, iq()) -> {error, stanza_error()} | - {result, undefined} | - {result, undefined, userlist()}. -process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}. +process_iq_set(Acc, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> #jid{luser = LUser, lserver = LServer} = From, - Res = case SubEl of - #block{items = []} -> - Txt = <<"No items found in this query">>, - {error, xmpp:err_bad_request(Txt, Lang)}; - #block{items = Items} -> - JIDs = [jid:tolower(Item) || Item <- Items], - process_blocklist_block(LUser, LServer, JIDs, Lang); - #unblock{items = []} -> - process_blocklist_unblock_all(LUser, LServer, Lang); - #unblock{items = Items} -> - JIDs = [jid:tolower(Item) || Item <- Items], - process_blocklist_unblock(LUser, LServer, JIDs, Lang); - _ -> - Txt = <<"Only and are allowed " - "in this request">>, - {error, xmpp:err_bad_request(Txt, Lang)} - end, - {stop, Res}; + case SubEl of + #block{items = []} -> + Txt = <<"No items found in this query">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + #block{items = Items} -> + JIDs = [jid:tolower(Item) || Item <- Items], + process_blocklist_block(LUser, LServer, JIDs, Lang); + #unblock{items = []} -> + process_blocklist_unblock_all(LUser, LServer, Lang); + #unblock{items = Items} -> + JIDs = [jid:tolower(Item) || Item <- Items], + process_blocklist_unblock(LUser, LServer, JIDs, Lang); + _ -> + Acc + end; process_iq_set(Acc, _) -> Acc. -spec list_to_blocklist_jids([listitem()], [ljid()]) -> [ljid()]. diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index f72f334f3..7f0658eff 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -277,7 +277,7 @@ get_queue(C2SState) -> get_stanzas(Queue, Host) -> lists:map(fun({_Key, Time, Stanza}) -> - xmpp_util:add_delay_info(Stanza, Host, Time, + xmpp_util:add_delay_info(Stanza, jid:make(Host), Time, <<"Client Inactive">>) end, Queue). diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 2529b7389..ea267c1c0 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -834,6 +834,10 @@ msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, #forwarded{sub_els = [Pkt2], delay = #delay{stamp = TS, from = jid:make(LServer)}}. +maybe_update_from_to(#xmlel{} = El, JidRequestor, JidArchive, Peer, + {groupchat, _, _} = MsgType, Nick) -> + Pkt = xmpp:decode(El, [ignore_els]), + maybe_update_from_to(Pkt, JidRequestor, JidArchive, Peer, MsgType, Nick); maybe_update_from_to(#message{sub_els = Els} = Pkt, JidRequestor, JidArchive, Peer, {groupchat, Role, #state{config = #config{anonymous = Anon}}}, @@ -908,7 +912,8 @@ send(Msgs, Count, IsComplete, Result = if NS == ?NS_MAM_TMP -> #mam_query{xmlns = NS, id = QID, rsm = RSMOut}; true -> - #mam_fin{id = QID, rsm = RSMOut, complete = IsComplete} + #mam_fin{xmlns = NS, id = QID, rsm = RSMOut, + complete = IsComplete} end, if NS == ?NS_MAM_TMP; NS == ?NS_MAM_1 -> lists:foreach( @@ -950,6 +955,8 @@ limit_max(#rsm_set{max = Max} = RSM, _NS) when Max > ?MAX_PAGE_SIZE -> limit_max(RSM, _NS) -> RSM. +match_interval(Now, Start, undefined) -> + Now >= Start; match_interval(Now, Start, End) -> (Now >= Start) and (Now =< End). diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl index cbe7c336c..ecaa4d053 100644 --- a/src/mod_mam_mnesia.erl +++ b/src/mod_mam_mnesia.erl @@ -134,7 +134,10 @@ select(_LServer, JidRequestor, #jid{luser = LUser, lserver = LServer} = JidArchive, #mam_query{start = Start, 'end' = End, with = With, rsm = RSM}, MsgType) -> - MS = make_matchspec(LUser, LServer, Start, End, With), + LWith = if With /= undefined -> jid:tolower(With); + true -> undefined + end, + MS = make_matchspec(LUser, LServer, Start, End, LWith), Msgs = mnesia:dirty_select(archive_msg, MS), SortedMsgs = lists:keysort(#archive_msg.timestamp, Msgs), {FilteredMsgs, IsComplete} = filter_by_rsm(SortedMsgs, RSM), @@ -155,6 +158,9 @@ select(_LServer, JidRequestor, now_to_usec({MSec, Sec, USec}) -> (MSec*1000000 + Sec)*1000000 + USec. +make_matchspec(LUser, LServer, Start, undefined, With) -> + %% List is always greater than a tuple + make_matchspec(LUser, LServer, Start, [], With); make_matchspec(LUser, LServer, Start, End, {_, _, <<>>} = With) -> ets:fun2ms( fun(#archive_msg{timestamp = TS, diff --git a/src/mod_mix.erl b/src/mod_mix.erl index f39408210..7ca09f4db 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -209,19 +209,18 @@ do_route(_State, _From, _To, _Packet) -> subscribe_nodes(From, To, Nodes) -> LTo = jid:tolower(jid:remove_resource(To)), LFrom = jid:tolower(jid:remove_resource(From)), - From_s = jid:to_string(LFrom), lists:foldl( fun(_Node, {error, _} = Err) -> Err; (Node, {result, _}) -> - case mod_pubsub:subscribe_node(LTo, Node, From, From_s, []) of + case mod_pubsub:subscribe_node(LTo, Node, From, From, []) of {error, _} = Err -> case is_item_not_found(Err) of true -> case mod_pubsub:create_node( LTo, To#jid.lserver, Node, LFrom, <<"mix">>) of {result, _} -> - mod_pubsub:subscribe_node(LTo, Node, From, From_s, []); + mod_pubsub:subscribe_node(LTo, Node, From, From, []); Error -> Error end; @@ -235,13 +234,12 @@ subscribe_nodes(From, To, Nodes) -> unsubscribe_nodes(From, To, Nodes) -> LTo = jid:tolower(jid:remove_resource(To)), - LFrom = jid:tolower(jid:remove_resource(From)), - From_s = jid:to_string(LFrom), + BareFrom = jid:remove_resource(From), lists:foldl( fun(_Node, {error, _} = Err) -> Err; (Node, {result, _} = Result) -> - case mod_pubsub:unsubscribe_node(LTo, Node, From, From_s, <<"">>) of + case mod_pubsub:unsubscribe_node(LTo, Node, From, BareFrom, <<"">>) of {error, _} = Err -> case is_not_subscribed(Err) of true -> Result; @@ -297,19 +295,16 @@ delete_item(From, To, Node, ItemID) -> end end. -is_item_not_found({error, ErrEl}) -> - case fxml:get_subtag_with_xmlns( - ErrEl, <<"item-not-found">>, ?NS_STANZAS) of - #xmlel{} -> true; - _ -> false - end. +-spec is_item_not_found({error, stanza_error()}) -> boolean(). +is_item_not_found({error, #stanza_error{reason = 'item-not-found'}}) -> true; +is_item_not_found({error, _}) -> false. -is_not_subscribed({error, ErrEl}) -> - case fxml:get_subtag_with_xmlns( - ErrEl, <<"not-subscribed">>, ?NS_PUBSUB_ERRORS) of - #xmlel{} -> true; - _ -> false - end. +-spec is_not_subscribed({error, stanza_error()}) -> boolean(). +is_not_subscribed({error, #stanza_error{sub_els = Els}}) -> + %% TODO: make xmpp:get_els function working for any XMPP element + %% with sub_els field + xmpp:has_subtag(#message{sub_els = Els}, + #ps_error{type = 'not-subscribed'}). depends(_Host, _Opts) -> [{mod_pubsub, hard}]. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 3eca79fec..66604394b 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -668,17 +668,17 @@ get_nick(ServerHost, Host, From) -> Mod:get_nick(LServer, Host, From). iq_get_register_info(ServerHost, Host, From, Lang) -> - {Nick, Registered} = case get_nick(ServerHost, Host, From) of - error -> {<<"">>, false}; - N -> {N, true} - end, + {Nick, NickVals, Registered} = case get_nick(ServerHost, Host, From) of + error -> {<<"">>, [], false}; + N -> {N, [N], true} + end, Title = <<(translate:translate( Lang, <<"Nickname Registration at ">>))/binary, Host/binary>>, Inst = translate:translate(Lang, <<"Enter nickname you want to register">>), Field = #xdata_field{type = 'text-single', label = translate:translate(Lang, <<"Nickname">>), var = <<"nick">>, - values = [Nick]}, + values = NickVals}, X = #xdata{type = form, title = Title, instructions = [Inst], fields = [Field]}, #register{nick = Nick, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 509406aa4..a2bcec894 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -616,7 +616,7 @@ offline_msg_to_route(LServer, #offline_msg{} = R) -> undefined -> Pkt; TS -> - xmpp_util:add_delay_info(Pkt, LServer, TS, + xmpp_util:add_delay_info(Pkt, jid:make(LServer), TS, <<"Offline Storage">>) end, {route, R#offline_msg.from, R#offline_msg.to, Pkt1}. diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 3be3f2d3b..2f318deec 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -101,7 +101,8 @@ process_iq(IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed()). -spec process_iq_get({error, stanza_error()} | {result, xmpp_element() | undefined}, - iq(), userlist()) -> {error, stanza_error()} | {result, privacy_query()}. + iq(), userlist()) -> {error, stanza_error()} | + {result, xmpp_element() | undefined}. process_iq_get(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{lists = Lists}]}, #userlist{name = Active}) -> @@ -114,7 +115,9 @@ process_iq_get(_, #iq{from = From, lang = Lang, _ -> Txt = <<"Too many elements">>, {error, xmpp:err_bad_request(Txt, Lang)} - end. + end; +process_iq_get(Acc, _, _) -> + Acc. -spec process_lists_get(binary(), binary(), binary(), binary()) -> {error, stanza_error()} | {result, privacy_query()}. @@ -218,7 +221,8 @@ decode_value(Type, Value) -> {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, iq()) -> {error, stanza_error()} | - {result, undefined, userlist()}. + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}. process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{default = Default, active = Active, @@ -236,7 +240,9 @@ process_iq_set(_, #iq{from = From, lang = Lang, Txt = <<"There should be exactly one element in this query: " ", or ">>, {error, xmpp:err_bad_request(Txt, Lang)} - end. + end; +process_iq_set(Acc, _) -> + Acc. -spec process_default_set(binary(), binary(), none | binary(), binary()) -> {error, stanza_error()} | {result, undefined}. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index b470d83d9..f7e1a9834 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -69,9 +69,7 @@ tree_action/3, node_action/4, node_call/4]). %% general helpers for plugins --export([subscription_to_string/1, affiliation_to_string/1, - string_to_subscription/1, string_to_affiliation/1, - extended_error/2, service_jid/1, +-export([extended_error/2, service_jid/1, tree/1, tree/2, plugin/2, plugins/1, config/3, host/1, serverhost/1]). @@ -2170,7 +2168,7 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) -> get_items(Host, Node) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) -> - node_call(Host, Type, get_items, [Nidx, service_jid(Host), none]) + node_call(Host, Type, get_items, [Nidx, service_jid(Host), undefined]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, {Items, _}}} -> Items; @@ -2187,7 +2185,7 @@ get_item(Host, Node, ItemId) -> end. get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) -> - case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners, none) of + case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners, undefined) of {result, {Items, _RSM}} -> {result, Items}; Error -> Error end. @@ -2203,7 +2201,7 @@ get_last_item(Host, Type, Nidx, LJID) -> LastItem -> LastItem end. get_last_item(Host, Type, Nidx, LJID, mnesia) -> - case node_action(Host, Type, get_items, [Nidx, LJID, none]) of + case node_action(Host, Type, get_items, [Nidx, LJID, undefined]) of {result, {[LastItem|_], _}} -> LastItem; _ -> undefined end; @@ -2218,7 +2216,7 @@ get_last_item(_Host, _Type, _Nidx, _LJID, _) -> get_last_items(Host, Type, Nidx, LJID, Number) -> get_last_items(Host, Type, Nidx, LJID, Number, gen_mod:db_type(serverhost(Host), ?MODULE)). get_last_items(Host, Type, Nidx, LJID, Number, mnesia) -> - case node_action(Host, Type, get_items, [Nidx, LJID, none]) of + case node_action(Host, Type, get_items, [Nidx, LJID, undefined]) of {result, {Items, _}} -> lists:sublist(Items, Number); _ -> [] end; @@ -2714,32 +2712,6 @@ get_roster_info(OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, _}, A get_roster_info(OwnerUser, OwnerServer, JID, AllowedGroups) -> get_roster_info(OwnerUser, OwnerServer, jid:tolower(JID), AllowedGroups). -string_to_affiliation(<<"owner">>) -> owner; -string_to_affiliation(<<"publisher">>) -> publisher; -string_to_affiliation(<<"publish-only">>) -> publish_only; -string_to_affiliation(<<"member">>) -> member; -string_to_affiliation(<<"outcast">>) -> outcast; -string_to_affiliation(<<"none">>) -> none; -string_to_affiliation(_) -> false. - -string_to_subscription(<<"subscribed">>) -> subscribed; -string_to_subscription(<<"pending">>) -> pending; -string_to_subscription(<<"unconfigured">>) -> unconfigured; -string_to_subscription(<<"none">>) -> none; -string_to_subscription(_) -> false. - -affiliation_to_string(owner) -> <<"owner">>; -affiliation_to_string(publisher) -> <<"publisher">>; -affiliation_to_string(publish_only) -> <<"publish-only">>; -affiliation_to_string(member) -> <<"member">>; -affiliation_to_string(outcast) -> <<"outcast">>; -affiliation_to_string(_) -> <<"none">>. - -subscription_to_string(subscribed) -> <<"subscribed">>; -subscription_to_string(pending) -> <<"pending">>; -subscription_to_string(unconfigured) -> <<"unconfigured">>; -subscription_to_string(_) -> <<"none">>. - -spec service_jid(jid() | ljid() | binary()) -> jid(). service_jid(#jid{} = Jid) -> Jid; service_jid({U, S, R}) -> jid:make(U, S, R); diff --git a/src/mod_register.erl b/src/mod_register.erl index 334af4514..44a64539e 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -146,12 +146,10 @@ process_iq(#iq{type = set, lang = Lang, to = To, from = From, end; true -> case From of - #jid{user = User, lserver = Server, resource = Resource} -> + #jid{luser = LUser, lserver = Server} -> ResIQ = xmpp:make_iq_result(IQ), - ejabberd_router:route(jid:make(User, Server, Resource), - jid:make(User, Server, Resource), - ResIQ), - ejabberd_auth:remove_user(User, Server), + ejabberd_router:route(From, From, ResIQ), + ejabberd_auth:remove_user(LUser, Server), ignore; _ -> Txt = <<"The query is only allowed from local users">>, diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 2a41907a4..feebd3945 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -308,13 +308,13 @@ encode_item(Item) -> end, groups = Item#roster.groups}. -decode_item(#roster_item{} = Item, R, Managed) -> +decode_item(Item, R, Managed) -> R#roster{jid = jid:tolower(Item#roster_item.jid), name = Item#roster_item.name, subscription = case Item#roster_item.subscription of remove -> remove; Sub when Managed -> Sub; - _ -> undefined + _ -> R#roster.subscription end, groups = Item#roster_item.groups}. @@ -334,45 +334,48 @@ try_process_iq_set(#iq{from = From, lang = Lang} = IQ) -> end. process_iq_set(#iq{from = From, to = To, id = Id, - sub_els = [#roster_query{items = Items}]} = IQ) -> + sub_els = [#roster_query{items = QueryItems}]} = IQ) -> Managed = is_managed_from_id(Id), - lists:foreach(fun (Item) -> process_item_set(From, To, Item, Managed) - end, - Items), - xmpp:make_iq_result(IQ). - -process_item_set(From, To, #roster_item{jid = JID1} = QueryItem, Managed) -> #jid{user = User, luser = LUser, lserver = LServer} = From, - LJID = jid:tolower(JID1), F = fun () -> - Item = get_roster_by_jid_t(LUser, LServer, LJID), - Item2 = decode_item(QueryItem, Item, Managed), - Item3 = ejabberd_hooks:run_fold(roster_process_item, - LServer, Item2, - [LServer]), - case Item3#roster.subscription of - remove -> del_roster_t(LUser, LServer, LJID); - _ -> update_roster_t(LUser, LServer, LJID, Item3) - end, - send_itemset_to_managers(From, Item3, Managed), - case roster_version_on_db(LServer) of - true -> write_roster_version_t(LUser, LServer); - false -> ok - end, - {Item, Item3} + lists:map( + fun(#roster_item{jid = JID1} = QueryItem) -> + LJID = jid:tolower(JID1), + Item = get_roster_by_jid_t(LUser, LServer, LJID), + Item2 = decode_item(QueryItem, Item, Managed), + Item3 = ejabberd_hooks:run_fold(roster_process_item, + LServer, Item2, + [LServer]), + case Item3#roster.subscription of + remove -> del_roster_t(LUser, LServer, LJID); + _ -> update_roster_t(LUser, LServer, LJID, Item3) + end, + case roster_version_on_db(LServer) of + true -> write_roster_version_t(LUser, LServer); + false -> ok + end, + {Item, Item3} + end, QueryItems) end, case transaction(LServer, F) of - {atomic, {OldItem, Item}} -> - push_item(User, LServer, To, Item), - case Item#roster.subscription of - remove -> - send_unsubscribing_presence(From, OldItem), ok; - _ -> ok - end; + {atomic, ItemPairs} -> + lists:foreach( + fun({OldItem, Item}) -> + send_itemset_to_managers(From, Item, Managed), + push_item(User, LServer, To, Item), + case Item#roster.subscription of + remove -> + send_unsubscribing_presence(From, OldItem); + _ -> + ok + end + end, ItemPairs), + xmpp:make_iq_result(IQ); E -> - ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok - end; -process_item_set(_From, _To, _, _Managed) -> ok. + ?ERROR_MSG("roster set failed:~nIQ = ~s~nError = ~p", + [xmpp:pp(IQ), E]), + xmpp:make_error(IQ, xmpp:err_internal_server_error()) + end. push_item(User, Server, From, Item) -> ejabberd_sm:route(jid:make(<<"">>, <<"">>, <<"">>), diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 1f6edb460..8333d32cf 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -137,7 +137,7 @@ stop(Host) -> ?NS_VCARD), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), - Mod = gen_mod:db_type(Host, ?MODULE), + Mod = gen_mod:db_mod(Host, ?MODULE), Mod:stop(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 191676224..d8efe30f5 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -248,10 +248,10 @@ ldap_attribute_to_vcard({Attr, Value}, V) -> <<"tel">> -> V#vcard_temp{tel = [#vcard_tel{number = Value}|Ts]}; <<"email">> -> V#vcard_temp{email = [#vcard_email{userid = Value}|Es]}; <<"photo">> -> V#vcard_temp{photo = #vcard_photo{binval = Value}}; - <<"family">> -> V#vcard_temp{n = N#vcard_name{family = V}}; - <<"given">> -> V#vcard_temp{n = N#vcard_name{given = V}}; - <<"middle">> -> V#vcard_temp{n = N#vcard_name{middle = V}}; - <<"orgname">> -> V#vcard_temp{org = O#vcard_org{name = V}}; + <<"family">> -> V#vcard_temp{n = N#vcard_name{family = Value}}; + <<"given">> -> V#vcard_temp{n = N#vcard_name{given = Value}}; + <<"middle">> -> V#vcard_temp{n = N#vcard_name{middle = Value}}; + <<"orgname">> -> V#vcard_temp{org = O#vcard_org{name = Value}}; <<"orgunit">> -> V#vcard_temp{org = O#vcard_org{units = [Value]}}; <<"locality">> -> V#vcard_temp{adr = [A#vcard_adr{locality = Value}]}; <<"street">> -> V#vcard_temp{adr = [A#vcard_adr{street = Value}]}; diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 5cc87056e..27688e8fb 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -52,7 +52,7 @@ depends(_Host, _Opts) -> %% Hooks %%==================================================================== -spec update_presence(presence(), binary(), binary()) -> presence(). -update_presence(#presence{type = undefined} = Packet, User, Host) -> +update_presence(#presence{type = available} = Packet, User, Host) -> presence_with_xupdate(Packet, User, Host); update_presence(Packet, _User, _Host) -> Packet. diff --git a/src/node_flat.erl b/src/node_flat.erl index 2ec9afe54..e80aaad34 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -707,7 +707,7 @@ del_state(Nidx, Key) -> %% relational database), or they can even decide not to persist any items.

    get_items(Nidx, _From, _RSM) -> Items = mnesia:match_object(#pubsub_item{itemid = {'_', Nidx}, _ = '_'}), - {result, {lists:reverse(lists:keysort(#pubsub_item.modification, Items)), none}}. + {result, {lists:reverse(lists:keysort(#pubsub_item.modification, Items)), undefined}}. get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) -> SubKey = jid:tolower(JID), diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 8653d591c..00ee53aaf 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -286,6 +286,8 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) -> _el); {<<"fin">>, <<"urn:xmpp:mam:0">>} -> decode_mam_fin(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"fin">>, <<"urn:xmpp:mam:1">>} -> + decode_mam_fin(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); {<<"prefs">>, <<"urn:xmpp:mam:1">>} -> @@ -1688,6 +1690,7 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) -> {<<"disable">>, <<"urn:xmpp:carbons:2">>} -> true; {<<"forwarded">>, <<"urn:xmpp:forward:0">>} -> true; {<<"fin">>, <<"urn:xmpp:mam:0">>} -> true; + {<<"fin">>, <<"urn:xmpp:mam:1">>} -> true; {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> true; {<<"prefs">>, <<"urn:xmpp:mam:1">>} -> true; {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> true; @@ -2978,9 +2981,8 @@ 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({mam_fin, _, _, _, _, _} = Fin) -> + encode_mam_fin(Fin, []); encode({forwarded, _, _} = Forwarded) -> encode_forwarded(Forwarded, [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]); @@ -3196,7 +3198,7 @@ get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; get_name({last, _, _}) -> <<"query">>; get_name({legacy_auth, _, _, _, _}) -> <<"query">>; get_name({mam_archived, _, _}) -> <<"archived">>; -get_name({mam_fin, _, _, _, _}) -> <<"fin">>; +get_name({mam_fin, _, _, _, _, _}) -> <<"fin">>; get_name({mam_prefs, _, _, _, _}) -> <<"prefs">>; get_name({mam_query, _, _, _, _, _, _, _, _}) -> <<"query">>; @@ -3466,7 +3468,7 @@ get_ns({last, _, _}) -> <<"jabber:iq:last">>; get_ns({legacy_auth, _, _, _, _}) -> <<"jabber:iq:auth">>; get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; -get_ns({mam_fin, _, _, _, _}) -> <<"urn:xmpp:mam:0">>; +get_ns({mam_fin, Xmlns, _, _, _, _}) -> Xmlns; get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; get_ns({mam_query, Xmlns, _, _, _, _, _, _, _}) -> Xmlns; @@ -3898,7 +3900,7 @@ pp(mam_query, 8) -> 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, 4) -> [id, rsm, stable, complete]; +pp(mam_fin, 5) -> [xmlns, id, rsm, stable, complete]; pp(forwarded, 2) -> [delay, sub_els]; pp(carbons_disable, 0) -> []; pp(carbons_enable, 0) -> []; @@ -8600,10 +8602,10 @@ decode_mam_fin(__TopXMLNS, __IgnoreEls, {xmlel, <<"fin">>, _attrs, _els}) -> Rsm = decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, undefined), - {Id, Stable, Complete} = + {Id, Xmlns, Stable, Complete} = decode_mam_fin_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined), - {mam_fin, Id, Rsm, Stable, Complete}. + undefined, undefined, undefined), + {mam_fin, Xmlns, Id, Rsm, Stable, Complete}. decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [], Rsm) -> Rsm; @@ -8622,37 +8624,45 @@ decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, Rsm). decode_mam_fin_attrs(__TopXMLNS, - [{<<"queryid">>, _val} | _attrs], _Id, Stable, + [{<<"queryid">>, _val} | _attrs], _Id, Xmlns, Stable, Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, _val, Stable, - Complete); + decode_mam_fin_attrs(__TopXMLNS, _attrs, _val, Xmlns, + Stable, Complete); decode_mam_fin_attrs(__TopXMLNS, - [{<<"stable">>, _val} | _attrs], Id, _Stable, + [{<<"xmlns">>, _val} | _attrs], Id, _Xmlns, Stable, Complete) -> decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, _val, - Complete); + Stable, Complete); +decode_mam_fin_attrs(__TopXMLNS, + [{<<"stable">>, _val} | _attrs], Id, Xmlns, _Stable, + Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, + _val, Complete); decode_mam_fin_attrs(__TopXMLNS, - [{<<"complete">>, _val} | _attrs], Id, Stable, + [{<<"complete">>, _val} | _attrs], Id, Xmlns, Stable, _Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Stable, - _val); + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, + Stable, _val); decode_mam_fin_attrs(__TopXMLNS, [_ | _attrs], Id, - Stable, Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Stable, - Complete); -decode_mam_fin_attrs(__TopXMLNS, [], Id, Stable, + Xmlns, Stable, Complete) -> + decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, + Stable, Complete); +decode_mam_fin_attrs(__TopXMLNS, [], Id, Xmlns, Stable, Complete) -> {decode_mam_fin_attr_queryid(__TopXMLNS, Id), + decode_mam_fin_attr_xmlns(__TopXMLNS, Xmlns), decode_mam_fin_attr_stable(__TopXMLNS, Stable), decode_mam_fin_attr_complete(__TopXMLNS, Complete)}. -encode_mam_fin({mam_fin, Id, Rsm, Stable, Complete}, +encode_mam_fin({mam_fin, Xmlns, Id, Rsm, Stable, + Complete}, _xmlns_attrs) -> _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, [])), _attrs = encode_mam_fin_attr_complete(Complete, encode_mam_fin_attr_stable(Stable, - encode_mam_fin_attr_queryid(Id, - _xmlns_attrs))), + encode_mam_fin_attr_xmlns(Xmlns, + encode_mam_fin_attr_queryid(Id, + _xmlns_attrs)))), {xmlel, <<"fin">>, _attrs, _els}. 'encode_mam_fin_$rsm'(undefined, _acc) -> _acc; @@ -8669,6 +8679,14 @@ encode_mam_fin_attr_queryid(<<>>, _acc) -> _acc; encode_mam_fin_attr_queryid(_val, _acc) -> [{<<"queryid">>, _val} | _acc]. +decode_mam_fin_attr_xmlns(__TopXMLNS, undefined) -> + <<>>; +decode_mam_fin_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_mam_fin_attr_xmlns(<<>>, _acc) -> _acc; +encode_mam_fin_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + decode_mam_fin_attr_stable(__TopXMLNS, undefined) -> undefined; decode_mam_fin_attr_stable(__TopXMLNS, _val) -> diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 20231fffa..43178e86f 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -68,7 +68,7 @@ unwrap_carbon(Stanza) -> Stanza. -spec is_standalone_chat_state(stanza()) -> boolean(). is_standalone_chat_state(Stanza) -> case unwrap_carbon(Stanza) of - #message{sub_els = Els} -> + #message{body = [], subject = [], sub_els = Els} -> IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY], Stripped = [El || El <- Els, not lists:member(xmpp:get_ns(El), IgnoreNS)], -- cgit v1.2.3 From 151668ac10613c7c47d62db6c3d102b536f7a3e4 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 13 Sep 2016 16:56:34 +0300 Subject: Fix dialyzer warnings for mod_mam --- src/mod_mam.erl | 2 +- src/mod_mam_sql.erl | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mod_mam.erl b/src/mod_mam.erl index ea267c1c0..5e4bebb75 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -945,7 +945,7 @@ filter_by_max(Msgs, Len) when is_integer(Len), Len >= 0 -> filter_by_max(_Msgs, _Junk) -> {[], true}. --spec limit_max(rsm_set(), binary()) -> rsm_set(). +-spec limit_max(rsm_set(), binary()) -> rsm_set() | undefined. limit_max(RSM, ?NS_MAM_TMP) -> RSM; % XEP-0313 v0.2 doesn't require clients to support RSM. limit_max(#rsm_set{max = Max} = RSM, _NS) when not is_integer(Max) -> diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 6e5231989..2a0dcce95 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -217,13 +217,10 @@ make_sql_query(User, LServer, true -> [] end, - WithTextClause = case WithText of - {text, <<>>} -> - []; - {text, Txt} -> + WithTextClause = if is_binary(WithText), WithText /= <<>> -> [<<" and match (txt) against ('">>, - Escape(Txt), <<"')">>]; - undefined -> + Escape(WithText), <<"')">>]; + true -> [] end, WithClause = case catch jid:tolower(With) of -- cgit v1.2.3 From a4ec06445593728af35149a2a111527f8515e43c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 20 Sep 2016 14:04:07 +0300 Subject: Add more tests for C2S --- src/ejabberd_c2s.erl | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 186f7e9a5..e98a9eb8f 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -323,24 +323,25 @@ get_subscribed(FsmRef) -> wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of - #stream_start{xmlns = NS_CLIENT, stream_xmlns = NS_STREAM, lang = Lang} + #stream_start{xmlns = NS_CLIENT, stream_xmlns = NS_STREAM, + version = Version, lang = Lang} when NS_CLIENT /= ?NS_CLIENT; NS_STREAM /= ?NS_STREAM -> - send_header(StateData, ?MYNAME, <<"">>, Lang), + send_header(StateData, ?MYNAME, Version, Lang), send_element(StateData, xmpp:serr_invalid_namespace()), {stop, normal, StateData}; - #stream_start{lang = Lang} when byte_size(Lang) > 35 -> + #stream_start{lang = Lang, version = Version} when byte_size(Lang) > 35 -> %% As stated in BCP47, 4.4.1: %% Protocols or specifications that specify limited buffer sizes for %% language tags MUST allow for language tags of at least 35 characters. %% Do not store long language tag to avoid possible DoS/flood attacks - send_header(StateData, ?MYNAME, <<"">>, ?MYLANG), + send_header(StateData, ?MYNAME, Version, ?MYLANG), Txt = <<"Too long value of 'xml:lang' attribute">>, send_element(StateData, xmpp:serr_policy_violation(Txt, ?MYLANG)), {stop, normal, StateData}; - #stream_start{to = undefined, lang = Lang} -> + #stream_start{to = undefined, lang = Lang, version = Version} -> Txt = <<"Missing 'to' attribute">>, - send_header(StateData, ?MYNAME, <<"">>, Lang), + send_header(StateData, ?MYNAME, Version, Lang), send_element(StateData, xmpp:serr_improper_addressing(Txt, Lang)), {stop, normal, StateData}; @@ -463,7 +464,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> end end; _ -> - send_header(StateData, Server, <<"">>, ?MYLANG), + send_header(StateData, Server, StreamVersion, ?MYLANG), if not StateData#state.tls_enabled and StateData#state.tls_required -> send_element( @@ -492,7 +493,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> end catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), - send_header(StateData, ?MYNAME, <<"">>, ?MYLANG), + send_header(StateData, ?MYNAME, <<"1.0">>, ?MYLANG), send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), {stop, normal, StateData} end; @@ -517,13 +518,8 @@ wait_for_auth({xmlstreamelement, #xmlel{} = El}, StateData) -> decode_element(El, wait_for_auth, StateData); wait_for_auth(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> fsm_next_state(wait_for_auth, dispatch_stream_mgmt(Pkt, StateData)); -wait_for_auth(#iq{type = get, - sub_els = [#legacy_auth{username = U}]} = IQ, StateData) -> - Username = case U of - undefined -> <<"">>; - _ -> U - end, - Auth = #legacy_auth{username = Username, password = <<>>, resource = <<>>}, +wait_for_auth(#iq{type = get, sub_els = [#legacy_auth{}]} = IQ, StateData) -> + Auth = #legacy_auth{username = <<>>, password = <<>>, resource = <<>>}, Res = case ejabberd_auth:plain_password_required(StateData#state.server) of false -> xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = <<>>}); -- cgit v1.2.3 From ceda0737666760e5fa93bed0a9ab160778d29358 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 21 Sep 2016 10:45:11 +0300 Subject: Add tests for external component --- src/ejabberd_c2s.erl | 2 +- src/ejabberd_service.erl | 29 ++++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index e98a9eb8f..7dc9960e6 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -494,7 +494,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), send_header(StateData, ?MYNAME, <<"1.0">>, ?MYLANG), - send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), + send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)), {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 002d74949..f4338593d 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -125,7 +125,12 @@ init([{SockMod, Socket}, Opts]) -> wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of - #stream_start{xmlns = ?NS_COMPONENT, to = To} when is_record(To, jid) -> + #stream_start{xmlns = NS_COMPONENT, stream_xmlns = NS_STREAM} + when NS_COMPONENT /= ?NS_COMPONENT; NS_STREAM /= ?NS_STREAM -> + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_invalid_namespace()), + {stop, normal, StateData}; + #stream_start{to = To} when is_record(To, jid) -> Host = To#jid.lserver, send_header(StateData, Host), HostOpts = case dict:is_key(Host, StateData#state.host_opts) of @@ -141,13 +146,9 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> end, {next_state, wait_for_handshake, StateData#state{host = Host, host_opts = HostOpts}}; - #stream_start{xmlns = ?NS_COMPONENT} -> - send_header(StateData, ?MYNAME), - send_element(StateData, xmpp:serr_improper_addressing()), - {stop, normal, StateData}; #stream_start{} -> send_header(StateData, ?MYNAME), - send_element(StateData, xmpp:serr_invalid_namespace()), + send_element(StateData, xmpp:serr_improper_addressing()), {stop, normal, StateData} catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), @@ -203,7 +204,8 @@ stream_established(El, StateData) when ?is_stanza(El) -> To = xmpp:get_to(El), Lang = xmpp:get_lang(El), if From == undefined orelse To == undefined -> - send_error(StateData, El, xmpp:err_jid_malformed()); + Txt = <<"Missing 'from' or 'to' attribute">>, + send_error(StateData, El, xmpp:err_jid_malformed(Txt, Lang)); true -> FromJID = case StateData#state.check_from of false -> @@ -214,19 +216,16 @@ stream_established(El, StateData) when ?is_stanza(El) -> From; _ -> %% The default is the standard behaviour in XEP-0114 - case From of - #jid{lserver = Server} -> - case dict:is_key(Server, StateData#state.host_opts) of - true -> From; - false -> error - end; - _ -> error + Server = From#jid.lserver, + case dict:is_key(Server, StateData#state.host_opts) of + true -> From; + false -> error end end, if FromJID /= error -> ejabberd_router:route(FromJID, To, El); true -> - Txt = <<"Incorrect value of 'from' or 'to' attribute">>, + Txt = <<"Improper domain part of 'from' attribute">>, send_error(StateData, El, xmpp:err_not_allowed(Txt, Lang)) end end, -- cgit v1.2.3 From 53209b9ab1c154334eafacd3ca9aebe965380d50 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 23 Sep 2016 12:30:33 +0300 Subject: Add tests for s2s code --- src/ejabberd_c2s.erl | 65 ++++++++++++------------------ src/ejabberd_s2s.erl | 18 ++++++++- src/ejabberd_s2s_in.erl | 101 ++++++++++++++++++++++++++++++----------------- src/ejabberd_s2s_out.erl | 48 +++++++++++----------- src/ejabberd_service.erl | 17 ++++---- src/xmpp_codec.erl | 23 +++++++++-- 6 files changed, 157 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 7dc9960e6..858e285a6 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -352,16 +352,16 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> S -> S end, StreamVersion = case Version of - <<"1.0">> -> <<"1.0">>; - _ -> <<"">> + {1,0} -> {1,0}; + _ -> undefined end, IsBlacklistedIP = is_ip_blacklisted(StateData#state.ip, Lang), case lists:member(Server, ?MYHOSTS) of true when IsBlacklistedIP == false -> change_shaper(StateData, jid:make(<<"">>, Server, <<"">>)), case StreamVersion of - <<"1.0">> -> - send_header(StateData, Server, <<"1.0">>, ?MYLANG), + {1,0} -> + send_header(StateData, Server, {1,0}, ?MYLANG), case StateData#state.authenticated of false -> TLS = StateData#state.tls, @@ -490,10 +490,14 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> send_header(StateData, ?MYNAME, StreamVersion, ?MYLANG), send_element(StateData, xmpp:serr_host_unknown()), {stop, normal, StateData} - end + end; + _ -> + send_header(StateData, ?MYNAME, {1,0}, ?MYLANG), + send_element(StateData, xmpp:serr_invalid_xml()), + {stop, normal, StateData} catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), - send_header(StateData, ?MYNAME, <<"1.0">>, ?MYLANG), + send_header(StateData, ?MYNAME, {1,0}, ?MYLANG), send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)), {stop, normal, StateData} end; @@ -506,7 +510,7 @@ wait_for_stream({xmlstreamend, _}, StateData) -> send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream({xmlstreamerror, _}, StateData) -> - send_header(StateData, ?MYNAME, <<"1.0">>, <<"">>), + send_header(StateData, ?MYNAME, {1,0}, <<"">>), send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> @@ -1374,7 +1378,7 @@ handle_info({'DOWN', Monitor, _Type, _Object, _Info}, handle_info(system_shutdown, StateName, StateData) -> case StateName of wait_for_stream -> - send_header(StateData, ?MYNAME, <<"1.0">>, <<"en">>), + send_header(StateData, ?MYNAME, {1,0}, <<"en">>), send_element(StateData, xmpp:serr_system_shutdown()), ok; _ -> @@ -1597,39 +1601,20 @@ send_packet(StateData, Packet) -> end. -spec send_header(state(), binary(), binary(), binary()) -> ok | {error, any()}. -send_header(StateData, Server, Version, Lang) - when StateData#state.xml_socket -> - VersionAttr = case Version of - <<"">> -> []; - _ -> [{<<"version">>, Version}] - end, - LangAttr = case Lang of - <<"">> -> []; - _ -> [{<<"xml:lang">>, Lang}] - end, - Header = {xmlstreamstart, <<"stream:stream">>, - VersionAttr ++ - LangAttr ++ - [{<<"xmlns">>, <<"jabber:client">>}, - {<<"xmlns:stream">>, - <<"http://etherx.jabber.org/streams">>}, - {<<"id">>, StateData#state.streamid}, - {<<"from">>, Server}]}, - (StateData#state.sockmod):send_xml(StateData#state.socket, - Header); send_header(StateData, Server, Version, Lang) -> - VersionStr = case Version of - <<"">> -> <<"">>; - _ -> [<<" version='">>, Version, <<"'">>] - end, - LangStr = case Lang of - <<"">> -> <<"">>; - _ -> [<<" xml:lang='">>, Lang, <<"'">>] - end, - Header = io_lib:format(?STREAM_HEADER, - [StateData#state.streamid, Server, VersionStr, - LangStr]), - send_text(StateData, iolist_to_binary(Header)). + Header = #xmlel{name = Name, attrs = Attrs} = + xmpp:encode(#stream_start{version = Version, + lang = Lang, + xmlns = ?NS_CLIENT, + stream_xmlns = ?NS_STREAM, + id = StateData#state.streamid, + from = jid:make(Server)}), + if StateData#state.xml_socket -> + (StateData#state.sockmod):send_xml(StateData#state.socket, + {xmlstreamstart, Name, Attrs}); + true -> + send_text(StateData, fxml:element_to_header(Header)) + end. -spec send_trailer(state()) -> ok | {error, any()}. send_trailer(StateData) diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index e585257e8..3c3e698ad 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -39,6 +39,7 @@ remove_connection/2, find_connection/2, dirty_get_connections/0, allow_host/2, incoming_s2s_number/0, outgoing_s2s_number/0, + stop_all_connections/0, clean_temporarily_blocked_table/0, list_temporarily_blocked_hosts/0, external_host_overloaded/1, is_temporarly_blocked/1, @@ -480,7 +481,13 @@ get_commands_spec() -> "the node", policy = admin, module = ?MODULE, function = outgoing_s2s_number, - args = [], result = {s2s_outgoing, integer}}]. + args = [], result = {s2s_outgoing, integer}}, + #ejabberd_commands{name = stop_all_connections, + tags = [s2s], + desc = "Stop all outgoing and incoming connections", + policy = admin, + module = ?MODULE, function = stop_all_connections, + args = [], result = {res, rescode}}]. incoming_s2s_number() -> length(supervisor:which_children(ejabberd_s2s_in_sup)). @@ -488,6 +495,15 @@ incoming_s2s_number() -> outgoing_s2s_number() -> length(supervisor:which_children(ejabberd_s2s_out_sup)). +stop_all_connections() -> + lists:foreach( + fun({_Id, Pid, _Type, _Module}) -> + exit(Pid, kill) + end, + supervisor:which_children(ejabberd_s2s_in_sup) ++ + supervisor:which_children(ejabberd_s2s_out_sup)), + mnesia:clear_table(s2s). + %%%---------------------------------------------------------------------- %%% Update Mnesia tables diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index fd560a451..6d1791d0b 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -168,21 +168,26 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of #stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM} when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM -> - send_header(StateData, <<" version='1.0'">>), + send_header(StateData, {1,0}), send_element(StateData, xmpp:serr_invalid_namespace()), {stop, normal, StateData}; #stream_start{to = #jid{lserver = Server}, - from = #jid{lserver = From}, - version = <<"1.0">>} + from = From, version = {1,0}} when StateData#state.tls and not StateData#state.authenticated -> - send_header(StateData, <<" version='1.0'">>), + send_header(StateData, {1,0}), Auth = if StateData#state.tls_enabled -> - {Result, Message} = - ejabberd_s2s:check_peer_certificate( - StateData#state.sockmod, - StateData#state.socket, - From), - {Result, From, Message}; + case From of + #jid{} -> + {Result, Message} = + ejabberd_s2s:check_peer_certificate( + StateData#state.sockmod, + StateData#state.socket, + From#jid.lserver), + {Result, From#jid.lserver, Message}; + undefined -> + {error, <<"(unknown)">>, + <<"Got no valid 'from' attribute">>} + end; true -> {no_verify, <<"(unknown)">>, <<"TLS not (yet) enabled">>} end, @@ -225,8 +230,8 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> NewStateData#state{server = Server}} end; #stream_start{to = #jid{lserver = Server}, - version = <<"1.0">>} when StateData#state.authenticated -> - send_header(StateData, <<" version='1.0'">>), + version = {1,0}} when StateData#state.authenticated -> + send_header(StateData, {1,0}), send_element(StateData, #stream_features{ sub_els = ejabberd_hooks:run_fold( @@ -236,24 +241,28 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> #stream_start{db_xmlns = ?NS_SERVER_DIALBACK} when (StateData#state.tls_required and StateData#state.tls_enabled) or (not StateData#state.tls_required) -> - send_header(StateData, <<"">>), + send_header(StateData, undefined), {next_state, stream_established, StateData}; #stream_start{} -> - send_header(StateData, <<" version='1.0'">>), + send_header(StateData, {1,0}), send_element(StateData, xmpp:serr_undefined_condition()), - {stop, normal, StateData} + {stop, normal, StateData}; + _ -> + send_header(StateData, {1,0}), + send_element(StateData, xmpp:serr_invalid_xml()), + {stop, normal, StateData} catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), - send_header(StateData, <<" version='1.0'">>), - send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), + send_header(StateData, {1,0}), + send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)), {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> - send_header(StateData, <<"">>), + send_header(StateData, {1,0}), send_element(StateData, xmpp:serr_not_well_formed()), {stop, normal, StateData}; wait_for_stream(timeout, StateData) -> - send_header(StateData, <<"">>), + send_header(StateData, {1,0}), send_element(StateData, xmpp:serr_connection_timeout()), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> @@ -277,13 +286,21 @@ wait_for_feature_request(#starttls{}, StateData#state.tls_options, {certfile, CertFile}) end, + TLSOpts2 = case ejabberd_config:get_option( + {s2s_cafile, StateData#state.server}, + fun iolist_to_binary/1) of + undefined -> TLSOpts1; + CAFile -> + lists:keystore(cafile, 1, TLSOpts1, + {cafile, CAFile}) + end, TLSOpts = case ejabberd_config:get_option( {s2s_tls_compression, StateData#state.server}, fun(true) -> true; (false) -> false end, false) of - true -> lists:delete(compression_none, TLSOpts1); - false -> [compression_none | TLSOpts1] + true -> lists:delete(compression_none, TLSOpts2); + false -> [compression_none | TLSOpts2] end, TLSSocket = (StateData#state.sockmod):starttls( Socket, TLSOpts, @@ -293,8 +310,7 @@ wait_for_feature_request(#starttls{}, StateData#state{socket = TLSSocket, streamid = new_id(), tls_enabled = true, tls_options = TLSOpts}}; _ -> - Txt = <<"Unsupported TLS transport">>, - send_element(StateData, xmpp:serr_policy_violation(Txt, ?MYLANG)), + send_element(StateData, #starttls_failure{}), {stop, normal, StateData} end; wait_for_feature_request(#sasl_auth{mechanism = Mech}, @@ -313,7 +329,10 @@ wait_for_feature_request(#sasl_auth{mechanism = Mech}, StateData#state{streamid = new_id(), authenticated = true}}; true -> - send_element(StateData, #sasl_failure{}), + Txt = xmpp:mk_text(<<"Denied by ACL">>, ?MYLANG), + send_element(StateData, + #sasl_failure{reason = 'not-authorized', + text = Txt}), {stop, normal, StateData} end; _ -> @@ -495,7 +514,7 @@ handle_info({send_text, Text}, StateName, StateData) -> handle_info({timeout, Timer, _}, StateName, #state{timer = Timer} = StateData) -> if StateName == wait_for_stream -> - send_header(StateData, <<"">>); + send_header(StateData, undefined); true -> ok end, @@ -555,15 +574,15 @@ send_error(StateData, Stanza, Error) -> send_trailer(StateData) -> send_text(StateData, <<"">>). --spec send_header(state(), binary()) -> ok. +-spec send_header(state(), undefined | {integer(), integer()}) -> ok. send_header(StateData, Version) -> - send_text(StateData, - <<"">>). + Header = xmpp:encode( + #stream_start{xmlns = ?NS_SERVER, + stream_xmlns = ?NS_STREAM, + db_xmlns = ?NS_SERVER_DIALBACK, + id = StateData#state.streamid, + version = Version}), + send_text(StateData, fxml:element_to_header(Header)). -spec change_shaper(state(), binary(), jid()) -> ok. change_shaper(StateData, Host, JID) -> @@ -606,9 +625,14 @@ fsm_limit_opts(Opts) -> end end. --spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). +-spec decode_element(xmlel() | xmpp_element(), state_name(), state()) -> fsm_transition(). decode_element(#xmlel{} = El, StateName, StateData) -> - try xmpp:decode(El) of + Opts = if StateName == stream_established -> + [ignore_els]; + true -> + [] + end, + try xmpp:decode(El, Opts) of Pkt -> ?MODULE:StateName(Pkt, StateData) catch error:{xmpp_codec, Why} -> case xmpp:is_stanza(El) of @@ -620,12 +644,15 @@ decode_element(#xmlel{} = El, StateName, StateData) -> ok end, {next_state, StateName, StateData} - end. + end; +decode_element(Pkt, StateName, StateData) -> + ?MODULE:StateName(Pkt, StateData). opt_type(domain_certfile) -> fun iolist_to_binary/1; opt_type(max_fsm_queue) -> fun (I) when is_integer(I), I > 0 -> I end; opt_type(s2s_certfile) -> fun iolist_to_binary/1; +opt_type(s2s_cafile) -> fun iolist_to_binary/1; opt_type(s2s_ciphers) -> fun iolist_to_binary/1; opt_type(s2s_dhfile) -> fun iolist_to_binary/1; opt_type(s2s_protocol_options) -> @@ -647,6 +674,6 @@ opt_type(s2s_use_starttls) -> (required_trusted) -> required_trusted end; opt_type(_) -> - [domain_certfile, max_fsm_queue, s2s_certfile, + [domain_certfile, max_fsm_queue, s2s_certfile, s2s_cafile, s2s_ciphers, s2s_dhfile, s2s_protocol_options, s2s_tls_compression, s2s_use_starttls]. diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index dd37445d7..06ba16863 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -106,12 +106,6 @@ %% Specified in miliseconds. Default value is 5 minutes. -define(MAX_RETRY_DELAY, 300000). --define(STREAM_HEADER, - <<"">>). - -define(SOCKET_DEFAULT_RESULT, {error, badarg}). %%%---------------------------------------------------------------------- @@ -228,9 +222,8 @@ open_socket(init, StateData) -> ?SOCKET_DEFAULT_RESULT, AddrList) of {ok, Socket} -> - Version = if StateData#state.use_v10 -> - <<" version='1.0'">>; - true -> <<"">> + Version = if StateData#state.use_v10 -> {1,0}; + true -> undefined end, NewStateData = StateData#state{socket = Socket, tls_enabled = false, @@ -318,11 +311,10 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData0) -> {stop, normal, StateData}; #stream_start{xmlns = NS_SERVER, stream_xmlns = NS_STREAM} when NS_SERVER /= ?NS_SERVER; NS_STREAM /= ?NS_STREAM -> - send_header(StateData, <<" version='1.0'">>), send_element(StateData, xmpp:serr_invalid_namespace()), {stop, normal, StateData}; #stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID, - version = V} when V /= <<"1.0">> -> + version = V} when V /= {1,0} -> send_db_request(StateData#state{remote_streamid = ID}); #stream_start{db_xmlns = ?NS_SERVER_DIALBACK, id = ID} when StateData#state.use_v10 -> @@ -337,13 +329,14 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData0) -> StateData#state{db_enabled = false, remote_streamid = ID}, ?FSMTIMEOUT}; #stream_start{} -> - send_header(StateData, <<"">>), send_element(StateData, xmpp:serr_invalid_namespace()), - {stop, normal, StateData} + {stop, normal, StateData}; + _ -> + send_element(StateData, xmpp:serr_invalid_xml()), + {stop, normal, StateData} catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), - send_header(StateData, <<" version='1.0'">>), - send_element(StateData, xmpp:serr_not_well_formed(Txt, ?MYLANG)), + send_element(StateData, xmpp:serr_invalid_xml(Txt, ?MYLANG)), {stop, normal, StateData} end; wait_for_stream(Event, StateData) -> @@ -469,7 +462,7 @@ wait_for_auth_result({xmlstreamelement, El}, StateData) -> wait_for_auth_result(#sasl_success{}, StateData) -> ?DEBUG("auth: ~p", [{StateData#state.myname, StateData#state.server}]), ejabberd_socket:reset_stream(StateData#state.socket), - send_header(StateData, <<" version='1.0'">>), + send_header(StateData, {1,0}), {next_state, wait_for_stream, StateData#state{streamid = new_id(), authenticated = true}, ?FSMTIMEOUT}; @@ -500,7 +493,7 @@ wait_for_starttls_proceed(#starttls_proceed{}, StateData) -> streamid = new_id(), tls_enabled = true, tls_options = TLSOpts}, - send_header(NewStateData, <<" version='1.0'">>), + send_header(NewStateData, {1,0}), {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; wait_for_starttls_proceed(Event, StateData) -> handle_unexpected_event(Event, wait_for_starttls_proceed, StateData). @@ -567,7 +560,8 @@ handle_unexpected_event(Event, StateName, StateData) -> {xmlstreamend, _} -> ?INFO_MSG("Closing s2s connection ~s -> ~s in state ~s: " "XML stream closed by peer", - [StateData#state.myname, StateData#state.server]), + [StateData#state.myname, StateData#state.server, + StateName]), {stop, normal, StateData}; timeout -> send_element(StateData, xmpp:serr_connection_timeout()), @@ -741,6 +735,7 @@ print_state(State) -> State. -spec send_text(state(), iodata()) -> ok. send_text(StateData, Text) -> + ?DEBUG("Send Text on stream = ~s", [Text]), ejabberd_socket:send(StateData#state.socket, Text). -spec send_element(state(), xmpp_element()) -> ok. @@ -748,15 +743,16 @@ send_element(StateData, El) -> El1 = fix_ns(xmpp:encode(El)), send_text(StateData, fxml:element_to_binary(El1)). --spec send_header(state(), binary()) -> ok. +-spec send_header(state(), undefined | {integer(), integer()}) -> ok. send_header(StateData, Version) -> - Txt = io_lib:format( - "", - [StateData#state.myname, StateData#state.server, Version]), - send_text(StateData, Txt). + Header = xmpp:encode( + #stream_start{xmlns = ?NS_SERVER, + stream_xmlns = ?NS_STREAM, + db_xmlns = ?NS_SERVER_DIALBACK, + from = jid:make(StateData#state.myname), + to = jid:make(StateData#state.server), + version = Version}), + send_text(StateData, fxml:element_to_header(Header)). -spec send_trailer(state()) -> ok. send_trailer(StateData) -> diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index f4338593d..46d32e4fd 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -149,6 +149,10 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> #stream_start{} -> send_header(StateData, ?MYNAME), send_element(StateData, xmpp:serr_improper_addressing()), + {stop, normal, StateData}; + _ -> + send_header(StateData, ?MYNAME), + send_element(StateData, xmpp:serr_invalid_xml()), {stop, normal, StateData} catch _:{xmpp_codec, Why} -> Txt = xmpp:format_error(Why), @@ -319,13 +323,12 @@ send_error(StateData, Stanza, Error) -> -spec send_header(state(), binary()) -> ok. send_header(StateData, Host) -> - send_text(StateData, - io_lib:format( - <<"">>, - [StateData#state.streamid, fxml:crypt(Host)])). + Header = xmpp:encode( + #stream_start{xmlns = ?NS_COMPONENT, + stream_xmlns = ?NS_STREAM, + from = jid:make(Host), + id = StateData#state.streamid}), + send_text(StateData, fxml:element_to_header(Header)). -spec send_trailer(state()) -> ok. send_trailer(StateData) -> diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 00ee53aaf..0a9258195 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -3955,6 +3955,14 @@ pp(upload_slot, 3) -> [get, put, xmlns]; pp(thumbnail, 4) -> [uri, 'media-type', width, height]; pp(_, _) -> no. +enc_version({Maj, Min}) -> + <<(integer_to_binary(Maj))/binary, $., + (integer_to_binary(Min))/binary>>. + +dec_version(S) -> + [Major, Minor] = binary:split(S, <<$.>>), + {binary_to_integer(Major), binary_to_integer(Minor)}. + enc_host_port(Host) when is_binary(Host) -> Host; enc_host_port({{_, _, _, _, _, _, _, _} = IPv6, Port}) -> @@ -5284,13 +5292,20 @@ encode_stream_start_attr_xmlns(_val, _acc) -> decode_stream_start_attr_version(__TopXMLNS, undefined) -> - <<>>; + undefined; decode_stream_start_attr_version(__TopXMLNS, _val) -> - _val. + case catch dec_version(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"version">>, <<"stream:stream">>, + __TopXMLNS}}); + _res -> _res + end. -encode_stream_start_attr_version(<<>>, _acc) -> _acc; +encode_stream_start_attr_version(undefined, _acc) -> + _acc; encode_stream_start_attr_version(_val, _acc) -> - [{<<"version">>, _val} | _acc]. + [{<<"version">>, enc_version(_val)} | _acc]. decode_stream_start_attr_id(__TopXMLNS, undefined) -> <<>>; -- cgit v1.2.3 From 58969fb854207637e8c3548c1b2a6a0c865dfe7e Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 24 Sep 2016 14:17:21 +0300 Subject: Improve namespace handling --- src/ejabberd_c2s.erl | 8 +- src/ejabberd_piefxis.erl | 8 +- src/ejabberd_router.erl | 6 +- src/ejabberd_s2s_in.erl | 18 +- src/ejabberd_s2s_out.erl | 23 +- src/ejabberd_service.erl | 16 +- src/gen_iq_handler.erl | 4 +- src/jd2ejd.erl | 2 +- src/mod_admin_extra.erl | 2 +- src/mod_announce.erl | 4 +- src/mod_mam.erl | 51 +- src/mod_muc_room.erl | 2 +- src/mod_offline.erl | 4 +- src/xmpp.erl | 60 +- src/xmpp_codec.erl | 12178 +++++++++++++++++++++++++++++++-------------- 15 files changed, 8493 insertions(+), 3893 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 858e285a6..d89290d47 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -862,10 +862,10 @@ resource_conflict_action(U, S, R) -> -spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). decode_element(#xmlel{} = El, StateName, StateData) -> - try case xmpp:decode(El, [ignore_els]) of + try case xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of #iq{sub_els = [_], type = T} = Pkt when T == set; T == get -> NewPkt = xmpp:decode_els( - Pkt, + Pkt, ?NS_CLIENT, fun(SubEl) when StateName == session_established -> case xmpp:get_ns(SubEl) of ?NS_PRIVACY -> true; @@ -873,7 +873,7 @@ decode_element(#xmlel{} = El, StateName, StateData) -> _ -> false end; (SubEl) -> - xmpp_codec:is_known_tag(SubEl) + xmpp:is_known_tag(SubEl) end), ?MODULE:StateName(NewPkt, StateData); Pkt -> @@ -1566,7 +1566,7 @@ send_element(StateData, #xmlel{} = El) when StateData#state.xml_socket -> send_element(StateData, #xmlel{} = El) -> send_text(StateData, fxml:element_to_binary(El)); send_element(StateData, Pkt) -> - send_element(StateData, xmpp:encode(Pkt)). + send_element(StateData, xmpp:encode(Pkt, ?NS_CLIENT)). -spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. send_error(StateData, Stanza, Error) -> diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index 7d7d01060..5e6e1bf58 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -440,11 +440,11 @@ process_user_el(#xmlel{name = Name, attrs = Attrs, children = Els} = El, process_private(xmpp:decode(El), State); {<<"vCard">>, ?NS_VCARD} -> process_vcard(El, State); - {<<"offline-messages">>, _} -> - Msgs = [xmpp:decode(E, [ignore_els]) || E <- Els], + {<<"offline-messages">>, NS} -> + Msgs = [xmpp:decode(E, NS, [ignore_els]) || E <- Els], process_offline_msgs(Msgs, State); - {<<"presence">>, <<"jabber:client">>} -> - process_presence(xmpp:decode(El, [ignore_els]), State); + {<<"presence">>, ?NS_CLIENT} -> + process_presence(xmpp:decode(El, ?NS_CLIENT, [ignore_els]), State); _ -> {ok, State} end diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index db82f67ea..c6d919097 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -253,7 +253,7 @@ process_iq(From, To, #iq{} = IQ) -> ejabberd_sm:process_iq(From, To, IQ) end; process_iq(From, To, El) -> - try xmpp:decode(El, [ignore_els]) of + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of IQ -> process_iq(From, To, IQ) catch _:{xmpp_codec, Why} -> Type = xmpp:get_type(El), @@ -390,7 +390,7 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> LDstDomain = To#jid.lserver, case mnesia:dirty_read(route, LDstDomain) of [] -> - try xmpp:decode(Packet, [ignore_els]) of + try xmpp:decode(Packet, ?NS_CLIENT, [ignore_els]) of Pkt -> ejabberd_s2s:route(From, To, Pkt) catch _:{xmpp_codec, Why} -> @@ -422,7 +422,7 @@ do_route(OrigFrom, OrigTo, OrigPacket) -> -spec do_route(jid(), jid(), xmlel() | xmpp_element(), #route{}) -> any(). do_route(From, To, Packet, #route{local_hint = LocalHint, pid = Pid}) when is_pid(Pid) -> - try xmpp:decode(Packet, [ignore_els]) of + try xmpp:decode(Packet, ?NS_CLIENT, [ignore_els]) of Pkt -> case LocalHint of {apply, Module, Function} when node(Pid) == node() -> diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 6d1791d0b..395a0fce7 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -557,7 +557,7 @@ send_text(StateData, Text) -> -spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - El1 = fix_ns(xmpp:encode(El)), + El1 = xmpp:encode(El, ?NS_SERVER), send_text(StateData, fxml:element_to_binary(El1)). -spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. @@ -591,20 +591,6 @@ change_shaper(StateData, Host, JID) -> (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper). --spec fix_ns(xmlel()) -> xmlel(). -fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; - Name == <<"iq">>; - Name == <<"presence">>; - Name == <<"db:verify">>, - Name == <<"db:result">> -> - Attrs = lists:filter( - fun({<<"xmlns">>, _}) -> false; - (_) -> true - end, El#xmlel.attrs), - El#xmlel{attrs = Attrs}; -fix_ns(El) -> - El. - -spec new_id() -> binary(). new_id() -> randoms:get_string(). @@ -632,7 +618,7 @@ decode_element(#xmlel{} = El, StateName, StateData) -> true -> [] end, - try xmpp:decode(El, Opts) of + try xmpp:decode(El, ?NS_SERVER, Opts) of Pkt -> ?MODULE:StateName(Pkt, StateData) catch error:{xmpp_codec, Why} -> case xmpp:is_stanza(El) of diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 06ba16863..62c07b068 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -740,7 +740,7 @@ send_text(StateData, Text) -> -spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - El1 = fix_ns(xmpp:encode(El)), + El1 = xmpp:encode(El, ?NS_SERVER), send_text(StateData, fxml:element_to_binary(El1)). -spec send_header(state(), undefined | {integer(), integer()}) -> ok. @@ -766,20 +766,6 @@ send_queue(StateData, Q) -> {empty, _Q1} -> ok end. --spec fix_ns(xmlel()) -> xmlel(). -fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; - Name == <<"iq">>; - Name == <<"presence">>; - Name == <<"db:verify">>, - Name == <<"db:result">> -> - Attrs = lists:filter( - fun({<<"xmlns">>, _}) -> false; - (_) -> true - end, El#xmlel.attrs), - El#xmlel{attrs = Attrs}; -fix_ns(El) -> - El. - %% Bounce a single message (xmlelement) -spec bounce_element(stanza(), stanza_error()) -> ok. bounce_element(El, Error) -> @@ -1083,7 +1069,12 @@ fsm_limit_opts() -> -spec decode_element(xmlel(), state_name(), state()) -> fsm_next(). decode_element(#xmlel{} = El, StateName, StateData) -> - try xmpp:decode(El) of + Opts = if StateName == stream_established -> + [ignore_els]; + true -> + [] + end, + try xmpp:decode(El, ?NS_SERVER, Opts) of Pkt -> ?MODULE:StateName(Pkt, StateData) catch error:{xmpp_codec, Why} -> Type = xmpp:get_type(El), diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 46d32e4fd..b1a4b433e 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -308,7 +308,7 @@ send_text(StateData, Text) -> -spec send_element(state(), xmpp_element()) -> ok. send_element(StateData, El) -> - El1 = fix_ns(xmpp:encode(El)), + El1 = xmpp:encode(El, ?NS_COMPONENT), send_text(StateData, fxml:element_to_binary(El1)). -spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. @@ -334,21 +334,9 @@ send_header(StateData, Host) -> send_trailer(StateData) -> send_text(StateData, <<"">>). --spec fix_ns(xmlel()) -> xmlel(). -fix_ns(#xmlel{name = Name} = El) when Name == <<"message">>; - Name == <<"iq">>; - Name == <<"presence">> -> - Attrs = lists:filter( - fun({<<"xmlns">>, _}) -> false; - (_) -> true - end, El#xmlel.attrs), - El#xmlel{attrs = Attrs}; -fix_ns(El) -> - El. - -spec decode_element(xmlel(), state_name(), state()) -> fsm_transition(). decode_element(#xmlel{} = El, StateName, StateData) -> - try xmpp:decode(El, [ignore_els]) of + try xmpp:decode(El, ?NS_COMPONENT, [ignore_els]) of Pkt -> ?MODULE:StateName(Pkt, StateData) catch error:{xmpp_codec, Why} -> case xmpp:is_stanza(El) of diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index fcfe9f3a7..b8a44c96c 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -144,7 +144,7 @@ process_iq(_Host, Module, Function, From, To, IQ0) -> end catch E:R -> ?ERROR_MSG("failed to process iq:~n~s~nReason = ~p", - [xmpp_codec:pp(IQ), {E, {R, erlang:get_stacktrace()}}]), + [xmpp:pp(IQ), {E, {R, erlang:get_stacktrace()}}]), Txt = <<"Module failed to handle the query">>, Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang), ejabberd_router:route(To, From, xmpp:make_error(IQ, Err)) @@ -169,7 +169,7 @@ process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) -> process_iq(Module, Function, From, To, IQ) -> case Module:Function(From, To, IQ) of ignore -> ignore; - ResIQ -> xmpp:decode(jlib:iq_to_xml(ResIQ), [ignore_els]) + ResIQ -> xmpp:decode(jlib:iq_to_xml(ResIQ), ?NS_CLIENT, [ignore_els]) end. -spec check_type(type()) -> type(). diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl index 81732547b..037d6d63a 100644 --- a/src/jd2ejd.erl +++ b/src/jd2ejd.erl @@ -155,7 +155,7 @@ process_offline(Server, To, #xmlel{children = Els}) -> LServer = jid:nameprep(Server), lists:foreach( fun(#xmlel{} = El) -> - try xmpp:decode(El, [ignore_els]) of + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of #message{from = JID} -> From = case JID of undefined -> jid:make(Server); diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index a147a5881..627b5b58f 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -1351,7 +1351,7 @@ send_stanza(FromString, ToString, Stanza) -> #xmlel{} = El = fxml_stream:parse_element(Stanza), #jid{} = From = jid:from_string(FromString), #jid{} = To = jid:to_string(ToString), - Pkt = xmpp:decode(El, [ignore_els]), + Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), ejabberd_router:route(From, To, Pkt) catch _:{xmpp_codec, Why} -> io:format("incorrect stanza: ~s~n", [xmpp:format_error(Why)]), diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 8d2fbebff..495cbf946 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -768,7 +768,7 @@ send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:get_motd(LServer) of {ok, Packet} -> - try xmpp:decode(Packet, [ignore_els]) of + try xmpp:decode(Packet, ?NS_CLIENT, [ignore_els]) of Msg -> case Mod:is_motd_user(LUser, LServer) of false -> @@ -792,7 +792,7 @@ get_stored_motd(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:get_motd(LServer) of {ok, Packet} -> - try xmpp:decode(Packet, [ignore_els]) of + try xmpp:decode(Packet, ?NS_CLIENT, [ignore_els]) of #message{body = Body, subject = Subject} -> {xmpp:get_text(Subject), xmpp:get_text(Body)} catch _:{xmpp_codec, Why} -> diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 5e4bebb75..8569ee020 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -540,18 +540,20 @@ should_archive(#message{body = Body} = Pkt, LServer) -> should_archive(_, _LServer) -> false. +-spec strip_my_archived_tag(stanza(), binary()) -> stanza(). strip_my_archived_tag(Pkt, LServer) -> NewPkt = xmpp:decode_els( - Pkt, fun(El) -> - case xmpp:get_name(El) of - <<"archived">> -> - xmpp:get_ns(El) == ?NS_MAM_TMP; - <<"stanza-id">> -> - xmpp:get_ns(El) == ?NS_SID_0; - _ -> - false - end - end), + Pkt, ?NS_CLIENT, + fun(El) -> + case xmpp:get_name(El) of + <<"archived">> -> + xmpp:get_ns(El) == ?NS_MAM_TMP; + <<"stanza-id">> -> + xmpp:get_ns(El) == ?NS_SID_0; + _ -> + false + end + end), NewEls = lists:filter( fun(#mam_archived{by = #jid{luser = <<>>} = By}) -> By#jid.lserver /= LServer; @@ -564,19 +566,20 @@ strip_my_archived_tag(Pkt, LServer) -> strip_x_jid_tags(Pkt) -> NewPkt = xmpp:decode_els( - Pkt, fun(El) -> - case xmpp:get_name(El) of - <<"x">> -> - case xmpp:get_ns(El) of - ?NS_MUC_USER -> true; - ?NS_MUC_ADMIN -> true; - ?NS_MUC_OWNER -> true; - _ -> false - end; - _ -> - false - end - end), + Pkt, ?NS_CLIENT, + fun(El) -> + case xmpp:get_name(El) of + <<"x">> -> + case xmpp:get_ns(El) of + ?NS_MUC_USER -> true; + ?NS_MUC_ADMIN -> true; + ?NS_MUC_OWNER -> true; + _ -> false + end; + _ -> + false + end + end), NewEls = lists:filter( fun(El) -> Items = case El of @@ -836,7 +839,7 @@ msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, maybe_update_from_to(#xmlel{} = El, JidRequestor, JidArchive, Peer, {groupchat, _, _} = MsgType, Nick) -> - Pkt = xmpp:decode(El, [ignore_els]), + Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), maybe_update_from_to(Pkt, JidRequestor, JidArchive, Peer, MsgType, Nick); maybe_update_from_to(#message{sub_els = Els} = Pkt, JidRequestor, JidArchive, Peer, {groupchat, Role, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index c32551091..339b85ecb 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -4343,7 +4343,7 @@ tab_count_user(JID) -> -spec element_size(stanza()) -> non_neg_integer(). element_size(El) -> - byte_size(fxml:element_to_binary(xmpp:encode(El))). + byte_size(fxml:element_to_binary(xmpp:encode(El, ?NS_CLIENT))). -spec store_room(state()) -> ok. store_room(StateData) -> diff --git a/src/mod_offline.erl b/src/mod_offline.erl index a2bcec894..9c062065d 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -611,7 +611,7 @@ get_offline_els(LUser, LServer) -> end, Hdrs). offline_msg_to_route(LServer, #offline_msg{} = R) -> - Pkt = xmpp:decode(R#offline_msg.packet, [ignore_els]), + Pkt = xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]), Pkt1 = case R#offline_msg.timestamp of undefined -> Pkt; @@ -626,7 +626,7 @@ read_message_headers(LUser, LServer) -> lists:map( fun({Seq, From, To, El}) -> Node = integer_to_binary(Seq), - Packet = xmpp:decode(El, [ignore_els]), + Packet = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), {Node, From, To, Packet} end, Mod:read_message_headers(LUser, LServer)). diff --git a/src/xmpp.erl b/src/xmpp.erl index 49d824af2..0abcda7ee 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -10,14 +10,15 @@ %% API -export([make_iq_result/1, make_iq_result/2, make_error/2, - decode/1, decode/2, encode/1, + decode/1, decode/3, encode/1, encode/2, get_type/1, get_to/1, get_from/1, get_id/1, get_lang/1, get_error/1, get_els/1, get_ns/1, set_type/2, set_to/2, set_from/2, set_id/2, set_lang/2, set_error/2, set_els/2, set_from_to/3, format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, - remove_subtag/2, has_subtag/2, decode_els/1, decode_els/2, - pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2]). + remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3, + pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2, + is_known_tag/1, is_known_tag/2]). %% XMPP errors -export([err_bad_request/0, err_bad_request/2, @@ -117,7 +118,7 @@ make_error(#xmlel{attrs = Attrs, children = Els} = El, Err) -> Attrs end, Attrs3 = lists:keystore(<<"type">>, 1, Attrs2, {<<"type">>, <<"error">>}), - El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err)]}. + El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err, ?NS_CLIENT)]}. -spec get_id(iq() | message() | presence() | xmlel()) -> binary(). get_id(#iq{id = ID}) -> ID; @@ -232,35 +233,30 @@ get_name(Pkt) -> -spec decode(xmlel() | xmpp_element()) -> {ok, xmpp_element()} | {error, any()}. decode(El) -> - decode(El, []). + decode(El, ?NS_CLIENT, []). --spec decode(xmlel() | xmpp_element(), - [proplists:property()] | - fun((xmlel() | xmpp_element()) -> boolean())) -> +-spec decode(xmlel() | xmpp_element(), binary(), [proplists:property()]) -> {ok, xmpp_element()} | {error, any()}. -decode(#xmlel{} = El, MatchFun) when is_function(MatchFun) -> - Pkt = xmpp_codec:decode(add_ns(El), [ignore_els]), - decode_els(Pkt, MatchFun); -decode(#xmlel{} = El, Opts) when is_list(Opts) -> - xmpp_codec:decode(add_ns(El), Opts); -decode(Pkt, _Opts) -> +decode(#xmlel{} = El, TopXMLNS, Opts) -> + xmpp_codec:decode(El, TopXMLNS, Opts); +decode(Pkt, _, _) -> Pkt. -spec decode_els(iq()) -> iq(); (message()) -> message(); (presence()) -> presence(). decode_els(Stanza) -> - decode_els(Stanza, fun xmpp_codec:is_known_tag/1). + decode_els(Stanza, ?NS_CLIENT, fun is_known_tag/1). -type match_fun() :: fun((xmlel()) -> boolean()). --spec decode_els(iq(), match_fun()) -> iq(); - (message(), match_fun()) -> message(); - (presence(), match_fun()) -> presence(). -decode_els(Stanza, MatchFun) -> +-spec decode_els(iq(), binary(), match_fun()) -> iq(); + (message(), binary(), match_fun()) -> message(); + (presence(), binary(), match_fun()) -> presence(). +decode_els(Stanza, TopXMLNS, MatchFun) -> Els = lists:map( fun(#xmlel{} = El) -> case MatchFun(El) of - true -> decode(El); + true -> decode(El, TopXMLNS, []); false -> El end; (Pkt) -> @@ -270,7 +266,19 @@ decode_els(Stanza, MatchFun) -> -spec encode(xmpp_element() | xmlel()) -> xmlel(). encode(Pkt) -> - xmpp_codec:encode(Pkt). + encode(Pkt, <<>>). + +-spec encode(xmpp_element() | xmlel(), binary()) -> xmlel(). +encode(Pkt, TopXMLNS) -> + xmpp_codec:encode(Pkt, TopXMLNS). + +-spec is_known_tag(xmlel()) -> boolean(). +is_known_tag(El) -> + is_known_tag(El, ?NS_CLIENT). + +-spec is_known_tag(xmlel(), binary()) -> boolean(). +is_known_tag(El, TopXMLNS) -> + xmpp_codec:is_known_tag(El, TopXMLNS). format_error(Reason) -> xmpp_codec:format_error(Reason). @@ -809,16 +817,6 @@ serr(Reason, Text, Lang) -> text = #text{lang = Lang, data = translate:translate(Lang, Text)}}. --spec add_ns(xmlel()) -> xmlel(). -add_ns(#xmlel{name = Name} = El) when Name == <<"message">>; - Name == <<"presence">>; - Name == <<"iq">> -> - Attrs = lists:keystore(<<"xmlns">>, 1, El#xmlel.attrs, - {<<"xmlns">>, ?NS_CLIENT}), - El#xmlel{attrs = Attrs}; -add_ns(El) -> - El. - -spec match_tag(xmlel() | xmpp_element(), binary(), binary()) -> boolean(). match_tag(El, TagName, XMLNS) -> get_name(El) == TagName andalso get_ns(El) == XMLNS. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 0a9258195..bffe2f1ad 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -5,3137 +5,5774 @@ -compile({nowarn_unused_function, [{dec_int, 3}, {dec_int, 1}, {dec_enum, 2}, - {enc_int, 1}, {get_attr, 2}, {enc_enum, 1}]}). + {enc_int, 1}, {get_attr, 2}, {enc_enum, 1}, + {choose_top_xmlns, 3}, {enc_xmlns_attrs, 2}]}). -export([pp/1, format_error/1, decode/1, decode/2, - is_known_tag/1, encode/1, get_name/1, get_ns/1]). + decode/3, is_known_tag/2, encode/1, encode/2, + get_name/1, get_ns/1]). -decode(_el) -> decode(_el, []). +decode(_el) -> decode(_el, <<>>, []). -decode({xmlel, _name, _attrs, _} = _el, Opts) -> +decode(_el, Opts) -> decode(_el, <<>>, Opts). + +decode({xmlel, _name, _attrs, _} = _el, TopXMLNS, + Opts) -> IgnoreEls = proplists:get_bool(ignore_els, Opts), - case {_name, get_attr(<<"xmlns">>, _attrs)} of - {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>} -> + case {_name, get_attr(<<"xmlns">>, _attrs), TopXMLNS} of + {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>, _} -> + decode_thumbnail(<<"urn:xmpp:thumbs:1">>, IgnoreEls, + _el); + {<<"thumbnail">>, <<>>, <<"urn:xmpp:thumbs:1">>} -> decode_thumbnail(<<"urn:xmpp:thumbs:1">>, IgnoreEls, _el); - {<<"slot">>, <<"urn:xmpp:http:upload">>} -> + {<<"slot">>, <<"urn:xmpp:http:upload">>, _} -> decode_upload_slot(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); - {<<"slot">>, + {<<"slot">>, <<>>, <<"urn:xmpp:http:upload">>} -> + decode_upload_slot(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"slot">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + decode_upload_slot(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"slot">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> decode_upload_slot(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"put">>, <<"urn:xmpp:http:upload">>} -> + {<<"put">>, <<"urn:xmpp:http:upload">>, _} -> decode_upload_put(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); - {<<"put">>, <<"eu:siacs:conversations:http:upload">>} -> + {<<"put">>, <<>>, <<"urn:xmpp:http:upload">>} -> + decode_upload_put(<<"urn:xmpp:http:upload">>, IgnoreEls, + _el); + {<<"put">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + decode_upload_put(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"put">>, <<>>, + <<"eu:siacs:conversations:http:upload">>} -> decode_upload_put(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"get">>, <<"urn:xmpp:http:upload">>} -> + {<<"get">>, <<"urn:xmpp:http:upload">>, _} -> decode_upload_get(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); - {<<"get">>, <<"eu:siacs:conversations:http:upload">>} -> + {<<"get">>, <<>>, <<"urn:xmpp:http:upload">>} -> + decode_upload_get(<<"urn:xmpp:http:upload">>, IgnoreEls, + _el); + {<<"get">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + decode_upload_get(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"get">>, <<>>, + <<"eu:siacs:conversations:http:upload">>} -> decode_upload_get(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"request">>, <<"urn:xmpp:http:upload">>} -> + {<<"request">>, <<"urn:xmpp:http:upload">>, _} -> + decode_upload_request(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"request">>, <<>>, <<"urn:xmpp:http:upload">>} -> decode_upload_request(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); {<<"request">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + decode_upload_request(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"request">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> decode_upload_request(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"content-type">>, <<"urn:xmpp:http:upload">>} -> + {<<"content-type">>, <<"urn:xmpp:http:upload">>, _} -> + decode_upload_content_type(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"content-type">>, <<>>, + <<"urn:xmpp:http:upload">>} -> decode_upload_content_type(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); {<<"content-type">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"content-type">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"size">>, <<"urn:xmpp:http:upload">>} -> + {<<"size">>, <<"urn:xmpp:http:upload">>, _} -> decode_upload_size(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); - {<<"size">>, + {<<"size">>, <<>>, <<"urn:xmpp:http:upload">>} -> + decode_upload_size(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"size">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + decode_upload_size(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"size">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> decode_upload_size(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"filename">>, <<"urn:xmpp:http:upload">>} -> + {<<"filename">>, <<"urn:xmpp:http:upload">>, _} -> + decode_upload_filename(<<"urn:xmpp:http:upload">>, + IgnoreEls, _el); + {<<"filename">>, <<>>, <<"urn:xmpp:http:upload">>} -> decode_upload_filename(<<"urn:xmpp:http:upload">>, IgnoreEls, _el); {<<"filename">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, + IgnoreEls, _el); + {<<"filename">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, IgnoreEls, _el); - {<<"address">>, <<"urn:xmpp:sic:0">>} -> + {<<"address">>, <<"urn:xmpp:sic:0">>, _} -> + decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); + {<<"address">>, <<>>, <<"urn:xmpp:sic:0">>} -> decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"address">>, <<"urn:xmpp:sic:1">>} -> + {<<"address">>, <<"urn:xmpp:sic:1">>, _} -> + decode_sic(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); + {<<"address">>, <<>>, <<"urn:xmpp:sic:1">>} -> decode_sic(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"port">>, <<"urn:xmpp:sic:1">>} -> + {<<"port">>, <<"urn:xmpp:sic:1">>, _} -> decode_sip_port(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"ip">>, <<"urn:xmpp:sic:0">>} -> + {<<"port">>, <<>>, <<"urn:xmpp:sic:1">>} -> + decode_sip_port(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); + {<<"ip">>, <<"urn:xmpp:sic:0">>, _} -> + decode_sic_ip(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); + {<<"ip">>, <<>>, <<"urn:xmpp:sic:0">>} -> decode_sic_ip(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"ip">>, <<"urn:xmpp:sic:1">>} -> + {<<"ip">>, <<"urn:xmpp:sic:1">>, _} -> + decode_sic_ip(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); + {<<"ip">>, <<>>, <<"urn:xmpp:sic:1">>} -> decode_sic_ip(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:oob">>} -> + {<<"x">>, <<"jabber:x:oob">>, _} -> decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"desc">>, <<"jabber:x:oob">>} -> + {<<"x">>, <<>>, <<"jabber:x:oob">>} -> + decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"desc">>, <<"jabber:x:oob">>, _} -> + decode_oob_desc(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"desc">>, <<>>, <<"jabber:x:oob">>} -> decode_oob_desc(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"url">>, <<"jabber:x:oob">>} -> + {<<"url">>, <<"jabber:x:oob">>, _} -> + decode_oob_url(<<"jabber:x:oob">>, IgnoreEls, _el); + {<<"url">>, <<>>, <<"jabber:x:oob">>} -> decode_oob_url(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"media">>, <<"urn:xmpp:media-element">>} -> + {<<"media">>, <<"urn:xmpp:media-element">>, _} -> decode_media(<<"urn:xmpp:media-element">>, IgnoreEls, _el); - {<<"uri">>, <<"urn:xmpp:media-element">>} -> + {<<"media">>, <<>>, <<"urn:xmpp:media-element">>} -> + decode_media(<<"urn:xmpp:media-element">>, IgnoreEls, + _el); + {<<"uri">>, <<"urn:xmpp:media-element">>, _} -> + decode_media_uri(<<"urn:xmpp:media-element">>, + IgnoreEls, _el); + {<<"uri">>, <<>>, <<"urn:xmpp:media-element">>} -> decode_media_uri(<<"urn:xmpp:media-element">>, IgnoreEls, _el); - {<<"captcha">>, <<"urn:xmpp:captcha">>} -> + {<<"captcha">>, <<"urn:xmpp:captcha">>, _} -> + decode_captcha(<<"urn:xmpp:captcha">>, IgnoreEls, _el); + {<<"captcha">>, <<>>, <<"urn:xmpp:captcha">>} -> decode_captcha(<<"urn:xmpp:captcha">>, IgnoreEls, _el); - {<<"data">>, <<"urn:xmpp:bob">>} -> + {<<"data">>, <<"urn:xmpp:bob">>, _} -> + decode_bob_data(<<"urn:xmpp:bob">>, IgnoreEls, _el); + {<<"data">>, <<>>, <<"urn:xmpp:bob">>} -> decode_bob_data(<<"urn:xmpp:bob">>, IgnoreEls, _el); - {<<"stream:stream">>, <<"jabber:client">>} -> + {<<"stream:stream">>, <<"jabber:client">>, _} -> decode_stream_start(<<"jabber:client">>, IgnoreEls, _el); - {<<"stream:stream">>, <<"jabber:server">>} -> + {<<"stream:stream">>, <<>>, <<"jabber:client">>} -> + decode_stream_start(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:stream">>, <<"jabber:server">>, _} -> decode_stream_start(<<"jabber:server">>, IgnoreEls, _el); - {<<"stream:stream">>, <<"jabber:component:accept">>} -> + {<<"stream:stream">>, <<>>, <<"jabber:server">>} -> + decode_stream_start(<<"jabber:server">>, IgnoreEls, + _el); + {<<"stream:stream">>, <<"jabber:component:accept">>, + _} -> + decode_stream_start(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"stream:stream">>, <<>>, + <<"jabber:component:accept">>} -> decode_stream_start(<<"jabber:component:accept">>, IgnoreEls, _el); - {<<"handshake">>, <<"jabber:client">>} -> - decode_handshake(<<"jabber:client">>, IgnoreEls, _el); - {<<"db:verify">>, <<"jabber:client">>} -> - decode_db_verify(<<"jabber:client">>, IgnoreEls, _el); - {<<"db:result">>, <<"jabber:client">>} -> - decode_db_result(<<"jabber:client">>, IgnoreEls, _el); + {<<"handshake">>, <<"jabber:component:accept">>, _} -> + decode_handshake(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"handshake">>, <<>>, + <<"jabber:component:accept">>} -> + decode_handshake(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"db:verify">>, <<"jabber:server">>, _} -> + decode_db_verify(<<"jabber:server">>, IgnoreEls, _el); + {<<"db:verify">>, <<>>, <<"jabber:server">>} -> + decode_db_verify(<<"jabber:server">>, IgnoreEls, _el); + {<<"db:result">>, <<"jabber:server">>, _} -> + decode_db_result(<<"jabber:server">>, IgnoreEls, _el); + {<<"db:result">>, <<>>, <<"jabber:server">>} -> + decode_db_result(<<"jabber:server">>, IgnoreEls, _el); {<<"command">>, + <<"http://jabber.org/protocol/commands">>, _} -> + decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"command">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); - {<<"note">>, + {<<"note">>, <<"http://jabber.org/protocol/commands">>, + _} -> + decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"note">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); {<<"actions">>, + <<"http://jabber.org/protocol/commands">>, _} -> + decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"actions">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); {<<"complete">>, + <<"http://jabber.org/protocol/commands">>, _} -> + decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"complete">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); - {<<"next">>, + {<<"next">>, <<"http://jabber.org/protocol/commands">>, + _} -> + decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"next">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); - {<<"prev">>, + {<<"prev">>, <<"http://jabber.org/protocol/commands">>, + _} -> + decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, + IgnoreEls, _el); + {<<"prev">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, IgnoreEls, _el); - {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> + {<<"client-id">>, <<"urn:xmpp:sid:0">>, _} -> + decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); + {<<"client-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); - {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> + {<<"stanza-id">>, <<"urn:xmpp:sid:0">>, _} -> + decode_stanza_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); + {<<"stanza-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> decode_stanza_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); {<<"addresses">>, + <<"http://jabber.org/protocol/address">>, _} -> + decode_addresses(<<"http://jabber.org/protocol/address">>, + IgnoreEls, _el); + {<<"addresses">>, <<>>, <<"http://jabber.org/protocol/address">>} -> decode_addresses(<<"http://jabber.org/protocol/address">>, IgnoreEls, _el); {<<"address">>, + <<"http://jabber.org/protocol/address">>, _} -> + decode_address(<<"http://jabber.org/protocol/address">>, + IgnoreEls, _el); + {<<"address">>, <<>>, <<"http://jabber.org/protocol/address">>} -> decode_address(<<"http://jabber.org/protocol/address">>, IgnoreEls, _el); - {<<"nick">>, <<"http://jabber.org/protocol/nick">>} -> + {<<"nick">>, <<"http://jabber.org/protocol/nick">>, + _} -> + decode_nick(<<"http://jabber.org/protocol/nick">>, + IgnoreEls, _el); + {<<"nick">>, <<>>, + <<"http://jabber.org/protocol/nick">>} -> decode_nick(<<"http://jabber.org/protocol/nick">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:expire">>} -> + {<<"x">>, <<"jabber:x:expire">>, _} -> decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:event">>} -> + {<<"x">>, <<>>, <<"jabber:x:expire">>} -> + decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); + {<<"x">>, <<"jabber:x:event">>, _} -> + decode_xevent(<<"jabber:x:event">>, IgnoreEls, _el); + {<<"x">>, <<>>, <<"jabber:x:event">>} -> decode_xevent(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"id">>, <<"jabber:x:event">>} -> + {<<"id">>, <<"jabber:x:event">>, _} -> + decode_xevent_id(<<"jabber:x:event">>, IgnoreEls, _el); + {<<"id">>, <<>>, <<"jabber:x:event">>} -> decode_xevent_id(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"composing">>, <<"jabber:x:event">>} -> + {<<"composing">>, <<"jabber:x:event">>, _} -> decode_xevent_composing(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"displayed">>, <<"jabber:x:event">>} -> + {<<"composing">>, <<>>, <<"jabber:x:event">>} -> + decode_xevent_composing(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"displayed">>, <<"jabber:x:event">>, _} -> + decode_xevent_displayed(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"displayed">>, <<>>, <<"jabber:x:event">>} -> decode_xevent_displayed(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"delivered">>, <<"jabber:x:event">>} -> + {<<"delivered">>, <<"jabber:x:event">>, _} -> + decode_xevent_delivered(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"delivered">>, <<>>, <<"jabber:x:event">>} -> decode_xevent_delivered(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"offline">>, <<"jabber:x:event">>} -> + {<<"offline">>, <<"jabber:x:event">>, _} -> decode_xevent_offline(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:search">>} -> + {<<"offline">>, <<>>, <<"jabber:x:event">>} -> + decode_xevent_offline(<<"jabber:x:event">>, IgnoreEls, + _el); + {<<"query">>, <<"jabber:iq:search">>, _} -> + decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); + {<<"query">>, <<>>, <<"jabber:iq:search">>} -> decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:iq:search">>} -> + {<<"item">>, <<"jabber:iq:search">>, _} -> decode_search_item(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"email">>, <<"jabber:iq:search">>} -> + {<<"item">>, <<>>, <<"jabber:iq:search">>} -> + decode_search_item(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"email">>, <<"jabber:iq:search">>, _} -> + decode_search_email(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"email">>, <<>>, <<"jabber:iq:search">>} -> decode_search_email(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"nick">>, <<"jabber:iq:search">>} -> + {<<"nick">>, <<"jabber:iq:search">>, _} -> + decode_search_nick(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"nick">>, <<>>, <<"jabber:iq:search">>} -> decode_search_nick(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"last">>, <<"jabber:iq:search">>} -> + {<<"last">>, <<"jabber:iq:search">>, _} -> decode_search_last(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"first">>, <<"jabber:iq:search">>} -> + {<<"last">>, <<>>, <<"jabber:iq:search">>} -> + decode_search_last(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"first">>, <<"jabber:iq:search">>, _} -> + decode_search_first(<<"jabber:iq:search">>, IgnoreEls, + _el); + {<<"first">>, <<>>, <<"jabber:iq:search">>} -> decode_search_first(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"instructions">>, <<"jabber:iq:search">>} -> + {<<"instructions">>, <<"jabber:iq:search">>, _} -> + decode_search_instructions(<<"jabber:iq:search">>, + IgnoreEls, _el); + {<<"instructions">>, <<>>, <<"jabber:iq:search">>} -> decode_search_instructions(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>} -> + {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>, _} -> decode_hint_no_permanent_storage(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> + {<<"no-permanent-storage">>, <<>>, + <<"urn:xmpp:hints">>} -> + decode_hint_no_permanent_storage(<<"urn:xmpp:hints">>, + IgnoreEls, _el); + {<<"no-permanent-store">>, <<"urn:xmpp:hints">>, _} -> + decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, + IgnoreEls, _el); + {<<"no-permanent-store">>, <<>>, + <<"urn:xmpp:hints">>} -> decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"store">>, <<"urn:xmpp:hints">>} -> + {<<"store">>, <<"urn:xmpp:hints">>, _} -> decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"no-storage">>, <<"urn:xmpp:hints">>} -> + {<<"store">>, <<>>, <<"urn:xmpp:hints">>} -> + decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); + {<<"no-storage">>, <<"urn:xmpp:hints">>, _} -> + decode_hint_no_storage(<<"urn:xmpp:hints">>, IgnoreEls, + _el); + {<<"no-storage">>, <<>>, <<"urn:xmpp:hints">>} -> decode_hint_no_storage(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"no-store">>, <<"urn:xmpp:hints">>} -> + {<<"no-store">>, <<"urn:xmpp:hints">>, _} -> decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"no-copy">>, <<"urn:xmpp:hints">>} -> + {<<"no-store">>, <<>>, <<"urn:xmpp:hints">>} -> + decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, + _el); + {<<"no-copy">>, <<"urn:xmpp:hints">>, _} -> + decode_hint_no_copy(<<"urn:xmpp:hints">>, IgnoreEls, + _el); + {<<"no-copy">>, <<>>, <<"urn:xmpp:hints">>} -> decode_hint_no_copy(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"participant">>, <<"urn:xmpp:mix:0">>} -> + {<<"participant">>, <<"urn:xmpp:mix:0">>, _} -> + decode_mix_participant(<<"urn:xmpp:mix:0">>, IgnoreEls, + _el); + {<<"participant">>, <<>>, <<"urn:xmpp:mix:0">>} -> decode_mix_participant(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"leave">>, <<"urn:xmpp:mix:0">>} -> + {<<"leave">>, <<"urn:xmpp:mix:0">>, _} -> decode_mix_leave(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"join">>, <<"urn:xmpp:mix:0">>} -> + {<<"leave">>, <<>>, <<"urn:xmpp:mix:0">>} -> + decode_mix_leave(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); + {<<"join">>, <<"urn:xmpp:mix:0">>, _} -> + decode_mix_join(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); + {<<"join">>, <<>>, <<"urn:xmpp:mix:0">>} -> decode_mix_join(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"subscribe">>, <<"urn:xmpp:mix:0">>} -> + {<<"subscribe">>, <<"urn:xmpp:mix:0">>, _} -> + decode_mix_subscribe(<<"urn:xmpp:mix:0">>, IgnoreEls, + _el); + {<<"subscribe">>, <<>>, <<"urn:xmpp:mix:0">>} -> decode_mix_subscribe(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); {<<"offline">>, + <<"http://jabber.org/protocol/offline">>, _} -> + decode_offline(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"offline">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> decode_offline(<<"http://jabber.org/protocol/offline">>, IgnoreEls, _el); - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/offline">>, + _} -> + decode_offline_item(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> decode_offline_item(<<"http://jabber.org/protocol/offline">>, IgnoreEls, _el); - {<<"fetch">>, + {<<"fetch">>, <<"http://jabber.org/protocol/offline">>, + _} -> + decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"fetch">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, IgnoreEls, _el); - {<<"purge">>, + {<<"purge">>, <<"http://jabber.org/protocol/offline">>, + _} -> + decode_offline_purge(<<"http://jabber.org/protocol/offline">>, + IgnoreEls, _el); + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> decode_offline_purge(<<"http://jabber.org/protocol/offline">>, IgnoreEls, _el); - {<<"failed">>, <<"urn:xmpp:sm:2">>} -> + {<<"failed">>, <<"urn:xmpp:sm:2">>, _} -> decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"failed">>, <<"urn:xmpp:sm:3">>} -> + {<<"failed">>, <<>>, <<"urn:xmpp:sm:2">>} -> + decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"failed">>, <<"urn:xmpp:sm:3">>, _} -> + decode_sm_failed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"failed">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_sm_failed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"a">>, <<"urn:xmpp:sm:2">>} -> + {<<"a">>, <<"urn:xmpp:sm:2">>, _} -> decode_sm_a(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"a">>, <<"urn:xmpp:sm:3">>} -> + {<<"a">>, <<>>, <<"urn:xmpp:sm:2">>} -> + decode_sm_a(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"a">>, <<"urn:xmpp:sm:3">>, _} -> + decode_sm_a(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"a">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_sm_a(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"r">>, <<"urn:xmpp:sm:2">>} -> + {<<"r">>, <<"urn:xmpp:sm:2">>, _} -> + decode_sm_r(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"r">>, <<>>, <<"urn:xmpp:sm:2">>} -> decode_sm_r(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"r">>, <<"urn:xmpp:sm:3">>} -> + {<<"r">>, <<"urn:xmpp:sm:3">>, _} -> decode_sm_r(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resumed">>, <<"urn:xmpp:sm:2">>} -> + {<<"r">>, <<>>, <<"urn:xmpp:sm:3">>} -> + decode_sm_r(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"resumed">>, <<"urn:xmpp:sm:2">>, _} -> + decode_sm_resumed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"resumed">>, <<>>, <<"urn:xmpp:sm:2">>} -> decode_sm_resumed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resumed">>, <<"urn:xmpp:sm:3">>} -> + {<<"resumed">>, <<"urn:xmpp:sm:3">>, _} -> + decode_sm_resumed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"resumed">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_sm_resumed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resume">>, <<"urn:xmpp:sm:2">>} -> + {<<"resume">>, <<"urn:xmpp:sm:2">>, _} -> decode_sm_resume(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resume">>, <<"urn:xmpp:sm:3">>} -> + {<<"resume">>, <<>>, <<"urn:xmpp:sm:2">>} -> + decode_sm_resume(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"resume">>, <<"urn:xmpp:sm:3">>, _} -> + decode_sm_resume(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"resume">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_sm_resume(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enabled">>, <<"urn:xmpp:sm:2">>} -> + {<<"enabled">>, <<"urn:xmpp:sm:2">>, _} -> + decode_sm_enabled(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"enabled">>, <<>>, <<"urn:xmpp:sm:2">>} -> decode_sm_enabled(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enabled">>, <<"urn:xmpp:sm:3">>} -> + {<<"enabled">>, <<"urn:xmpp:sm:3">>, _} -> decode_sm_enabled(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:sm:2">>} -> + {<<"enabled">>, <<>>, <<"urn:xmpp:sm:3">>} -> + decode_sm_enabled(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"enable">>, <<"urn:xmpp:sm:2">>, _} -> + decode_sm_enable(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"enable">>, <<>>, <<"urn:xmpp:sm:2">>} -> decode_sm_enable(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:sm:3">>} -> + {<<"enable">>, <<"urn:xmpp:sm:3">>, _} -> + decode_sm_enable(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"enable">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_sm_enable(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"sm">>, <<"urn:xmpp:sm:2">>} -> + {<<"sm">>, <<"urn:xmpp:sm:2">>, _} -> decode_feature_sm(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"sm">>, <<"urn:xmpp:sm:3">>} -> + {<<"sm">>, <<>>, <<"urn:xmpp:sm:2">>} -> + decode_feature_sm(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); + {<<"sm">>, <<"urn:xmpp:sm:3">>, _} -> + decode_feature_sm(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); + {<<"sm">>, <<>>, <<"urn:xmpp:sm:3">>} -> decode_feature_sm(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"inactive">>, <<"urn:xmpp:csi:0">>} -> + {<<"inactive">>, <<"urn:xmpp:csi:0">>, _} -> + decode_csi_inactive(<<"urn:xmpp:csi:0">>, IgnoreEls, + _el); + {<<"inactive">>, <<>>, <<"urn:xmpp:csi:0">>} -> decode_csi_inactive(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); - {<<"active">>, <<"urn:xmpp:csi:0">>} -> + {<<"active">>, <<"urn:xmpp:csi:0">>, _} -> + decode_csi_active(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); + {<<"active">>, <<>>, <<"urn:xmpp:csi:0">>} -> decode_csi_active(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); - {<<"csi">>, <<"urn:xmpp:csi:0">>} -> + {<<"csi">>, <<"urn:xmpp:csi:0">>, _} -> + decode_feature_csi(<<"urn:xmpp:csi:0">>, IgnoreEls, + _el); + {<<"csi">>, <<>>, <<"urn:xmpp:csi:0">>} -> decode_feature_csi(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); - {<<"sent">>, <<"urn:xmpp:carbons:2">>} -> + {<<"sent">>, <<"urn:xmpp:carbons:2">>, _} -> + decode_carbons_sent(<<"urn:xmpp:carbons:2">>, IgnoreEls, + _el); + {<<"sent">>, <<>>, <<"urn:xmpp:carbons:2">>} -> decode_carbons_sent(<<"urn:xmpp:carbons:2">>, IgnoreEls, _el); - {<<"received">>, <<"urn:xmpp:carbons:2">>} -> + {<<"received">>, <<"urn:xmpp:carbons:2">>, _} -> decode_carbons_received(<<"urn:xmpp:carbons:2">>, IgnoreEls, _el); - {<<"private">>, <<"urn:xmpp:carbons:2">>} -> + {<<"received">>, <<>>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_received(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"private">>, <<"urn:xmpp:carbons:2">>, _} -> + decode_carbons_private(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"private">>, <<>>, <<"urn:xmpp:carbons:2">>} -> decode_carbons_private(<<"urn:xmpp:carbons:2">>, IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:carbons:2">>} -> + {<<"enable">>, <<"urn:xmpp:carbons:2">>, _} -> decode_carbons_enable(<<"urn:xmpp:carbons:2">>, IgnoreEls, _el); - {<<"disable">>, <<"urn:xmpp:carbons:2">>} -> + {<<"enable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_enable(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"disable">>, <<"urn:xmpp:carbons:2">>, _} -> decode_carbons_disable(<<"urn:xmpp:carbons:2">>, IgnoreEls, _el); - {<<"forwarded">>, <<"urn:xmpp:forward:0">>} -> + {<<"disable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> + decode_carbons_disable(<<"urn:xmpp:carbons:2">>, + IgnoreEls, _el); + {<<"forwarded">>, <<"urn:xmpp:forward:0">>, _} -> + decode_forwarded(<<"urn:xmpp:forward:0">>, IgnoreEls, + _el); + {<<"forwarded">>, <<>>, <<"urn:xmpp:forward:0">>} -> decode_forwarded(<<"urn:xmpp:forward:0">>, IgnoreEls, _el); - {<<"fin">>, <<"urn:xmpp:mam:0">>} -> + {<<"fin">>, <<"urn:xmpp:mam:0">>, _} -> decode_mam_fin(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"fin">>, <<"urn:xmpp:mam:1">>} -> + {<<"fin">>, <<>>, <<"urn:xmpp:mam:0">>} -> + decode_mam_fin(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"fin">>, <<"urn:xmpp:mam:1">>, _} -> + decode_mam_fin(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"fin">>, <<>>, <<"urn:xmpp:mam:1">>} -> decode_mam_fin(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> + {<<"prefs">>, <<"urn:xmpp:mam:0">>, _} -> + decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:0">>} -> decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:1">>} -> + {<<"prefs">>, <<"urn:xmpp:mam:1">>, _} -> decode_mam_prefs(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:1">>} -> + decode_mam_prefs(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"prefs">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"always">>, <<"urn:xmpp:mam:0">>} -> + {<<"always">>, <<"urn:xmpp:mam:0">>, _} -> decode_mam_always(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"always">>, <<"urn:xmpp:mam:1">>} -> + {<<"always">>, <<>>, <<"urn:xmpp:mam:0">>} -> + decode_mam_always(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"always">>, <<"urn:xmpp:mam:1">>, _} -> + decode_mam_always(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"always">>, <<>>, <<"urn:xmpp:mam:1">>} -> decode_mam_always(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"always">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"always">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"always">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"never">>, <<"urn:xmpp:mam:0">>} -> + {<<"never">>, <<"urn:xmpp:mam:0">>, _} -> + decode_mam_never(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"never">>, <<>>, <<"urn:xmpp:mam:0">>} -> decode_mam_never(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"never">>, <<"urn:xmpp:mam:1">>} -> + {<<"never">>, <<"urn:xmpp:mam:1">>, _} -> + decode_mam_never(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"never">>, <<>>, <<"urn:xmpp:mam:1">>} -> decode_mam_never(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"never">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"never">>, <<"urn:xmpp:mam:tmp">>, _} -> decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:xmpp:mam:0">>} -> + {<<"never">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> + decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"jid">>, <<"urn:xmpp:mam:0">>, _} -> + decode_mam_jid(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"jid">>, <<>>, <<"urn:xmpp:mam:0">>} -> decode_mam_jid(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:xmpp:mam:1">>} -> + {<<"jid">>, <<"urn:xmpp:mam:1">>, _} -> decode_mam_jid(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"jid">>, <<>>, <<"urn:xmpp:mam:1">>} -> + decode_mam_jid(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"jid">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_jid(<<"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">>} -> + {<<"result">>, <<"urn:xmpp:mam:0">>, _} -> + decode_mam_result(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); + {<<"result">>, <<>>, <<"urn:xmpp:mam:0">>} -> decode_mam_result(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"result">>, <<"urn:xmpp:mam:1">>} -> + {<<"result">>, <<"urn:xmpp:mam:1">>, _} -> decode_mam_result(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"result">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"result">>, <<>>, <<"urn:xmpp:mam:1">>} -> + decode_mam_result(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"result">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_result(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"result">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_result(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"archived">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"archived">>, <<"urn:xmpp:mam:tmp">>, _} -> decode_mam_archived(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"query">>, <<"urn:xmpp:mam:0">>} -> + {<<"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:0">>} -> decode_mam_query(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"query">>, <<"urn:xmpp:mam:1">>} -> + {<<"query">>, <<"urn:xmpp:mam:1">>, _} -> decode_mam_query(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"query">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"query">>, <<>>, <<"urn:xmpp:mam:1">>} -> + decode_mam_query(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); + {<<"query">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"query">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"withtext">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"withtext">>, <<"urn:xmpp:mam:tmp">>, _} -> decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"with">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"withtext">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> + decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, IgnoreEls, + _el); + {<<"with">>, <<"urn:xmpp:mam:tmp">>, _} -> + decode_mam_with(<<"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">>} -> + {<<"end">>, <<"urn:xmpp:mam:tmp">>, _} -> decode_mam_end(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"start">>, <<"urn:xmpp:mam:tmp">>} -> + {<<"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); + {<<"start">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> decode_mam_start(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el); - {<<"set">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"set">>, <<"http://jabber.org/protocol/rsm">>, _} -> decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"first">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"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); + {<<"first">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> decode_rsm_first(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"max">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"max">>, <<"http://jabber.org/protocol/rsm">>, _} -> + decode_rsm_max(<<"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">>} -> + {<<"index">>, <<"http://jabber.org/protocol/rsm">>, + _} -> decode_rsm_index(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"count">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"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); + {<<"count">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> decode_rsm_count(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"last">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"last">>, <<"http://jabber.org/protocol/rsm">>, _} -> decode_rsm_last(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"before">>, <<"http://jabber.org/protocol/rsm">>} -> + {<<"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">>} -> + {<<"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); + {<<"after">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> decode_rsm_after(<<"http://jabber.org/protocol/rsm">>, IgnoreEls, _el); - {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>} -> + {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> decode_muc_unsubscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, _el); - {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>} -> + {<<"unsubscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_unsubscribe(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> decode_muc_subscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, _el); - {<<"event">>, <<"urn:xmpp:mucsub:0">>} -> + {<<"subscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, + _el); + {<<"event">>, <<"urn:xmpp:mucsub:0">>, _} -> + decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"event">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, IgnoreEls, _el); - {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>} -> + {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>, _} -> decode_muc_subscriptions(<<"urn:xmpp:mucsub:0">>, IgnoreEls, _el); - {<<"subscription">>, <<"urn:xmpp:mucsub:0">>} -> + {<<"subscriptions">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + decode_muc_subscriptions(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscription">>, <<"urn:xmpp:mucsub:0">>, _} -> + decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, + IgnoreEls, _el); + {<<"subscription">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:conference">>} -> + {<<"x">>, <<"jabber:x:conference">>, _} -> + decode_x_conference(<<"jabber:x:conference">>, + IgnoreEls, _el); + {<<"x">>, <<>>, <<"jabber:x:conference">>} -> decode_x_conference(<<"jabber:x:conference">>, IgnoreEls, _el); {<<"unique">>, + <<"http://jabber.org/protocol/muc#unique">>, _} -> + decode_muc_unique(<<"http://jabber.org/protocol/muc#unique">>, + IgnoreEls, _el); + {<<"unique">>, <<>>, <<"http://jabber.org/protocol/muc#unique">>} -> decode_muc_unique(<<"http://jabber.org/protocol/muc#unique">>, IgnoreEls, _el); - {<<"x">>, <<"http://jabber.org/protocol/muc">>} -> + {<<"x">>, <<"http://jabber.org/protocol/muc">>, _} -> + decode_muc(<<"http://jabber.org/protocol/muc">>, + IgnoreEls, _el); + {<<"x">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> decode_muc(<<"http://jabber.org/protocol/muc">>, IgnoreEls, _el); {<<"query">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"query">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); {<<"continue">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"continue">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); {<<"actor">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"actor">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/muc#admin">>, + _} -> + decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/muc#owner">>, + _} -> + decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); {<<"query">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"query">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); {<<"password">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); {<<"password">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); - {<<"password">>, + {<<"password">>, <<"http://jabber.org/protocol/muc">>, + _} -> + decode_muc_password(<<"http://jabber.org/protocol/muc">>, + IgnoreEls, _el); + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> decode_muc_password(<<"http://jabber.org/protocol/muc">>, IgnoreEls, _el); - {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> + {<<"x">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); - {<<"item">>, + {<<"x">>, <<>>, + <<"http://jabber.org/protocol/muc#user">>} -> + decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"item">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> + decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"status">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"status">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"continue">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"continue">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); - {<<"actor">>, + {<<"actor">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> + decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"actor">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"invite">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"invite">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"destroy">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"destroy">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"destroy">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); {<<"decline">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"decline">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"reason">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, + IgnoreEls, _el); + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, IgnoreEls, _el); {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, + IgnoreEls, _el); + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, IgnoreEls, _el); {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, + IgnoreEls, _el); + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, IgnoreEls, _el); - {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> + {<<"history">>, <<"http://jabber.org/protocol/muc">>, + _} -> + decode_muc_history(<<"http://jabber.org/protocol/muc">>, + IgnoreEls, _el); + {<<"history">>, <<>>, + <<"http://jabber.org/protocol/muc">>} -> decode_muc_history(<<"http://jabber.org/protocol/muc">>, IgnoreEls, _el); {<<"query">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + decode_bytestreams(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"query">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> decode_bytestreams(<<"http://jabber.org/protocol/bytestreams">>, IgnoreEls, _el); {<<"activate">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"activate">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, IgnoreEls, _el); {<<"streamhost-used">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"streamhost-used">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, IgnoreEls, _el); {<<"streamhost">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, + IgnoreEls, _el); + {<<"streamhost">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, IgnoreEls, _el); - {<<"delay">>, <<"urn:xmpp:delay">>} -> + {<<"delay">>, <<"urn:xmpp:delay">>, _} -> + decode_delay(<<"urn:xmpp:delay">>, IgnoreEls, _el); + {<<"delay">>, <<>>, <<"urn:xmpp:delay">>} -> decode_delay(<<"urn:xmpp:delay">>, IgnoreEls, _el); {<<"paused">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + decode_chatstate_paused(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"paused">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> decode_chatstate_paused(<<"http://jabber.org/protocol/chatstates">>, IgnoreEls, _el); {<<"inactive">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + decode_chatstate_inactive(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"inactive">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> decode_chatstate_inactive(<<"http://jabber.org/protocol/chatstates">>, IgnoreEls, _el); {<<"gone">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + decode_chatstate_gone(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"gone">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> decode_chatstate_gone(<<"http://jabber.org/protocol/chatstates">>, IgnoreEls, _el); {<<"composing">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + decode_chatstate_composing(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"composing">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> decode_chatstate_composing(<<"http://jabber.org/protocol/chatstates">>, IgnoreEls, _el); {<<"active">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + decode_chatstate_active(<<"http://jabber.org/protocol/chatstates">>, + IgnoreEls, _el); + {<<"active">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> decode_chatstate_active(<<"http://jabber.org/protocol/chatstates">>, IgnoreEls, _el); - {<<"headers">>, + {<<"headers">>, <<"http://jabber.org/protocol/shim">>, + _} -> + decode_shim_headers(<<"http://jabber.org/protocol/shim">>, + IgnoreEls, _el); + {<<"headers">>, <<>>, <<"http://jabber.org/protocol/shim">>} -> decode_shim_headers(<<"http://jabber.org/protocol/shim">>, IgnoreEls, _el); - {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> + {<<"header">>, <<"http://jabber.org/protocol/shim">>, + _} -> + decode_shim_header(<<"http://jabber.org/protocol/shim">>, + IgnoreEls, _el); + {<<"header">>, <<>>, + <<"http://jabber.org/protocol/shim">>} -> decode_shim_header(<<"http://jabber.org/protocol/shim">>, IgnoreEls, _el); {<<"unsupported-access-model">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_unsupported_access_model(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"unsupported-access-model">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_unsupported_access_model(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"unsupported">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_unsupported(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"unsupported">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_unsupported(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"too-many-subscriptions">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_too_many_subscriptions(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"too-many-subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_too_many_subscriptions(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"subid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_subid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"subid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_subid_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"presence-subscription-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_presence_subscription_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"presence-subscription-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_presence_subscription_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"pending-subscription">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_pending_subscription(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"pending-subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_pending_subscription(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"payload-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_payload_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"payload-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_payload_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"payload-too-big">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_payload_too_big(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"payload-too-big">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_payload_too_big(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"not-subscribed">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_not_subscribed(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"not-subscribed">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_not_subscribed(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"not-in-roster-group">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_not_in_roster_group(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"not-in-roster-group">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_not_in_roster_group(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"nodeid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_nodeid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"nodeid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_nodeid_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"max-nodes-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_max_nodes_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"max-nodes-exceeded">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_max_nodes_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"max-items-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_max_items_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"max-items-exceeded">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_max_items_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"jid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_jid_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"jid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_jid_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"item-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_item_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"item-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_item_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"item-forbidden">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_item_forbidden(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"item-forbidden">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_item_forbidden(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"invalid-subid">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_invalid_subid(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-subid">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_invalid_subid(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"invalid-payload">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_invalid_payload(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-payload">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_invalid_payload(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"invalid-options">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_invalid_options(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-options">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_invalid_options(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"invalid-jid">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_invalid_jid(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"invalid-jid">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_invalid_jid(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"configuration-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_configuration_required(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"configuration-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_configuration_required(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"closed-node">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + decode_pubsub_error_closed_node(<<"http://jabber.org/protocol/pubsub#errors">>, + IgnoreEls, _el); + {<<"closed-node">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> decode_pubsub_error_closed_node(<<"http://jabber.org/protocol/pubsub#errors">>, IgnoreEls, _el); {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_owner(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"pubsub">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_owner(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); - {<<"pubsub">>, + {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"pubsub">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); - {<<"purge">>, + {<<"purge">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"delete">>, + {<<"delete">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"default">>, + {<<"default">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"default">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"default">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"default">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"publish-options">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"publish-options">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"configure">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"configure">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"configure">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"configure">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); - {<<"create">>, + {<<"create">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"create">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"create">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"create">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"retract">>, + {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"retract">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); - {<<"options">>, + {<<"options">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"options">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); - {<<"publish">>, + {<<"publish">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"publish">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"unsubscribe">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"unsubscribe">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"subscribe">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscribe">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"affiliations">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"affiliations">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"event">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"event">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"items">>, + {<<"items">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"items">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"items">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"items">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"item">>, <<>>, + <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"item">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); {<<"retract">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"retract">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); {<<"configuration">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"configuration">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"affiliation">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"affiliation">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, + IgnoreEls, _el); + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, IgnoreEls, _el); {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, + IgnoreEls, _el); + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, IgnoreEls, _el); {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, + IgnoreEls, _el); + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:data">>} -> + {<<"x">>, <<"jabber:x:data">>, _} -> + decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"x">>, <<>>, <<"jabber:x:data">>} -> decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:x:data">>} -> + {<<"item">>, <<"jabber:x:data">>, _} -> decode_xdata_item(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"reported">>, <<"jabber:x:data">>} -> + {<<"item">>, <<>>, <<"jabber:x:data">>} -> + decode_xdata_item(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"reported">>, <<"jabber:x:data">>, _} -> + decode_xdata_reported(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"reported">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_reported(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"title">>, <<"jabber:x:data">>} -> + {<<"title">>, <<"jabber:x:data">>, _} -> + decode_xdata_title(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"title">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_title(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"instructions">>, <<"jabber:x:data">>} -> + {<<"instructions">>, <<"jabber:x:data">>, _} -> + decode_xdata_instructions(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"instructions">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_instructions(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"field">>, <<"jabber:x:data">>} -> + {<<"field">>, <<"jabber:x:data">>, _} -> decode_xdata_field(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"option">>, <<"jabber:x:data">>} -> + {<<"field">>, <<>>, <<"jabber:x:data">>} -> + decode_xdata_field(<<"jabber:x:data">>, IgnoreEls, _el); + {<<"option">>, <<"jabber:x:data">>, _} -> + decode_xdata_field_option(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"option">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_field_option(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"value">>, <<"jabber:x:data">>} -> + {<<"value">>, <<"jabber:x:data">>, _} -> + decode_xdata_field_value(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"value">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_field_value(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"desc">>, <<"jabber:x:data">>} -> + {<<"desc">>, <<"jabber:x:data">>, _} -> + decode_xdata_field_desc(<<"jabber:x:data">>, IgnoreEls, + _el); + {<<"desc">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_field_desc(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"required">>, <<"jabber:x:data">>} -> + {<<"required">>, <<"jabber:x:data">>, _} -> + decode_xdata_field_required(<<"jabber:x:data">>, + IgnoreEls, _el); + {<<"required">>, <<>>, <<"jabber:x:data">>} -> decode_xdata_field_required(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"x">>, <<"vcard-temp:x:update">>} -> + {<<"x">>, <<"vcard-temp:x:update">>, _} -> + decode_vcard_xupdate(<<"vcard-temp:x:update">>, + IgnoreEls, _el); + {<<"x">>, <<>>, <<"vcard-temp:x:update">>} -> decode_vcard_xupdate(<<"vcard-temp:x:update">>, IgnoreEls, _el); - {<<"photo">>, <<"vcard-temp:x:update">>} -> + {<<"photo">>, <<"vcard-temp:x:update">>, _} -> + decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, + IgnoreEls, _el); + {<<"photo">>, <<>>, <<"vcard-temp:x:update">>} -> decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, IgnoreEls, _el); - {<<"vCard">>, <<"vcard-temp">>} -> + {<<"vCard">>, <<"vcard-temp">>, _} -> + decode_vcard_temp(<<"vcard-temp">>, IgnoreEls, _el); + {<<"vCard">>, <<>>, <<"vcard-temp">>} -> decode_vcard_temp(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CLASS">>, <<"vcard-temp">>} -> + {<<"CLASS">>, <<"vcard-temp">>, _} -> decode_vcard_CLASS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CATEGORIES">>, <<"vcard-temp">>} -> + {<<"CLASS">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_CLASS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CATEGORIES">>, <<"vcard-temp">>, _} -> + decode_vcard_CATEGORIES(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"CATEGORIES">>, <<>>, <<"vcard-temp">>} -> decode_vcard_CATEGORIES(<<"vcard-temp">>, IgnoreEls, _el); - {<<"KEY">>, <<"vcard-temp">>} -> + {<<"KEY">>, <<"vcard-temp">>, _} -> + decode_vcard_KEY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"KEY">>, <<>>, <<"vcard-temp">>} -> decode_vcard_KEY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SOUND">>, <<"vcard-temp">>} -> + {<<"SOUND">>, <<"vcard-temp">>, _} -> decode_vcard_SOUND(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORG">>, <<"vcard-temp">>} -> + {<<"SOUND">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_SOUND(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORG">>, <<"vcard-temp">>, _} -> + decode_vcard_ORG(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORG">>, <<>>, <<"vcard-temp">>} -> decode_vcard_ORG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHOTO">>, <<"vcard-temp">>} -> + {<<"PHOTO">>, <<"vcard-temp">>, _} -> decode_vcard_PHOTO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOGO">>, <<"vcard-temp">>} -> + {<<"PHOTO">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PHOTO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOGO">>, <<"vcard-temp">>, _} -> + decode_vcard_LOGO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOGO">>, <<>>, <<"vcard-temp">>} -> decode_vcard_LOGO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BINVAL">>, <<"vcard-temp">>} -> + {<<"BINVAL">>, <<"vcard-temp">>, _} -> decode_vcard_BINVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GEO">>, <<"vcard-temp">>} -> + {<<"BINVAL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_BINVAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"GEO">>, <<"vcard-temp">>, _} -> + decode_vcard_GEO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"GEO">>, <<>>, <<"vcard-temp">>} -> decode_vcard_GEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EMAIL">>, <<"vcard-temp">>} -> + {<<"EMAIL">>, <<"vcard-temp">>, _} -> decode_vcard_EMAIL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TEL">>, <<"vcard-temp">>} -> + {<<"EMAIL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_EMAIL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TEL">>, <<"vcard-temp">>, _} -> + decode_vcard_TEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TEL">>, <<>>, <<"vcard-temp">>} -> decode_vcard_TEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LABEL">>, <<"vcard-temp">>} -> + {<<"LABEL">>, <<"vcard-temp">>, _} -> decode_vcard_LABEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ADR">>, <<"vcard-temp">>} -> + {<<"LABEL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_LABEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ADR">>, <<"vcard-temp">>, _} -> + decode_vcard_ADR(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ADR">>, <<>>, <<"vcard-temp">>} -> decode_vcard_ADR(<<"vcard-temp">>, IgnoreEls, _el); - {<<"N">>, <<"vcard-temp">>} -> + {<<"N">>, <<"vcard-temp">>, _} -> decode_vcard_N(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CONFIDENTIAL">>, <<"vcard-temp">>} -> + {<<"N">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_N(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CONFIDENTIAL">>, <<"vcard-temp">>, _} -> + decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"CONFIDENTIAL">>, <<>>, <<"vcard-temp">>} -> decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PRIVATE">>, <<"vcard-temp">>} -> + {<<"PRIVATE">>, <<"vcard-temp">>, _} -> + decode_vcard_PRIVATE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PRIVATE">>, <<>>, <<"vcard-temp">>} -> decode_vcard_PRIVATE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PUBLIC">>, <<"vcard-temp">>} -> + {<<"PUBLIC">>, <<"vcard-temp">>, _} -> decode_vcard_PUBLIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTVAL">>, <<"vcard-temp">>} -> + {<<"PUBLIC">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PUBLIC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTVAL">>, <<"vcard-temp">>, _} -> + decode_vcard_EXTVAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTVAL">>, <<>>, <<"vcard-temp">>} -> decode_vcard_EXTVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TYPE">>, <<"vcard-temp">>} -> + {<<"TYPE">>, <<"vcard-temp">>, _} -> decode_vcard_TYPE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DESC">>, <<"vcard-temp">>} -> + {<<"TYPE">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_TYPE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"DESC">>, <<"vcard-temp">>, _} -> + decode_vcard_DESC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"DESC">>, <<>>, <<"vcard-temp">>} -> decode_vcard_DESC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"URL">>, <<"vcard-temp">>} -> + {<<"URL">>, <<"vcard-temp">>, _} -> decode_vcard_URL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"UID">>, <<"vcard-temp">>} -> + {<<"URL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_URL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"UID">>, <<"vcard-temp">>, _} -> + decode_vcard_UID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"UID">>, <<>>, <<"vcard-temp">>} -> decode_vcard_UID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SORT-STRING">>, <<"vcard-temp">>} -> + {<<"SORT-STRING">>, <<"vcard-temp">>, _} -> + decode_vcard_SORT_STRING(<<"vcard-temp">>, IgnoreEls, + _el); + {<<"SORT-STRING">>, <<>>, <<"vcard-temp">>} -> decode_vcard_SORT_STRING(<<"vcard-temp">>, IgnoreEls, _el); - {<<"REV">>, <<"vcard-temp">>} -> + {<<"REV">>, <<"vcard-temp">>, _} -> decode_vcard_REV(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PRODID">>, <<"vcard-temp">>} -> + {<<"REV">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_REV(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PRODID">>, <<"vcard-temp">>, _} -> + decode_vcard_PRODID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PRODID">>, <<>>, <<"vcard-temp">>} -> decode_vcard_PRODID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NOTE">>, <<"vcard-temp">>} -> + {<<"NOTE">>, <<"vcard-temp">>, _} -> decode_vcard_NOTE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"KEYWORD">>, <<"vcard-temp">>} -> + {<<"NOTE">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_NOTE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"KEYWORD">>, <<"vcard-temp">>, _} -> + decode_vcard_KEYWORD(<<"vcard-temp">>, IgnoreEls, _el); + {<<"KEYWORD">>, <<>>, <<"vcard-temp">>} -> decode_vcard_KEYWORD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ROLE">>, <<"vcard-temp">>} -> + {<<"ROLE">>, <<"vcard-temp">>, _} -> decode_vcard_ROLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TITLE">>, <<"vcard-temp">>} -> + {<<"ROLE">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_ROLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TITLE">>, <<"vcard-temp">>, _} -> + decode_vcard_TITLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"TITLE">>, <<>>, <<"vcard-temp">>} -> decode_vcard_TITLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TZ">>, <<"vcard-temp">>} -> + {<<"TZ">>, <<"vcard-temp">>, _} -> decode_vcard_TZ(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MAILER">>, <<"vcard-temp">>} -> + {<<"TZ">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_TZ(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MAILER">>, <<"vcard-temp">>, _} -> + decode_vcard_MAILER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MAILER">>, <<>>, <<"vcard-temp">>} -> decode_vcard_MAILER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"JABBERID">>, <<"vcard-temp">>} -> + {<<"JABBERID">>, <<"vcard-temp">>, _} -> decode_vcard_JABBERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BDAY">>, <<"vcard-temp">>} -> + {<<"JABBERID">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_JABBERID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"BDAY">>, <<"vcard-temp">>, _} -> + decode_vcard_BDAY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"BDAY">>, <<>>, <<"vcard-temp">>} -> decode_vcard_BDAY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NICKNAME">>, <<"vcard-temp">>} -> + {<<"NICKNAME">>, <<"vcard-temp">>, _} -> decode_vcard_NICKNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FN">>, <<"vcard-temp">>} -> + {<<"NICKNAME">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_NICKNAME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FN">>, <<"vcard-temp">>, _} -> + decode_vcard_FN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FN">>, <<>>, <<"vcard-temp">>} -> decode_vcard_FN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VERSION">>, <<"vcard-temp">>} -> + {<<"VERSION">>, <<"vcard-temp">>, _} -> decode_vcard_VERSION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CRED">>, <<"vcard-temp">>} -> + {<<"VERSION">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_VERSION(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CRED">>, <<"vcard-temp">>, _} -> + decode_vcard_CRED(<<"vcard-temp">>, IgnoreEls, _el); + {<<"CRED">>, <<>>, <<"vcard-temp">>} -> decode_vcard_CRED(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHONETIC">>, <<"vcard-temp">>} -> + {<<"PHONETIC">>, <<"vcard-temp">>, _} -> decode_vcard_PHONETIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGUNIT">>, <<"vcard-temp">>} -> + {<<"PHONETIC">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PHONETIC(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORGUNIT">>, <<"vcard-temp">>, _} -> + decode_vcard_ORGUNIT(<<"vcard-temp">>, IgnoreEls, _el); + {<<"ORGUNIT">>, <<>>, <<"vcard-temp">>} -> decode_vcard_ORGUNIT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGNAME">>, <<"vcard-temp">>} -> + {<<"ORGNAME">>, <<"vcard-temp">>, _} -> decode_vcard_ORGNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LON">>, <<"vcard-temp">>} -> + {<<"ORGNAME">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_ORGNAME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LON">>, <<"vcard-temp">>, _} -> + decode_vcard_LON(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LON">>, <<>>, <<"vcard-temp">>} -> decode_vcard_LON(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LAT">>, <<"vcard-temp">>} -> + {<<"LAT">>, <<"vcard-temp">>, _} -> decode_vcard_LAT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"USERID">>, <<"vcard-temp">>} -> + {<<"LAT">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_LAT(<<"vcard-temp">>, IgnoreEls, _el); + {<<"USERID">>, <<"vcard-temp">>, _} -> + decode_vcard_USERID(<<"vcard-temp">>, IgnoreEls, _el); + {<<"USERID">>, <<>>, <<"vcard-temp">>} -> decode_vcard_USERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NUMBER">>, <<"vcard-temp">>} -> + {<<"NUMBER">>, <<"vcard-temp">>, _} -> decode_vcard_NUMBER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LINE">>, <<"vcard-temp">>} -> + {<<"NUMBER">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_NUMBER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LINE">>, <<"vcard-temp">>, _} -> + decode_vcard_LINE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LINE">>, <<>>, <<"vcard-temp">>} -> decode_vcard_LINE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CTRY">>, <<"vcard-temp">>} -> + {<<"CTRY">>, <<"vcard-temp">>, _} -> decode_vcard_CTRY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCODE">>, <<"vcard-temp">>} -> + {<<"CTRY">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_CTRY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCODE">>, <<"vcard-temp">>, _} -> + decode_vcard_PCODE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCODE">>, <<>>, <<"vcard-temp">>} -> decode_vcard_PCODE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"REGION">>, <<"vcard-temp">>} -> + {<<"REGION">>, <<"vcard-temp">>, _} -> decode_vcard_REGION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOCALITY">>, <<"vcard-temp">>} -> + {<<"REGION">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_REGION(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOCALITY">>, <<"vcard-temp">>, _} -> + decode_vcard_LOCALITY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"LOCALITY">>, <<>>, <<"vcard-temp">>} -> decode_vcard_LOCALITY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"STREET">>, <<"vcard-temp">>} -> + {<<"STREET">>, <<"vcard-temp">>, _} -> decode_vcard_STREET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTADD">>, <<"vcard-temp">>} -> + {<<"STREET">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_STREET(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTADD">>, <<"vcard-temp">>, _} -> + decode_vcard_EXTADD(<<"vcard-temp">>, IgnoreEls, _el); + {<<"EXTADD">>, <<>>, <<"vcard-temp">>} -> decode_vcard_EXTADD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POBOX">>, <<"vcard-temp">>} -> + {<<"POBOX">>, <<"vcard-temp">>, _} -> decode_vcard_POBOX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SUFFIX">>, <<"vcard-temp">>} -> + {<<"POBOX">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_POBOX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"SUFFIX">>, <<"vcard-temp">>, _} -> + decode_vcard_SUFFIX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"SUFFIX">>, <<>>, <<"vcard-temp">>} -> decode_vcard_SUFFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREFIX">>, <<"vcard-temp">>} -> + {<<"PREFIX">>, <<"vcard-temp">>, _} -> decode_vcard_PREFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MIDDLE">>, <<"vcard-temp">>} -> + {<<"PREFIX">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PREFIX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MIDDLE">>, <<"vcard-temp">>, _} -> + decode_vcard_MIDDLE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MIDDLE">>, <<>>, <<"vcard-temp">>} -> decode_vcard_MIDDLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GIVEN">>, <<"vcard-temp">>} -> + {<<"GIVEN">>, <<"vcard-temp">>, _} -> decode_vcard_GIVEN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAMILY">>, <<"vcard-temp">>} -> + {<<"GIVEN">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_GIVEN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAMILY">>, <<"vcard-temp">>, _} -> + decode_vcard_FAMILY(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAMILY">>, <<>>, <<"vcard-temp">>} -> decode_vcard_FAMILY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"X400">>, <<"vcard-temp">>} -> + {<<"X400">>, <<"vcard-temp">>, _} -> decode_vcard_X400(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTERNET">>, <<"vcard-temp">>} -> + {<<"X400">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_X400(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTERNET">>, <<"vcard-temp">>, _} -> + decode_vcard_INTERNET(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTERNET">>, <<>>, <<"vcard-temp">>} -> decode_vcard_INTERNET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREF">>, <<"vcard-temp">>} -> + {<<"PREF">>, <<"vcard-temp">>, _} -> decode_vcard_PREF(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTL">>, <<"vcard-temp">>} -> + {<<"PREF">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PREF(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTL">>, <<"vcard-temp">>, _} -> + decode_vcard_INTL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"INTL">>, <<>>, <<"vcard-temp">>} -> decode_vcard_INTL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DOM">>, <<"vcard-temp">>} -> + {<<"DOM">>, <<"vcard-temp">>, _} -> decode_vcard_DOM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PARCEL">>, <<"vcard-temp">>} -> + {<<"DOM">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_DOM(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PARCEL">>, <<"vcard-temp">>, _} -> + decode_vcard_PARCEL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PARCEL">>, <<>>, <<"vcard-temp">>} -> decode_vcard_PARCEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POSTAL">>, <<"vcard-temp">>} -> + {<<"POSTAL">>, <<"vcard-temp">>, _} -> decode_vcard_POSTAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCS">>, <<"vcard-temp">>} -> + {<<"POSTAL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_POSTAL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCS">>, <<"vcard-temp">>, _} -> + decode_vcard_PCS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"PCS">>, <<>>, <<"vcard-temp">>} -> decode_vcard_PCS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ISDN">>, <<"vcard-temp">>} -> + {<<"ISDN">>, <<"vcard-temp">>, _} -> decode_vcard_ISDN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MODEM">>, <<"vcard-temp">>} -> + {<<"ISDN">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_ISDN(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MODEM">>, <<"vcard-temp">>, _} -> + decode_vcard_MODEM(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MODEM">>, <<>>, <<"vcard-temp">>} -> decode_vcard_MODEM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BBS">>, <<"vcard-temp">>} -> + {<<"BBS">>, <<"vcard-temp">>, _} -> decode_vcard_BBS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VIDEO">>, <<"vcard-temp">>} -> + {<<"BBS">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_BBS(<<"vcard-temp">>, IgnoreEls, _el); + {<<"VIDEO">>, <<"vcard-temp">>, _} -> + decode_vcard_VIDEO(<<"vcard-temp">>, IgnoreEls, _el); + {<<"VIDEO">>, <<>>, <<"vcard-temp">>} -> decode_vcard_VIDEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CELL">>, <<"vcard-temp">>} -> + {<<"CELL">>, <<"vcard-temp">>, _} -> decode_vcard_CELL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MSG">>, <<"vcard-temp">>} -> + {<<"CELL">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_CELL(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MSG">>, <<"vcard-temp">>, _} -> + decode_vcard_MSG(<<"vcard-temp">>, IgnoreEls, _el); + {<<"MSG">>, <<>>, <<"vcard-temp">>} -> decode_vcard_MSG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PAGER">>, <<"vcard-temp">>} -> + {<<"PAGER">>, <<"vcard-temp">>, _} -> decode_vcard_PAGER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAX">>, <<"vcard-temp">>} -> + {<<"PAGER">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_PAGER(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAX">>, <<"vcard-temp">>, _} -> + decode_vcard_FAX(<<"vcard-temp">>, IgnoreEls, _el); + {<<"FAX">>, <<>>, <<"vcard-temp">>} -> decode_vcard_FAX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VOICE">>, <<"vcard-temp">>} -> + {<<"VOICE">>, <<"vcard-temp">>, _} -> decode_vcard_VOICE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"WORK">>, <<"vcard-temp">>} -> + {<<"VOICE">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_VOICE(<<"vcard-temp">>, IgnoreEls, _el); + {<<"WORK">>, <<"vcard-temp">>, _} -> + decode_vcard_WORK(<<"vcard-temp">>, IgnoreEls, _el); + {<<"WORK">>, <<>>, <<"vcard-temp">>} -> decode_vcard_WORK(<<"vcard-temp">>, IgnoreEls, _el); - {<<"HOME">>, <<"vcard-temp">>} -> + {<<"HOME">>, <<"vcard-temp">>, _} -> decode_vcard_HOME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"stream:error">>, - <<"http://etherx.jabber.org/streams">>} -> - decode_stream_error(<<"http://etherx.jabber.org/streams">>, + {<<"HOME">>, <<>>, <<"vcard-temp">>} -> + decode_vcard_HOME(<<"vcard-temp">>, IgnoreEls, _el); + {<<"stream:error">>, <<"jabber:client">>, _} -> + decode_stream_error(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:error">>, <<>>, <<"jabber:client">>} -> + decode_stream_error(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:error">>, <<"jabber:server">>, _} -> + decode_stream_error(<<"jabber:server">>, IgnoreEls, + _el); + {<<"stream:error">>, <<>>, <<"jabber:server">>} -> + decode_stream_error(<<"jabber:server">>, IgnoreEls, + _el); + {<<"stream:error">>, <<"jabber:component:accept">>, + _} -> + decode_stream_error(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"stream:error">>, <<>>, + <<"jabber:component:accept">>} -> + decode_stream_error(<<"jabber:component:accept">>, IgnoreEls, _el); {<<"unsupported-version">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"unsupported-version">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"unsupported-stanza-type">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"unsupported-stanza-type">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"unsupported-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"unsupported-encoding">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"undefined-condition">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"system-shutdown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"system-shutdown">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"see-other-host">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"see-other-host">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"restricted-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"restricted-xml">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"resource-constraint">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); - {<<"reset">>, + {<<"reset">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, + _} -> + decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"reset">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"remote-connection-failed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"remote-connection-failed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"policy-violation">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"not-well-formed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"not-well-formed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"invalid-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-xml">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"invalid-namespace">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-namespace">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"invalid-id">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-id">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"invalid-from">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"invalid-from">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"internal-server-error">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"improper-addressing">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"improper-addressing">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"host-unknown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"host-unknown">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"host-gone">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"host-gone">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"connection-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"connection-timeout">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"conflict">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"bad-namespace-prefix">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"bad-namespace-prefix">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); {<<"bad-format">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"bad-format">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); - {<<"text">>, + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, + _} -> + decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + IgnoreEls, _el); + {<<"text">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, IgnoreEls, _el); - {<<"time">>, <<"urn:xmpp:time">>} -> + {<<"time">>, <<"urn:xmpp:time">>, _} -> decode_time(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"tzo">>, <<"urn:xmpp:time">>} -> + {<<"time">>, <<>>, <<"urn:xmpp:time">>} -> + decode_time(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"tzo">>, <<"urn:xmpp:time">>, _} -> + decode_time_tzo(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"tzo">>, <<>>, <<"urn:xmpp:time">>} -> decode_time_tzo(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"utc">>, <<"urn:xmpp:time">>} -> + {<<"utc">>, <<"urn:xmpp:time">>, _} -> decode_time_utc(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"ping">>, <<"urn:xmpp:ping">>} -> + {<<"utc">>, <<>>, <<"urn:xmpp:time">>} -> + decode_time_utc(<<"urn:xmpp:time">>, IgnoreEls, _el); + {<<"ping">>, <<"urn:xmpp:ping">>, _} -> + decode_ping(<<"urn:xmpp:ping">>, IgnoreEls, _el); + {<<"ping">>, <<>>, <<"urn:xmpp:ping">>} -> decode_ping(<<"urn:xmpp:ping">>, IgnoreEls, _el); {<<"session">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> + decode_session(<<"urn:ietf:params:xml:ns:xmpp-session">>, + IgnoreEls, _el); + {<<"session">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-session">>} -> decode_session(<<"urn:ietf:params:xml:ns:xmpp-session">>, IgnoreEls, _el); {<<"optional">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> + decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, + IgnoreEls, _el); + {<<"optional">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-session">>} -> decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:register">>} -> + {<<"query">>, <<"jabber:iq:register">>, _} -> + decode_register(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"query">>, <<>>, <<"jabber:iq:register">>} -> decode_register(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"key">>, <<"jabber:iq:register">>} -> + {<<"key">>, <<"jabber:iq:register">>, _} -> decode_register_key(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"text">>, <<"jabber:iq:register">>} -> + {<<"key">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_key(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"text">>, <<"jabber:iq:register">>, _} -> + decode_register_text(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"text">>, <<>>, <<"jabber:iq:register">>} -> decode_register_text(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"misc">>, <<"jabber:iq:register">>} -> + {<<"misc">>, <<"jabber:iq:register">>, _} -> decode_register_misc(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"date">>, <<"jabber:iq:register">>} -> + {<<"misc">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_misc(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"date">>, <<"jabber:iq:register">>, _} -> + decode_register_date(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"date">>, <<>>, <<"jabber:iq:register">>} -> decode_register_date(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"url">>, <<"jabber:iq:register">>} -> + {<<"url">>, <<"jabber:iq:register">>, _} -> decode_register_url(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"phone">>, <<"jabber:iq:register">>} -> + {<<"url">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_url(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"phone">>, <<"jabber:iq:register">>, _} -> + decode_register_phone(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"phone">>, <<>>, <<"jabber:iq:register">>} -> decode_register_phone(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"zip">>, <<"jabber:iq:register">>} -> + {<<"zip">>, <<"jabber:iq:register">>, _} -> decode_register_zip(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"state">>, <<"jabber:iq:register">>} -> + {<<"zip">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_zip(<<"jabber:iq:register">>, IgnoreEls, + _el); + {<<"state">>, <<"jabber:iq:register">>, _} -> + decode_register_state(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"state">>, <<>>, <<"jabber:iq:register">>} -> decode_register_state(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"city">>, <<"jabber:iq:register">>} -> + {<<"city">>, <<"jabber:iq:register">>, _} -> decode_register_city(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"address">>, <<"jabber:iq:register">>} -> + {<<"city">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_city(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"address">>, <<"jabber:iq:register">>, _} -> + decode_register_address(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"address">>, <<>>, <<"jabber:iq:register">>} -> decode_register_address(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"email">>, <<"jabber:iq:register">>} -> + {<<"email">>, <<"jabber:iq:register">>, _} -> decode_register_email(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"last">>, <<"jabber:iq:register">>} -> + {<<"email">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_email(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"last">>, <<"jabber:iq:register">>, _} -> + decode_register_last(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"last">>, <<>>, <<"jabber:iq:register">>} -> decode_register_last(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"first">>, <<"jabber:iq:register">>} -> + {<<"first">>, <<"jabber:iq:register">>, _} -> decode_register_first(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"name">>, <<"jabber:iq:register">>} -> + {<<"first">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_first(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"name">>, <<"jabber:iq:register">>, _} -> + decode_register_name(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"name">>, <<>>, <<"jabber:iq:register">>} -> decode_register_name(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"password">>, <<"jabber:iq:register">>} -> + {<<"password">>, <<"jabber:iq:register">>, _} -> decode_register_password(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"nick">>, <<"jabber:iq:register">>} -> + {<<"password">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_password(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"nick">>, <<"jabber:iq:register">>, _} -> + decode_register_nick(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"nick">>, <<>>, <<"jabber:iq:register">>} -> decode_register_nick(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"username">>, <<"jabber:iq:register">>} -> + {<<"username">>, <<"jabber:iq:register">>, _} -> decode_register_username(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"instructions">>, <<"jabber:iq:register">>} -> + {<<"username">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_username(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"instructions">>, <<"jabber:iq:register">>, _} -> + decode_register_instructions(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"instructions">>, <<>>, <<"jabber:iq:register">>} -> decode_register_instructions(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"remove">>, <<"jabber:iq:register">>} -> + {<<"remove">>, <<"jabber:iq:register">>, _} -> decode_register_remove(<<"jabber:iq:register">>, IgnoreEls, _el); - {<<"registered">>, <<"jabber:iq:register">>} -> + {<<"remove">>, <<>>, <<"jabber:iq:register">>} -> + decode_register_remove(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"registered">>, <<"jabber:iq:register">>, _} -> + decode_register_registered(<<"jabber:iq:register">>, + IgnoreEls, _el); + {<<"registered">>, <<>>, <<"jabber:iq:register">>} -> decode_register_registered(<<"jabber:iq:register">>, IgnoreEls, _el); {<<"register">>, + <<"http://jabber.org/features/iq-register">>, _} -> + decode_feature_register(<<"http://jabber.org/features/iq-register">>, + IgnoreEls, _el); + {<<"register">>, <<>>, <<"http://jabber.org/features/iq-register">>} -> decode_feature_register(<<"http://jabber.org/features/iq-register">>, IgnoreEls, _el); - {<<"c">>, <<"http://jabber.org/protocol/caps">>} -> + {<<"c">>, <<"http://jabber.org/protocol/caps">>, _} -> + decode_caps(<<"http://jabber.org/protocol/caps">>, + IgnoreEls, _el); + {<<"c">>, <<>>, + <<"http://jabber.org/protocol/caps">>} -> decode_caps(<<"http://jabber.org/protocol/caps">>, IgnoreEls, _el); - {<<"ack">>, <<"p1:ack">>} -> + {<<"ack">>, <<"p1:ack">>, _} -> decode_p1_ack(<<"p1:ack">>, IgnoreEls, _el); - {<<"rebind">>, <<"p1:rebind">>} -> + {<<"ack">>, <<>>, <<"p1:ack">>} -> + decode_p1_ack(<<"p1:ack">>, IgnoreEls, _el); + {<<"rebind">>, <<"p1:rebind">>, _} -> + decode_p1_rebind(<<"p1:rebind">>, IgnoreEls, _el); + {<<"rebind">>, <<>>, <<"p1:rebind">>} -> decode_p1_rebind(<<"p1:rebind">>, IgnoreEls, _el); - {<<"push">>, <<"p1:push">>} -> + {<<"push">>, <<"p1:push">>, _} -> decode_p1_push(<<"p1:push">>, IgnoreEls, _el); - {<<"stream:features">>, - <<"http://etherx.jabber.org/streams">>} -> - decode_stream_features(<<"http://etherx.jabber.org/streams">>, - IgnoreEls, _el); + {<<"push">>, <<>>, <<"p1:push">>} -> + decode_p1_push(<<"p1:push">>, IgnoreEls, _el); + {<<"stream:features">>, <<"jabber:client">>, _} -> + decode_stream_features(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:features">>, <<>>, <<"jabber:client">>} -> + decode_stream_features(<<"jabber:client">>, IgnoreEls, + _el); + {<<"stream:features">>, <<"jabber:server">>, _} -> + decode_stream_features(<<"jabber:server">>, IgnoreEls, + _el); + {<<"stream:features">>, <<>>, <<"jabber:server">>} -> + decode_stream_features(<<"jabber:server">>, IgnoreEls, + _el); {<<"compression">>, + <<"http://jabber.org/features/compress">>, _} -> + decode_compression(<<"http://jabber.org/features/compress">>, + IgnoreEls, _el); + {<<"compression">>, <<>>, <<"http://jabber.org/features/compress">>} -> decode_compression(<<"http://jabber.org/features/compress">>, IgnoreEls, _el); {<<"method">>, + <<"http://jabber.org/features/compress">>, _} -> + decode_compression_method(<<"http://jabber.org/features/compress">>, + IgnoreEls, _el); + {<<"method">>, <<>>, <<"http://jabber.org/features/compress">>} -> decode_compression_method(<<"http://jabber.org/features/compress">>, IgnoreEls, _el); {<<"compressed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compressed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"compressed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compressed(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"compress">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"compress">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"method">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress_method(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"method">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress_method(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"failure">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress_failure(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"failure">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress_failure(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"unsupported-method">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"unsupported-method">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"processing-failed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"processing-failed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); {<<"setup-failed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, + IgnoreEls, _el); + {<<"setup-failed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, IgnoreEls, _el); - {<<"failure">>, + {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + decode_starttls_failure(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> decode_starttls_failure(<<"urn:ietf:params:xml:ns:xmpp-tls">>, IgnoreEls, _el); - {<<"proceed">>, + {<<"proceed">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + decode_starttls_proceed(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"proceed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> decode_starttls_proceed(<<"urn:ietf:params:xml:ns:xmpp-tls">>, IgnoreEls, _el); - {<<"starttls">>, + {<<"starttls">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + decode_starttls(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"starttls">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> decode_starttls(<<"urn:ietf:params:xml:ns:xmpp-tls">>, IgnoreEls, _el); - {<<"required">>, + {<<"required">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + IgnoreEls, _el); + {<<"required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, IgnoreEls, _el); {<<"mechanisms">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_mechanisms(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"mechanisms">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_mechanisms(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"mechanism">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"failure">>, + {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"temporary-auth-failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"temporary-auth-failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"bad-protocol">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"bad-protocol">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"mechanism-too-weak">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"mechanism-too-weak">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"malformed-request">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"malformed-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"invalid-mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"invalid-mechanism">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"invalid-authzid">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"invalid-authzid">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"incorrect-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"incorrect-encoding">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"encryption-required">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"encryption-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"credentials-expired">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"credentials-expired">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"account-disabled">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"account-disabled">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"aborted">>, + {<<"aborted">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"aborted">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"text">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"success">>, + {<<"success">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_success(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"success">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_success(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"response">>, + {<<"response">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_response(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"response">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_response(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); {<<"challenge">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + decode_sasl_challenge(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"challenge">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_challenge(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_abort(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"abort">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_abort(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + decode_sasl_auth(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + IgnoreEls, _el); + {<<"auth">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> decode_sasl_auth(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:auth">>} -> + {<<"query">>, <<"jabber:iq:auth">>, _} -> + decode_legacy_auth(<<"jabber:iq:auth">>, IgnoreEls, + _el); + {<<"query">>, <<>>, <<"jabber:iq:auth">>} -> decode_legacy_auth(<<"jabber:iq:auth">>, IgnoreEls, _el); - {<<"resource">>, <<"jabber:iq:auth">>} -> + {<<"resource">>, <<"jabber:iq:auth">>, _} -> + decode_legacy_auth_resource(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"resource">>, <<>>, <<"jabber:iq:auth">>} -> decode_legacy_auth_resource(<<"jabber:iq:auth">>, IgnoreEls, _el); - {<<"digest">>, <<"jabber:iq:auth">>} -> + {<<"digest">>, <<"jabber:iq:auth">>, _} -> + decode_legacy_auth_digest(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"digest">>, <<>>, <<"jabber:iq:auth">>} -> decode_legacy_auth_digest(<<"jabber:iq:auth">>, IgnoreEls, _el); - {<<"password">>, <<"jabber:iq:auth">>} -> + {<<"password">>, <<"jabber:iq:auth">>, _} -> + decode_legacy_auth_password(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"password">>, <<>>, <<"jabber:iq:auth">>} -> decode_legacy_auth_password(<<"jabber:iq:auth">>, IgnoreEls, _el); - {<<"username">>, <<"jabber:iq:auth">>} -> + {<<"username">>, <<"jabber:iq:auth">>, _} -> + decode_legacy_auth_username(<<"jabber:iq:auth">>, + IgnoreEls, _el); + {<<"username">>, <<>>, <<"jabber:iq:auth">>} -> decode_legacy_auth_username(<<"jabber:iq:auth">>, IgnoreEls, _el); - {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> + decode_bind(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"bind">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> decode_bind(<<"urn:ietf:params:xml:ns:xmpp-bind">>, IgnoreEls, _el); - {<<"resource">>, + {<<"resource">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> + decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"resource">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, IgnoreEls, _el); - {<<"error">>, <<"jabber:client">>} -> + {<<"jid">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + IgnoreEls, _el); + {<<"error">>, <<"jabber:client">>, _} -> + decode_error(<<"jabber:client">>, IgnoreEls, _el); + {<<"error">>, <<>>, <<"jabber:client">>} -> decode_error(<<"jabber:client">>, IgnoreEls, _el); - {<<"text">>, + {<<"error">>, <<"jabber:server">>, _} -> + decode_error(<<"jabber:server">>, IgnoreEls, _el); + {<<"error">>, <<>>, <<"jabber:server">>} -> + decode_error(<<"jabber:server">>, IgnoreEls, _el); + {<<"error">>, <<"jabber:component:accept">>, _} -> + decode_error(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"error">>, <<>>, <<"jabber:component:accept">>} -> + decode_error(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + _} -> + decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"text">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"unexpected-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"unexpected-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"undefined-condition">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"subscription-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"subscription-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"service-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"service-unavailable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"resource-constraint">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"remote-server-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"remote-server-timeout">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"remote-server-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"remote-server-not-found">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"registration-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"registration-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"redirect">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"redirect">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"recipient-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"recipient-unavailable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"policy-violation">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"payment-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"payment-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"not-allowed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-allowed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"not-acceptable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"not-acceptable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"jid-malformed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"jid-malformed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"item-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"item-not-found">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"internal-server-error">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); - {<<"gone">>, + {<<"gone">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + _} -> + decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"gone">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"forbidden">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"forbidden">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"feature-not-implemented">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"feature-not-implemented">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"conflict">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); {<<"bad-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + IgnoreEls, _el); + {<<"bad-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, IgnoreEls, _el); - {<<"presence">>, <<"jabber:client">>} -> + {<<"presence">>, <<"jabber:client">>, _} -> + decode_presence(<<"jabber:client">>, IgnoreEls, _el); + {<<"presence">>, <<>>, <<"jabber:client">>} -> decode_presence(<<"jabber:client">>, IgnoreEls, _el); - {<<"priority">>, <<"jabber:client">>} -> + {<<"presence">>, <<"jabber:server">>, _} -> + decode_presence(<<"jabber:server">>, IgnoreEls, _el); + {<<"presence">>, <<>>, <<"jabber:server">>} -> + decode_presence(<<"jabber:server">>, IgnoreEls, _el); + {<<"presence">>, <<"jabber:component:accept">>, _} -> + decode_presence(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"presence">>, <<>>, <<"jabber:component:accept">>} -> + decode_presence(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"priority">>, <<"jabber:client">>, _} -> + decode_presence_priority(<<"jabber:client">>, IgnoreEls, + _el); + {<<"priority">>, <<>>, <<"jabber:client">>} -> decode_presence_priority(<<"jabber:client">>, IgnoreEls, _el); - {<<"status">>, <<"jabber:client">>} -> + {<<"priority">>, <<"jabber:server">>, _} -> + decode_presence_priority(<<"jabber:server">>, IgnoreEls, + _el); + {<<"priority">>, <<>>, <<"jabber:server">>} -> + decode_presence_priority(<<"jabber:server">>, IgnoreEls, + _el); + {<<"priority">>, <<"jabber:component:accept">>, _} -> + decode_presence_priority(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"priority">>, <<>>, <<"jabber:component:accept">>} -> + decode_presence_priority(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"status">>, <<"jabber:client">>, _} -> decode_presence_status(<<"jabber:client">>, IgnoreEls, _el); - {<<"show">>, <<"jabber:client">>} -> + {<<"status">>, <<>>, <<"jabber:client">>} -> + decode_presence_status(<<"jabber:client">>, IgnoreEls, + _el); + {<<"status">>, <<"jabber:server">>, _} -> + decode_presence_status(<<"jabber:server">>, IgnoreEls, + _el); + {<<"status">>, <<>>, <<"jabber:server">>} -> + decode_presence_status(<<"jabber:server">>, IgnoreEls, + _el); + {<<"status">>, <<"jabber:component:accept">>, _} -> + decode_presence_status(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"status">>, <<>>, <<"jabber:component:accept">>} -> + decode_presence_status(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"show">>, <<"jabber:client">>, _} -> + decode_presence_show(<<"jabber:client">>, IgnoreEls, + _el); + {<<"show">>, <<>>, <<"jabber:client">>} -> decode_presence_show(<<"jabber:client">>, IgnoreEls, _el); - {<<"message">>, <<"jabber:client">>} -> + {<<"show">>, <<"jabber:server">>, _} -> + decode_presence_show(<<"jabber:server">>, IgnoreEls, + _el); + {<<"show">>, <<>>, <<"jabber:server">>} -> + decode_presence_show(<<"jabber:server">>, IgnoreEls, + _el); + {<<"show">>, <<"jabber:component:accept">>, _} -> + decode_presence_show(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"show">>, <<>>, <<"jabber:component:accept">>} -> + decode_presence_show(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"message">>, <<"jabber:client">>, _} -> decode_message(<<"jabber:client">>, IgnoreEls, _el); - {<<"thread">>, <<"jabber:client">>} -> + {<<"message">>, <<>>, <<"jabber:client">>} -> + decode_message(<<"jabber:client">>, IgnoreEls, _el); + {<<"message">>, <<"jabber:server">>, _} -> + decode_message(<<"jabber:server">>, IgnoreEls, _el); + {<<"message">>, <<>>, <<"jabber:server">>} -> + decode_message(<<"jabber:server">>, IgnoreEls, _el); + {<<"message">>, <<"jabber:component:accept">>, _} -> + decode_message(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"message">>, <<>>, <<"jabber:component:accept">>} -> + decode_message(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"thread">>, <<"jabber:client">>, _} -> + decode_message_thread(<<"jabber:client">>, IgnoreEls, + _el); + {<<"thread">>, <<>>, <<"jabber:client">>} -> decode_message_thread(<<"jabber:client">>, IgnoreEls, _el); - {<<"body">>, <<"jabber:client">>} -> + {<<"thread">>, <<"jabber:server">>, _} -> + decode_message_thread(<<"jabber:server">>, IgnoreEls, + _el); + {<<"thread">>, <<>>, <<"jabber:server">>} -> + decode_message_thread(<<"jabber:server">>, IgnoreEls, + _el); + {<<"thread">>, <<"jabber:component:accept">>, _} -> + decode_message_thread(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"thread">>, <<>>, <<"jabber:component:accept">>} -> + decode_message_thread(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"body">>, <<"jabber:client">>, _} -> + decode_message_body(<<"jabber:client">>, IgnoreEls, + _el); + {<<"body">>, <<>>, <<"jabber:client">>} -> decode_message_body(<<"jabber:client">>, IgnoreEls, _el); - {<<"subject">>, <<"jabber:client">>} -> + {<<"body">>, <<"jabber:server">>, _} -> + decode_message_body(<<"jabber:server">>, IgnoreEls, + _el); + {<<"body">>, <<>>, <<"jabber:server">>} -> + decode_message_body(<<"jabber:server">>, IgnoreEls, + _el); + {<<"body">>, <<"jabber:component:accept">>, _} -> + decode_message_body(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"body">>, <<>>, <<"jabber:component:accept">>} -> + decode_message_body(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"subject">>, <<"jabber:client">>, _} -> + decode_message_subject(<<"jabber:client">>, IgnoreEls, + _el); + {<<"subject">>, <<>>, <<"jabber:client">>} -> decode_message_subject(<<"jabber:client">>, IgnoreEls, _el); - {<<"iq">>, <<"jabber:client">>} -> + {<<"subject">>, <<"jabber:server">>, _} -> + decode_message_subject(<<"jabber:server">>, IgnoreEls, + _el); + {<<"subject">>, <<>>, <<"jabber:server">>} -> + decode_message_subject(<<"jabber:server">>, IgnoreEls, + _el); + {<<"subject">>, <<"jabber:component:accept">>, _} -> + decode_message_subject(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"subject">>, <<>>, <<"jabber:component:accept">>} -> + decode_message_subject(<<"jabber:component:accept">>, + IgnoreEls, _el); + {<<"iq">>, <<"jabber:client">>, _} -> + decode_iq(<<"jabber:client">>, IgnoreEls, _el); + {<<"iq">>, <<>>, <<"jabber:client">>} -> decode_iq(<<"jabber:client">>, IgnoreEls, _el); - {<<"query">>, <<"http://jabber.org/protocol/stats">>} -> + {<<"iq">>, <<"jabber:server">>, _} -> + decode_iq(<<"jabber:server">>, IgnoreEls, _el); + {<<"iq">>, <<>>, <<"jabber:server">>} -> + decode_iq(<<"jabber:server">>, IgnoreEls, _el); + {<<"iq">>, <<"jabber:component:accept">>, _} -> + decode_iq(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"iq">>, <<>>, <<"jabber:component:accept">>} -> + decode_iq(<<"jabber:component:accept">>, IgnoreEls, + _el); + {<<"query">>, <<"http://jabber.org/protocol/stats">>, + _} -> decode_stats(<<"http://jabber.org/protocol/stats">>, IgnoreEls, _el); - {<<"stat">>, <<"http://jabber.org/protocol/stats">>} -> + {<<"query">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> + decode_stats(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"stat">>, <<"http://jabber.org/protocol/stats">>, + _} -> + decode_stat(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"stat">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> decode_stat(<<"http://jabber.org/protocol/stats">>, IgnoreEls, _el); - {<<"error">>, <<"http://jabber.org/protocol/stats">>} -> + {<<"error">>, <<"http://jabber.org/protocol/stats">>, + _} -> decode_stat_error(<<"http://jabber.org/protocol/stats">>, IgnoreEls, _el); - {<<"storage">>, <<"storage:bookmarks">>} -> + {<<"error">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> + decode_stat_error(<<"http://jabber.org/protocol/stats">>, + IgnoreEls, _el); + {<<"storage">>, <<"storage:bookmarks">>, _} -> + decode_bookmarks_storage(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"storage">>, <<>>, <<"storage:bookmarks">>} -> decode_bookmarks_storage(<<"storage:bookmarks">>, IgnoreEls, _el); - {<<"url">>, <<"storage:bookmarks">>} -> + {<<"url">>, <<"storage:bookmarks">>, _} -> decode_bookmark_url(<<"storage:bookmarks">>, IgnoreEls, _el); - {<<"conference">>, <<"storage:bookmarks">>} -> + {<<"url">>, <<>>, <<"storage:bookmarks">>} -> + decode_bookmark_url(<<"storage:bookmarks">>, IgnoreEls, + _el); + {<<"conference">>, <<"storage:bookmarks">>, _} -> + decode_bookmark_conference(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"conference">>, <<>>, <<"storage:bookmarks">>} -> decode_bookmark_conference(<<"storage:bookmarks">>, IgnoreEls, _el); - {<<"password">>, <<"storage:bookmarks">>} -> + {<<"password">>, <<"storage:bookmarks">>, _} -> decode_conference_password(<<"storage:bookmarks">>, IgnoreEls, _el); - {<<"nick">>, <<"storage:bookmarks">>} -> + {<<"password">>, <<>>, <<"storage:bookmarks">>} -> + decode_conference_password(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"nick">>, <<"storage:bookmarks">>, _} -> + decode_conference_nick(<<"storage:bookmarks">>, + IgnoreEls, _el); + {<<"nick">>, <<>>, <<"storage:bookmarks">>} -> decode_conference_nick(<<"storage:bookmarks">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:private">>} -> + {<<"query">>, <<"jabber:iq:private">>, _} -> + decode_private(<<"jabber:iq:private">>, IgnoreEls, _el); + {<<"query">>, <<>>, <<"jabber:iq:private">>} -> decode_private(<<"jabber:iq:private">>, IgnoreEls, _el); {<<"query">>, + <<"http://jabber.org/protocol/disco#items">>, _} -> + decode_disco_items(<<"http://jabber.org/protocol/disco#items">>, + IgnoreEls, _el); + {<<"query">>, <<>>, <<"http://jabber.org/protocol/disco#items">>} -> decode_disco_items(<<"http://jabber.org/protocol/disco#items">>, IgnoreEls, _el); {<<"item">>, + <<"http://jabber.org/protocol/disco#items">>, _} -> + decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, + IgnoreEls, _el); + {<<"item">>, <<>>, <<"http://jabber.org/protocol/disco#items">>} -> decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, IgnoreEls, _el); {<<"query">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + decode_disco_info(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"query">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> decode_disco_info(<<"http://jabber.org/protocol/disco#info">>, IgnoreEls, _el); {<<"feature">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"feature">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, IgnoreEls, _el); {<<"identity">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, + IgnoreEls, _el); + {<<"identity">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, IgnoreEls, _el); - {<<"blocklist">>, <<"urn:xmpp:blocking">>} -> + {<<"blocklist">>, <<"urn:xmpp:blocking">>, _} -> + decode_block_list(<<"urn:xmpp:blocking">>, IgnoreEls, + _el); + {<<"blocklist">>, <<>>, <<"urn:xmpp:blocking">>} -> decode_block_list(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"unblock">>, <<"urn:xmpp:blocking">>} -> + {<<"unblock">>, <<"urn:xmpp:blocking">>, _} -> + decode_unblock(<<"urn:xmpp:blocking">>, IgnoreEls, _el); + {<<"unblock">>, <<>>, <<"urn:xmpp:blocking">>} -> decode_unblock(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"block">>, <<"urn:xmpp:blocking">>} -> + {<<"block">>, <<"urn:xmpp:blocking">>, _} -> decode_block(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"item">>, <<"urn:xmpp:blocking">>} -> + {<<"block">>, <<>>, <<"urn:xmpp:blocking">>} -> + decode_block(<<"urn:xmpp:blocking">>, IgnoreEls, _el); + {<<"item">>, <<"urn:xmpp:blocking">>, _} -> + decode_block_item(<<"urn:xmpp:blocking">>, IgnoreEls, + _el); + {<<"item">>, <<>>, <<"urn:xmpp:blocking">>} -> decode_block_item(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:privacy">>} -> + {<<"query">>, <<"jabber:iq:privacy">>, _} -> + decode_privacy(<<"jabber:iq:privacy">>, IgnoreEls, _el); + {<<"query">>, <<>>, <<"jabber:iq:privacy">>} -> decode_privacy(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"active">>, <<"jabber:iq:privacy">>} -> + {<<"active">>, <<"jabber:iq:privacy">>, _} -> + decode_privacy_active_list(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"active">>, <<>>, <<"jabber:iq:privacy">>} -> decode_privacy_active_list(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"default">>, <<"jabber:iq:privacy">>} -> + {<<"default">>, <<"jabber:iq:privacy">>, _} -> decode_privacy_default_list(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"list">>, <<"jabber:iq:privacy">>} -> + {<<"default">>, <<>>, <<"jabber:iq:privacy">>} -> + decode_privacy_default_list(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"list">>, <<"jabber:iq:privacy">>, _} -> + decode_privacy_list(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"list">>, <<>>, <<"jabber:iq:privacy">>} -> decode_privacy_list(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:iq:privacy">>} -> + {<<"item">>, <<"jabber:iq:privacy">>, _} -> decode_privacy_item(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"presence-out">>, <<"jabber:iq:privacy">>} -> + {<<"item">>, <<>>, <<"jabber:iq:privacy">>} -> + decode_privacy_item(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"presence-out">>, <<"jabber:iq:privacy">>, _} -> + decode_privacy_presence_out(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"presence-out">>, <<>>, <<"jabber:iq:privacy">>} -> decode_privacy_presence_out(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"presence-in">>, <<"jabber:iq:privacy">>} -> + {<<"presence-in">>, <<"jabber:iq:privacy">>, _} -> decode_privacy_presence_in(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"iq">>, <<"jabber:iq:privacy">>} -> + {<<"presence-in">>, <<>>, <<"jabber:iq:privacy">>} -> + decode_privacy_presence_in(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"iq">>, <<"jabber:iq:privacy">>, _} -> + decode_privacy_iq(<<"jabber:iq:privacy">>, IgnoreEls, + _el); + {<<"iq">>, <<>>, <<"jabber:iq:privacy">>} -> decode_privacy_iq(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"message">>, <<"jabber:iq:privacy">>} -> + {<<"message">>, <<"jabber:iq:privacy">>, _} -> decode_privacy_message(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"ver">>, <<"urn:xmpp:features:rosterver">>} -> + {<<"message">>, <<>>, <<"jabber:iq:privacy">>} -> + decode_privacy_message(<<"jabber:iq:privacy">>, + IgnoreEls, _el); + {<<"ver">>, <<"urn:xmpp:features:rosterver">>, _} -> + decode_rosterver_feature(<<"urn:xmpp:features:rosterver">>, + IgnoreEls, _el); + {<<"ver">>, <<>>, <<"urn:xmpp:features:rosterver">>} -> decode_rosterver_feature(<<"urn:xmpp:features:rosterver">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:roster">>} -> + {<<"query">>, <<"jabber:iq:roster">>, _} -> decode_roster_query(<<"jabber:iq:roster">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:iq:roster">>} -> + {<<"query">>, <<>>, <<"jabber:iq:roster">>} -> + decode_roster_query(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"item">>, <<"jabber:iq:roster">>, _} -> + decode_roster_item(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"item">>, <<>>, <<"jabber:iq:roster">>} -> decode_roster_item(<<"jabber:iq:roster">>, IgnoreEls, _el); - {<<"group">>, <<"jabber:iq:roster">>} -> + {<<"group">>, <<"jabber:iq:roster">>, _} -> decode_roster_group(<<"jabber:iq:roster">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:version">>} -> + {<<"group">>, <<>>, <<"jabber:iq:roster">>} -> + decode_roster_group(<<"jabber:iq:roster">>, IgnoreEls, + _el); + {<<"query">>, <<"jabber:iq:version">>, _} -> decode_version(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"os">>, <<"jabber:iq:version">>} -> + {<<"query">>, <<>>, <<"jabber:iq:version">>} -> + decode_version(<<"jabber:iq:version">>, IgnoreEls, _el); + {<<"os">>, <<"jabber:iq:version">>, _} -> + decode_version_os(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"os">>, <<>>, <<"jabber:iq:version">>} -> decode_version_os(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"version">>, <<"jabber:iq:version">>} -> + {<<"version">>, <<"jabber:iq:version">>, _} -> + decode_version_ver(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"version">>, <<>>, <<"jabber:iq:version">>} -> decode_version_ver(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"name">>, <<"jabber:iq:version">>} -> + {<<"name">>, <<"jabber:iq:version">>, _} -> + decode_version_name(<<"jabber:iq:version">>, IgnoreEls, + _el); + {<<"name">>, <<>>, <<"jabber:iq:version">>} -> decode_version_name(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:last">>} -> + {<<"query">>, <<"jabber:iq:last">>, _} -> + decode_last(<<"jabber:iq:last">>, IgnoreEls, _el); + {<<"query">>, <<>>, <<"jabber:iq:last">>} -> decode_last(<<"jabber:iq:last">>, IgnoreEls, _el); - {_name, _xmlns} -> + {_name, <<>>, <<>>} -> + erlang:error({xmpp_codec, {missing_tag_xmlns, _name}}); + {_name, <<>>, _} -> + erlang:error({xmpp_codec, + {unknown_tag, _name, TopXMLNS}}); + {_name, _xmlns, _} -> erlang:error({xmpp_codec, {unknown_tag, _name, _xmlns}}) end. -is_known_tag({xmlel, _name, _attrs, _} = _el) -> - case {_name, get_attr(<<"xmlns">>, _attrs)} of - {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>} -> true; - {<<"slot">>, <<"urn:xmpp:http:upload">>} -> true; - {<<"slot">>, +is_known_tag({xmlel, _name, _attrs, _} = _el, + TopXMLNS) -> + case {_name, get_attr(<<"xmlns">>, _attrs), TopXMLNS} of + {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>, _} -> true; + {<<"thumbnail">>, <<>>, <<"urn:xmpp:thumbs:1">>} -> + true; + {<<"slot">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"slot">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; + {<<"slot">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + true; + {<<"slot">>, <<>>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"put">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"put">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; + {<<"put">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + true; + {<<"put">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> true; - {<<"put">>, <<"urn:xmpp:http:upload">>} -> true; - {<<"put">>, <<"eu:siacs:conversations:http:upload">>} -> + {<<"get">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"get">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; + {<<"get">>, <<"eu:siacs:conversations:http:upload">>, + _} -> true; - {<<"get">>, <<"urn:xmpp:http:upload">>} -> true; - {<<"get">>, <<"eu:siacs:conversations:http:upload">>} -> + {<<"get">>, <<>>, + <<"eu:siacs:conversations:http:upload">>} -> + true; + {<<"request">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"request">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; - {<<"request">>, <<"urn:xmpp:http:upload">>} -> true; {<<"request">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + true; + {<<"request">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> true; - {<<"content-type">>, <<"urn:xmpp:http:upload">>} -> + {<<"content-type">>, <<"urn:xmpp:http:upload">>, _} -> + true; + {<<"content-type">>, <<>>, + <<"urn:xmpp:http:upload">>} -> true; {<<"content-type">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + true; + {<<"content-type">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> true; - {<<"size">>, <<"urn:xmpp:http:upload">>} -> true; - {<<"size">>, + {<<"size">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"size">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; + {<<"size">>, <<"eu:siacs:conversations:http:upload">>, + _} -> + true; + {<<"size">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> true; - {<<"filename">>, <<"urn:xmpp:http:upload">>} -> true; + {<<"filename">>, <<"urn:xmpp:http:upload">>, _} -> true; + {<<"filename">>, <<>>, <<"urn:xmpp:http:upload">>} -> + true; {<<"filename">>, + <<"eu:siacs:conversations:http:upload">>, _} -> + true; + {<<"filename">>, <<>>, <<"eu:siacs:conversations:http:upload">>} -> true; - {<<"address">>, <<"urn:xmpp:sic:0">>} -> true; - {<<"address">>, <<"urn:xmpp:sic:1">>} -> true; - {<<"port">>, <<"urn:xmpp:sic:1">>} -> true; - {<<"ip">>, <<"urn:xmpp:sic:0">>} -> true; - {<<"ip">>, <<"urn:xmpp:sic:1">>} -> true; - {<<"x">>, <<"jabber:x:oob">>} -> true; - {<<"desc">>, <<"jabber:x:oob">>} -> true; - {<<"url">>, <<"jabber:x:oob">>} -> true; - {<<"media">>, <<"urn:xmpp:media-element">>} -> true; - {<<"uri">>, <<"urn:xmpp:media-element">>} -> true; - {<<"captcha">>, <<"urn:xmpp:captcha">>} -> true; - {<<"data">>, <<"urn:xmpp:bob">>} -> true; - {<<"stream:stream">>, <<"jabber:client">>} -> true; - {<<"stream:stream">>, <<"jabber:server">>} -> true; - {<<"stream:stream">>, <<"jabber:component:accept">>} -> - true; - {<<"handshake">>, <<"jabber:client">>} -> true; - {<<"db:verify">>, <<"jabber:client">>} -> true; - {<<"db:result">>, <<"jabber:client">>} -> true; + {<<"address">>, <<"urn:xmpp:sic:0">>, _} -> true; + {<<"address">>, <<>>, <<"urn:xmpp:sic:0">>} -> true; + {<<"address">>, <<"urn:xmpp:sic:1">>, _} -> true; + {<<"address">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; + {<<"port">>, <<"urn:xmpp:sic:1">>, _} -> true; + {<<"port">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; + {<<"ip">>, <<"urn:xmpp:sic:0">>, _} -> true; + {<<"ip">>, <<>>, <<"urn:xmpp:sic:0">>} -> true; + {<<"ip">>, <<"urn:xmpp:sic:1">>, _} -> true; + {<<"ip">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; + {<<"x">>, <<"jabber:x:oob">>, _} -> true; + {<<"x">>, <<>>, <<"jabber:x:oob">>} -> true; + {<<"desc">>, <<"jabber:x:oob">>, _} -> true; + {<<"desc">>, <<>>, <<"jabber:x:oob">>} -> true; + {<<"url">>, <<"jabber:x:oob">>, _} -> true; + {<<"url">>, <<>>, <<"jabber:x:oob">>} -> true; + {<<"media">>, <<"urn:xmpp:media-element">>, _} -> true; + {<<"media">>, <<>>, <<"urn:xmpp:media-element">>} -> + true; + {<<"uri">>, <<"urn:xmpp:media-element">>, _} -> true; + {<<"uri">>, <<>>, <<"urn:xmpp:media-element">>} -> true; + {<<"captcha">>, <<"urn:xmpp:captcha">>, _} -> true; + {<<"captcha">>, <<>>, <<"urn:xmpp:captcha">>} -> true; + {<<"data">>, <<"urn:xmpp:bob">>, _} -> true; + {<<"data">>, <<>>, <<"urn:xmpp:bob">>} -> true; + {<<"stream:stream">>, <<"jabber:client">>, _} -> true; + {<<"stream:stream">>, <<>>, <<"jabber:client">>} -> + true; + {<<"stream:stream">>, <<"jabber:server">>, _} -> true; + {<<"stream:stream">>, <<>>, <<"jabber:server">>} -> + true; + {<<"stream:stream">>, <<"jabber:component:accept">>, + _} -> + true; + {<<"stream:stream">>, <<>>, + <<"jabber:component:accept">>} -> + true; + {<<"handshake">>, <<"jabber:component:accept">>, _} -> + true; + {<<"handshake">>, <<>>, + <<"jabber:component:accept">>} -> + true; + {<<"db:verify">>, <<"jabber:server">>, _} -> true; + {<<"db:verify">>, <<>>, <<"jabber:server">>} -> true; + {<<"db:result">>, <<"jabber:server">>, _} -> true; + {<<"db:result">>, <<>>, <<"jabber:server">>} -> true; {<<"command">>, + <<"http://jabber.org/protocol/commands">>, _} -> + true; + {<<"command">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; - {<<"note">>, + {<<"note">>, <<"http://jabber.org/protocol/commands">>, + _} -> + true; + {<<"note">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; {<<"actions">>, + <<"http://jabber.org/protocol/commands">>, _} -> + true; + {<<"actions">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; {<<"complete">>, + <<"http://jabber.org/protocol/commands">>, _} -> + true; + {<<"complete">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; - {<<"next">>, + {<<"next">>, <<"http://jabber.org/protocol/commands">>, + _} -> + true; + {<<"next">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; - {<<"prev">>, + {<<"prev">>, <<"http://jabber.org/protocol/commands">>, + _} -> + true; + {<<"prev">>, <<>>, <<"http://jabber.org/protocol/commands">>} -> true; - {<<"client-id">>, <<"urn:xmpp:sid:0">>} -> true; - {<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> true; + {<<"client-id">>, <<"urn:xmpp:sid:0">>, _} -> true; + {<<"client-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> true; + {<<"stanza-id">>, <<"urn:xmpp:sid:0">>, _} -> true; + {<<"stanza-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> true; {<<"addresses">>, + <<"http://jabber.org/protocol/address">>, _} -> + true; + {<<"addresses">>, <<>>, <<"http://jabber.org/protocol/address">>} -> true; {<<"address">>, + <<"http://jabber.org/protocol/address">>, _} -> + true; + {<<"address">>, <<>>, <<"http://jabber.org/protocol/address">>} -> true; - {<<"nick">>, <<"http://jabber.org/protocol/nick">>} -> - true; - {<<"x">>, <<"jabber:x:expire">>} -> true; - {<<"x">>, <<"jabber:x:event">>} -> true; - {<<"id">>, <<"jabber:x:event">>} -> true; - {<<"composing">>, <<"jabber:x:event">>} -> true; - {<<"displayed">>, <<"jabber:x:event">>} -> true; - {<<"delivered">>, <<"jabber:x:event">>} -> true; - {<<"offline">>, <<"jabber:x:event">>} -> true; - {<<"query">>, <<"jabber:iq:search">>} -> true; - {<<"item">>, <<"jabber:iq:search">>} -> true; - {<<"email">>, <<"jabber:iq:search">>} -> true; - {<<"nick">>, <<"jabber:iq:search">>} -> true; - {<<"last">>, <<"jabber:iq:search">>} -> true; - {<<"first">>, <<"jabber:iq:search">>} -> true; - {<<"instructions">>, <<"jabber:iq:search">>} -> true; - {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>} -> - true; - {<<"no-permanent-store">>, <<"urn:xmpp:hints">>} -> - true; - {<<"store">>, <<"urn:xmpp:hints">>} -> true; - {<<"no-storage">>, <<"urn:xmpp:hints">>} -> true; - {<<"no-store">>, <<"urn:xmpp:hints">>} -> true; - {<<"no-copy">>, <<"urn:xmpp:hints">>} -> true; - {<<"participant">>, <<"urn:xmpp:mix:0">>} -> true; - {<<"leave">>, <<"urn:xmpp:mix:0">>} -> true; - {<<"join">>, <<"urn:xmpp:mix:0">>} -> true; - {<<"subscribe">>, <<"urn:xmpp:mix:0">>} -> true; + {<<"nick">>, <<"http://jabber.org/protocol/nick">>, + _} -> + true; + {<<"nick">>, <<>>, + <<"http://jabber.org/protocol/nick">>} -> + true; + {<<"x">>, <<"jabber:x:expire">>, _} -> true; + {<<"x">>, <<>>, <<"jabber:x:expire">>} -> true; + {<<"x">>, <<"jabber:x:event">>, _} -> true; + {<<"x">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"id">>, <<"jabber:x:event">>, _} -> true; + {<<"id">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"composing">>, <<"jabber:x:event">>, _} -> true; + {<<"composing">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"displayed">>, <<"jabber:x:event">>, _} -> true; + {<<"displayed">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"delivered">>, <<"jabber:x:event">>, _} -> true; + {<<"delivered">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"offline">>, <<"jabber:x:event">>, _} -> true; + {<<"offline">>, <<>>, <<"jabber:x:event">>} -> true; + {<<"query">>, <<"jabber:iq:search">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"item">>, <<"jabber:iq:search">>, _} -> true; + {<<"item">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"email">>, <<"jabber:iq:search">>, _} -> true; + {<<"email">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"nick">>, <<"jabber:iq:search">>, _} -> true; + {<<"nick">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"last">>, <<"jabber:iq:search">>, _} -> true; + {<<"last">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"first">>, <<"jabber:iq:search">>, _} -> true; + {<<"first">>, <<>>, <<"jabber:iq:search">>} -> true; + {<<"instructions">>, <<"jabber:iq:search">>, _} -> true; + {<<"instructions">>, <<>>, <<"jabber:iq:search">>} -> + true; + {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>, _} -> + true; + {<<"no-permanent-storage">>, <<>>, + <<"urn:xmpp:hints">>} -> + true; + {<<"no-permanent-store">>, <<"urn:xmpp:hints">>, _} -> + true; + {<<"no-permanent-store">>, <<>>, + <<"urn:xmpp:hints">>} -> + true; + {<<"store">>, <<"urn:xmpp:hints">>, _} -> true; + {<<"store">>, <<>>, <<"urn:xmpp:hints">>} -> true; + {<<"no-storage">>, <<"urn:xmpp:hints">>, _} -> true; + {<<"no-storage">>, <<>>, <<"urn:xmpp:hints">>} -> true; + {<<"no-store">>, <<"urn:xmpp:hints">>, _} -> true; + {<<"no-store">>, <<>>, <<"urn:xmpp:hints">>} -> true; + {<<"no-copy">>, <<"urn:xmpp:hints">>, _} -> true; + {<<"no-copy">>, <<>>, <<"urn:xmpp:hints">>} -> true; + {<<"participant">>, <<"urn:xmpp:mix:0">>, _} -> true; + {<<"participant">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; + {<<"leave">>, <<"urn:xmpp:mix:0">>, _} -> true; + {<<"leave">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; + {<<"join">>, <<"urn:xmpp:mix:0">>, _} -> true; + {<<"join">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; + {<<"subscribe">>, <<"urn:xmpp:mix:0">>, _} -> true; + {<<"subscribe">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; {<<"offline">>, + <<"http://jabber.org/protocol/offline">>, _} -> + true; + {<<"offline">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> true; - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/offline">>, + _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> true; - {<<"fetch">>, + {<<"fetch">>, <<"http://jabber.org/protocol/offline">>, + _} -> + true; + {<<"fetch">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> true; - {<<"purge">>, + {<<"purge">>, <<"http://jabber.org/protocol/offline">>, + _} -> + true; + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/offline">>} -> true; - {<<"failed">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"failed">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"a">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"a">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"r">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"r">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"resumed">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"resumed">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"resume">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"resume">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"enabled">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"enabled">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"enable">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"enable">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"sm">>, <<"urn:xmpp:sm:2">>} -> true; - {<<"sm">>, <<"urn:xmpp:sm:3">>} -> true; - {<<"inactive">>, <<"urn:xmpp:csi:0">>} -> true; - {<<"active">>, <<"urn:xmpp:csi:0">>} -> true; - {<<"csi">>, <<"urn:xmpp:csi:0">>} -> true; - {<<"sent">>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"received">>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"private">>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"enable">>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"disable">>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"forwarded">>, <<"urn:xmpp:forward:0">>} -> true; - {<<"fin">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"fin">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"archived">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:0">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:1">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"withtext">>, <<"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; - {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"event">>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"subscription">>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"x">>, <<"jabber:x:conference">>} -> true; + {<<"failed">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"failed">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"failed">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"failed">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"a">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"a">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"a">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"a">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"r">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"r">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"r">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"r">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"resumed">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"resumed">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"resumed">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"resumed">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"resume">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"resume">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"resume">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"resume">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"enabled">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"enabled">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"enabled">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"enabled">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"enable">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"enable">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"enable">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"enable">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"sm">>, <<"urn:xmpp:sm:2">>, _} -> true; + {<<"sm">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; + {<<"sm">>, <<"urn:xmpp:sm:3">>, _} -> true; + {<<"sm">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; + {<<"inactive">>, <<"urn:xmpp:csi:0">>, _} -> true; + {<<"inactive">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; + {<<"active">>, <<"urn:xmpp:csi:0">>, _} -> true; + {<<"active">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; + {<<"csi">>, <<"urn:xmpp:csi:0">>, _} -> true; + {<<"csi">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; + {<<"sent">>, <<"urn:xmpp:carbons:2">>, _} -> true; + {<<"sent">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"received">>, <<"urn:xmpp:carbons:2">>, _} -> true; + {<<"received">>, <<>>, <<"urn:xmpp:carbons:2">>} -> + true; + {<<"private">>, <<"urn:xmpp:carbons:2">>, _} -> true; + {<<"private">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"enable">>, <<"urn:xmpp:carbons:2">>, _} -> true; + {<<"enable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"disable">>, <<"urn:xmpp:carbons:2">>, _} -> true; + {<<"disable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; + {<<"forwarded">>, <<"urn:xmpp:forward:0">>, _} -> true; + {<<"forwarded">>, <<>>, <<"urn:xmpp:forward:0">>} -> + true; + {<<"fin">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"fin">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"fin">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"fin">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"prefs">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"prefs">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"prefs">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"prefs">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"always">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"always">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"always">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"always">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"always">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"always">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"never">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"never">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"never">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"never">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"never">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"never">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"jid">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"jid">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"jid">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"jid">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"jid">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"jid">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"result">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"result">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"result">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"result">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"result">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"result">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"archived">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"archived">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"query">>, <<"urn:xmpp:mam:0">>, _} -> true; + {<<"query">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; + {<<"query">>, <<"urn:xmpp:mam:1">>, _} -> true; + {<<"query">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; + {<<"query">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"query">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"withtext">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"withtext">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"with">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"with">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"end">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"end">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"start">>, <<"urn:xmpp:mam:tmp">>, _} -> true; + {<<"start">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; + {<<"set">>, <<"http://jabber.org/protocol/rsm">>, _} -> + true; + {<<"set">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"first">>, <<"http://jabber.org/protocol/rsm">>, + _} -> + true; + {<<"first">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"max">>, <<"http://jabber.org/protocol/rsm">>, _} -> + true; + {<<"max">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"index">>, <<"http://jabber.org/protocol/rsm">>, + _} -> + true; + {<<"index">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"count">>, <<"http://jabber.org/protocol/rsm">>, + _} -> + true; + {<<"count">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"last">>, <<"http://jabber.org/protocol/rsm">>, _} -> + true; + {<<"last">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"before">>, <<"http://jabber.org/protocol/rsm">>, + _} -> + true; + {<<"before">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"after">>, <<"http://jabber.org/protocol/rsm">>, + _} -> + true; + {<<"after">>, <<>>, + <<"http://jabber.org/protocol/rsm">>} -> + true; + {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> true; + {<<"unsubscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + true; + {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> true; + {<<"subscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + true; + {<<"event">>, <<"urn:xmpp:mucsub:0">>, _} -> true; + {<<"event">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> true; + {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>, _} -> + true; + {<<"subscriptions">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + true; + {<<"subscription">>, <<"urn:xmpp:mucsub:0">>, _} -> + true; + {<<"subscription">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> + true; + {<<"x">>, <<"jabber:x:conference">>, _} -> true; + {<<"x">>, <<>>, <<"jabber:x:conference">>} -> true; {<<"unique">>, + <<"http://jabber.org/protocol/muc#unique">>, _} -> + true; + {<<"unique">>, <<>>, <<"http://jabber.org/protocol/muc#unique">>} -> true; - {<<"x">>, <<"http://jabber.org/protocol/muc">>} -> true; + {<<"x">>, <<"http://jabber.org/protocol/muc">>, _} -> + true; + {<<"x">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> + true; {<<"query">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + true; + {<<"query">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> true; {<<"continue">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + true; + {<<"continue">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> true; {<<"actor">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + true; + {<<"actor">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> true; - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/muc#admin">>, + _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> true; - {<<"item">>, + {<<"item">>, <<"http://jabber.org/protocol/muc#owner">>, + _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> true; {<<"query">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + true; + {<<"query">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> true; {<<"password">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + true; + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> true; {<<"password">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; - {<<"password">>, + {<<"password">>, <<"http://jabber.org/protocol/muc">>, + _} -> + true; + {<<"password">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> true; - {<<"x">>, <<"http://jabber.org/protocol/muc#user">>} -> + {<<"x">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> true; - {<<"item">>, + {<<"x">>, <<>>, + <<"http://jabber.org/protocol/muc#user">>} -> + true; + {<<"item">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"status">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"status">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"continue">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"continue">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; - {<<"actor">>, + {<<"actor">>, <<"http://jabber.org/protocol/muc#user">>, + _} -> + true; + {<<"actor">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"invite">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"invite">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"destroy">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"destroy">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"destroy">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + true; + {<<"destroy">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> true; {<<"decline">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"decline">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"reason">>, + <<"http://jabber.org/protocol/muc#user">>, _} -> + true; + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#user">>} -> true; {<<"reason">>, + <<"http://jabber.org/protocol/muc#admin">>, _} -> + true; + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#admin">>} -> true; {<<"reason">>, + <<"http://jabber.org/protocol/muc#owner">>, _} -> + true; + {<<"reason">>, <<>>, <<"http://jabber.org/protocol/muc#owner">>} -> true; - {<<"history">>, <<"http://jabber.org/protocol/muc">>} -> + {<<"history">>, <<"http://jabber.org/protocol/muc">>, + _} -> + true; + {<<"history">>, <<>>, + <<"http://jabber.org/protocol/muc">>} -> true; {<<"query">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + true; + {<<"query">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> true; {<<"activate">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + true; + {<<"activate">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> true; {<<"streamhost-used">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + true; + {<<"streamhost-used">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> true; {<<"streamhost">>, + <<"http://jabber.org/protocol/bytestreams">>, _} -> + true; + {<<"streamhost">>, <<>>, <<"http://jabber.org/protocol/bytestreams">>} -> true; - {<<"delay">>, <<"urn:xmpp:delay">>} -> true; + {<<"delay">>, <<"urn:xmpp:delay">>, _} -> true; + {<<"delay">>, <<>>, <<"urn:xmpp:delay">>} -> true; {<<"paused">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + true; + {<<"paused">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> true; {<<"inactive">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + true; + {<<"inactive">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> true; {<<"gone">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + true; + {<<"gone">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> true; {<<"composing">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + true; + {<<"composing">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> true; {<<"active">>, + <<"http://jabber.org/protocol/chatstates">>, _} -> + true; + {<<"active">>, <<>>, <<"http://jabber.org/protocol/chatstates">>} -> true; - {<<"headers">>, + {<<"headers">>, <<"http://jabber.org/protocol/shim">>, + _} -> + true; + {<<"headers">>, <<>>, <<"http://jabber.org/protocol/shim">>} -> true; - {<<"header">>, <<"http://jabber.org/protocol/shim">>} -> + {<<"header">>, <<"http://jabber.org/protocol/shim">>, + _} -> + true; + {<<"header">>, <<>>, + <<"http://jabber.org/protocol/shim">>} -> true; {<<"unsupported-access-model">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"unsupported-access-model">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"unsupported">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"unsupported">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"too-many-subscriptions">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"too-many-subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"subid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"subid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"presence-subscription-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"presence-subscription-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"pending-subscription">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"pending-subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"payload-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"payload-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"payload-too-big">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"payload-too-big">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"not-subscribed">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"not-subscribed">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"not-in-roster-group">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"not-in-roster-group">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"nodeid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"nodeid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"max-nodes-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"max-nodes-exceeded">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"max-items-exceeded">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"max-items-exceeded">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"jid-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"jid-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"item-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"item-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"item-forbidden">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"item-forbidden">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"invalid-subid">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"invalid-subid">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"invalid-payload">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"invalid-payload">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"invalid-options">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"invalid-options">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"invalid-jid">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"invalid-jid">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"configuration-required">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"configuration-required">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"closed-node">>, + <<"http://jabber.org/protocol/pubsub#errors">>, _} -> + true; + {<<"closed-node">>, <<>>, <<"http://jabber.org/protocol/pubsub#errors">>} -> true; {<<"pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"pubsub">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; - {<<"pubsub">>, + {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"pubsub">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; - {<<"purge">>, + {<<"purge">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"purge">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"purge">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"delete">>, + {<<"delete">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"delete">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"delete">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"redirect">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"redirect">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"default">>, + {<<"default">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"default">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"default">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"default">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"publish-options">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"publish-options">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"configure">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"configure">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"configure">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"configure">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; - {<<"create">>, + {<<"create">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"create">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"create">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"create">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"retract">>, + {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"retract">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; - {<<"options">>, + {<<"options">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"options">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; - {<<"publish">>, + {<<"publish">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"publish">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"unsubscribe">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"unsubscribe">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscribe">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"subscribe">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"affiliations">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"affiliations">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"affiliations">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscriptions">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"subscriptions">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"event">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"event">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"items">>, + {<<"items">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"items">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"items">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"items">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>} -> + {<<"item">>, <<"http://jabber.org/protocol/pubsub">>, + _} -> + true; + {<<"item">>, <<>>, + <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"item">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; {<<"retract">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"retract">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; {<<"configuration">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"configuration">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"affiliation">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"affiliation">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"affiliation">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub">>, _} -> + true; + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub">>} -> true; {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#owner">>, _} -> + true; + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#owner">>} -> true; {<<"subscription">>, + <<"http://jabber.org/protocol/pubsub#event">>, _} -> + true; + {<<"subscription">>, <<>>, <<"http://jabber.org/protocol/pubsub#event">>} -> true; - {<<"x">>, <<"jabber:x:data">>} -> true; - {<<"item">>, <<"jabber:x:data">>} -> true; - {<<"reported">>, <<"jabber:x:data">>} -> true; - {<<"title">>, <<"jabber:x:data">>} -> true; - {<<"instructions">>, <<"jabber:x:data">>} -> true; - {<<"field">>, <<"jabber:x:data">>} -> true; - {<<"option">>, <<"jabber:x:data">>} -> true; - {<<"value">>, <<"jabber:x:data">>} -> true; - {<<"desc">>, <<"jabber:x:data">>} -> true; - {<<"required">>, <<"jabber:x:data">>} -> true; - {<<"x">>, <<"vcard-temp:x:update">>} -> true; - {<<"photo">>, <<"vcard-temp:x:update">>} -> true; - {<<"vCard">>, <<"vcard-temp">>} -> true; - {<<"CLASS">>, <<"vcard-temp">>} -> true; - {<<"CATEGORIES">>, <<"vcard-temp">>} -> true; - {<<"KEY">>, <<"vcard-temp">>} -> true; - {<<"SOUND">>, <<"vcard-temp">>} -> true; - {<<"ORG">>, <<"vcard-temp">>} -> true; - {<<"PHOTO">>, <<"vcard-temp">>} -> true; - {<<"LOGO">>, <<"vcard-temp">>} -> true; - {<<"BINVAL">>, <<"vcard-temp">>} -> true; - {<<"GEO">>, <<"vcard-temp">>} -> true; - {<<"EMAIL">>, <<"vcard-temp">>} -> true; - {<<"TEL">>, <<"vcard-temp">>} -> true; - {<<"LABEL">>, <<"vcard-temp">>} -> true; - {<<"ADR">>, <<"vcard-temp">>} -> true; - {<<"N">>, <<"vcard-temp">>} -> true; - {<<"CONFIDENTIAL">>, <<"vcard-temp">>} -> true; - {<<"PRIVATE">>, <<"vcard-temp">>} -> true; - {<<"PUBLIC">>, <<"vcard-temp">>} -> true; - {<<"EXTVAL">>, <<"vcard-temp">>} -> true; - {<<"TYPE">>, <<"vcard-temp">>} -> true; - {<<"DESC">>, <<"vcard-temp">>} -> true; - {<<"URL">>, <<"vcard-temp">>} -> true; - {<<"UID">>, <<"vcard-temp">>} -> true; - {<<"SORT-STRING">>, <<"vcard-temp">>} -> true; - {<<"REV">>, <<"vcard-temp">>} -> true; - {<<"PRODID">>, <<"vcard-temp">>} -> true; - {<<"NOTE">>, <<"vcard-temp">>} -> true; - {<<"KEYWORD">>, <<"vcard-temp">>} -> true; - {<<"ROLE">>, <<"vcard-temp">>} -> true; - {<<"TITLE">>, <<"vcard-temp">>} -> true; - {<<"TZ">>, <<"vcard-temp">>} -> true; - {<<"MAILER">>, <<"vcard-temp">>} -> true; - {<<"JABBERID">>, <<"vcard-temp">>} -> true; - {<<"BDAY">>, <<"vcard-temp">>} -> true; - {<<"NICKNAME">>, <<"vcard-temp">>} -> true; - {<<"FN">>, <<"vcard-temp">>} -> true; - {<<"VERSION">>, <<"vcard-temp">>} -> true; - {<<"CRED">>, <<"vcard-temp">>} -> true; - {<<"PHONETIC">>, <<"vcard-temp">>} -> true; - {<<"ORGUNIT">>, <<"vcard-temp">>} -> true; - {<<"ORGNAME">>, <<"vcard-temp">>} -> true; - {<<"LON">>, <<"vcard-temp">>} -> true; - {<<"LAT">>, <<"vcard-temp">>} -> true; - {<<"USERID">>, <<"vcard-temp">>} -> true; - {<<"NUMBER">>, <<"vcard-temp">>} -> true; - {<<"LINE">>, <<"vcard-temp">>} -> true; - {<<"CTRY">>, <<"vcard-temp">>} -> true; - {<<"PCODE">>, <<"vcard-temp">>} -> true; - {<<"REGION">>, <<"vcard-temp">>} -> true; - {<<"LOCALITY">>, <<"vcard-temp">>} -> true; - {<<"STREET">>, <<"vcard-temp">>} -> true; - {<<"EXTADD">>, <<"vcard-temp">>} -> true; - {<<"POBOX">>, <<"vcard-temp">>} -> true; - {<<"SUFFIX">>, <<"vcard-temp">>} -> true; - {<<"PREFIX">>, <<"vcard-temp">>} -> true; - {<<"MIDDLE">>, <<"vcard-temp">>} -> true; - {<<"GIVEN">>, <<"vcard-temp">>} -> true; - {<<"FAMILY">>, <<"vcard-temp">>} -> true; - {<<"X400">>, <<"vcard-temp">>} -> true; - {<<"INTERNET">>, <<"vcard-temp">>} -> true; - {<<"PREF">>, <<"vcard-temp">>} -> true; - {<<"INTL">>, <<"vcard-temp">>} -> true; - {<<"DOM">>, <<"vcard-temp">>} -> true; - {<<"PARCEL">>, <<"vcard-temp">>} -> true; - {<<"POSTAL">>, <<"vcard-temp">>} -> true; - {<<"PCS">>, <<"vcard-temp">>} -> true; - {<<"ISDN">>, <<"vcard-temp">>} -> true; - {<<"MODEM">>, <<"vcard-temp">>} -> true; - {<<"BBS">>, <<"vcard-temp">>} -> true; - {<<"VIDEO">>, <<"vcard-temp">>} -> true; - {<<"CELL">>, <<"vcard-temp">>} -> true; - {<<"MSG">>, <<"vcard-temp">>} -> true; - {<<"PAGER">>, <<"vcard-temp">>} -> true; - {<<"FAX">>, <<"vcard-temp">>} -> true; - {<<"VOICE">>, <<"vcard-temp">>} -> true; - {<<"WORK">>, <<"vcard-temp">>} -> true; - {<<"HOME">>, <<"vcard-temp">>} -> true; - {<<"stream:error">>, - <<"http://etherx.jabber.org/streams">>} -> + {<<"x">>, <<"jabber:x:data">>, _} -> true; + {<<"x">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"item">>, <<"jabber:x:data">>, _} -> true; + {<<"item">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"reported">>, <<"jabber:x:data">>, _} -> true; + {<<"reported">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"title">>, <<"jabber:x:data">>, _} -> true; + {<<"title">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"instructions">>, <<"jabber:x:data">>, _} -> true; + {<<"instructions">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"field">>, <<"jabber:x:data">>, _} -> true; + {<<"field">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"option">>, <<"jabber:x:data">>, _} -> true; + {<<"option">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"value">>, <<"jabber:x:data">>, _} -> true; + {<<"value">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"desc">>, <<"jabber:x:data">>, _} -> true; + {<<"desc">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"required">>, <<"jabber:x:data">>, _} -> true; + {<<"required">>, <<>>, <<"jabber:x:data">>} -> true; + {<<"x">>, <<"vcard-temp:x:update">>, _} -> true; + {<<"x">>, <<>>, <<"vcard-temp:x:update">>} -> true; + {<<"photo">>, <<"vcard-temp:x:update">>, _} -> true; + {<<"photo">>, <<>>, <<"vcard-temp:x:update">>} -> true; + {<<"vCard">>, <<"vcard-temp">>, _} -> true; + {<<"vCard">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CLASS">>, <<"vcard-temp">>, _} -> true; + {<<"CLASS">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CATEGORIES">>, <<"vcard-temp">>, _} -> true; + {<<"CATEGORIES">>, <<>>, <<"vcard-temp">>} -> true; + {<<"KEY">>, <<"vcard-temp">>, _} -> true; + {<<"KEY">>, <<>>, <<"vcard-temp">>} -> true; + {<<"SOUND">>, <<"vcard-temp">>, _} -> true; + {<<"SOUND">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ORG">>, <<"vcard-temp">>, _} -> true; + {<<"ORG">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PHOTO">>, <<"vcard-temp">>, _} -> true; + {<<"PHOTO">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LOGO">>, <<"vcard-temp">>, _} -> true; + {<<"LOGO">>, <<>>, <<"vcard-temp">>} -> true; + {<<"BINVAL">>, <<"vcard-temp">>, _} -> true; + {<<"BINVAL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"GEO">>, <<"vcard-temp">>, _} -> true; + {<<"GEO">>, <<>>, <<"vcard-temp">>} -> true; + {<<"EMAIL">>, <<"vcard-temp">>, _} -> true; + {<<"EMAIL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"TEL">>, <<"vcard-temp">>, _} -> true; + {<<"TEL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LABEL">>, <<"vcard-temp">>, _} -> true; + {<<"LABEL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ADR">>, <<"vcard-temp">>, _} -> true; + {<<"ADR">>, <<>>, <<"vcard-temp">>} -> true; + {<<"N">>, <<"vcard-temp">>, _} -> true; + {<<"N">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CONFIDENTIAL">>, <<"vcard-temp">>, _} -> true; + {<<"CONFIDENTIAL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PRIVATE">>, <<"vcard-temp">>, _} -> true; + {<<"PRIVATE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PUBLIC">>, <<"vcard-temp">>, _} -> true; + {<<"PUBLIC">>, <<>>, <<"vcard-temp">>} -> true; + {<<"EXTVAL">>, <<"vcard-temp">>, _} -> true; + {<<"EXTVAL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"TYPE">>, <<"vcard-temp">>, _} -> true; + {<<"TYPE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"DESC">>, <<"vcard-temp">>, _} -> true; + {<<"DESC">>, <<>>, <<"vcard-temp">>} -> true; + {<<"URL">>, <<"vcard-temp">>, _} -> true; + {<<"URL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"UID">>, <<"vcard-temp">>, _} -> true; + {<<"UID">>, <<>>, <<"vcard-temp">>} -> true; + {<<"SORT-STRING">>, <<"vcard-temp">>, _} -> true; + {<<"SORT-STRING">>, <<>>, <<"vcard-temp">>} -> true; + {<<"REV">>, <<"vcard-temp">>, _} -> true; + {<<"REV">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PRODID">>, <<"vcard-temp">>, _} -> true; + {<<"PRODID">>, <<>>, <<"vcard-temp">>} -> true; + {<<"NOTE">>, <<"vcard-temp">>, _} -> true; + {<<"NOTE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"KEYWORD">>, <<"vcard-temp">>, _} -> true; + {<<"KEYWORD">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ROLE">>, <<"vcard-temp">>, _} -> true; + {<<"ROLE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"TITLE">>, <<"vcard-temp">>, _} -> true; + {<<"TITLE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"TZ">>, <<"vcard-temp">>, _} -> true; + {<<"TZ">>, <<>>, <<"vcard-temp">>} -> true; + {<<"MAILER">>, <<"vcard-temp">>, _} -> true; + {<<"MAILER">>, <<>>, <<"vcard-temp">>} -> true; + {<<"JABBERID">>, <<"vcard-temp">>, _} -> true; + {<<"JABBERID">>, <<>>, <<"vcard-temp">>} -> true; + {<<"BDAY">>, <<"vcard-temp">>, _} -> true; + {<<"BDAY">>, <<>>, <<"vcard-temp">>} -> true; + {<<"NICKNAME">>, <<"vcard-temp">>, _} -> true; + {<<"NICKNAME">>, <<>>, <<"vcard-temp">>} -> true; + {<<"FN">>, <<"vcard-temp">>, _} -> true; + {<<"FN">>, <<>>, <<"vcard-temp">>} -> true; + {<<"VERSION">>, <<"vcard-temp">>, _} -> true; + {<<"VERSION">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CRED">>, <<"vcard-temp">>, _} -> true; + {<<"CRED">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PHONETIC">>, <<"vcard-temp">>, _} -> true; + {<<"PHONETIC">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ORGUNIT">>, <<"vcard-temp">>, _} -> true; + {<<"ORGUNIT">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ORGNAME">>, <<"vcard-temp">>, _} -> true; + {<<"ORGNAME">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LON">>, <<"vcard-temp">>, _} -> true; + {<<"LON">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LAT">>, <<"vcard-temp">>, _} -> true; + {<<"LAT">>, <<>>, <<"vcard-temp">>} -> true; + {<<"USERID">>, <<"vcard-temp">>, _} -> true; + {<<"USERID">>, <<>>, <<"vcard-temp">>} -> true; + {<<"NUMBER">>, <<"vcard-temp">>, _} -> true; + {<<"NUMBER">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LINE">>, <<"vcard-temp">>, _} -> true; + {<<"LINE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CTRY">>, <<"vcard-temp">>, _} -> true; + {<<"CTRY">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PCODE">>, <<"vcard-temp">>, _} -> true; + {<<"PCODE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"REGION">>, <<"vcard-temp">>, _} -> true; + {<<"REGION">>, <<>>, <<"vcard-temp">>} -> true; + {<<"LOCALITY">>, <<"vcard-temp">>, _} -> true; + {<<"LOCALITY">>, <<>>, <<"vcard-temp">>} -> true; + {<<"STREET">>, <<"vcard-temp">>, _} -> true; + {<<"STREET">>, <<>>, <<"vcard-temp">>} -> true; + {<<"EXTADD">>, <<"vcard-temp">>, _} -> true; + {<<"EXTADD">>, <<>>, <<"vcard-temp">>} -> true; + {<<"POBOX">>, <<"vcard-temp">>, _} -> true; + {<<"POBOX">>, <<>>, <<"vcard-temp">>} -> true; + {<<"SUFFIX">>, <<"vcard-temp">>, _} -> true; + {<<"SUFFIX">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PREFIX">>, <<"vcard-temp">>, _} -> true; + {<<"PREFIX">>, <<>>, <<"vcard-temp">>} -> true; + {<<"MIDDLE">>, <<"vcard-temp">>, _} -> true; + {<<"MIDDLE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"GIVEN">>, <<"vcard-temp">>, _} -> true; + {<<"GIVEN">>, <<>>, <<"vcard-temp">>} -> true; + {<<"FAMILY">>, <<"vcard-temp">>, _} -> true; + {<<"FAMILY">>, <<>>, <<"vcard-temp">>} -> true; + {<<"X400">>, <<"vcard-temp">>, _} -> true; + {<<"X400">>, <<>>, <<"vcard-temp">>} -> true; + {<<"INTERNET">>, <<"vcard-temp">>, _} -> true; + {<<"INTERNET">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PREF">>, <<"vcard-temp">>, _} -> true; + {<<"PREF">>, <<>>, <<"vcard-temp">>} -> true; + {<<"INTL">>, <<"vcard-temp">>, _} -> true; + {<<"INTL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"DOM">>, <<"vcard-temp">>, _} -> true; + {<<"DOM">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PARCEL">>, <<"vcard-temp">>, _} -> true; + {<<"PARCEL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"POSTAL">>, <<"vcard-temp">>, _} -> true; + {<<"POSTAL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PCS">>, <<"vcard-temp">>, _} -> true; + {<<"PCS">>, <<>>, <<"vcard-temp">>} -> true; + {<<"ISDN">>, <<"vcard-temp">>, _} -> true; + {<<"ISDN">>, <<>>, <<"vcard-temp">>} -> true; + {<<"MODEM">>, <<"vcard-temp">>, _} -> true; + {<<"MODEM">>, <<>>, <<"vcard-temp">>} -> true; + {<<"BBS">>, <<"vcard-temp">>, _} -> true; + {<<"BBS">>, <<>>, <<"vcard-temp">>} -> true; + {<<"VIDEO">>, <<"vcard-temp">>, _} -> true; + {<<"VIDEO">>, <<>>, <<"vcard-temp">>} -> true; + {<<"CELL">>, <<"vcard-temp">>, _} -> true; + {<<"CELL">>, <<>>, <<"vcard-temp">>} -> true; + {<<"MSG">>, <<"vcard-temp">>, _} -> true; + {<<"MSG">>, <<>>, <<"vcard-temp">>} -> true; + {<<"PAGER">>, <<"vcard-temp">>, _} -> true; + {<<"PAGER">>, <<>>, <<"vcard-temp">>} -> true; + {<<"FAX">>, <<"vcard-temp">>, _} -> true; + {<<"FAX">>, <<>>, <<"vcard-temp">>} -> true; + {<<"VOICE">>, <<"vcard-temp">>, _} -> true; + {<<"VOICE">>, <<>>, <<"vcard-temp">>} -> true; + {<<"WORK">>, <<"vcard-temp">>, _} -> true; + {<<"WORK">>, <<>>, <<"vcard-temp">>} -> true; + {<<"HOME">>, <<"vcard-temp">>, _} -> true; + {<<"HOME">>, <<>>, <<"vcard-temp">>} -> true; + {<<"stream:error">>, <<"jabber:client">>, _} -> true; + {<<"stream:error">>, <<>>, <<"jabber:client">>} -> true; + {<<"stream:error">>, <<"jabber:server">>, _} -> true; + {<<"stream:error">>, <<>>, <<"jabber:server">>} -> true; + {<<"stream:error">>, <<"jabber:component:accept">>, + _} -> + true; + {<<"stream:error">>, <<>>, + <<"jabber:component:accept">>} -> true; {<<"unsupported-version">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"unsupported-version">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"unsupported-stanza-type">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"unsupported-stanza-type">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"unsupported-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"unsupported-encoding">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"undefined-condition">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"system-shutdown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"system-shutdown">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"see-other-host">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"see-other-host">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"restricted-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"restricted-xml">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"resource-constraint">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; - {<<"reset">>, + {<<"reset">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, + _} -> + true; + {<<"reset">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"remote-connection-failed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"remote-connection-failed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"policy-violation">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"not-well-formed">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"not-well-formed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"invalid-xml">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"invalid-xml">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"invalid-namespace">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"invalid-namespace">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"invalid-id">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"invalid-id">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"invalid-from">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"invalid-from">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"internal-server-error">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"improper-addressing">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"improper-addressing">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"host-unknown">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"host-unknown">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"host-gone">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"host-gone">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"connection-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"connection-timeout">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"conflict">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"bad-namespace-prefix">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"bad-namespace-prefix">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; {<<"bad-format">>, + <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> + true; + {<<"bad-format">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; - {<<"text">>, + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, + _} -> + true; + {<<"text">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> true; - {<<"time">>, <<"urn:xmpp:time">>} -> true; - {<<"tzo">>, <<"urn:xmpp:time">>} -> true; - {<<"utc">>, <<"urn:xmpp:time">>} -> true; - {<<"ping">>, <<"urn:xmpp:ping">>} -> true; + {<<"time">>, <<"urn:xmpp:time">>, _} -> true; + {<<"time">>, <<>>, <<"urn:xmpp:time">>} -> true; + {<<"tzo">>, <<"urn:xmpp:time">>, _} -> true; + {<<"tzo">>, <<>>, <<"urn:xmpp:time">>} -> true; + {<<"utc">>, <<"urn:xmpp:time">>, _} -> true; + {<<"utc">>, <<>>, <<"urn:xmpp:time">>} -> true; + {<<"ping">>, <<"urn:xmpp:ping">>, _} -> true; + {<<"ping">>, <<>>, <<"urn:xmpp:ping">>} -> true; {<<"session">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> + true; + {<<"session">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-session">>} -> true; {<<"optional">>, + <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> + true; + {<<"optional">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-session">>} -> true; - {<<"query">>, <<"jabber:iq:register">>} -> true; - {<<"key">>, <<"jabber:iq:register">>} -> true; - {<<"text">>, <<"jabber:iq:register">>} -> true; - {<<"misc">>, <<"jabber:iq:register">>} -> true; - {<<"date">>, <<"jabber:iq:register">>} -> true; - {<<"url">>, <<"jabber:iq:register">>} -> true; - {<<"phone">>, <<"jabber:iq:register">>} -> true; - {<<"zip">>, <<"jabber:iq:register">>} -> true; - {<<"state">>, <<"jabber:iq:register">>} -> true; - {<<"city">>, <<"jabber:iq:register">>} -> true; - {<<"address">>, <<"jabber:iq:register">>} -> true; - {<<"email">>, <<"jabber:iq:register">>} -> true; - {<<"last">>, <<"jabber:iq:register">>} -> true; - {<<"first">>, <<"jabber:iq:register">>} -> true; - {<<"name">>, <<"jabber:iq:register">>} -> true; - {<<"password">>, <<"jabber:iq:register">>} -> true; - {<<"nick">>, <<"jabber:iq:register">>} -> true; - {<<"username">>, <<"jabber:iq:register">>} -> true; - {<<"instructions">>, <<"jabber:iq:register">>} -> true; - {<<"remove">>, <<"jabber:iq:register">>} -> true; - {<<"registered">>, <<"jabber:iq:register">>} -> true; + {<<"query">>, <<"jabber:iq:register">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"key">>, <<"jabber:iq:register">>, _} -> true; + {<<"key">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"text">>, <<"jabber:iq:register">>, _} -> true; + {<<"text">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"misc">>, <<"jabber:iq:register">>, _} -> true; + {<<"misc">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"date">>, <<"jabber:iq:register">>, _} -> true; + {<<"date">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"url">>, <<"jabber:iq:register">>, _} -> true; + {<<"url">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"phone">>, <<"jabber:iq:register">>, _} -> true; + {<<"phone">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"zip">>, <<"jabber:iq:register">>, _} -> true; + {<<"zip">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"state">>, <<"jabber:iq:register">>, _} -> true; + {<<"state">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"city">>, <<"jabber:iq:register">>, _} -> true; + {<<"city">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"address">>, <<"jabber:iq:register">>, _} -> true; + {<<"address">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"email">>, <<"jabber:iq:register">>, _} -> true; + {<<"email">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"last">>, <<"jabber:iq:register">>, _} -> true; + {<<"last">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"first">>, <<"jabber:iq:register">>, _} -> true; + {<<"first">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"name">>, <<"jabber:iq:register">>, _} -> true; + {<<"name">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"password">>, <<"jabber:iq:register">>, _} -> true; + {<<"password">>, <<>>, <<"jabber:iq:register">>} -> + true; + {<<"nick">>, <<"jabber:iq:register">>, _} -> true; + {<<"nick">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"username">>, <<"jabber:iq:register">>, _} -> true; + {<<"username">>, <<>>, <<"jabber:iq:register">>} -> + true; + {<<"instructions">>, <<"jabber:iq:register">>, _} -> + true; + {<<"instructions">>, <<>>, <<"jabber:iq:register">>} -> + true; + {<<"remove">>, <<"jabber:iq:register">>, _} -> true; + {<<"remove">>, <<>>, <<"jabber:iq:register">>} -> true; + {<<"registered">>, <<"jabber:iq:register">>, _} -> true; + {<<"registered">>, <<>>, <<"jabber:iq:register">>} -> + true; {<<"register">>, + <<"http://jabber.org/features/iq-register">>, _} -> + true; + {<<"register">>, <<>>, <<"http://jabber.org/features/iq-register">>} -> true; - {<<"c">>, <<"http://jabber.org/protocol/caps">>} -> + {<<"c">>, <<"http://jabber.org/protocol/caps">>, _} -> true; - {<<"ack">>, <<"p1:ack">>} -> true; - {<<"rebind">>, <<"p1:rebind">>} -> true; - {<<"push">>, <<"p1:push">>} -> true; - {<<"stream:features">>, - <<"http://etherx.jabber.org/streams">>} -> + {<<"c">>, <<>>, + <<"http://jabber.org/protocol/caps">>} -> + true; + {<<"ack">>, <<"p1:ack">>, _} -> true; + {<<"ack">>, <<>>, <<"p1:ack">>} -> true; + {<<"rebind">>, <<"p1:rebind">>, _} -> true; + {<<"rebind">>, <<>>, <<"p1:rebind">>} -> true; + {<<"push">>, <<"p1:push">>, _} -> true; + {<<"push">>, <<>>, <<"p1:push">>} -> true; + {<<"stream:features">>, <<"jabber:client">>, _} -> true; + {<<"stream:features">>, <<>>, <<"jabber:client">>} -> + true; + {<<"stream:features">>, <<"jabber:server">>, _} -> true; + {<<"stream:features">>, <<>>, <<"jabber:server">>} -> true; {<<"compression">>, + <<"http://jabber.org/features/compress">>, _} -> + true; + {<<"compression">>, <<>>, <<"http://jabber.org/features/compress">>} -> true; {<<"method">>, + <<"http://jabber.org/features/compress">>, _} -> + true; + {<<"method">>, <<>>, <<"http://jabber.org/features/compress">>} -> true; {<<"compressed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"compressed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"compress">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"compress">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"method">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"method">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"failure">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"failure">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"unsupported-method">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"unsupported-method">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"processing-failed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"processing-failed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; {<<"setup-failed">>, + <<"http://jabber.org/protocol/compress">>, _} -> + true; + {<<"setup-failed">>, <<>>, <<"http://jabber.org/protocol/compress">>} -> true; - {<<"failure">>, + {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + true; + {<<"failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> true; - {<<"proceed">>, + {<<"proceed">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + true; + {<<"proceed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> true; - {<<"starttls">>, + {<<"starttls">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + true; + {<<"starttls">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> true; - {<<"required">>, + {<<"required">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, + _} -> + true; + {<<"required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> true; {<<"mechanisms">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"mechanisms">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"mechanism">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; - {<<"failure">>, + {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"temporary-auth-failure">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"temporary-auth-failure">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"bad-protocol">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"bad-protocol">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"mechanism-too-weak">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"mechanism-too-weak">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"malformed-request">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"malformed-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"invalid-mechanism">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"invalid-mechanism">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"invalid-authzid">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"invalid-authzid">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"incorrect-encoding">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"incorrect-encoding">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"encryption-required">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"encryption-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"credentials-expired">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"credentials-expired">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"account-disabled">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"account-disabled">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"aborted">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"aborted">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; - {<<"aborted">>, + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"text">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"success">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> true; - {<<"success">>, + {<<"success">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; - {<<"response">>, + {<<"response">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"response">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; {<<"challenge">>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> + true; + {<<"challenge">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"abort">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> true; - {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, + _} -> + true; + {<<"auth">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + true; + {<<"query">>, <<"jabber:iq:auth">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:auth">>} -> true; + {<<"resource">>, <<"jabber:iq:auth">>, _} -> true; + {<<"resource">>, <<>>, <<"jabber:iq:auth">>} -> true; + {<<"digest">>, <<"jabber:iq:auth">>, _} -> true; + {<<"digest">>, <<>>, <<"jabber:iq:auth">>} -> true; + {<<"password">>, <<"jabber:iq:auth">>, _} -> true; + {<<"password">>, <<>>, <<"jabber:iq:auth">>} -> true; + {<<"username">>, <<"jabber:iq:auth">>, _} -> true; + {<<"username">>, <<>>, <<"jabber:iq:auth">>} -> true; + {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> + true; + {<<"bind">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + true; + {<<"resource">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> true; - {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> + {<<"resource">>, <<>>, + <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> true; - {<<"query">>, <<"jabber:iq:auth">>} -> true; - {<<"resource">>, <<"jabber:iq:auth">>} -> true; - {<<"digest">>, <<"jabber:iq:auth">>} -> true; - {<<"password">>, <<"jabber:iq:auth">>} -> true; - {<<"username">>, <<"jabber:iq:auth">>} -> true; - {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, + _} -> true; - {<<"resource">>, + {<<"jid">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> true; - {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> + {<<"error">>, <<"jabber:client">>, _} -> true; + {<<"error">>, <<>>, <<"jabber:client">>} -> true; + {<<"error">>, <<"jabber:server">>, _} -> true; + {<<"error">>, <<>>, <<"jabber:server">>} -> true; + {<<"error">>, <<"jabber:component:accept">>, _} -> true; + {<<"error">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + _} -> true; - {<<"error">>, <<"jabber:client">>} -> true; - {<<"text">>, + {<<"text">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"unexpected-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"unexpected-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"undefined-condition">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"undefined-condition">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"subscription-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"subscription-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"service-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"service-unavailable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"resource-constraint">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"resource-constraint">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"remote-server-timeout">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"remote-server-timeout">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"remote-server-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"remote-server-not-found">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"registration-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"registration-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"redirect">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"redirect">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"recipient-unavailable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"recipient-unavailable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"policy-violation">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"policy-violation">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"payment-required">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"payment-required">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"not-authorized">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"not-authorized">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"not-allowed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"not-allowed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"not-acceptable">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"not-acceptable">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"jid-malformed">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"jid-malformed">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"item-not-found">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"item-not-found">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"internal-server-error">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"internal-server-error">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; - {<<"gone">>, + {<<"gone">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + _} -> + true; + {<<"gone">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"forbidden">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"forbidden">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"feature-not-implemented">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"feature-not-implemented">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"conflict">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"conflict">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; {<<"bad-request">>, + <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> + true; + {<<"bad-request">>, <<>>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> true; - {<<"presence">>, <<"jabber:client">>} -> true; - {<<"priority">>, <<"jabber:client">>} -> true; - {<<"status">>, <<"jabber:client">>} -> true; - {<<"show">>, <<"jabber:client">>} -> true; - {<<"message">>, <<"jabber:client">>} -> true; - {<<"thread">>, <<"jabber:client">>} -> true; - {<<"body">>, <<"jabber:client">>} -> true; - {<<"subject">>, <<"jabber:client">>} -> true; - {<<"iq">>, <<"jabber:client">>} -> true; - {<<"query">>, <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"stat">>, <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"error">>, <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"storage">>, <<"storage:bookmarks">>} -> true; - {<<"url">>, <<"storage:bookmarks">>} -> true; - {<<"conference">>, <<"storage:bookmarks">>} -> true; - {<<"password">>, <<"storage:bookmarks">>} -> true; - {<<"nick">>, <<"storage:bookmarks">>} -> true; - {<<"query">>, <<"jabber:iq:private">>} -> true; + {<<"presence">>, <<"jabber:client">>, _} -> true; + {<<"presence">>, <<>>, <<"jabber:client">>} -> true; + {<<"presence">>, <<"jabber:server">>, _} -> true; + {<<"presence">>, <<>>, <<"jabber:server">>} -> true; + {<<"presence">>, <<"jabber:component:accept">>, _} -> + true; + {<<"presence">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"priority">>, <<"jabber:client">>, _} -> true; + {<<"priority">>, <<>>, <<"jabber:client">>} -> true; + {<<"priority">>, <<"jabber:server">>, _} -> true; + {<<"priority">>, <<>>, <<"jabber:server">>} -> true; + {<<"priority">>, <<"jabber:component:accept">>, _} -> + true; + {<<"priority">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"status">>, <<"jabber:client">>, _} -> true; + {<<"status">>, <<>>, <<"jabber:client">>} -> true; + {<<"status">>, <<"jabber:server">>, _} -> true; + {<<"status">>, <<>>, <<"jabber:server">>} -> true; + {<<"status">>, <<"jabber:component:accept">>, _} -> + true; + {<<"status">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"show">>, <<"jabber:client">>, _} -> true; + {<<"show">>, <<>>, <<"jabber:client">>} -> true; + {<<"show">>, <<"jabber:server">>, _} -> true; + {<<"show">>, <<>>, <<"jabber:server">>} -> true; + {<<"show">>, <<"jabber:component:accept">>, _} -> true; + {<<"show">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"message">>, <<"jabber:client">>, _} -> true; + {<<"message">>, <<>>, <<"jabber:client">>} -> true; + {<<"message">>, <<"jabber:server">>, _} -> true; + {<<"message">>, <<>>, <<"jabber:server">>} -> true; + {<<"message">>, <<"jabber:component:accept">>, _} -> + true; + {<<"message">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"thread">>, <<"jabber:client">>, _} -> true; + {<<"thread">>, <<>>, <<"jabber:client">>} -> true; + {<<"thread">>, <<"jabber:server">>, _} -> true; + {<<"thread">>, <<>>, <<"jabber:server">>} -> true; + {<<"thread">>, <<"jabber:component:accept">>, _} -> + true; + {<<"thread">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"body">>, <<"jabber:client">>, _} -> true; + {<<"body">>, <<>>, <<"jabber:client">>} -> true; + {<<"body">>, <<"jabber:server">>, _} -> true; + {<<"body">>, <<>>, <<"jabber:server">>} -> true; + {<<"body">>, <<"jabber:component:accept">>, _} -> true; + {<<"body">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"subject">>, <<"jabber:client">>, _} -> true; + {<<"subject">>, <<>>, <<"jabber:client">>} -> true; + {<<"subject">>, <<"jabber:server">>, _} -> true; + {<<"subject">>, <<>>, <<"jabber:server">>} -> true; + {<<"subject">>, <<"jabber:component:accept">>, _} -> + true; + {<<"subject">>, <<>>, <<"jabber:component:accept">>} -> + true; + {<<"iq">>, <<"jabber:client">>, _} -> true; + {<<"iq">>, <<>>, <<"jabber:client">>} -> true; + {<<"iq">>, <<"jabber:server">>, _} -> true; + {<<"iq">>, <<>>, <<"jabber:server">>} -> true; + {<<"iq">>, <<"jabber:component:accept">>, _} -> true; + {<<"iq">>, <<>>, <<"jabber:component:accept">>} -> true; + {<<"query">>, <<"http://jabber.org/protocol/stats">>, + _} -> + true; + {<<"query">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"stat">>, <<"http://jabber.org/protocol/stats">>, + _} -> + true; + {<<"stat">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"error">>, <<"http://jabber.org/protocol/stats">>, + _} -> + true; + {<<"error">>, <<>>, + <<"http://jabber.org/protocol/stats">>} -> + true; + {<<"storage">>, <<"storage:bookmarks">>, _} -> true; + {<<"storage">>, <<>>, <<"storage:bookmarks">>} -> true; + {<<"url">>, <<"storage:bookmarks">>, _} -> true; + {<<"url">>, <<>>, <<"storage:bookmarks">>} -> true; + {<<"conference">>, <<"storage:bookmarks">>, _} -> true; + {<<"conference">>, <<>>, <<"storage:bookmarks">>} -> + true; + {<<"password">>, <<"storage:bookmarks">>, _} -> true; + {<<"password">>, <<>>, <<"storage:bookmarks">>} -> true; + {<<"nick">>, <<"storage:bookmarks">>, _} -> true; + {<<"nick">>, <<>>, <<"storage:bookmarks">>} -> true; + {<<"query">>, <<"jabber:iq:private">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:private">>} -> true; {<<"query">>, + <<"http://jabber.org/protocol/disco#items">>, _} -> + true; + {<<"query">>, <<>>, <<"http://jabber.org/protocol/disco#items">>} -> true; {<<"item">>, + <<"http://jabber.org/protocol/disco#items">>, _} -> + true; + {<<"item">>, <<>>, <<"http://jabber.org/protocol/disco#items">>} -> true; {<<"query">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + true; + {<<"query">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> true; {<<"feature">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + true; + {<<"feature">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> true; {<<"identity">>, + <<"http://jabber.org/protocol/disco#info">>, _} -> + true; + {<<"identity">>, <<>>, <<"http://jabber.org/protocol/disco#info">>} -> true; - {<<"blocklist">>, <<"urn:xmpp:blocking">>} -> true; - {<<"unblock">>, <<"urn:xmpp:blocking">>} -> true; - {<<"block">>, <<"urn:xmpp:blocking">>} -> true; - {<<"item">>, <<"urn:xmpp:blocking">>} -> true; - {<<"query">>, <<"jabber:iq:privacy">>} -> true; - {<<"active">>, <<"jabber:iq:privacy">>} -> true; - {<<"default">>, <<"jabber:iq:privacy">>} -> true; - {<<"list">>, <<"jabber:iq:privacy">>} -> true; - {<<"item">>, <<"jabber:iq:privacy">>} -> true; - {<<"presence-out">>, <<"jabber:iq:privacy">>} -> true; - {<<"presence-in">>, <<"jabber:iq:privacy">>} -> true; - {<<"iq">>, <<"jabber:iq:privacy">>} -> true; - {<<"message">>, <<"jabber:iq:privacy">>} -> true; - {<<"ver">>, <<"urn:xmpp:features:rosterver">>} -> true; - {<<"query">>, <<"jabber:iq:roster">>} -> true; - {<<"item">>, <<"jabber:iq:roster">>} -> true; - {<<"group">>, <<"jabber:iq:roster">>} -> true; - {<<"query">>, <<"jabber:iq:version">>} -> true; - {<<"os">>, <<"jabber:iq:version">>} -> true; - {<<"version">>, <<"jabber:iq:version">>} -> true; - {<<"name">>, <<"jabber:iq:version">>} -> true; - {<<"query">>, <<"jabber:iq:last">>} -> true; + {<<"blocklist">>, <<"urn:xmpp:blocking">>, _} -> true; + {<<"blocklist">>, <<>>, <<"urn:xmpp:blocking">>} -> + true; + {<<"unblock">>, <<"urn:xmpp:blocking">>, _} -> true; + {<<"unblock">>, <<>>, <<"urn:xmpp:blocking">>} -> true; + {<<"block">>, <<"urn:xmpp:blocking">>, _} -> true; + {<<"block">>, <<>>, <<"urn:xmpp:blocking">>} -> true; + {<<"item">>, <<"urn:xmpp:blocking">>, _} -> true; + {<<"item">>, <<>>, <<"urn:xmpp:blocking">>} -> true; + {<<"query">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"active">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"active">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"default">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"default">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"list">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"list">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"item">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"item">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"presence-out">>, <<"jabber:iq:privacy">>, _} -> + true; + {<<"presence-out">>, <<>>, <<"jabber:iq:privacy">>} -> + true; + {<<"presence-in">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"presence-in">>, <<>>, <<"jabber:iq:privacy">>} -> + true; + {<<"iq">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"iq">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"message">>, <<"jabber:iq:privacy">>, _} -> true; + {<<"message">>, <<>>, <<"jabber:iq:privacy">>} -> true; + {<<"ver">>, <<"urn:xmpp:features:rosterver">>, _} -> + true; + {<<"ver">>, <<>>, <<"urn:xmpp:features:rosterver">>} -> + true; + {<<"query">>, <<"jabber:iq:roster">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:roster">>} -> true; + {<<"item">>, <<"jabber:iq:roster">>, _} -> true; + {<<"item">>, <<>>, <<"jabber:iq:roster">>} -> true; + {<<"group">>, <<"jabber:iq:roster">>, _} -> true; + {<<"group">>, <<>>, <<"jabber:iq:roster">>} -> true; + {<<"query">>, <<"jabber:iq:version">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:version">>} -> true; + {<<"os">>, <<"jabber:iq:version">>, _} -> true; + {<<"os">>, <<>>, <<"jabber:iq:version">>} -> true; + {<<"version">>, <<"jabber:iq:version">>, _} -> true; + {<<"version">>, <<>>, <<"jabber:iq:version">>} -> true; + {<<"name">>, <<"jabber:iq:version">>, _} -> true; + {<<"name">>, <<>>, <<"jabber:iq:version">>} -> true; + {<<"query">>, <<"jabber:iq:last">>, _} -> true; + {<<"query">>, <<>>, <<"jabber:iq:last">>} -> true; _ -> false end. -encode({xmlel, _, _, _} = El) -> El; -encode({last, _, _} = Query) -> - encode_last(Query, - [{<<"xmlns">>, <<"jabber:iq:last">>}]); -encode({version, _, _, _} = Query) -> - encode_version(Query, - [{<<"xmlns">>, <<"jabber:iq:version">>}]); -encode({roster_item, _, _, _, _, _} = Item) -> - encode_roster_item(Item, - [{<<"xmlns">>, <<"jabber:iq:roster">>}]); -encode({roster_query, _, _} = Query) -> - encode_roster_query(Query, - [{<<"xmlns">>, <<"jabber:iq:roster">>}]); -encode({rosterver_feature} = Ver) -> - encode_rosterver_feature(Ver, - [{<<"xmlns">>, - <<"urn:xmpp:features:rosterver">>}]); -encode({privacy_item, _, _, _, _, _, _, _, _} = Item) -> - encode_privacy_item(Item, - [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); -encode({privacy_list, _, _} = List) -> - encode_privacy_list(List, - [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); -encode({privacy_query, _, _, _} = Query) -> - encode_privacy(Query, - [{<<"xmlns">>, <<"jabber:iq:privacy">>}]); -encode({block, _} = Block) -> - encode_block(Block, - [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); -encode({unblock, _} = Unblock) -> - encode_unblock(Unblock, - [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); -encode({block_list, _} = Blocklist) -> - encode_block_list(Blocklist, - [{<<"xmlns">>, <<"urn:xmpp:blocking">>}]); -encode({identity, _, _, _, _} = Identity) -> - encode_disco_identity(Identity, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/disco#info">>}]); -encode({disco_info, _, _, _, _} = Query) -> - encode_disco_info(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/disco#info">>}]); -encode({disco_item, _, _, _} = Item) -> - encode_disco_item(Item, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/disco#items">>}]); -encode({disco_items, _, _, _} = Query) -> - encode_disco_items(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/disco#items">>}]); -encode({private, _} = Query) -> - encode_private(Query, - [{<<"xmlns">>, <<"jabber:iq:private">>}]); +encode(_el) -> encode(_el, <<>>). + +encode({xmlel, _, _, _} = El, _) -> El; +encode({last, _, _} = Query, TopXMLNS) -> + encode_last(Query, TopXMLNS); +encode({version, _, _, _} = Query, TopXMLNS) -> + encode_version(Query, TopXMLNS); +encode({roster_item, _, _, _, _, _} = Item, TopXMLNS) -> + encode_roster_item(Item, TopXMLNS); +encode({roster_query, _, _} = Query, TopXMLNS) -> + encode_roster_query(Query, TopXMLNS); +encode({rosterver_feature} = Ver, TopXMLNS) -> + encode_rosterver_feature(Ver, TopXMLNS); +encode({privacy_item, _, _, _, _, _, _, _, _} = Item, + TopXMLNS) -> + encode_privacy_item(Item, TopXMLNS); +encode({privacy_list, _, _} = List, TopXMLNS) -> + encode_privacy_list(List, TopXMLNS); +encode({privacy_query, _, _, _} = Query, TopXMLNS) -> + encode_privacy(Query, TopXMLNS); +encode({block, _} = Block, TopXMLNS) -> + encode_block(Block, TopXMLNS); +encode({unblock, _} = Unblock, TopXMLNS) -> + encode_unblock(Unblock, TopXMLNS); +encode({block_list, _} = Blocklist, TopXMLNS) -> + encode_block_list(Blocklist, TopXMLNS); +encode({identity, _, _, _, _} = Identity, TopXMLNS) -> + encode_disco_identity(Identity, TopXMLNS); +encode({disco_info, _, _, _, _} = Query, TopXMLNS) -> + encode_disco_info(Query, TopXMLNS); +encode({disco_item, _, _, _} = Item, TopXMLNS) -> + encode_disco_item(Item, TopXMLNS); +encode({disco_items, _, _, _} = Query, TopXMLNS) -> + encode_disco_items(Query, TopXMLNS); +encode({private, _} = Query, TopXMLNS) -> + encode_private(Query, TopXMLNS); encode({bookmark_conference, _, _, _, _, _} = - Conference) -> - encode_bookmark_conference(Conference, - [{<<"xmlns">>, <<"storage:bookmarks">>}]); -encode({bookmark_url, _, _} = Url) -> - encode_bookmark_url(Url, - [{<<"xmlns">>, <<"storage:bookmarks">>}]); -encode({bookmark_storage, _, _} = Storage) -> - encode_bookmarks_storage(Storage, - [{<<"xmlns">>, <<"storage:bookmarks">>}]); -encode({stat_error, _, _} = Error) -> - encode_stat_error(Error, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/stats">>}]); -encode({stat, _, _, _, _} = Stat) -> - encode_stat(Stat, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/stats">>}]); -encode({stats, _, _} = Query) -> - encode_stats(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/stats">>}]); -encode({iq, _, _, _, _, _, _} = Iq) -> - encode_iq(Iq, [{<<"xmlns">>, <<"jabber:client">>}]); -encode({message, _, _, _, _, _, _, _, _, _} = - Message) -> - encode_message(Message, - [{<<"xmlns">>, <<"jabber:client">>}]); -encode({presence, _, _, _, _, _, _, _, _, _} = - Presence) -> - encode_presence(Presence, - [{<<"xmlns">>, <<"jabber:client">>}]); -encode({gone, _} = Gone) -> - encode_error_gone(Gone, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); -encode({redirect, _} = Redirect) -> - encode_error_redirect(Redirect, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); -encode({stanza_error, _, _, _, _, _, _} = Error) -> - encode_error(Error, - [{<<"xmlns">>, <<"jabber:client">>}]); -encode({bind, _, _} = Bind) -> - encode_bind(Bind, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>}]); -encode({legacy_auth, _, _, _, _} = Query) -> - encode_legacy_auth(Query, - [{<<"xmlns">>, <<"jabber:iq:auth">>}]); -encode({sasl_auth, _, _} = Auth) -> - encode_sasl_auth(Auth, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_abort} = Abort) -> - encode_sasl_abort(Abort, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_challenge, _} = Challenge) -> - encode_sasl_challenge(Challenge, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_response, _} = Response) -> - encode_sasl_response(Response, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_success, _} = Success) -> - encode_sasl_success(Success, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_failure, _, _} = Failure) -> - encode_sasl_failure(Failure, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({sasl_mechanisms, _} = Mechanisms) -> - encode_sasl_mechanisms(Mechanisms, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]); -encode({starttls, _} = Starttls) -> - encode_starttls(Starttls, - [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); -encode({starttls_proceed} = Proceed) -> - encode_starttls_proceed(Proceed, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); -encode({starttls_failure} = Failure) -> - encode_starttls_failure(Failure, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>}]); -encode({compress_failure, _} = Failure) -> - encode_compress_failure(Failure, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/compress">>}]); -encode({compress, _} = Compress) -> - encode_compress(Compress, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/compress">>}]); -encode({compressed} = Compressed) -> - encode_compressed(Compressed, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/compress">>}]); -encode({compression, _} = Compression) -> - encode_compression(Compression, - [{<<"xmlns">>, - <<"http://jabber.org/features/compress">>}]); -encode({stream_features, _} = Stream_features) -> - encode_stream_features(Stream_features, - [{<<"xmlns">>, - <<"http://etherx.jabber.org/streams">>}]); -encode({p1_push} = Push) -> - encode_p1_push(Push, [{<<"xmlns">>, <<"p1:push">>}]); -encode({p1_rebind} = Rebind) -> - encode_p1_rebind(Rebind, - [{<<"xmlns">>, <<"p1:rebind">>}]); -encode({p1_ack} = Ack) -> - encode_p1_ack(Ack, [{<<"xmlns">>, <<"p1:ack">>}]); -encode({caps, _, _, _, _} = C) -> - encode_caps(C, - [{<<"xmlns">>, <<"http://jabber.org/protocol/caps">>}]); -encode({feature_register} = Register) -> - encode_feature_register(Register, - [{<<"xmlns">>, - <<"http://jabber.org/features/iq-register">>}]); + Conference, + TopXMLNS) -> + encode_bookmark_conference(Conference, TopXMLNS); +encode({bookmark_url, _, _} = Url, TopXMLNS) -> + encode_bookmark_url(Url, TopXMLNS); +encode({bookmark_storage, _, _} = Storage, TopXMLNS) -> + encode_bookmarks_storage(Storage, TopXMLNS); +encode({stat_error, _, _} = Error, TopXMLNS) -> + encode_stat_error(Error, TopXMLNS); +encode({stat, _, _, _, _} = Stat, TopXMLNS) -> + encode_stat(Stat, TopXMLNS); +encode({stats, _, _} = Query, TopXMLNS) -> + encode_stats(Query, TopXMLNS); +encode({iq, _, _, _, _, _, _} = Iq, TopXMLNS) -> + encode_iq(Iq, TopXMLNS); +encode({message, _, _, _, _, _, _, _, _, _} = Message, + TopXMLNS) -> + encode_message(Message, TopXMLNS); +encode({presence, _, _, _, _, _, _, _, _, _} = Presence, + TopXMLNS) -> + encode_presence(Presence, TopXMLNS); +encode({gone, _} = Gone, TopXMLNS) -> + encode_error_gone(Gone, TopXMLNS); +encode({redirect, _} = Redirect, TopXMLNS) -> + encode_error_redirect(Redirect, TopXMLNS); +encode({stanza_error, _, _, _, _, _, _} = Error, + TopXMLNS) -> + encode_error(Error, TopXMLNS); +encode({bind, _, _} = Bind, TopXMLNS) -> + encode_bind(Bind, TopXMLNS); +encode({legacy_auth, _, _, _, _} = Query, TopXMLNS) -> + encode_legacy_auth(Query, TopXMLNS); +encode({sasl_auth, _, _} = Auth, TopXMLNS) -> + encode_sasl_auth(Auth, TopXMLNS); +encode({sasl_abort} = Abort, TopXMLNS) -> + encode_sasl_abort(Abort, TopXMLNS); +encode({sasl_challenge, _} = Challenge, TopXMLNS) -> + encode_sasl_challenge(Challenge, TopXMLNS); +encode({sasl_response, _} = Response, TopXMLNS) -> + encode_sasl_response(Response, TopXMLNS); +encode({sasl_success, _} = Success, TopXMLNS) -> + encode_sasl_success(Success, TopXMLNS); +encode({sasl_failure, _, _} = Failure, TopXMLNS) -> + encode_sasl_failure(Failure, TopXMLNS); +encode({sasl_mechanisms, _} = Mechanisms, TopXMLNS) -> + encode_sasl_mechanisms(Mechanisms, TopXMLNS); +encode({starttls, _} = Starttls, TopXMLNS) -> + encode_starttls(Starttls, TopXMLNS); +encode({starttls_proceed} = Proceed, TopXMLNS) -> + encode_starttls_proceed(Proceed, TopXMLNS); +encode({starttls_failure} = Failure, TopXMLNS) -> + encode_starttls_failure(Failure, TopXMLNS); +encode({compress_failure, _} = Failure, TopXMLNS) -> + encode_compress_failure(Failure, TopXMLNS); +encode({compress, _} = Compress, TopXMLNS) -> + encode_compress(Compress, TopXMLNS); +encode({compressed} = Compressed, TopXMLNS) -> + encode_compressed(Compressed, TopXMLNS); +encode({compression, _} = Compression, TopXMLNS) -> + encode_compression(Compression, TopXMLNS); +encode({stream_features, _} = Stream_features, + TopXMLNS) -> + encode_stream_features(Stream_features, TopXMLNS); +encode({p1_push} = Push, TopXMLNS) -> + encode_p1_push(Push, TopXMLNS); +encode({p1_rebind} = Rebind, TopXMLNS) -> + encode_p1_rebind(Rebind, TopXMLNS); +encode({p1_ack} = Ack, TopXMLNS) -> + encode_p1_ack(Ack, TopXMLNS); +encode({caps, _, _, _, _} = C, TopXMLNS) -> + encode_caps(C, TopXMLNS); +encode({feature_register} = Register, TopXMLNS) -> + encode_feature_register(Register, TopXMLNS); encode({register, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Query) -> - encode_register(Query, - [{<<"xmlns">>, <<"jabber:iq:register">>}]); -encode({xmpp_session, _} = Session) -> - encode_session(Session, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-session">>}]); -encode({ping} = Ping) -> - encode_ping(Ping, [{<<"xmlns">>, <<"urn:xmpp:ping">>}]); -encode({time, _, _} = Time) -> - encode_time(Time, [{<<"xmlns">>, <<"urn:xmpp:time">>}]); -encode({text, _, _} = Text) -> - encode_stream_error_text(Text, []); -encode({'see-other-host', _} = See_other_host) -> + Query, + TopXMLNS) -> + encode_register(Query, TopXMLNS); +encode({xmpp_session, _} = Session, TopXMLNS) -> + encode_session(Session, TopXMLNS); +encode({ping} = Ping, TopXMLNS) -> + encode_ping(Ping, TopXMLNS); +encode({time, _, _} = Time, TopXMLNS) -> + encode_time(Time, TopXMLNS); +encode({text, _, _} = Text, TopXMLNS) -> + encode_stream_error_text(Text, TopXMLNS); +encode({'see-other-host', _} = See_other_host, + TopXMLNS) -> encode_stream_error_see_other_host(See_other_host, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]); -encode({stream_error, _, _} = Stream_error) -> - encode_stream_error(Stream_error, - [{<<"xmlns">>, - <<"http://etherx.jabber.org/streams">>}]); -encode({vcard_name, _, _, _, _, _} = N) -> - encode_vcard_N(N, [{<<"xmlns">>, <<"vcard-temp">>}]); + TopXMLNS); +encode({stream_error, _, _} = Stream_error, TopXMLNS) -> + encode_stream_error(Stream_error, TopXMLNS); +encode({vcard_name, _, _, _, _, _} = N, TopXMLNS) -> + encode_vcard_N(N, TopXMLNS); encode({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Adr) -> - encode_vcard_ADR(Adr, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_label, _, _, _, _, _, _, _, _} = Label) -> - encode_vcard_LABEL(Label, - [{<<"xmlns">>, <<"vcard-temp">>}]); + Adr, + TopXMLNS) -> + encode_vcard_ADR(Adr, TopXMLNS); +encode({vcard_label, _, _, _, _, _, _, _, _} = Label, + TopXMLNS) -> + encode_vcard_LABEL(Label, TopXMLNS); encode({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Tel) -> - encode_vcard_TEL(Tel, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_email, _, _, _, _, _, _} = Email) -> - encode_vcard_EMAIL(Email, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_geo, _, _} = Geo) -> - encode_vcard_GEO(Geo, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_logo, _, _, _} = Logo) -> - encode_vcard_LOGO(Logo, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_photo, _, _, _} = Photo) -> - encode_vcard_PHOTO(Photo, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_org, _, _} = Org) -> - encode_vcard_ORG(Org, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_sound, _, _, _} = Sound) -> - encode_vcard_SOUND(Sound, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_key, _, _} = Key) -> - encode_vcard_KEY(Key, - [{<<"xmlns">>, <<"vcard-temp">>}]); + Tel, + TopXMLNS) -> + encode_vcard_TEL(Tel, TopXMLNS); +encode({vcard_email, _, _, _, _, _, _} = Email, + TopXMLNS) -> + encode_vcard_EMAIL(Email, TopXMLNS); +encode({vcard_geo, _, _} = Geo, TopXMLNS) -> + encode_vcard_GEO(Geo, TopXMLNS); +encode({vcard_logo, _, _, _} = Logo, TopXMLNS) -> + encode_vcard_LOGO(Logo, TopXMLNS); +encode({vcard_photo, _, _, _} = Photo, TopXMLNS) -> + encode_vcard_PHOTO(Photo, TopXMLNS); +encode({vcard_org, _, _} = Org, TopXMLNS) -> + encode_vcard_ORG(Org, TopXMLNS); +encode({vcard_sound, _, _, _} = Sound, TopXMLNS) -> + encode_vcard_SOUND(Sound, TopXMLNS); +encode({vcard_key, _, _} = Key, TopXMLNS) -> + encode_vcard_KEY(Key, TopXMLNS); encode({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Vcard) -> - encode_vcard_temp(Vcard, - [{<<"xmlns">>, <<"vcard-temp">>}]); -encode({vcard_xupdate, _, _} = X) -> - encode_vcard_xupdate(X, - [{<<"xmlns">>, <<"vcard-temp:x:update">>}]); -encode({xdata_option, _, _} = Option) -> - encode_xdata_field_option(Option, - [{<<"xmlns">>, <<"jabber:x:data">>}]); -encode({xdata_field, _, _, _, _, _, _, _, _} = Field) -> - encode_xdata_field(Field, - [{<<"xmlns">>, <<"jabber:x:data">>}]); -encode({xdata, _, _, _, _, _, _} = X) -> - encode_xdata(X, [{<<"xmlns">>, <<"jabber:x:data">>}]); + Vcard, + TopXMLNS) -> + encode_vcard_temp(Vcard, TopXMLNS); +encode({vcard_xupdate, _, _} = X, TopXMLNS) -> + encode_vcard_xupdate(X, TopXMLNS); +encode({xdata_option, _, _} = Option, TopXMLNS) -> + encode_xdata_field_option(Option, TopXMLNS); +encode({xdata_field, _, _, _, _, _, _, _, _} = Field, + TopXMLNS) -> + encode_xdata_field(Field, TopXMLNS); +encode({xdata, _, _, _, _, _, _} = X, TopXMLNS) -> + encode_xdata(X, TopXMLNS); encode({ps_subscription, _, _, _, _, _, _} = - Subscription) -> - encode_pubsub_subscription(Subscription, []); + Subscription, + TopXMLNS) -> + encode_pubsub_subscription(Subscription, TopXMLNS); encode({ps_affiliation, <<"http://jabber.org/protocol/pubsub">>, _, _, _} = - Affiliation) -> - encode_pubsub_affiliation(Affiliation, []); + Affiliation, + TopXMLNS) -> + encode_pubsub_affiliation(Affiliation, TopXMLNS); +encode({ps_affiliation, <<>>, _, _, _} = Affiliation, + TopXMLNS = <<"http://jabber.org/protocol/pubsub">>) -> + encode_pubsub_affiliation(Affiliation, TopXMLNS); encode({ps_affiliation, <<"http://jabber.org/protocol/pubsub#owner">>, _, _, _} = - Affiliation) -> - encode_pubsub_owner_affiliation(Affiliation, []); -encode({ps_item, _, _, _, _, _} = Item) -> - encode_pubsub_item(Item, []); -encode({ps_items, _, _, _, _, _, _} = Items) -> - encode_pubsub_items(Items, []); -encode({ps_event, _, _, _, _, _, _} = Event) -> - encode_pubsub_event(Event, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#event">>}]); -encode({ps_subscribe, _, _} = Subscribe) -> - encode_pubsub_subscribe(Subscribe, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({ps_unsubscribe, _, _, _} = Unsubscribe) -> - encode_pubsub_unsubscribe(Unsubscribe, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({ps_publish, _, _} = Publish) -> - encode_pubsub_publish(Publish, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({ps_options, _, _, _, _} = Options) -> - encode_pubsub_options(Options, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({ps_retract, _, _, _} = Retract) -> - encode_pubsub_retract(Retract, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); + Affiliation, + TopXMLNS) -> + encode_pubsub_owner_affiliation(Affiliation, TopXMLNS); +encode({ps_affiliation, <<>>, _, _, _} = Affiliation, + TopXMLNS = + <<"http://jabber.org/protocol/pubsub#owner">>) -> + encode_pubsub_owner_affiliation(Affiliation, TopXMLNS); +encode({ps_item, _, _, _, _, _} = Item, TopXMLNS) -> + encode_pubsub_item(Item, TopXMLNS); +encode({ps_items, _, _, _, _, _, _} = Items, + TopXMLNS) -> + encode_pubsub_items(Items, TopXMLNS); +encode({ps_event, _, _, _, _, _, _} = Event, + TopXMLNS) -> + encode_pubsub_event(Event, TopXMLNS); +encode({ps_subscribe, _, _} = Subscribe, TopXMLNS) -> + encode_pubsub_subscribe(Subscribe, TopXMLNS); +encode({ps_unsubscribe, _, _, _} = Unsubscribe, + TopXMLNS) -> + encode_pubsub_unsubscribe(Unsubscribe, TopXMLNS); +encode({ps_publish, _, _} = Publish, TopXMLNS) -> + encode_pubsub_publish(Publish, TopXMLNS); +encode({ps_options, _, _, _, _} = Options, TopXMLNS) -> + encode_pubsub_options(Options, TopXMLNS); +encode({ps_retract, _, _, _} = Retract, TopXMLNS) -> + encode_pubsub_retract(Retract, TopXMLNS); encode({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Pubsub) -> - encode_pubsub(Pubsub, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub">>}]); -encode({pubsub_owner, _, _, _, _, _, _} = Pubsub) -> - encode_pubsub_owner(Pubsub, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#owner">>}]); -encode({ps_error, 'closed-node', _} = Closed_node) -> - encode_pubsub_error_closed_node(Closed_node, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + Pubsub, + TopXMLNS) -> + encode_pubsub(Pubsub, TopXMLNS); +encode({pubsub_owner, _, _, _, _, _, _} = Pubsub, + TopXMLNS) -> + encode_pubsub_owner(Pubsub, TopXMLNS); +encode({ps_error, 'closed-node', _} = Closed_node, + TopXMLNS) -> + encode_pubsub_error_closed_node(Closed_node, TopXMLNS); encode({ps_error, 'configuration-required', _} = - Configuration_required) -> + Configuration_required, + TopXMLNS) -> encode_pubsub_error_configuration_required(Configuration_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'invalid-jid', _} = Invalid_jid) -> - encode_pubsub_error_invalid_jid(Invalid_jid, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); +encode({ps_error, 'invalid-jid', _} = Invalid_jid, + TopXMLNS) -> + encode_pubsub_error_invalid_jid(Invalid_jid, TopXMLNS); encode({ps_error, 'invalid-options', _} = - Invalid_options) -> + Invalid_options, + TopXMLNS) -> encode_pubsub_error_invalid_options(Invalid_options, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'invalid-payload', _} = - Invalid_payload) -> + Invalid_payload, + TopXMLNS) -> encode_pubsub_error_invalid_payload(Invalid_payload, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'invalid-subid', _} = - Invalid_subid) -> + TopXMLNS); +encode({ps_error, 'invalid-subid', _} = Invalid_subid, + TopXMLNS) -> encode_pubsub_error_invalid_subid(Invalid_subid, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'item-forbidden', _} = - Item_forbidden) -> + TopXMLNS); +encode({ps_error, 'item-forbidden', _} = Item_forbidden, + TopXMLNS) -> encode_pubsub_error_item_forbidden(Item_forbidden, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'item-required', _} = - Item_required) -> + TopXMLNS); +encode({ps_error, 'item-required', _} = Item_required, + TopXMLNS) -> encode_pubsub_error_item_required(Item_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'jid-required', _} = Jid_required) -> + TopXMLNS); +encode({ps_error, 'jid-required', _} = Jid_required, + TopXMLNS) -> encode_pubsub_error_jid_required(Jid_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'max-items-exceeded', _} = - Max_items_exceeded) -> + Max_items_exceeded, + TopXMLNS) -> encode_pubsub_error_max_items_exceeded(Max_items_exceeded, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'max-nodes-exceeded', _} = - Max_nodes_exceeded) -> + Max_nodes_exceeded, + TopXMLNS) -> encode_pubsub_error_max_nodes_exceeded(Max_nodes_exceeded, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'nodeid-required', _} = - Nodeid_required) -> + Nodeid_required, + TopXMLNS) -> encode_pubsub_error_nodeid_required(Nodeid_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'not-in-roster-group', _} = - Not_in_roster_group) -> + Not_in_roster_group, + TopXMLNS) -> encode_pubsub_error_not_in_roster_group(Not_in_roster_group, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'not-subscribed', _} = - Not_subscribed) -> + TopXMLNS); +encode({ps_error, 'not-subscribed', _} = Not_subscribed, + TopXMLNS) -> encode_pubsub_error_not_subscribed(Not_subscribed, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'payload-too-big', _} = - Payload_too_big) -> + Payload_too_big, + TopXMLNS) -> encode_pubsub_error_payload_too_big(Payload_too_big, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'payload-required', _} = - Payload_required) -> + Payload_required, + TopXMLNS) -> encode_pubsub_error_payload_required(Payload_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'pending-subscription', _} = - Pending_subscription) -> + Pending_subscription, + TopXMLNS) -> encode_pubsub_error_pending_subscription(Pending_subscription, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'presence-subscription-required', _} = - Presence_subscription_required) -> + Presence_subscription_required, + TopXMLNS) -> encode_pubsub_error_presence_subscription_required(Presence_subscription_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, 'subid-required', _} = - Subid_required) -> + TopXMLNS); +encode({ps_error, 'subid-required', _} = Subid_required, + TopXMLNS) -> encode_pubsub_error_subid_required(Subid_required, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); encode({ps_error, 'too-many-subscriptions', _} = - Too_many_subscriptions) -> + Too_many_subscriptions, + TopXMLNS) -> encode_pubsub_error_too_many_subscriptions(Too_many_subscriptions, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({ps_error, unsupported, _} = Unsupported) -> - encode_pubsub_error_unsupported(Unsupported, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); + TopXMLNS); +encode({ps_error, unsupported, _} = Unsupported, + TopXMLNS) -> + encode_pubsub_error_unsupported(Unsupported, TopXMLNS); encode({ps_error, 'unsupported-access-model', _} = - Unsupported_access_model) -> + Unsupported_access_model, + TopXMLNS) -> encode_pubsub_error_unsupported_access_model(Unsupported_access_model, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/pubsub#errors">>}]); -encode({shim, _} = Headers) -> - encode_shim_headers(Headers, - [{<<"xmlns">>, <<"http://jabber.org/protocol/shim">>}]); -encode({chatstate, active} = Active) -> - encode_chatstate_active(Active, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/chatstates">>}]); -encode({chatstate, composing} = Composing) -> - encode_chatstate_composing(Composing, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/chatstates">>}]); -encode({chatstate, gone} = Gone) -> - encode_chatstate_gone(Gone, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/chatstates">>}]); -encode({chatstate, inactive} = Inactive) -> - encode_chatstate_inactive(Inactive, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/chatstates">>}]); -encode({chatstate, paused} = Paused) -> - encode_chatstate_paused(Paused, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/chatstates">>}]); -encode({delay, _, _, _} = Delay) -> - encode_delay(Delay, - [{<<"xmlns">>, <<"urn:xmpp:delay">>}]); -encode({streamhost, _, _, _} = Streamhost) -> - encode_bytestreams_streamhost(Streamhost, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/bytestreams">>}]); -encode({bytestreams, _, _, _, _, _, _} = Query) -> - encode_bytestreams(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/bytestreams">>}]); -encode({muc_history, _, _, _, _} = History) -> - encode_muc_history(History, - [{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]); -encode({muc_decline, _, _, _} = Decline) -> - encode_muc_user_decline(Decline, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_destroy, _, _, _, _} = Destroy) -> - encode_muc_destroy(Destroy, []); -encode({muc_invite, _, _, _, _} = Invite) -> - encode_muc_user_invite(Invite, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_user, _, _, _, _, _, _} = X) -> - encode_muc_user(X, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#user">>}]); -encode({muc_owner, _, _, _} = Query) -> - encode_muc_owner(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#owner">>}]); -encode({muc_item, _, _, _, _, _, _, _} = Item) -> - encode_muc_admin_item(Item, []); -encode({muc_actor, _, _} = Actor) -> - encode_muc_admin_actor(Actor, []); -encode({muc_admin, _} = Query) -> - encode_muc_admin(Query, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#admin">>}]); -encode({muc, _, _} = X) -> - encode_muc(X, - [{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]); -encode({muc_unique, _} = Unique) -> - encode_muc_unique(Unique, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#unique">>}]); -encode({x_conference, _, _, _, _, _} = X) -> - encode_x_conference(X, - [{<<"xmlns">>, <<"jabber:x:conference">>}]); -encode({muc_subscriptions, _} = Subscriptions) -> - encode_muc_subscriptions(Subscriptions, - [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); -encode({muc_subscribe, _, _} = Subscribe) -> - encode_muc_subscribe(Subscribe, - [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); -encode({muc_unsubscribe} = Unsubscribe) -> - encode_muc_unsubscribe(Unsubscribe, - [{<<"xmlns">>, <<"urn:xmpp:mucsub:0">>}]); -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, []); -encode({forwarded, _, _} = Forwarded) -> - encode_forwarded(Forwarded, - [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]); -encode({carbons_disable} = Disable) -> - encode_carbons_disable(Disable, - [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({carbons_enable} = Enable) -> - encode_carbons_enable(Enable, - [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({carbons_private} = Private) -> - encode_carbons_private(Private, - [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({carbons_received, _} = Received) -> - encode_carbons_received(Received, - [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({carbons_sent, _} = Sent) -> - encode_carbons_sent(Sent, - [{<<"xmlns">>, <<"urn:xmpp:carbons:2">>}]); -encode({feature_csi, <<"urn:xmpp:csi:0">>} = Csi) -> - encode_feature_csi(Csi, []); -encode({csi, active} = Active) -> - encode_csi_active(Active, - [{<<"xmlns">>, <<"urn:xmpp:csi:0">>}]); -encode({csi, inactive} = Inactive) -> - encode_csi_inactive(Inactive, - [{<<"xmlns">>, <<"urn:xmpp:csi:0">>}]); -encode({feature_sm, _} = Sm) -> - encode_feature_sm(Sm, []); -encode({sm_enable, _, _, _} = Enable) -> - encode_sm_enable(Enable, []); -encode({sm_enabled, _, _, _, _, _} = Enabled) -> - encode_sm_enabled(Enabled, []); -encode({sm_resume, _, _, _} = Resume) -> - encode_sm_resume(Resume, []); -encode({sm_resumed, _, _, _} = Resumed) -> - encode_sm_resumed(Resumed, []); -encode({sm_r, _} = R) -> encode_sm_r(R, []); -encode({sm_a, _, _} = A) -> encode_sm_a(A, []); -encode({sm_failed, _, _, _} = Failed) -> - encode_sm_failed(Failed, []); -encode({offline_item, _, _} = Item) -> - encode_offline_item(Item, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/offline">>}]); -encode({offline, _, _, _} = Offline) -> - encode_offline(Offline, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/offline">>}]); -encode({mix_join, _, _} = Join) -> - encode_mix_join(Join, - [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); -encode({mix_leave} = Leave) -> - encode_mix_leave(Leave, - [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); -encode({mix_participant, _, _} = Participant) -> - encode_mix_participant(Participant, - [{<<"xmlns">>, <<"urn:xmpp:mix:0">>}]); -encode({hint, 'no-copy'} = No_copy) -> - encode_hint_no_copy(No_copy, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); -encode({hint, 'no-store'} = No_store) -> - encode_hint_no_store(No_store, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); -encode({hint, 'no-storage'} = No_storage) -> - encode_hint_no_storage(No_storage, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); -encode({hint, store} = Store) -> - encode_hint_store(Store, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); + TopXMLNS); +encode({shim, _} = Headers, TopXMLNS) -> + encode_shim_headers(Headers, TopXMLNS); +encode({chatstate, active} = Active, TopXMLNS) -> + encode_chatstate_active(Active, TopXMLNS); +encode({chatstate, composing} = Composing, TopXMLNS) -> + encode_chatstate_composing(Composing, TopXMLNS); +encode({chatstate, gone} = Gone, TopXMLNS) -> + encode_chatstate_gone(Gone, TopXMLNS); +encode({chatstate, inactive} = Inactive, TopXMLNS) -> + encode_chatstate_inactive(Inactive, TopXMLNS); +encode({chatstate, paused} = Paused, TopXMLNS) -> + encode_chatstate_paused(Paused, TopXMLNS); +encode({delay, _, _, _} = Delay, TopXMLNS) -> + encode_delay(Delay, TopXMLNS); +encode({streamhost, _, _, _} = Streamhost, TopXMLNS) -> + encode_bytestreams_streamhost(Streamhost, TopXMLNS); +encode({bytestreams, _, _, _, _, _, _} = Query, + TopXMLNS) -> + encode_bytestreams(Query, TopXMLNS); +encode({muc_history, _, _, _, _} = History, TopXMLNS) -> + encode_muc_history(History, TopXMLNS); +encode({muc_decline, _, _, _} = Decline, TopXMLNS) -> + encode_muc_user_decline(Decline, TopXMLNS); +encode({muc_destroy, _, _, _, _} = Destroy, TopXMLNS) -> + encode_muc_destroy(Destroy, TopXMLNS); +encode({muc_invite, _, _, _, _} = Invite, TopXMLNS) -> + encode_muc_user_invite(Invite, TopXMLNS); +encode({muc_user, _, _, _, _, _, _} = X, TopXMLNS) -> + encode_muc_user(X, TopXMLNS); +encode({muc_owner, _, _, _} = Query, TopXMLNS) -> + encode_muc_owner(Query, TopXMLNS); +encode({muc_item, _, _, _, _, _, _, _} = Item, + TopXMLNS) -> + encode_muc_admin_item(Item, TopXMLNS); +encode({muc_actor, _, _} = Actor, TopXMLNS) -> + encode_muc_admin_actor(Actor, TopXMLNS); +encode({muc_admin, _} = Query, TopXMLNS) -> + encode_muc_admin(Query, TopXMLNS); +encode({muc, _, _} = X, TopXMLNS) -> + encode_muc(X, TopXMLNS); +encode({muc_unique, _} = Unique, TopXMLNS) -> + encode_muc_unique(Unique, TopXMLNS); +encode({x_conference, _, _, _, _, _} = X, TopXMLNS) -> + encode_x_conference(X, TopXMLNS); +encode({muc_subscriptions, _} = Subscriptions, + TopXMLNS) -> + encode_muc_subscriptions(Subscriptions, TopXMLNS); +encode({muc_subscribe, _, _} = Subscribe, TopXMLNS) -> + encode_muc_subscribe(Subscribe, TopXMLNS); +encode({muc_unsubscribe} = Unsubscribe, TopXMLNS) -> + encode_muc_unsubscribe(Unsubscribe, TopXMLNS); +encode({rsm_first, _, _} = First, TopXMLNS) -> + encode_rsm_first(First, TopXMLNS); +encode({rsm_set, _, _, _, _, _, _, _} = Set, + TopXMLNS) -> + encode_rsm_set(Set, TopXMLNS); +encode({mam_query, _, _, _, _, _, _, _, _} = Query, + TopXMLNS) -> + encode_mam_query(Query, TopXMLNS); +encode({mam_archived, _, _} = Archived, TopXMLNS) -> + encode_mam_archived(Archived, TopXMLNS); +encode({mam_result, _, _, _, _} = Result, TopXMLNS) -> + encode_mam_result(Result, TopXMLNS); +encode({mam_prefs, _, _, _, _} = Prefs, TopXMLNS) -> + encode_mam_prefs(Prefs, TopXMLNS); +encode({mam_fin, _, _, _, _, _} = Fin, TopXMLNS) -> + encode_mam_fin(Fin, TopXMLNS); +encode({forwarded, _, _} = Forwarded, TopXMLNS) -> + encode_forwarded(Forwarded, TopXMLNS); +encode({carbons_disable} = Disable, TopXMLNS) -> + encode_carbons_disable(Disable, TopXMLNS); +encode({carbons_enable} = Enable, TopXMLNS) -> + encode_carbons_enable(Enable, TopXMLNS); +encode({carbons_private} = Private, TopXMLNS) -> + encode_carbons_private(Private, TopXMLNS); +encode({carbons_received, _} = Received, TopXMLNS) -> + encode_carbons_received(Received, TopXMLNS); +encode({carbons_sent, _} = Sent, TopXMLNS) -> + encode_carbons_sent(Sent, TopXMLNS); +encode({feature_csi, <<"urn:xmpp:csi:0">>} = Csi, + TopXMLNS) -> + encode_feature_csi(Csi, TopXMLNS); +encode({feature_csi, <<>>} = Csi, + TopXMLNS = <<"urn:xmpp:csi:0">>) -> + encode_feature_csi(Csi, TopXMLNS); +encode({csi, active} = Active, TopXMLNS) -> + encode_csi_active(Active, TopXMLNS); +encode({csi, inactive} = Inactive, TopXMLNS) -> + encode_csi_inactive(Inactive, TopXMLNS); +encode({feature_sm, _} = Sm, TopXMLNS) -> + encode_feature_sm(Sm, TopXMLNS); +encode({sm_enable, _, _, _} = Enable, TopXMLNS) -> + encode_sm_enable(Enable, TopXMLNS); +encode({sm_enabled, _, _, _, _, _} = Enabled, + TopXMLNS) -> + encode_sm_enabled(Enabled, TopXMLNS); +encode({sm_resume, _, _, _} = Resume, TopXMLNS) -> + encode_sm_resume(Resume, TopXMLNS); +encode({sm_resumed, _, _, _} = Resumed, TopXMLNS) -> + encode_sm_resumed(Resumed, TopXMLNS); +encode({sm_r, _} = R, TopXMLNS) -> + encode_sm_r(R, TopXMLNS); +encode({sm_a, _, _} = A, TopXMLNS) -> + encode_sm_a(A, TopXMLNS); +encode({sm_failed, _, _, _} = Failed, TopXMLNS) -> + encode_sm_failed(Failed, TopXMLNS); +encode({offline_item, _, _} = Item, TopXMLNS) -> + encode_offline_item(Item, TopXMLNS); +encode({offline, _, _, _} = Offline, TopXMLNS) -> + encode_offline(Offline, TopXMLNS); +encode({mix_join, _, _} = Join, TopXMLNS) -> + encode_mix_join(Join, TopXMLNS); +encode({mix_leave} = Leave, TopXMLNS) -> + encode_mix_leave(Leave, TopXMLNS); +encode({mix_participant, _, _} = Participant, + TopXMLNS) -> + encode_mix_participant(Participant, TopXMLNS); +encode({hint, 'no-copy'} = No_copy, TopXMLNS) -> + encode_hint_no_copy(No_copy, TopXMLNS); +encode({hint, 'no-store'} = No_store, TopXMLNS) -> + encode_hint_no_store(No_store, TopXMLNS); +encode({hint, 'no-storage'} = No_storage, TopXMLNS) -> + encode_hint_no_storage(No_storage, TopXMLNS); +encode({hint, store} = Store, TopXMLNS) -> + encode_hint_store(Store, TopXMLNS); encode({hint, 'no-permanent-store'} = - No_permanent_store) -> + No_permanent_store, + TopXMLNS) -> encode_hint_no_permanent_store(No_permanent_store, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); + TopXMLNS); encode({hint, 'no-permanent-storage'} = - No_permanent_storage) -> + No_permanent_storage, + TopXMLNS) -> encode_hint_no_permanent_storage(No_permanent_storage, - [{<<"xmlns">>, <<"urn:xmpp:hints">>}]); -encode({search_item, _, _, _, _, _} = Item) -> - encode_search_item(Item, - [{<<"xmlns">>, <<"jabber:iq:search">>}]); -encode({search, _, _, _, _, _, _, _} = Query) -> - encode_search(Query, - [{<<"xmlns">>, <<"jabber:iq:search">>}]); -encode({xevent, _, _, _, _, _} = X) -> - encode_xevent(X, [{<<"xmlns">>, <<"jabber:x:event">>}]); -encode({expire, _, _} = X) -> - encode_expire(X, - [{<<"xmlns">>, <<"jabber:x:expire">>}]); -encode({nick, _} = Nick) -> - encode_nick(Nick, - [{<<"xmlns">>, <<"http://jabber.org/protocol/nick">>}]); -encode({address, _, _, _, _, _} = Address) -> - encode_address(Address, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/address">>}]); -encode({addresses, _} = Addresses) -> - encode_addresses(Addresses, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/address">>}]); -encode({stanza_id, _, _} = Stanza_id) -> - encode_stanza_id(Stanza_id, - [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]); -encode({client_id, _} = Client_id) -> - encode_client_id(Client_id, - [{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]); -encode({adhoc_actions, _, _, _, _} = Actions) -> - encode_adhoc_command_actions(Actions, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/commands">>}]); -encode({adhoc_note, _, _} = Note) -> - encode_adhoc_command_notes(Note, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/commands">>}]); + TopXMLNS); +encode({search_item, _, _, _, _, _} = Item, TopXMLNS) -> + encode_search_item(Item, TopXMLNS); +encode({search, _, _, _, _, _, _, _} = Query, + TopXMLNS) -> + encode_search(Query, TopXMLNS); +encode({xevent, _, _, _, _, _} = X, TopXMLNS) -> + encode_xevent(X, TopXMLNS); +encode({expire, _, _} = X, TopXMLNS) -> + encode_expire(X, TopXMLNS); +encode({nick, _} = Nick, TopXMLNS) -> + encode_nick(Nick, TopXMLNS); +encode({address, _, _, _, _, _} = Address, TopXMLNS) -> + encode_address(Address, TopXMLNS); +encode({addresses, _} = Addresses, TopXMLNS) -> + encode_addresses(Addresses, TopXMLNS); +encode({stanza_id, _, _} = Stanza_id, TopXMLNS) -> + encode_stanza_id(Stanza_id, TopXMLNS); +encode({client_id, _} = Client_id, TopXMLNS) -> + encode_client_id(Client_id, TopXMLNS); +encode({adhoc_actions, _, _, _, _} = Actions, + TopXMLNS) -> + encode_adhoc_command_actions(Actions, TopXMLNS); +encode({adhoc_note, _, _} = Note, TopXMLNS) -> + encode_adhoc_command_notes(Note, TopXMLNS); encode({adhoc_command, _, _, _, _, _, _, _, _} = - Command) -> - encode_adhoc_command(Command, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/commands">>}]); -encode({db_result, _, _, _, _, _} = Db_result) -> - encode_db_result(Db_result, - [{<<"xmlns">>, <<"jabber:client">>}]); -encode({db_verify, _, _, _, _, _, _} = Db_verify) -> - encode_db_verify(Db_verify, - [{<<"xmlns">>, <<"jabber:client">>}]); -encode({handshake, _} = Handshake) -> - encode_handshake(Handshake, - [{<<"xmlns">>, <<"jabber:client">>}]); + Command, + TopXMLNS) -> + encode_adhoc_command(Command, TopXMLNS); +encode({db_result, _, _, _, _, _} = Db_result, + TopXMLNS) -> + encode_db_result(Db_result, TopXMLNS); +encode({db_verify, _, _, _, _, _, _} = Db_verify, + TopXMLNS) -> + encode_db_verify(Db_verify, TopXMLNS); +encode({handshake, _} = Handshake, TopXMLNS) -> + encode_handshake(Handshake, TopXMLNS); encode({stream_start, _, _, _, _, _, _, _, _} = - Stream_stream) -> - encode_stream_start(Stream_stream, []); -encode({bob_data, _, _, _, _} = Data) -> - encode_bob_data(Data, - [{<<"xmlns">>, <<"urn:xmpp:bob">>}]); -encode({xcaptcha, _} = Captcha) -> - encode_captcha(Captcha, - [{<<"xmlns">>, <<"urn:xmpp:captcha">>}]); -encode({media_uri, _, _} = Uri) -> - encode_media_uri(Uri, - [{<<"xmlns">>, <<"urn:xmpp:media-element">>}]); -encode({media, _, _, _} = Media) -> - encode_media(Media, - [{<<"xmlns">>, <<"urn:xmpp:media-element">>}]); -encode({oob_x, _, _, _} = X) -> - encode_oob_x(X, [{<<"xmlns">>, <<"jabber:x:oob">>}]); -encode({sic, _, _, _} = Address) -> - encode_sic(Address, []); -encode({upload_request, _, _, _, _} = Request) -> - encode_upload_request(Request, []); -encode({upload_slot, _, _, _} = Slot) -> - encode_upload_slot(Slot, []); -encode({thumbnail, _, _, _, _} = Thumbnail) -> - encode_thumbnail(Thumbnail, - [{<<"xmlns">>, <<"urn:xmpp:thumbs:1">>}]). + Stream_stream, + TopXMLNS) -> + encode_stream_start(Stream_stream, TopXMLNS); +encode({bob_data, _, _, _, _} = Data, TopXMLNS) -> + encode_bob_data(Data, TopXMLNS); +encode({xcaptcha, _} = Captcha, TopXMLNS) -> + encode_captcha(Captcha, TopXMLNS); +encode({media_uri, _, _} = Uri, TopXMLNS) -> + encode_media_uri(Uri, TopXMLNS); +encode({media, _, _, _} = Media, TopXMLNS) -> + encode_media(Media, TopXMLNS); +encode({oob_x, _, _, _} = X, TopXMLNS) -> + encode_oob_x(X, TopXMLNS); +encode({sic, _, _, _} = Address, TopXMLNS) -> + encode_sic(Address, TopXMLNS); +encode({upload_request, _, _, _, _} = Request, + TopXMLNS) -> + encode_upload_request(Request, TopXMLNS); +encode({upload_slot, _, _, _} = Slot, TopXMLNS) -> + encode_upload_slot(Slot, TopXMLNS); +encode({thumbnail, _, _, _, _} = Thumbnail, TopXMLNS) -> + encode_thumbnail(Thumbnail, TopXMLNS). get_name({address, _, _, _, _, _}) -> <<"address">>; get_name({addresses, _}) -> <<"addresses">>; @@ -3434,9 +6071,9 @@ get_ns({compression, _}) -> get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>; get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>; get_ns({db_result, _, _, _, _, _}) -> - <<"jabber:client">>; + <<"jabber:server">>; get_ns({db_verify, _, _, _, _, _, _}) -> - <<"jabber:client">>; + <<"jabber:server">>; get_ns({delay, _, _, _}) -> <<"urn:xmpp:delay">>; get_ns({disco_info, _, _, _, _}) -> <<"http://jabber.org/protocol/disco#info">>; @@ -3452,7 +6089,7 @@ get_ns({feature_sm, Xmlns}) -> Xmlns; get_ns({forwarded, _, _}) -> <<"urn:xmpp:forward:0">>; get_ns({gone, _}) -> <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; -get_ns({handshake, _}) -> <<"jabber:client">>; +get_ns({handshake, _}) -> <<"jabber:component:accept">>; get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; get_ns({hint, 'no-permanent-storage'}) -> <<"urn:xmpp:hints">>; @@ -3649,10 +6286,8 @@ get_ns({stat_error, _, _}) -> <<"http://jabber.org/protocol/stats">>; get_ns({stats, _, _}) -> <<"http://jabber.org/protocol/stats">>; -get_ns({stream_error, _, _}) -> - <<"http://etherx.jabber.org/streams">>; -get_ns({stream_features, _}) -> - <<"http://etherx.jabber.org/streams">>; +get_ns({stream_error, _, _}) -> <<"jabber:client">>; +get_ns({stream_features, _}) -> <<"jabber:client">>; get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> Xmlns; get_ns({streamhost, _, _, _}) -> @@ -3735,7 +6370,9 @@ format_error({missing_cdata, <<>>, Tag, XMLNS}) -> "/> qualified by namespace '", XMLNS/binary, "'">>; format_error({unknown_tag, Tag, XMLNS}) -> <<"Unknown tag <", Tag/binary, - "/> qualified by namespace '", XMLNS/binary, "'">>. + "/> qualified by namespace '", XMLNS/binary, "'">>; +format_error({missing_tag_xmlns, Tag}) -> + <<"Missing namespace for tag <", Tag/binary, "/>">>. get_attr(Attr, Attrs) -> case lists:keyfind(Attr, 1, Attrs) of @@ -3743,6 +6380,16 @@ get_attr(Attr, Attrs) -> false -> <<>> end. +enc_xmlns_attrs(XMLNS, XMLNS) -> []; +enc_xmlns_attrs(XMLNS, _) -> [{<<"xmlns">>, XMLNS}]. + +choose_top_xmlns(<<>>, NSList, TopXMLNS) -> + case lists:member(TopXMLNS, NSList) of + true -> TopXMLNS; + false -> hd(NSList) + end; +choose_top_xmlns(XMLNS, _, _) -> XMLNS. + pp(Term) -> io_lib_pretty:print(Term, fun pp/2). pp(last, 2) -> [seconds, status]; @@ -4084,13 +6731,17 @@ decode_thumbnail_attrs(__TopXMLNS, [], Uri, Media_type, encode_thumbnail({thumbnail, Uri, Media_type, Width, Height}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:thumbs:1">>, [], + __TopXMLNS), _els = [], _attrs = encode_thumbnail_attr_height(Height, encode_thumbnail_attr_width(Width, 'encode_thumbnail_attr_media-type'(Media_type, encode_thumbnail_attr_uri(Uri, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"thumbnail">>, _attrs, _els}. decode_thumbnail_attr_uri(__TopXMLNS, undefined) -> @@ -4221,30 +6872,35 @@ decode_upload_slot_attrs(__TopXMLNS, [], Xmlns) -> decode_upload_slot_attr_xmlns(__TopXMLNS, Xmlns). encode_upload_slot({upload_slot, Get, Put, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = lists:reverse('encode_upload_slot_$put'(Put, + __NewTopXMLNS, 'encode_upload_slot_$get'(Get, + __NewTopXMLNS, []))), - _attrs = encode_upload_slot_attr_xmlns(Xmlns, - _xmlns_attrs), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"slot">>, _attrs, _els}. -'encode_upload_slot_$put'(undefined, _acc) -> _acc; -'encode_upload_slot_$put'(Put, _acc) -> - [encode_upload_put(Put, []) | _acc]. +'encode_upload_slot_$put'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_upload_slot_$put'(Put, __TopXMLNS, _acc) -> + [encode_upload_put(Put, __TopXMLNS) | _acc]. -'encode_upload_slot_$get'(undefined, _acc) -> _acc; -'encode_upload_slot_$get'(Get, _acc) -> - [encode_upload_get(Get, []) | _acc]. +'encode_upload_slot_$get'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_upload_slot_$get'(Get, __TopXMLNS, _acc) -> + [encode_upload_get(Get, __TopXMLNS) | _acc]. decode_upload_slot_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_upload_slot_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_upload_slot_attr_xmlns(<<>>, _acc) -> _acc; -encode_upload_slot_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_upload_put(__TopXMLNS, __IgnoreEls, {xmlel, <<"put">>, _attrs, _els}) -> Cdata = decode_upload_put_els(__TopXMLNS, __IgnoreEls, @@ -4263,9 +6919,13 @@ decode_upload_put_els(__TopXMLNS, __IgnoreEls, decode_upload_put_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_upload_put(Cdata, _xmlns_attrs) -> +encode_upload_put(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = encode_upload_put_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"put">>, _attrs, _els}. decode_upload_put_cdata(__TopXMLNS, <<>>) -> @@ -4294,9 +6954,13 @@ decode_upload_get_els(__TopXMLNS, __IgnoreEls, decode_upload_get_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_upload_get(Cdata, _xmlns_attrs) -> +encode_upload_get(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = encode_upload_get_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"get">>, _attrs, _els}. decode_upload_get_cdata(__TopXMLNS, <<>>) -> @@ -4437,27 +7101,36 @@ decode_upload_request_attrs(__TopXMLNS, [], Xmlns) -> encode_upload_request({upload_request, Filename, Size, Content_type, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = lists:reverse('encode_upload_request_$content-type'(Content_type, + __NewTopXMLNS, 'encode_upload_request_$size'(Size, + __NewTopXMLNS, 'encode_upload_request_$filename'(Filename, + __NewTopXMLNS, [])))), - _attrs = encode_upload_request_attr_xmlns(Xmlns, - _xmlns_attrs), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"request">>, _attrs, _els}. -'encode_upload_request_$content-type'(<<>>, _acc) -> +'encode_upload_request_$content-type'(<<>>, __TopXMLNS, + _acc) -> _acc; 'encode_upload_request_$content-type'(Content_type, - _acc) -> - [encode_upload_content_type(Content_type, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_upload_content_type(Content_type, __TopXMLNS) + | _acc]. -'encode_upload_request_$size'(Size, _acc) -> - [encode_upload_size(Size, []) | _acc]. +'encode_upload_request_$size'(Size, __TopXMLNS, _acc) -> + [encode_upload_size(Size, __TopXMLNS) | _acc]. -'encode_upload_request_$filename'(Filename, _acc) -> - [encode_upload_filename(Filename, []) | _acc]. +'encode_upload_request_$filename'(Filename, __TopXMLNS, + _acc) -> + [encode_upload_filename(Filename, __TopXMLNS) | _acc]. decode_upload_request_attr_xmlns(__TopXMLNS, undefined) -> @@ -4465,10 +7138,6 @@ decode_upload_request_attr_xmlns(__TopXMLNS, decode_upload_request_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_upload_request_attr_xmlns(<<>>, _acc) -> _acc; -encode_upload_request_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_upload_content_type(__TopXMLNS, __IgnoreEls, {xmlel, <<"content-type">>, _attrs, _els}) -> Cdata = decode_upload_content_type_els(__TopXMLNS, @@ -4487,9 +7156,13 @@ decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_upload_content_type(Cdata, _xmlns_attrs) -> +encode_upload_content_type(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = encode_upload_content_type_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"content-type">>, _attrs, _els}. decode_upload_content_type_cdata(__TopXMLNS, <<>>) -> @@ -4519,9 +7192,13 @@ decode_upload_size_els(__TopXMLNS, __IgnoreEls, decode_upload_size_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_upload_size(Cdata, _xmlns_attrs) -> +encode_upload_size(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = encode_upload_size_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"size">>, _attrs, _els}. decode_upload_size_cdata(__TopXMLNS, <<>>) -> @@ -4556,9 +7233,13 @@ decode_upload_filename_els(__TopXMLNS, __IgnoreEls, decode_upload_filename_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_upload_filename(Cdata, _xmlns_attrs) -> +encode_upload_filename(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:http:upload">>, + <<"eu:siacs:conversations:http:upload">>], + __TopXMLNS), _els = encode_upload_filename_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"filename">>, _attrs, _els}. decode_upload_filename_cdata(__TopXMLNS, <<>>) -> @@ -4624,27 +7305,29 @@ decode_sic_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> decode_sic_attrs(__TopXMLNS, [], Xmlns) -> decode_sic_attr_xmlns(__TopXMLNS, Xmlns). -encode_sic({sic, Ip, Port, Xmlns}, _xmlns_attrs) -> - _els = lists:reverse('encode_sic_$ip'(Ip, - 'encode_sic_$port'(Port, []))), - _attrs = encode_sic_attr_xmlns(Xmlns, _xmlns_attrs), +encode_sic({sic, Ip, Port, Xmlns}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sic:0">>, + <<"urn:xmpp:sic:1">>], + __TopXMLNS), + _els = lists:reverse('encode_sic_$ip'(Ip, __NewTopXMLNS, + 'encode_sic_$port'(Port, + __NewTopXMLNS, + []))), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"address">>, _attrs, _els}. -'encode_sic_$ip'(undefined, _acc) -> _acc; -'encode_sic_$ip'(Ip, _acc) -> - [encode_sic_ip(Ip, []) | _acc]. +'encode_sic_$ip'(undefined, __TopXMLNS, _acc) -> _acc; +'encode_sic_$ip'(Ip, __TopXMLNS, _acc) -> + [encode_sic_ip(Ip, __TopXMLNS) | _acc]. -'encode_sic_$port'(undefined, _acc) -> _acc; -'encode_sic_$port'(Port, _acc) -> - [encode_sip_port(Port, []) | _acc]. +'encode_sic_$port'(undefined, __TopXMLNS, _acc) -> _acc; +'encode_sic_$port'(Port, __TopXMLNS, _acc) -> + [encode_sip_port(Port, __TopXMLNS) | _acc]. decode_sic_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sic_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sic_attr_xmlns(<<>>, _acc) -> _acc; -encode_sic_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sip_port(__TopXMLNS, __IgnoreEls, {xmlel, <<"port">>, _attrs, _els}) -> Cdata = decode_sip_port_els(__TopXMLNS, __IgnoreEls, @@ -4663,9 +7346,11 @@ decode_sip_port_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_sip_port_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_sip_port(Cdata, _xmlns_attrs) -> +encode_sip_port(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sic:1">>, + [], __TopXMLNS), _els = encode_sip_port_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"port">>, _attrs, _els}. decode_sip_port_cdata(__TopXMLNS, <<>>) -> @@ -4698,9 +7383,13 @@ decode_sic_ip_els(__TopXMLNS, __IgnoreEls, [_ | _els], Cdata) -> decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_sic_ip(Cdata, _xmlns_attrs) -> +encode_sic_ip(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:sic:0">>, + <<"urn:xmpp:sic:1">>], + __TopXMLNS), _els = encode_sic_ip_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ip">>, _attrs, _els}. decode_sic_ip_cdata(__TopXMLNS, <<>>) -> @@ -4779,18 +7468,24 @@ decode_oob_x_attrs(__TopXMLNS, [_ | _attrs], Sid) -> decode_oob_x_attrs(__TopXMLNS, [], Sid) -> decode_oob_x_attr_sid(__TopXMLNS, Sid). -encode_oob_x({oob_x, Url, Desc, Sid}, _xmlns_attrs) -> +encode_oob_x({oob_x, Url, Desc, Sid}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], + __TopXMLNS), _els = lists:reverse('encode_oob_x_$desc'(Desc, - 'encode_oob_x_$url'(Url, []))), - _attrs = encode_oob_x_attr_sid(Sid, _xmlns_attrs), + __NewTopXMLNS, + 'encode_oob_x_$url'(Url, + __NewTopXMLNS, + []))), + _attrs = encode_oob_x_attr_sid(Sid, + enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), {xmlel, <<"x">>, _attrs, _els}. -'encode_oob_x_$desc'(<<>>, _acc) -> _acc; -'encode_oob_x_$desc'(Desc, _acc) -> - [encode_oob_desc(Desc, []) | _acc]. +'encode_oob_x_$desc'(<<>>, __TopXMLNS, _acc) -> _acc; +'encode_oob_x_$desc'(Desc, __TopXMLNS, _acc) -> + [encode_oob_desc(Desc, __TopXMLNS) | _acc]. -'encode_oob_x_$url'(Url, _acc) -> - [encode_oob_url(Url, []) | _acc]. +'encode_oob_x_$url'(Url, __TopXMLNS, _acc) -> + [encode_oob_url(Url, __TopXMLNS) | _acc]. decode_oob_x_attr_sid(__TopXMLNS, undefined) -> <<>>; decode_oob_x_attr_sid(__TopXMLNS, _val) -> _val. @@ -4817,9 +7512,11 @@ decode_oob_desc_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_oob_desc_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_oob_desc(Cdata, _xmlns_attrs) -> +encode_oob_desc(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], + __TopXMLNS), _els = encode_oob_desc_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"desc">>, _attrs, _els}. decode_oob_desc_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -4847,9 +7544,11 @@ decode_oob_url_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_oob_url_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_oob_url(Cdata, _xmlns_attrs) -> +encode_oob_url(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], + __TopXMLNS), _els = encode_oob_url_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"url">>, _attrs, _els}. decode_oob_url_cdata(__TopXMLNS, <<>>) -> @@ -4903,18 +7602,22 @@ decode_media_attrs(__TopXMLNS, [], Height, Width) -> {decode_media_attr_height(__TopXMLNS, Height), decode_media_attr_width(__TopXMLNS, Width)}. -encode_media({media, Height, Width, Uri}, - _xmlns_attrs) -> - _els = lists:reverse('encode_media_$uri'(Uri, [])), +encode_media({media, Height, Width, Uri}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:media-element">>, [], + __TopXMLNS), + _els = lists:reverse('encode_media_$uri'(Uri, + __NewTopXMLNS, [])), _attrs = encode_media_attr_width(Width, encode_media_attr_height(Height, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"media">>, _attrs, _els}. -'encode_media_$uri'([], _acc) -> _acc; -'encode_media_$uri'([Uri | _els], _acc) -> - 'encode_media_$uri'(_els, - [encode_media_uri(Uri, []) | _acc]). +'encode_media_$uri'([], __TopXMLNS, _acc) -> _acc; +'encode_media_$uri'([Uri | _els], __TopXMLNS, _acc) -> + 'encode_media_$uri'(_els, __TopXMLNS, + [encode_media_uri(Uri, __TopXMLNS) | _acc]). decode_media_attr_height(__TopXMLNS, undefined) -> undefined; @@ -4975,10 +7678,14 @@ decode_media_uri_attrs(__TopXMLNS, [_ | _attrs], decode_media_uri_attrs(__TopXMLNS, [], Type) -> decode_media_uri_attr_type(__TopXMLNS, Type). -encode_media_uri({media_uri, Type, Uri}, - _xmlns_attrs) -> +encode_media_uri({media_uri, Type, Uri}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:media-element">>, [], + __TopXMLNS), _els = encode_media_uri_cdata(Uri, []), - _attrs = encode_media_uri_attr_type(Type, _xmlns_attrs), + _attrs = encode_media_uri_attr_type(Type, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"uri">>, _attrs, _els}. decode_media_uri_attr_type(__TopXMLNS, undefined) -> @@ -5026,16 +7733,16 @@ decode_captcha_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, Xdata). -encode_captcha({xcaptcha, Xdata}, _xmlns_attrs) -> +encode_captcha({xcaptcha, Xdata}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:captcha">>, + [], __TopXMLNS), _els = lists:reverse('encode_captcha_$xdata'(Xdata, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"captcha">>, _attrs, _els}. -'encode_captcha_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_captcha_$xdata'(Xdata, __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_bob_data(__TopXMLNS, __IgnoreEls, {xmlel, <<"data">>, _attrs, _els}) -> @@ -5082,12 +7789,15 @@ decode_bob_data_attrs(__TopXMLNS, [], Cid, Max_age, decode_bob_data_attr_type(__TopXMLNS, Type)}. encode_bob_data({bob_data, Cid, Max_age, Type, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:bob">>, [], + __TopXMLNS), _els = encode_bob_data_cdata(Data, []), _attrs = encode_bob_data_attr_type(Type, 'encode_bob_data_attr_max-age'(Max_age, encode_bob_data_attr_cid(Cid, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"data">>, _attrs, _els}. decode_bob_data_attr_cid(__TopXMLNS, undefined) -> @@ -5206,17 +7916,21 @@ decode_stream_start_attrs(__TopXMLNS, [], From, To, encode_stream_start({stream_start, From, To, Id, Version, Xmlns, Stream_xmlns, Db_xmlns, Lang}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = [], _attrs = encode_stream_start_attr_id(Id, encode_stream_start_attr_version(Version, 'encode_stream_start_attr_xml:lang'(Lang, 'encode_stream_start_attr_xmlns:db'(Db_xmlns, 'encode_stream_start_attr_xmlns:stream'(Stream_xmlns, - encode_stream_start_attr_xmlns(Xmlns, - encode_stream_start_attr_to(To, - encode_stream_start_attr_from(From, - _xmlns_attrs)))))))), + encode_stream_start_attr_to(To, + encode_stream_start_attr_from(From, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))))), {xmlel, <<"stream:stream">>, _attrs, _els}. decode_stream_start_attr_from(__TopXMLNS, undefined) -> @@ -5254,10 +7968,6 @@ decode_stream_start_attr_xmlns(__TopXMLNS, undefined) -> decode_stream_start_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_stream_start_attr_xmlns(<<>>, _acc) -> _acc; -encode_stream_start_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - 'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, undefined) -> <<>>; @@ -5333,9 +8043,12 @@ decode_handshake_els(__TopXMLNS, __IgnoreEls, decode_handshake_els(__TopXMLNS, __IgnoreEls, _els, Data). -encode_handshake({handshake, Data}, _xmlns_attrs) -> +encode_handshake({handshake, Data}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:component:accept">>, [], + __TopXMLNS), _els = encode_handshake_cdata(Data, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"handshake">>, _attrs, _els}. decode_handshake_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -5368,10 +8081,10 @@ decode_db_verify_els(__TopXMLNS, __IgnoreEls, decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, __Els) @@ -5407,14 +8120,17 @@ decode_db_verify_attrs(__TopXMLNS, [], From, To, Id, encode_db_verify({db_verify, From, To, Id, Type, Key, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:server">>, + [], __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _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, encode_db_verify_attr_from(From, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"db:verify">>, _attrs, _els}. decode_db_verify_attr_from(__TopXMLNS, undefined) -> @@ -5501,10 +8217,10 @@ decode_db_result_els(__TopXMLNS, __IgnoreEls, decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, __Els) @@ -5535,13 +8251,16 @@ decode_db_result_attrs(__TopXMLNS, [], From, To, encode_db_result({db_result, From, To, Type, Key, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:server">>, + [], __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _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))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"db:result">>, _attrs, _els}. decode_db_result_attr_from(__TopXMLNS, undefined) -> @@ -5715,36 +8434,49 @@ decode_adhoc_command_attrs(__TopXMLNS, [], Node, Lang, encode_adhoc_command({adhoc_command, Node, Action, Sid, Status, Lang, Actions, Notes, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = lists:reverse('encode_adhoc_command_$xdata'(Xdata, + __NewTopXMLNS, 'encode_adhoc_command_$notes'(Notes, + __NewTopXMLNS, 'encode_adhoc_command_$actions'(Actions, + __NewTopXMLNS, [])))), _attrs = encode_adhoc_command_attr_action(Action, encode_adhoc_command_attr_status(Status, encode_adhoc_command_attr_sessionid(Sid, 'encode_adhoc_command_attr_xml:lang'(Lang, encode_adhoc_command_attr_node(Node, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"command">>, _attrs, _els}. -'encode_adhoc_command_$xdata'(undefined, _acc) -> _acc; -'encode_adhoc_command_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_adhoc_command_$xdata'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_adhoc_command_$xdata'(Xdata, __TopXMLNS, + _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. -'encode_adhoc_command_$notes'([], _acc) -> _acc; -'encode_adhoc_command_$notes'([Notes | _els], _acc) -> - 'encode_adhoc_command_$notes'(_els, - [encode_adhoc_command_notes(Notes, []) +'encode_adhoc_command_$notes'([], __TopXMLNS, _acc) -> + _acc; +'encode_adhoc_command_$notes'([Notes | _els], + __TopXMLNS, _acc) -> + 'encode_adhoc_command_$notes'(_els, __TopXMLNS, + [encode_adhoc_command_notes(Notes, __TopXMLNS) | _acc]). -'encode_adhoc_command_$actions'(undefined, _acc) -> +'encode_adhoc_command_$actions'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_adhoc_command_$actions'(Actions, _acc) -> - [encode_adhoc_command_actions(Actions, []) | _acc]. +'encode_adhoc_command_$actions'(Actions, __TopXMLNS, + _acc) -> + [encode_adhoc_command_actions(Actions, __TopXMLNS) + | _acc]. decode_adhoc_command_attr_node(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -5847,10 +8579,14 @@ decode_adhoc_command_notes_attrs(__TopXMLNS, [], decode_adhoc_command_notes_attr_type(__TopXMLNS, Type). encode_adhoc_command_notes({adhoc_note, Type, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = encode_adhoc_command_notes_cdata(Data, []), _attrs = encode_adhoc_command_notes_attr_type(Type, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"note">>, _attrs, _els}. decode_adhoc_command_notes_attr_type(__TopXMLNS, @@ -5991,32 +8727,45 @@ decode_adhoc_command_actions_attrs(__TopXMLNS, [], encode_adhoc_command_actions({adhoc_actions, Execute, Prev, Next, Complete}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = lists:reverse('encode_adhoc_command_actions_$next'(Next, + __NewTopXMLNS, 'encode_adhoc_command_actions_$complete'(Complete, + __NewTopXMLNS, 'encode_adhoc_command_actions_$prev'(Prev, + __NewTopXMLNS, [])))), _attrs = encode_adhoc_command_actions_attr_execute(Execute, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"actions">>, _attrs, _els}. -'encode_adhoc_command_actions_$next'(false, _acc) -> +'encode_adhoc_command_actions_$next'(false, __TopXMLNS, + _acc) -> _acc; -'encode_adhoc_command_actions_$next'(Next, _acc) -> - [encode_adhoc_command_next(Next, []) | _acc]. +'encode_adhoc_command_actions_$next'(Next, __TopXMLNS, + _acc) -> + [encode_adhoc_command_next(Next, __TopXMLNS) | _acc]. -'encode_adhoc_command_actions_$complete'(false, _acc) -> +'encode_adhoc_command_actions_$complete'(false, + __TopXMLNS, _acc) -> _acc; 'encode_adhoc_command_actions_$complete'(Complete, - _acc) -> - [encode_adhoc_command_complete(Complete, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_adhoc_command_complete(Complete, __TopXMLNS) + | _acc]. -'encode_adhoc_command_actions_$prev'(false, _acc) -> +'encode_adhoc_command_actions_$prev'(false, __TopXMLNS, + _acc) -> _acc; -'encode_adhoc_command_actions_$prev'(Prev, _acc) -> - [encode_adhoc_command_prev(Prev, []) | _acc]. +'encode_adhoc_command_actions_$prev'(Prev, __TopXMLNS, + _acc) -> + [encode_adhoc_command_prev(Prev, __TopXMLNS) | _acc]. decode_adhoc_command_actions_attr_execute(__TopXMLNS, undefined) -> @@ -6041,27 +8790,36 @@ decode_adhoc_command_complete(__TopXMLNS, __IgnoreEls, {xmlel, <<"complete">>, _attrs, _els}) -> true. -encode_adhoc_command_complete(true, _xmlns_attrs) -> +encode_adhoc_command_complete(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"complete">>, _attrs, _els}. decode_adhoc_command_next(__TopXMLNS, __IgnoreEls, {xmlel, <<"next">>, _attrs, _els}) -> true. -encode_adhoc_command_next(true, _xmlns_attrs) -> +encode_adhoc_command_next(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"next">>, _attrs, _els}. decode_adhoc_command_prev(__TopXMLNS, __IgnoreEls, {xmlel, <<"prev">>, _attrs, _els}) -> true. -encode_adhoc_command_prev(true, _xmlns_attrs) -> +encode_adhoc_command_prev(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"prev">>, _attrs, _els}. decode_client_id(__TopXMLNS, __IgnoreEls, @@ -6078,9 +8836,13 @@ decode_client_id_attrs(__TopXMLNS, [_ | _attrs], Id) -> decode_client_id_attrs(__TopXMLNS, [], Id) -> decode_client_id_attr_id(__TopXMLNS, Id). -encode_client_id({client_id, Id}, _xmlns_attrs) -> +encode_client_id({client_id, Id}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sid:0">>, + [], __TopXMLNS), _els = [], - _attrs = encode_client_id_attr_id(Id, _xmlns_attrs), + _attrs = encode_client_id_attr_id(Id, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"client-id">>, _attrs, _els}. decode_client_id_attr_id(__TopXMLNS, undefined) -> @@ -6110,11 +8872,14 @@ decode_stanza_id_attrs(__TopXMLNS, [], Id, By) -> {decode_stanza_id_attr_id(__TopXMLNS, Id), decode_stanza_id_attr_by(__TopXMLNS, By)}. -encode_stanza_id({stanza_id, By, Id}, _xmlns_attrs) -> +encode_stanza_id({stanza_id, By, Id}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sid:0">>, + [], __TopXMLNS), _els = [], _attrs = encode_stanza_id_attr_by(By, encode_stanza_id_attr_id(Id, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"stanza-id">>, _attrs, _els}. decode_stanza_id_attr_id(__TopXMLNS, undefined) -> @@ -6173,16 +8938,20 @@ decode_addresses_els(__TopXMLNS, __IgnoreEls, decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, List). -encode_addresses({addresses, List}, _xmlns_attrs) -> +encode_addresses({addresses, List}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/address">>, + [], __TopXMLNS), _els = lists:reverse('encode_addresses_$list'(List, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"addresses">>, _attrs, _els}. -'encode_addresses_$list'([], _acc) -> _acc; -'encode_addresses_$list'([List | _els], _acc) -> - 'encode_addresses_$list'(_els, - [encode_address(List, []) | _acc]). +'encode_addresses_$list'([], __TopXMLNS, _acc) -> _acc; +'encode_addresses_$list'([List | _els], __TopXMLNS, + _acc) -> + 'encode_addresses_$list'(_els, __TopXMLNS, + [encode_address(List, __TopXMLNS) | _acc]). decode_address(__TopXMLNS, __IgnoreEls, {xmlel, <<"address">>, _attrs, _els}) -> @@ -6230,14 +8999,18 @@ decode_address_attrs(__TopXMLNS, [], Type, Jid, Desc, encode_address({address, Type, Jid, Desc, Node, Delivered}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/address">>, + [], __TopXMLNS), _els = [], _attrs = encode_address_attr_delivered(Delivered, encode_address_attr_node(Node, encode_address_attr_desc(Desc, encode_address_attr_jid(Jid, encode_address_attr_type(Type, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"address">>, _attrs, _els}. decode_address_attr_type(__TopXMLNS, undefined) -> @@ -6317,9 +9090,12 @@ decode_nick_els(__TopXMLNS, __IgnoreEls, [_ | _els], Name) -> decode_nick_els(__TopXMLNS, __IgnoreEls, _els, Name). -encode_nick({nick, Name}, _xmlns_attrs) -> +encode_nick({nick, Name}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/nick">>, + [], __TopXMLNS), _els = encode_nick_cdata(Name, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"nick">>, _attrs, _els}. decode_nick_cdata(__TopXMLNS, <<>>) -> @@ -6350,12 +9126,14 @@ decode_expire_attrs(__TopXMLNS, [], Seconds, Stored) -> {decode_expire_attr_seconds(__TopXMLNS, Seconds), decode_expire_attr_stored(__TopXMLNS, Stored)}. -encode_expire({expire, Seconds, Stored}, - _xmlns_attrs) -> +encode_expire({expire, Seconds, Stored}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:expire">>, + [], __TopXMLNS), _els = [], _attrs = encode_expire_attr_stored(Stored, encode_expire_attr_seconds(Seconds, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"x">>, _attrs, _els}. decode_expire_attr_seconds(__TopXMLNS, undefined) -> @@ -6495,35 +9273,50 @@ decode_xevent_els(__TopXMLNS, __IgnoreEls, [_ | _els], encode_xevent({xevent, Offline, Delivered, Displayed, Composing, Id}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = lists:reverse('encode_xevent_$id'(Id, + __NewTopXMLNS, 'encode_xevent_$displayed'(Displayed, + __NewTopXMLNS, 'encode_xevent_$delivered'(Delivered, + __NewTopXMLNS, 'encode_xevent_$offline'(Offline, + __NewTopXMLNS, 'encode_xevent_$composing'(Composing, + __NewTopXMLNS, [])))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"x">>, _attrs, _els}. -'encode_xevent_$id'(undefined, _acc) -> _acc; -'encode_xevent_$id'(Id, _acc) -> - [encode_xevent_id(Id, []) | _acc]. +'encode_xevent_$id'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_xevent_$id'(Id, __TopXMLNS, _acc) -> + [encode_xevent_id(Id, __TopXMLNS) | _acc]. -'encode_xevent_$displayed'(false, _acc) -> _acc; -'encode_xevent_$displayed'(Displayed, _acc) -> - [encode_xevent_displayed(Displayed, []) | _acc]. +'encode_xevent_$displayed'(false, __TopXMLNS, _acc) -> + _acc; +'encode_xevent_$displayed'(Displayed, __TopXMLNS, + _acc) -> + [encode_xevent_displayed(Displayed, __TopXMLNS) | _acc]. -'encode_xevent_$delivered'(false, _acc) -> _acc; -'encode_xevent_$delivered'(Delivered, _acc) -> - [encode_xevent_delivered(Delivered, []) | _acc]. +'encode_xevent_$delivered'(false, __TopXMLNS, _acc) -> + _acc; +'encode_xevent_$delivered'(Delivered, __TopXMLNS, + _acc) -> + [encode_xevent_delivered(Delivered, __TopXMLNS) | _acc]. -'encode_xevent_$offline'(false, _acc) -> _acc; -'encode_xevent_$offline'(Offline, _acc) -> - [encode_xevent_offline(Offline, []) | _acc]. +'encode_xevent_$offline'(false, __TopXMLNS, _acc) -> + _acc; +'encode_xevent_$offline'(Offline, __TopXMLNS, _acc) -> + [encode_xevent_offline(Offline, __TopXMLNS) | _acc]. -'encode_xevent_$composing'(false, _acc) -> _acc; -'encode_xevent_$composing'(Composing, _acc) -> - [encode_xevent_composing(Composing, []) | _acc]. +'encode_xevent_$composing'(false, __TopXMLNS, _acc) -> + _acc; +'encode_xevent_$composing'(Composing, __TopXMLNS, + _acc) -> + [encode_xevent_composing(Composing, __TopXMLNS) | _acc]. decode_xevent_id(__TopXMLNS, __IgnoreEls, {xmlel, <<"id">>, _attrs, _els}) -> @@ -6543,9 +9336,11 @@ decode_xevent_id_els(__TopXMLNS, __IgnoreEls, decode_xevent_id_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_xevent_id(Cdata, _xmlns_attrs) -> +encode_xevent_id(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = encode_xevent_id_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"id">>, _attrs, _els}. decode_xevent_id_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -6559,36 +9354,44 @@ decode_xevent_composing(__TopXMLNS, __IgnoreEls, {xmlel, <<"composing">>, _attrs, _els}) -> true. -encode_xevent_composing(true, _xmlns_attrs) -> +encode_xevent_composing(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"composing">>, _attrs, _els}. decode_xevent_displayed(__TopXMLNS, __IgnoreEls, {xmlel, <<"displayed">>, _attrs, _els}) -> true. -encode_xevent_displayed(true, _xmlns_attrs) -> +encode_xevent_displayed(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"displayed">>, _attrs, _els}. decode_xevent_delivered(__TopXMLNS, __IgnoreEls, {xmlel, <<"delivered">>, _attrs, _els}) -> true. -encode_xevent_delivered(true, _xmlns_attrs) -> +encode_xevent_delivered(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"delivered">>, _attrs, _els}. decode_xevent_offline(__TopXMLNS, __IgnoreEls, {xmlel, <<"offline">>, _attrs, _els}) -> true. -encode_xevent_offline(true, _xmlns_attrs) -> +encode_xevent_offline(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"offline">>, _attrs, _els}. decode_search(__TopXMLNS, __IgnoreEls, @@ -6736,48 +9539,65 @@ decode_search_els(__TopXMLNS, __IgnoreEls, [_ | _els], encode_search({search, Instructions, First, Last, Nick, Email, Items, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = lists:reverse('encode_search_$xdata'(Xdata, + __NewTopXMLNS, 'encode_search_$items'(Items, + __NewTopXMLNS, 'encode_search_$instructions'(Instructions, + __NewTopXMLNS, 'encode_search_$last'(Last, + __NewTopXMLNS, 'encode_search_$first'(First, + __NewTopXMLNS, 'encode_search_$nick'(Nick, + __NewTopXMLNS, 'encode_search_$email'(Email, + __NewTopXMLNS, [])))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_search_$xdata'(undefined, _acc) -> _acc; -'encode_search_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_search_$xdata'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_search_$xdata'(Xdata, __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. -'encode_search_$items'([], _acc) -> _acc; -'encode_search_$items'([Items | _els], _acc) -> - 'encode_search_$items'(_els, - [encode_search_item(Items, []) | _acc]). +'encode_search_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_search_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_search_$items'(_els, __TopXMLNS, + [encode_search_item(Items, __TopXMLNS) | _acc]). -'encode_search_$instructions'(undefined, _acc) -> _acc; -'encode_search_$instructions'(Instructions, _acc) -> - [encode_search_instructions(Instructions, []) | _acc]. +'encode_search_$instructions'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_search_$instructions'(Instructions, __TopXMLNS, + _acc) -> + [encode_search_instructions(Instructions, __TopXMLNS) + | _acc]. -'encode_search_$last'(undefined, _acc) -> _acc; -'encode_search_$last'(Last, _acc) -> - [encode_search_last(Last, []) | _acc]. +'encode_search_$last'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_search_$last'(Last, __TopXMLNS, _acc) -> + [encode_search_last(Last, __TopXMLNS) | _acc]. -'encode_search_$first'(undefined, _acc) -> _acc; -'encode_search_$first'(First, _acc) -> - [encode_search_first(First, []) | _acc]. +'encode_search_$first'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_search_$first'(First, __TopXMLNS, _acc) -> + [encode_search_first(First, __TopXMLNS) | _acc]. -'encode_search_$nick'(undefined, _acc) -> _acc; -'encode_search_$nick'(Nick, _acc) -> - [encode_search_nick(Nick, []) | _acc]. +'encode_search_$nick'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_search_$nick'(Nick, __TopXMLNS, _acc) -> + [encode_search_nick(Nick, __TopXMLNS) | _acc]. -'encode_search_$email'(undefined, _acc) -> _acc; -'encode_search_$email'(Email, _acc) -> - [encode_search_email(Email, []) | _acc]. +'encode_search_$email'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_search_$email'(Email, __TopXMLNS, _acc) -> + [encode_search_email(Email, __TopXMLNS) | _acc]. decode_search_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> @@ -6883,30 +9703,46 @@ decode_search_item_attrs(__TopXMLNS, [], Jid) -> encode_search_item({search_item, Jid, First, Last, Nick, Email}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = lists:reverse('encode_search_item_$last'(Last, + __NewTopXMLNS, 'encode_search_item_$first'(First, + __NewTopXMLNS, 'encode_search_item_$nick'(Nick, + __NewTopXMLNS, 'encode_search_item_$email'(Email, + __NewTopXMLNS, []))))), - _attrs = encode_search_item_attr_jid(Jid, _xmlns_attrs), + _attrs = encode_search_item_attr_jid(Jid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"item">>, _attrs, _els}. -'encode_search_item_$last'(undefined, _acc) -> _acc; -'encode_search_item_$last'(Last, _acc) -> - [encode_search_last(Last, []) | _acc]. +'encode_search_item_$last'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_search_item_$last'(Last, __TopXMLNS, _acc) -> + [encode_search_last(Last, __TopXMLNS) | _acc]. -'encode_search_item_$first'(undefined, _acc) -> _acc; -'encode_search_item_$first'(First, _acc) -> - [encode_search_first(First, []) | _acc]. +'encode_search_item_$first'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_search_item_$first'(First, __TopXMLNS, _acc) -> + [encode_search_first(First, __TopXMLNS) | _acc]. -'encode_search_item_$nick'(undefined, _acc) -> _acc; -'encode_search_item_$nick'(Nick, _acc) -> - [encode_search_nick(Nick, []) | _acc]. +'encode_search_item_$nick'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_search_item_$nick'(Nick, __TopXMLNS, _acc) -> + [encode_search_nick(Nick, __TopXMLNS) | _acc]. -'encode_search_item_$email'(undefined, _acc) -> _acc; -'encode_search_item_$email'(Email, _acc) -> - [encode_search_email(Email, []) | _acc]. +'encode_search_item_$email'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_search_item_$email'(Email, __TopXMLNS, _acc) -> + [encode_search_email(Email, __TopXMLNS) | _acc]. decode_search_item_attr_jid(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -6940,9 +9776,11 @@ decode_search_email_els(__TopXMLNS, __IgnoreEls, decode_search_email_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_search_email(Cdata, _xmlns_attrs) -> +encode_search_email(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = encode_search_email_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"email">>, _attrs, _els}. decode_search_email_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -6970,9 +9808,11 @@ decode_search_nick_els(__TopXMLNS, __IgnoreEls, decode_search_nick_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_search_nick(Cdata, _xmlns_attrs) -> +encode_search_nick(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = encode_search_nick_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"nick">>, _attrs, _els}. decode_search_nick_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -7000,9 +9840,11 @@ decode_search_last_els(__TopXMLNS, __IgnoreEls, decode_search_last_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_search_last(Cdata, _xmlns_attrs) -> +encode_search_last(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = encode_search_last_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"last">>, _attrs, _els}. decode_search_last_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -7030,9 +9872,11 @@ decode_search_first_els(__TopXMLNS, __IgnoreEls, decode_search_first_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_search_first(Cdata, _xmlns_attrs) -> +encode_search_first(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = encode_search_first_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"first">>, _attrs, _els}. decode_search_first_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -7060,9 +9904,11 @@ decode_search_instructions_els(__TopXMLNS, __IgnoreEls, decode_search_instructions_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_search_instructions(Cdata, _xmlns_attrs) -> +encode_search_instructions(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, + [], __TopXMLNS), _els = encode_search_instructions_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"instructions">>, _attrs, _els}. decode_search_instructions_cdata(__TopXMLNS, <<>>) -> @@ -7082,9 +9928,11 @@ decode_hint_no_permanent_storage(__TopXMLNS, encode_hint_no_permanent_storage({hint, 'no-permanent-storage'}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"no-permanent-storage">>, _attrs, _els}. decode_hint_no_permanent_store(__TopXMLNS, __IgnoreEls, @@ -7094,18 +9942,22 @@ decode_hint_no_permanent_store(__TopXMLNS, __IgnoreEls, encode_hint_no_permanent_store({hint, 'no-permanent-store'}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"no-permanent-store">>, _attrs, _els}. decode_hint_store(__TopXMLNS, __IgnoreEls, {xmlel, <<"store">>, _attrs, _els}) -> {hint, store}. -encode_hint_store({hint, store}, _xmlns_attrs) -> +encode_hint_store({hint, store}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"store">>, _attrs, _els}. decode_hint_no_storage(__TopXMLNS, __IgnoreEls, @@ -7113,28 +9965,33 @@ decode_hint_no_storage(__TopXMLNS, __IgnoreEls, {hint, 'no-storage'}. encode_hint_no_storage({hint, 'no-storage'}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"no-storage">>, _attrs, _els}. decode_hint_no_store(__TopXMLNS, __IgnoreEls, {xmlel, <<"no-store">>, _attrs, _els}) -> {hint, 'no-store'}. -encode_hint_no_store({hint, 'no-store'}, - _xmlns_attrs) -> +encode_hint_no_store({hint, 'no-store'}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"no-store">>, _attrs, _els}. decode_hint_no_copy(__TopXMLNS, __IgnoreEls, {xmlel, <<"no-copy">>, _attrs, _els}) -> {hint, 'no-copy'}. -encode_hint_no_copy({hint, 'no-copy'}, _xmlns_attrs) -> +encode_hint_no_copy({hint, 'no-copy'}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"no-copy">>, _attrs, _els}. decode_mix_participant(__TopXMLNS, __IgnoreEls, @@ -7161,11 +10018,14 @@ decode_mix_participant_attrs(__TopXMLNS, [], Jid, decode_mix_participant_attr_nick(__TopXMLNS, Nick)}. encode_mix_participant({mix_participant, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, + [], __TopXMLNS), _els = [], _attrs = encode_mix_participant_attr_nick(Nick, encode_mix_participant_attr_jid(Jid, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"participant">>, _attrs, _els}. decode_mix_participant_attr_jid(__TopXMLNS, @@ -7199,9 +10059,11 @@ decode_mix_leave(__TopXMLNS, __IgnoreEls, {xmlel, <<"leave">>, _attrs, _els}) -> {mix_leave}. -encode_mix_leave({mix_leave}, _xmlns_attrs) -> +encode_mix_leave({mix_leave}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"leave">>, _attrs, _els}. decode_mix_join(__TopXMLNS, __IgnoreEls, @@ -7247,18 +10109,24 @@ decode_mix_join_attrs(__TopXMLNS, [], Jid) -> decode_mix_join_attr_jid(__TopXMLNS, Jid). encode_mix_join({mix_join, Jid, Subscribe}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, + [], __TopXMLNS), _els = lists:reverse('encode_mix_join_$subscribe'(Subscribe, - [])), - _attrs = encode_mix_join_attr_jid(Jid, _xmlns_attrs), + __NewTopXMLNS, [])), + _attrs = encode_mix_join_attr_jid(Jid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"join">>, _attrs, _els}. -'encode_mix_join_$subscribe'([], _acc) -> _acc; +'encode_mix_join_$subscribe'([], __TopXMLNS, _acc) -> + _acc; 'encode_mix_join_$subscribe'([Subscribe | _els], - _acc) -> - 'encode_mix_join_$subscribe'(_els, - [encode_mix_subscribe(Subscribe, []) | _acc]). + __TopXMLNS, _acc) -> + 'encode_mix_join_$subscribe'(_els, __TopXMLNS, + [encode_mix_subscribe(Subscribe, __TopXMLNS) + | _acc]). decode_mix_join_attr_jid(__TopXMLNS, undefined) -> undefined; @@ -7289,10 +10157,13 @@ decode_mix_subscribe_attrs(__TopXMLNS, [_ | _attrs], decode_mix_subscribe_attrs(__TopXMLNS, [], Node) -> decode_mix_subscribe_attr_node(__TopXMLNS, Node). -encode_mix_subscribe(Node, _xmlns_attrs) -> +encode_mix_subscribe(Node, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, + [], __TopXMLNS), _els = [], _attrs = encode_mix_subscribe_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"subscribe">>, _attrs, _els}. decode_mix_subscribe_attr_node(__TopXMLNS, undefined) -> @@ -7381,26 +10252,35 @@ decode_offline_els(__TopXMLNS, __IgnoreEls, [_ | _els], Purge, Fetch). encode_offline({offline, Items, Purge, Fetch}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, + [], __TopXMLNS), _els = lists:reverse('encode_offline_$items'(Items, + __NewTopXMLNS, 'encode_offline_$purge'(Purge, + __NewTopXMLNS, 'encode_offline_$fetch'(Fetch, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"offline">>, _attrs, _els}. -'encode_offline_$items'([], _acc) -> _acc; -'encode_offline_$items'([Items | _els], _acc) -> - 'encode_offline_$items'(_els, - [encode_offline_item(Items, []) | _acc]). +'encode_offline_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_offline_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_offline_$items'(_els, __TopXMLNS, + [encode_offline_item(Items, __TopXMLNS) | _acc]). -'encode_offline_$purge'(false, _acc) -> _acc; -'encode_offline_$purge'(Purge, _acc) -> - [encode_offline_purge(Purge, []) | _acc]. +'encode_offline_$purge'(false, __TopXMLNS, _acc) -> + _acc; +'encode_offline_$purge'(Purge, __TopXMLNS, _acc) -> + [encode_offline_purge(Purge, __TopXMLNS) | _acc]. -'encode_offline_$fetch'(false, _acc) -> _acc; -'encode_offline_$fetch'(Fetch, _acc) -> - [encode_offline_fetch(Fetch, []) | _acc]. +'encode_offline_$fetch'(false, __TopXMLNS, _acc) -> + _acc; +'encode_offline_$fetch'(Fetch, __TopXMLNS, _acc) -> + [encode_offline_fetch(Fetch, __TopXMLNS) | _acc]. decode_offline_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> @@ -7426,11 +10306,15 @@ decode_offline_item_attrs(__TopXMLNS, [], Node, decode_offline_item_attr_action(__TopXMLNS, Action)}. encode_offline_item({offline_item, Node, Action}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, + [], __TopXMLNS), _els = [], _attrs = encode_offline_item_attr_action(Action, encode_offline_item_attr_node(Node, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"item">>, _attrs, _els}. decode_offline_item_attr_node(__TopXMLNS, undefined) -> @@ -7462,18 +10346,24 @@ decode_offline_fetch(__TopXMLNS, __IgnoreEls, {xmlel, <<"fetch">>, _attrs, _els}) -> true. -encode_offline_fetch(true, _xmlns_attrs) -> +encode_offline_fetch(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"fetch">>, _attrs, _els}. decode_offline_purge(__TopXMLNS, __IgnoreEls, {xmlel, <<"purge">>, _attrs, _els}) -> true. -encode_offline_purge(true, _xmlns_attrs) -> +encode_offline_purge(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"purge">>, _attrs, _els}. decode_sm_failed(__TopXMLNS, __IgnoreEls, @@ -7793,154 +10683,113 @@ decode_sm_failed_attrs(__TopXMLNS, [], H, Xmlns) -> decode_sm_failed_attr_xmlns(__TopXMLNS, Xmlns)}. encode_sm_failed({sm_failed, Reason, H, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = lists:reverse('encode_sm_failed_$reason'(Reason, - [])), - _attrs = encode_sm_failed_attr_xmlns(Xmlns, - encode_sm_failed_attr_h(H, - _xmlns_attrs)), + __NewTopXMLNS, [])), + _attrs = encode_sm_failed_attr_h(H, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"failed">>, _attrs, _els}. -'encode_sm_failed_$reason'(undefined, _acc) -> _acc; -'encode_sm_failed_$reason'('bad-request' = Reason, +'encode_sm_failed_$reason'(undefined, __TopXMLNS, _acc) -> - [encode_error_bad_request(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_sm_failed_$reason'(conflict = Reason, _acc) -> - [encode_error_conflict(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; + _acc; +'encode_sm_failed_$reason'('bad-request' = Reason, + __TopXMLNS, _acc) -> + [encode_error_bad_request(Reason, __TopXMLNS) | _acc]; +'encode_sm_failed_$reason'(conflict = Reason, + __TopXMLNS, _acc) -> + [encode_error_conflict(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('feature-not-implemented' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_error_feature_not_implemented(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_sm_failed_$reason'(forbidden = Reason, _acc) -> - [encode_error_forbidden(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_sm_failed_$reason'({gone, _} = Reason, _acc) -> - [encode_error_gone(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS) | _acc]; +'encode_sm_failed_$reason'(forbidden = Reason, + __TopXMLNS, _acc) -> + [encode_error_forbidden(Reason, __TopXMLNS) | _acc]; +'encode_sm_failed_$reason'({gone, _} = Reason, + __TopXMLNS, _acc) -> + [encode_error_gone(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('internal-server-error' = Reason, - _acc) -> - [encode_error_internal_server_error(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_internal_server_error(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('item-not-found' = Reason, - _acc) -> - [encode_error_item_not_found(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_item_not_found(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('jid-malformed' = Reason, - _acc) -> - [encode_error_jid_malformed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; + __TopXMLNS, _acc) -> + [encode_error_jid_malformed(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('not-acceptable' = Reason, - _acc) -> - [encode_error_not_acceptable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_not_acceptable(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('not-allowed' = Reason, - _acc) -> - [encode_error_not_allowed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; + __TopXMLNS, _acc) -> + [encode_error_not_allowed(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('not-authorized' = Reason, - _acc) -> - [encode_error_not_authorized(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_not_authorized(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('policy-violation' = Reason, - _acc) -> - [encode_error_policy_violation(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_policy_violation(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('recipient-unavailable' = Reason, - _acc) -> - [encode_error_recipient_unavailable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_recipient_unavailable(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'({redirect, _} = Reason, - _acc) -> - [encode_error_redirect(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; + __TopXMLNS, _acc) -> + [encode_error_redirect(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('registration-required' = Reason, - _acc) -> - [encode_error_registration_required(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_registration_required(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('remote-server-not-found' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_error_remote_server_not_found(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('remote-server-timeout' = Reason, - _acc) -> - [encode_error_remote_server_timeout(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_remote_server_timeout(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('resource-constraint' = Reason, - _acc) -> - [encode_error_resource_constraint(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_resource_constraint(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('service-unavailable' = Reason, - _acc) -> - [encode_error_service_unavailable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_service_unavailable(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('subscription-required' = Reason, - _acc) -> - [encode_error_subscription_required(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_subscription_required(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('undefined-condition' = Reason, - _acc) -> - [encode_error_undefined_condition(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_undefined_condition(Reason, __TopXMLNS) | _acc]; 'encode_sm_failed_$reason'('unexpected-request' = Reason, - _acc) -> - [encode_error_unexpected_request(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_unexpected_request(Reason, __TopXMLNS) | _acc]. decode_sm_failed_attr_h(__TopXMLNS, undefined) -> @@ -7961,10 +10810,6 @@ decode_sm_failed_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_failed_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_failed_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_failed_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_a(__TopXMLNS, __IgnoreEls, {xmlel, <<"a">>, _attrs, _els}) -> {H, Xmlns} = decode_sm_a_attrs(__TopXMLNS, _attrs, @@ -7983,10 +10828,13 @@ decode_sm_a_attrs(__TopXMLNS, [], H, Xmlns) -> {decode_sm_a_attr_h(__TopXMLNS, H), decode_sm_a_attr_xmlns(__TopXMLNS, Xmlns)}. -encode_sm_a({sm_a, H, Xmlns}, _xmlns_attrs) -> +encode_sm_a({sm_a, H, Xmlns}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], - _attrs = encode_sm_a_attr_xmlns(Xmlns, - encode_sm_a_attr_h(H, _xmlns_attrs)), + _attrs = encode_sm_a_attr_h(H, + enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), {xmlel, <<"a">>, _attrs, _els}. decode_sm_a_attr_h(__TopXMLNS, undefined) -> @@ -8006,10 +10854,6 @@ encode_sm_a_attr_h(_val, _acc) -> decode_sm_a_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_a_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_a_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_a_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_r(__TopXMLNS, __IgnoreEls, {xmlel, <<"r">>, _attrs, _els}) -> Xmlns = decode_sm_r_attrs(__TopXMLNS, _attrs, @@ -8024,18 +10868,17 @@ decode_sm_r_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> decode_sm_r_attrs(__TopXMLNS, [], Xmlns) -> decode_sm_r_attr_xmlns(__TopXMLNS, Xmlns). -encode_sm_r({sm_r, Xmlns}, _xmlns_attrs) -> +encode_sm_r({sm_r, Xmlns}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], - _attrs = encode_sm_r_attr_xmlns(Xmlns, _xmlns_attrs), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"r">>, _attrs, _els}. decode_sm_r_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_r_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_r_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_r_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_resumed(__TopXMLNS, __IgnoreEls, {xmlel, <<"resumed">>, _attrs, _els}) -> {H, Xmlns, Previd} = decode_sm_resumed_attrs(__TopXMLNS, @@ -8066,12 +10909,15 @@ decode_sm_resumed_attrs(__TopXMLNS, [], H, Xmlns, decode_sm_resumed_attr_previd(__TopXMLNS, Previd)}. encode_sm_resumed({sm_resumed, H, Previd, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], _attrs = encode_sm_resumed_attr_previd(Previd, - encode_sm_resumed_attr_xmlns(Xmlns, - encode_sm_resumed_attr_h(H, - _xmlns_attrs))), + encode_sm_resumed_attr_h(H, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"resumed">>, _attrs, _els}. decode_sm_resumed_attr_h(__TopXMLNS, undefined) -> @@ -8092,10 +10938,6 @@ decode_sm_resumed_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_resumed_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_resumed_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_resumed_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_resumed_attr_previd(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, {missing_attr, <<"previd">>, <<"resumed">>, @@ -8135,12 +10977,15 @@ decode_sm_resume_attrs(__TopXMLNS, [], H, Xmlns, decode_sm_resume_attr_previd(__TopXMLNS, Previd)}. encode_sm_resume({sm_resume, H, Previd, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], _attrs = encode_sm_resume_attr_previd(Previd, - encode_sm_resume_attr_xmlns(Xmlns, - encode_sm_resume_attr_h(H, - _xmlns_attrs))), + encode_sm_resume_attr_h(H, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"resume">>, _attrs, _els}. decode_sm_resume_attr_h(__TopXMLNS, undefined) -> @@ -8161,10 +11006,6 @@ decode_sm_resume_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_resume_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_resume_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_resume_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_resume_attr_previd(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, {missing_attr, <<"previd">>, <<"resume">>, @@ -8220,14 +11061,17 @@ decode_sm_enabled_attrs(__TopXMLNS, [], Id, Location, encode_sm_enabled({sm_enabled, Id, Location, Max, Resume, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], _attrs = encode_sm_enabled_attr_resume(Resume, encode_sm_enabled_attr_max(Max, - encode_sm_enabled_attr_xmlns(Xmlns, - encode_sm_enabled_attr_location(Location, - encode_sm_enabled_attr_id(Id, - _xmlns_attrs))))), + encode_sm_enabled_attr_location(Location, + encode_sm_enabled_attr_id(Id, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"enabled">>, _attrs, _els}. decode_sm_enabled_attr_id(__TopXMLNS, undefined) -> @@ -8252,10 +11096,6 @@ decode_sm_enabled_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_enabled_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_enabled_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_enabled_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_enabled_attr_max(__TopXMLNS, undefined) -> undefined; decode_sm_enabled_attr_max(__TopXMLNS, _val) -> @@ -8316,12 +11156,15 @@ decode_sm_enable_attrs(__TopXMLNS, [], Max, Xmlns, decode_sm_enable_attr_resume(__TopXMLNS, Resume)}. encode_sm_enable({sm_enable, Max, Resume, Xmlns}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], _attrs = encode_sm_enable_attr_resume(Resume, - encode_sm_enable_attr_xmlns(Xmlns, - encode_sm_enable_attr_max(Max, - _xmlns_attrs))), + encode_sm_enable_attr_max(Max, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"enable">>, _attrs, _els}. decode_sm_enable_attr_max(__TopXMLNS, undefined) -> @@ -8342,10 +11185,6 @@ decode_sm_enable_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_sm_enable_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_sm_enable_attr_xmlns(<<>>, _acc) -> _acc; -encode_sm_enable_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_sm_enable_attr_resume(__TopXMLNS, undefined) -> false; decode_sm_enable_attr_resume(__TopXMLNS, _val) -> @@ -8376,36 +11215,38 @@ decode_feature_sm_attrs(__TopXMLNS, [_ | _attrs], decode_feature_sm_attrs(__TopXMLNS, [], Xmlns) -> decode_feature_sm_attr_xmlns(__TopXMLNS, Xmlns). -encode_feature_sm({feature_sm, Xmlns}, _xmlns_attrs) -> +encode_feature_sm({feature_sm, Xmlns}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], + __TopXMLNS), _els = [], - _attrs = encode_feature_sm_attr_xmlns(Xmlns, - _xmlns_attrs), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"sm">>, _attrs, _els}. decode_feature_sm_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_feature_sm_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_feature_sm_attr_xmlns(<<>>, _acc) -> _acc; -encode_feature_sm_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_csi_inactive(__TopXMLNS, __IgnoreEls, {xmlel, <<"inactive">>, _attrs, _els}) -> {csi, inactive}. -encode_csi_inactive({csi, inactive}, _xmlns_attrs) -> +encode_csi_inactive({csi, inactive}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:csi:0">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"inactive">>, _attrs, _els}. decode_csi_active(__TopXMLNS, __IgnoreEls, {xmlel, <<"active">>, _attrs, _els}) -> {csi, active}. -encode_csi_active({csi, active}, _xmlns_attrs) -> +encode_csi_active({csi, active}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:csi:0">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"active">>, _attrs, _els}. decode_feature_csi(__TopXMLNS, __IgnoreEls, @@ -8423,21 +11264,17 @@ decode_feature_csi_attrs(__TopXMLNS, [_ | _attrs], decode_feature_csi_attrs(__TopXMLNS, [], Xmlns) -> decode_feature_csi_attr_xmlns(__TopXMLNS, Xmlns). -encode_feature_csi({feature_csi, Xmlns}, - _xmlns_attrs) -> +encode_feature_csi({feature_csi, Xmlns}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:csi:0">>], __TopXMLNS), _els = [], - _attrs = encode_feature_csi_attr_xmlns(Xmlns, - _xmlns_attrs), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"csi">>, _attrs, _els}. decode_feature_csi_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_feature_csi_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_feature_csi_attr_xmlns(<<>>, _acc) -> _acc; -encode_feature_csi_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_carbons_sent(__TopXMLNS, __IgnoreEls, {xmlel, <<"sent">>, _attrs, _els}) -> Forwarded = decode_carbons_sent_els(__TopXMLNS, @@ -8471,17 +11308,19 @@ decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, Forwarded). encode_carbons_sent({carbons_sent, Forwarded}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], + __TopXMLNS), _els = lists:reverse('encode_carbons_sent_$forwarded'(Forwarded, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"sent">>, _attrs, _els}. -'encode_carbons_sent_$forwarded'(Forwarded, _acc) -> - [encode_forwarded(Forwarded, - [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]) - | _acc]. +'encode_carbons_sent_$forwarded'(Forwarded, __TopXMLNS, + _acc) -> + [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. decode_carbons_received(__TopXMLNS, __IgnoreEls, {xmlel, <<"received">>, _attrs, _els}) -> @@ -8517,45 +11356,54 @@ decode_carbons_received_els(__TopXMLNS, __IgnoreEls, _els, Forwarded). encode_carbons_received({carbons_received, Forwarded}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], + __TopXMLNS), _els = lists:reverse('encode_carbons_received_$forwarded'(Forwarded, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"received">>, _attrs, _els}. -'encode_carbons_received_$forwarded'(Forwarded, _acc) -> - [encode_forwarded(Forwarded, - [{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]) - | _acc]. +'encode_carbons_received_$forwarded'(Forwarded, + __TopXMLNS, _acc) -> + [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. decode_carbons_private(__TopXMLNS, __IgnoreEls, {xmlel, <<"private">>, _attrs, _els}) -> {carbons_private}. -encode_carbons_private({carbons_private}, - _xmlns_attrs) -> +encode_carbons_private({carbons_private}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"private">>, _attrs, _els}. decode_carbons_enable(__TopXMLNS, __IgnoreEls, {xmlel, <<"enable">>, _attrs, _els}) -> {carbons_enable}. -encode_carbons_enable({carbons_enable}, _xmlns_attrs) -> +encode_carbons_enable({carbons_enable}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"enable">>, _attrs, _els}. decode_carbons_disable(__TopXMLNS, __IgnoreEls, {xmlel, <<"disable">>, _attrs, _els}) -> {carbons_disable}. -encode_carbons_disable({carbons_disable}, - _xmlns_attrs) -> +encode_carbons_disable({carbons_disable}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"disable">>, _attrs, _els}. decode_forwarded(__TopXMLNS, __IgnoreEls, @@ -8586,10 +11434,11 @@ decode_forwarded_els(__TopXMLNS, __IgnoreEls, decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, Delay, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, [decode(_el) | __Els]); + Delay, + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, Delay, __Els) @@ -8601,17 +11450,21 @@ decode_forwarded_els(__TopXMLNS, __IgnoreEls, Delay, __Els). encode_forwarded({forwarded, Delay, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_forwarded_$delay'(Delay, [])), - _attrs = _xmlns_attrs, + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:forward:0">>, [], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ + lists:reverse('encode_forwarded_$delay'(Delay, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"forwarded">>, _attrs, _els}. -'encode_forwarded_$delay'(undefined, _acc) -> _acc; -'encode_forwarded_$delay'(Delay, _acc) -> - [encode_delay(Delay, - [{<<"xmlns">>, <<"urn:xmpp:delay">>}]) - | _acc]. +'encode_forwarded_$delay'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_forwarded_$delay'(Delay, __TopXMLNS, _acc) -> + [encode_delay(Delay, __TopXMLNS) | _acc]. decode_mam_fin(__TopXMLNS, __IgnoreEls, {xmlel, <<"fin">>, _attrs, _els}) -> @@ -8671,20 +11524,24 @@ decode_mam_fin_attrs(__TopXMLNS, [], Id, Xmlns, Stable, encode_mam_fin({mam_fin, Xmlns, Id, Rsm, Stable, Complete}, - _xmlns_attrs) -> - _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, [])), + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>], + __TopXMLNS), + _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, + __NewTopXMLNS, [])), _attrs = encode_mam_fin_attr_complete(Complete, encode_mam_fin_attr_stable(Stable, - encode_mam_fin_attr_xmlns(Xmlns, - encode_mam_fin_attr_queryid(Id, - _xmlns_attrs)))), + encode_mam_fin_attr_queryid(Id, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {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]. +'encode_mam_fin_$rsm'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_mam_fin_$rsm'(Rsm, __TopXMLNS, _acc) -> + [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. decode_mam_fin_attr_queryid(__TopXMLNS, undefined) -> <<>>; @@ -8698,10 +11555,6 @@ decode_mam_fin_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_mam_fin_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_mam_fin_attr_xmlns(<<>>, _acc) -> _acc; -encode_mam_fin_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_mam_fin_attr_stable(__TopXMLNS, undefined) -> undefined; decode_mam_fin_attr_stable(__TopXMLNS, _val) -> @@ -8826,22 +11679,33 @@ decode_mam_prefs_attrs(__TopXMLNS, [], Default, encode_mam_prefs({mam_prefs, Xmlns, Default, Always, Never}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), _els = lists:reverse('encode_mam_prefs_$never'(Never, + __NewTopXMLNS, 'encode_mam_prefs_$always'(Always, + __NewTopXMLNS, []))), - _attrs = encode_mam_prefs_attr_xmlns(Xmlns, - encode_mam_prefs_attr_default(Default, - _xmlns_attrs)), + _attrs = encode_mam_prefs_attr_default(Default, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"prefs">>, _attrs, _els}. -'encode_mam_prefs_$never'(undefined, _acc) -> _acc; -'encode_mam_prefs_$never'(Never, _acc) -> - [encode_mam_never(Never, []) | _acc]. +'encode_mam_prefs_$never'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_mam_prefs_$never'(Never, __TopXMLNS, _acc) -> + [encode_mam_never(Never, __TopXMLNS) | _acc]. -'encode_mam_prefs_$always'(undefined, _acc) -> _acc; -'encode_mam_prefs_$always'(Always, _acc) -> - [encode_mam_always(Always, []) | _acc]. +'encode_mam_prefs_$always'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_mam_prefs_$always'(Always, __TopXMLNS, _acc) -> + [encode_mam_always(Always, __TopXMLNS) | _acc]. decode_mam_prefs_attr_default(__TopXMLNS, undefined) -> undefined; @@ -8862,10 +11726,6 @@ decode_mam_prefs_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_mam_prefs_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_mam_prefs_attr_xmlns(<<>>, _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, @@ -8909,16 +11769,22 @@ decode_mam_always_els(__TopXMLNS, __IgnoreEls, decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, Jids). -encode_mam_always(Jids, _xmlns_attrs) -> +encode_mam_always(Jids, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), _els = lists:reverse('encode_mam_always_$jids'(Jids, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {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]). +'encode_mam_always_$jids'([], __TopXMLNS, _acc) -> _acc; +'encode_mam_always_$jids'([Jids | _els], __TopXMLNS, + _acc) -> + 'encode_mam_always_$jids'(_els, __TopXMLNS, + [encode_mam_jid(Jids, __TopXMLNS) | _acc]). decode_mam_never(__TopXMLNS, __IgnoreEls, {xmlel, <<"never">>, _attrs, _els}) -> @@ -8963,16 +11829,22 @@ decode_mam_never_els(__TopXMLNS, __IgnoreEls, decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, Jids). -encode_mam_never(Jids, _xmlns_attrs) -> +encode_mam_never(Jids, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), _els = lists:reverse('encode_mam_never_$jids'(Jids, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {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]). +'encode_mam_never_$jids'([], __TopXMLNS, _acc) -> _acc; +'encode_mam_never_$jids'([Jids | _els], __TopXMLNS, + _acc) -> + 'encode_mam_never_$jids'(_els, __TopXMLNS, + [encode_mam_jid(Jids, __TopXMLNS) | _acc]). decode_mam_jid(__TopXMLNS, __IgnoreEls, {xmlel, <<"jid">>, _attrs, _els}) -> @@ -8992,9 +11864,14 @@ decode_mam_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_mam_jid_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_mam_jid(Cdata, _xmlns_attrs) -> +encode_mam_jid(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), _els = encode_mam_jid_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"jid">>, _attrs, _els}. decode_mam_jid_cdata(__TopXMLNS, <<>>) -> @@ -9029,10 +11906,10 @@ decode_mam_result_els(__TopXMLNS, __IgnoreEls, decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, __Els) @@ -9068,12 +11945,17 @@ decode_mam_result_attrs(__TopXMLNS, [], Queryid, Xmlns, encode_mam_result({mam_result, Xmlns, Queryid, Id, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els], + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], _attrs = encode_mam_result_attr_id(Id, - encode_mam_result_attr_xmlns(Xmlns, - encode_mam_result_attr_queryid(Queryid, - _xmlns_attrs))), + encode_mam_result_attr_queryid(Queryid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"result">>, _attrs, _els}. decode_mam_result_attr_queryid(__TopXMLNS, undefined) -> @@ -9089,10 +11971,6 @@ decode_mam_result_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_mam_result_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_mam_result_attr_xmlns(<<>>, _acc) -> _acc; -encode_mam_result_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_mam_result_attr_id(__TopXMLNS, undefined) -> <<>>; decode_mam_result_attr_id(__TopXMLNS, _val) -> _val. @@ -9121,11 +11999,14 @@ decode_mam_archived_attrs(__TopXMLNS, [], Id, By) -> decode_mam_archived_attr_by(__TopXMLNS, By)}. encode_mam_archived({mam_archived, By, Id}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, + [], __TopXMLNS), _els = [], _attrs = encode_mam_archived_attr_by(By, encode_mam_archived_attr_id(Id, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"archived">>, _attrs, _els}. decode_mam_archived_attr_id(__TopXMLNS, undefined) -> @@ -9288,46 +12169,63 @@ decode_mam_query_attrs(__TopXMLNS, [], Id, Xmlns) -> encode_mam_query({mam_query, Xmlns, Id, Start, End, With, Withtext, Rsm, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"urn:xmpp:mam:0">>, + <<"urn:xmpp:mam:1">>, + <<"urn:xmpp:mam:tmp">>], + __TopXMLNS), _els = lists:reverse('encode_mam_query_$xdata'(Xdata, + __NewTopXMLNS, 'encode_mam_query_$withtext'(Withtext, + __NewTopXMLNS, 'encode_mam_query_$end'(End, + __NewTopXMLNS, 'encode_mam_query_$start'(Start, + __NewTopXMLNS, 'encode_mam_query_$with'(With, + __NewTopXMLNS, 'encode_mam_query_$rsm'(Rsm, + __NewTopXMLNS, []))))))), - _attrs = encode_mam_query_attr_xmlns(Xmlns, - encode_mam_query_attr_queryid(Id, - _xmlns_attrs)), + _attrs = encode_mam_query_attr_queryid(Id, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {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_$xdata'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_mam_query_$xdata'(Xdata, __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. -'encode_mam_query_$withtext'(undefined, _acc) -> _acc; -'encode_mam_query_$withtext'(Withtext, _acc) -> - [encode_mam_withtext(Withtext, []) | _acc]. +'encode_mam_query_$withtext'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_mam_query_$withtext'(Withtext, __TopXMLNS, + _acc) -> + [encode_mam_withtext(Withtext, __TopXMLNS) | _acc]. -'encode_mam_query_$end'(undefined, _acc) -> _acc; -'encode_mam_query_$end'(End, _acc) -> - [encode_mam_end(End, []) | _acc]. +'encode_mam_query_$end'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_mam_query_$end'(End, __TopXMLNS, _acc) -> + [encode_mam_end(End, __TopXMLNS) | _acc]. -'encode_mam_query_$start'(undefined, _acc) -> _acc; -'encode_mam_query_$start'(Start, _acc) -> - [encode_mam_start(Start, []) | _acc]. +'encode_mam_query_$start'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_mam_query_$start'(Start, __TopXMLNS, _acc) -> + [encode_mam_start(Start, __TopXMLNS) | _acc]. -'encode_mam_query_$with'(undefined, _acc) -> _acc; -'encode_mam_query_$with'(With, _acc) -> - [encode_mam_with(With, []) | _acc]. +'encode_mam_query_$with'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_mam_query_$with'(With, __TopXMLNS, _acc) -> + [encode_mam_with(With, __TopXMLNS) | _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]. +'encode_mam_query_$rsm'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_mam_query_$rsm'(Rsm, __TopXMLNS, _acc) -> + [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. decode_mam_query_attr_queryid(__TopXMLNS, undefined) -> <<>>; @@ -9341,10 +12239,6 @@ decode_mam_query_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_mam_query_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_mam_query_attr_xmlns(<<>>, _acc) -> _acc; -encode_mam_query_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_mam_withtext(__TopXMLNS, __IgnoreEls, {xmlel, <<"withtext">>, _attrs, _els}) -> Cdata = decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, @@ -9363,9 +12257,11 @@ decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_mam_withtext(Cdata, _xmlns_attrs) -> +encode_mam_withtext(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, + [], __TopXMLNS), _els = encode_mam_withtext_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"withtext">>, _attrs, _els}. decode_mam_withtext_cdata(__TopXMLNS, <<>>) -> @@ -9394,9 +12290,11 @@ decode_mam_with_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_mam_with_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_mam_with(Cdata, _xmlns_attrs) -> +encode_mam_with(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, + [], __TopXMLNS), _els = encode_mam_with_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"with">>, _attrs, _els}. decode_mam_with_cdata(__TopXMLNS, <<>>) -> @@ -9431,9 +12329,11 @@ decode_mam_end_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_mam_end(Cdata, _xmlns_attrs) -> +encode_mam_end(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, + [], __TopXMLNS), _els = encode_mam_end_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"end">>, _attrs, _els}. decode_mam_end_cdata(__TopXMLNS, <<>>) -> @@ -9468,9 +12368,11 @@ decode_mam_start_els(__TopXMLNS, __IgnoreEls, decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_mam_start(Cdata, _xmlns_attrs) -> +encode_mam_start(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, + [], __TopXMLNS), _els = encode_mam_start_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"start">>, _attrs, _els}. decode_mam_start_cdata(__TopXMLNS, <<>>) -> @@ -9647,45 +12549,62 @@ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, [_ | _els], encode_rsm_set({rsm_set, After, Before, Count, First, Index, Last, Max}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = lists:reverse('encode_rsm_set_$after'(After, + __NewTopXMLNS, 'encode_rsm_set_$last'(Last, + __NewTopXMLNS, 'encode_rsm_set_$first'(First, + __NewTopXMLNS, 'encode_rsm_set_$count'(Count, + __NewTopXMLNS, 'encode_rsm_set_$before'(Before, + __NewTopXMLNS, 'encode_rsm_set_$max'(Max, + __NewTopXMLNS, 'encode_rsm_set_$index'(Index, + __NewTopXMLNS, [])))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {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_$after'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$after'(After, __TopXMLNS, _acc) -> + [encode_rsm_after(After, __TopXMLNS) | _acc]. -'encode_rsm_set_$last'(undefined, _acc) -> _acc; -'encode_rsm_set_$last'(Last, _acc) -> - [encode_rsm_last(Last, []) | _acc]. +'encode_rsm_set_$last'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$last'(Last, __TopXMLNS, _acc) -> + [encode_rsm_last(Last, __TopXMLNS) | _acc]. -'encode_rsm_set_$first'(undefined, _acc) -> _acc; -'encode_rsm_set_$first'(First, _acc) -> - [encode_rsm_first(First, []) | _acc]. +'encode_rsm_set_$first'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$first'(First, __TopXMLNS, _acc) -> + [encode_rsm_first(First, __TopXMLNS) | _acc]. -'encode_rsm_set_$count'(undefined, _acc) -> _acc; -'encode_rsm_set_$count'(Count, _acc) -> - [encode_rsm_count(Count, []) | _acc]. +'encode_rsm_set_$count'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$count'(Count, __TopXMLNS, _acc) -> + [encode_rsm_count(Count, __TopXMLNS) | _acc]. -'encode_rsm_set_$before'(undefined, _acc) -> _acc; -'encode_rsm_set_$before'(Before, _acc) -> - [encode_rsm_before(Before, []) | _acc]. +'encode_rsm_set_$before'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$before'(Before, __TopXMLNS, _acc) -> + [encode_rsm_before(Before, __TopXMLNS) | _acc]. -'encode_rsm_set_$max'(undefined, _acc) -> _acc; -'encode_rsm_set_$max'(Max, _acc) -> - [encode_rsm_max(Max, []) | _acc]. +'encode_rsm_set_$max'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$max'(Max, __TopXMLNS, _acc) -> + [encode_rsm_max(Max, __TopXMLNS) | _acc]. -'encode_rsm_set_$index'(undefined, _acc) -> _acc; -'encode_rsm_set_$index'(Index, _acc) -> - [encode_rsm_index(Index, []) | _acc]. +'encode_rsm_set_$index'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_rsm_set_$index'(Index, __TopXMLNS, _acc) -> + [encode_rsm_index(Index, __TopXMLNS) | _acc]. decode_rsm_first(__TopXMLNS, __IgnoreEls, {xmlel, <<"first">>, _attrs, _els}) -> @@ -9717,10 +12636,14 @@ decode_rsm_first_attrs(__TopXMLNS, [], Index) -> decode_rsm_first_attr_index(__TopXMLNS, Index). encode_rsm_first({rsm_first, Index, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_first_cdata(Data, []), _attrs = encode_rsm_first_attr_index(Index, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"first">>, _attrs, _els}. decode_rsm_first_attr_index(__TopXMLNS, undefined) -> @@ -9763,9 +12686,12 @@ decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_max(Cdata, _xmlns_attrs) -> +encode_rsm_max(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_max_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"max">>, _attrs, _els}. decode_rsm_max_cdata(__TopXMLNS, <<>>) -> undefined; @@ -9799,9 +12725,12 @@ decode_rsm_index_els(__TopXMLNS, __IgnoreEls, decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_index(Cdata, _xmlns_attrs) -> +encode_rsm_index(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_index_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"index">>, _attrs, _els}. decode_rsm_index_cdata(__TopXMLNS, <<>>) -> undefined; @@ -9835,9 +12764,12 @@ decode_rsm_count_els(__TopXMLNS, __IgnoreEls, decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_count(Cdata, _xmlns_attrs) -> +encode_rsm_count(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_count_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"count">>, _attrs, _els}. decode_rsm_count_cdata(__TopXMLNS, <<>>) -> undefined; @@ -9871,9 +12803,12 @@ decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_last(Cdata, _xmlns_attrs) -> +encode_rsm_last(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_last_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"last">>, _attrs, _els}. decode_rsm_last_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -9901,9 +12836,12 @@ decode_rsm_before_els(__TopXMLNS, __IgnoreEls, decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_before(Cdata, _xmlns_attrs) -> +encode_rsm_before(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_before_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"before">>, _attrs, _els}. decode_rsm_before_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -9931,9 +12869,12 @@ decode_rsm_after_els(__TopXMLNS, __IgnoreEls, decode_rsm_after_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_rsm_after(Cdata, _xmlns_attrs) -> +encode_rsm_after(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, + [], __TopXMLNS), _els = encode_rsm_after_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"after">>, _attrs, _els}. decode_rsm_after_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -9947,10 +12888,12 @@ decode_muc_unsubscribe(__TopXMLNS, __IgnoreEls, {xmlel, <<"unsubscribe">>, _attrs, _els}) -> {muc_unsubscribe}. -encode_muc_unsubscribe({muc_unsubscribe}, - _xmlns_attrs) -> +encode_muc_unsubscribe({muc_unsubscribe}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsubscribe">>, _attrs, _els}. decode_muc_subscribe(__TopXMLNS, __IgnoreEls, @@ -9997,18 +12940,25 @@ decode_muc_subscribe_attrs(__TopXMLNS, [], Nick) -> decode_muc_subscribe_attr_nick(__TopXMLNS, Nick). encode_muc_subscribe({muc_subscribe, Nick, Events}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], + __TopXMLNS), _els = lists:reverse('encode_muc_subscribe_$events'(Events, - [])), + __NewTopXMLNS, [])), _attrs = encode_muc_subscribe_attr_nick(Nick, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"subscribe">>, _attrs, _els}. -'encode_muc_subscribe_$events'([], _acc) -> _acc; -'encode_muc_subscribe_$events'([Events | _els], _acc) -> - 'encode_muc_subscribe_$events'(_els, - [encode_muc_subscribe_event(Events, []) +'encode_muc_subscribe_$events'([], __TopXMLNS, _acc) -> + _acc; +'encode_muc_subscribe_$events'([Events | _els], + __TopXMLNS, _acc) -> + 'encode_muc_subscribe_$events'(_els, __TopXMLNS, + [encode_muc_subscribe_event(Events, + __TopXMLNS) | _acc]). decode_muc_subscribe_attr_nick(__TopXMLNS, undefined) -> @@ -10039,10 +12989,14 @@ decode_muc_subscribe_event_attrs(__TopXMLNS, [], Node) -> decode_muc_subscribe_event_attr_node(__TopXMLNS, Node). -encode_muc_subscribe_event(Node, _xmlns_attrs) -> +encode_muc_subscribe_event(Node, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], + __TopXMLNS), _els = [], _attrs = encode_muc_subscribe_event_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"event">>, _attrs, _els}. decode_muc_subscribe_event_attr_node(__TopXMLNS, @@ -10094,17 +13048,23 @@ decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, _els, List). encode_muc_subscriptions({muc_subscriptions, List}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], + __TopXMLNS), _els = lists:reverse('encode_muc_subscriptions_$list'(List, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"subscriptions">>, _attrs, _els}. -'encode_muc_subscriptions_$list'([], _acc) -> _acc; -'encode_muc_subscriptions_$list'([List | _els], _acc) -> - 'encode_muc_subscriptions_$list'(_els, - [encode_muc_subscription(List, []) +'encode_muc_subscriptions_$list'([], __TopXMLNS, + _acc) -> + _acc; +'encode_muc_subscriptions_$list'([List | _els], + __TopXMLNS, _acc) -> + 'encode_muc_subscriptions_$list'(_els, __TopXMLNS, + [encode_muc_subscription(List, __TopXMLNS) | _acc]). decode_muc_subscription(__TopXMLNS, __IgnoreEls, @@ -10122,10 +13082,14 @@ decode_muc_subscription_attrs(__TopXMLNS, [_ | _attrs], decode_muc_subscription_attrs(__TopXMLNS, [], Jid) -> decode_muc_subscription_attr_jid(__TopXMLNS, Jid). -encode_muc_subscription(Jid, _xmlns_attrs) -> +encode_muc_subscription(Jid, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], + __TopXMLNS), _els = [], _attrs = encode_muc_subscription_attr_jid(Jid, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"subscription">>, _attrs, _els}. decode_muc_subscription_attr_jid(__TopXMLNS, @@ -10192,14 +13156,18 @@ decode_x_conference_attrs(__TopXMLNS, [], Jid, Password, encode_x_conference({x_conference, Jid, Password, Reason, Continue, Thread}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:x:conference">>, [], + __TopXMLNS), _els = [], _attrs = encode_x_conference_attr_continue(Continue, encode_x_conference_attr_thread(Thread, encode_x_conference_attr_reason(Reason, encode_x_conference_attr_password(Password, encode_x_conference_attr_jid(Jid, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"x">>, _attrs, _els}. decode_x_conference_attr_jid(__TopXMLNS, undefined) -> @@ -10280,9 +13248,12 @@ decode_muc_unique_els(__TopXMLNS, __IgnoreEls, decode_muc_unique_els(__TopXMLNS, __IgnoreEls, _els, Name). -encode_muc_unique({muc_unique, Name}, _xmlns_attrs) -> +encode_muc_unique({muc_unique, Name}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#unique">>, + [], __TopXMLNS), _els = encode_muc_unique_cdata(Name, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unique">>, _attrs, _els}. decode_muc_unique_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -10353,20 +13324,27 @@ decode_muc_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, History). -encode_muc({muc, History, Password}, _xmlns_attrs) -> +encode_muc({muc, History, Password}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_$password'(Password, + __NewTopXMLNS, 'encode_muc_$history'(History, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"x">>, _attrs, _els}. -'encode_muc_$password'(undefined, _acc) -> _acc; -'encode_muc_$password'(Password, _acc) -> - [encode_muc_password(Password, []) | _acc]. +'encode_muc_$password'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_muc_$password'(Password, __TopXMLNS, _acc) -> + [encode_muc_password(Password, __TopXMLNS) | _acc]. -'encode_muc_$history'(undefined, _acc) -> _acc; -'encode_muc_$history'(History, _acc) -> - [encode_muc_history(History, []) | _acc]. +'encode_muc_$history'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_muc_$history'(History, __TopXMLNS, _acc) -> + [encode_muc_history(History, __TopXMLNS) | _acc]. decode_muc_admin(__TopXMLNS, __IgnoreEls, {xmlel, <<"query">>, _attrs, _els}) -> @@ -10401,16 +13379,21 @@ decode_muc_admin_els(__TopXMLNS, __IgnoreEls, decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, Items). -encode_muc_admin({muc_admin, Items}, _xmlns_attrs) -> +encode_muc_admin({muc_admin, Items}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_admin_$items'(Items, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_muc_admin_$items'([], _acc) -> _acc; -'encode_muc_admin_$items'([Items | _els], _acc) -> - 'encode_muc_admin_$items'(_els, - [encode_muc_admin_item(Items, []) | _acc]). +'encode_muc_admin_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_muc_admin_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_muc_admin_$items'(_els, __TopXMLNS, + [encode_muc_admin_item(Items, __TopXMLNS) + | _acc]). decode_muc_admin_continue(__TopXMLNS, __IgnoreEls, {xmlel, <<"continue">>, _attrs, _els}) -> @@ -10431,10 +13414,14 @@ decode_muc_admin_continue_attrs(__TopXMLNS, [], decode_muc_admin_continue_attr_thread(__TopXMLNS, Thread). -encode_muc_admin_continue(Thread, _xmlns_attrs) -> +encode_muc_admin_continue(Thread, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_admin_continue_attr_thread(Thread, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"continue">>, _attrs, _els}. decode_muc_admin_continue_attr_thread(__TopXMLNS, @@ -10473,11 +13460,15 @@ decode_muc_admin_actor_attrs(__TopXMLNS, [], Jid, decode_muc_admin_actor_attr_nick(__TopXMLNS, Nick)}. encode_muc_admin_actor({muc_actor, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_admin_actor_attr_nick(Nick, encode_muc_admin_actor_attr_jid(Jid, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"actor">>, _attrs, _els}. decode_muc_admin_actor_attr_jid(__TopXMLNS, @@ -10631,31 +13622,47 @@ decode_muc_admin_item_attrs(__TopXMLNS, [], Affiliation, encode_muc_admin_item({muc_item, Actor, Continue, Reason, Affiliation, Role, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_admin_item_$actor'(Actor, + __NewTopXMLNS, 'encode_muc_admin_item_$continue'(Continue, + __NewTopXMLNS, 'encode_muc_admin_item_$reason'(Reason, + __NewTopXMLNS, [])))), _attrs = encode_muc_admin_item_attr_nick(Nick, encode_muc_admin_item_attr_jid(Jid, encode_muc_admin_item_attr_role(Role, encode_muc_admin_item_attr_affiliation(Affiliation, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"item">>, _attrs, _els}. -'encode_muc_admin_item_$actor'(undefined, _acc) -> _acc; -'encode_muc_admin_item_$actor'(Actor, _acc) -> - [encode_muc_admin_actor(Actor, []) | _acc]. +'encode_muc_admin_item_$actor'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_admin_item_$actor'(Actor, __TopXMLNS, + _acc) -> + [encode_muc_admin_actor(Actor, __TopXMLNS) | _acc]. -'encode_muc_admin_item_$continue'(undefined, _acc) -> +'encode_muc_admin_item_$continue'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_muc_admin_item_$continue'(Continue, _acc) -> - [encode_muc_admin_continue(Continue, []) | _acc]. +'encode_muc_admin_item_$continue'(Continue, __TopXMLNS, + _acc) -> + [encode_muc_admin_continue(Continue, __TopXMLNS) + | _acc]. -'encode_muc_admin_item_$reason'(<<>>, _acc) -> _acc; -'encode_muc_admin_item_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_admin_item_$reason'(<<>>, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_admin_item_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_admin_item_attr_affiliation(__TopXMLNS, undefined) -> @@ -10830,37 +13837,47 @@ decode_muc_owner_item_attrs(__TopXMLNS, [], Affiliation, encode_muc_owner_item({muc_item, Actor, Continue, Reason, Affiliation, Role, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#owner">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_owner_item_$actor'(Actor, + __NewTopXMLNS, 'encode_muc_owner_item_$continue'(Continue, + __NewTopXMLNS, 'encode_muc_owner_item_$reason'(Reason, + __NewTopXMLNS, [])))), _attrs = encode_muc_owner_item_attr_nick(Nick, encode_muc_owner_item_attr_jid(Jid, encode_muc_owner_item_attr_role(Role, encode_muc_owner_item_attr_affiliation(Affiliation, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"item">>, _attrs, _els}. -'encode_muc_owner_item_$actor'(undefined, _acc) -> _acc; -'encode_muc_owner_item_$actor'(Actor, _acc) -> - [encode_muc_admin_actor(Actor, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#admin">>}]) - | _acc]. +'encode_muc_owner_item_$actor'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_owner_item_$actor'(Actor, __TopXMLNS, + _acc) -> + [encode_muc_admin_actor(Actor, __TopXMLNS) | _acc]. -'encode_muc_owner_item_$continue'(undefined, _acc) -> +'encode_muc_owner_item_$continue'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_muc_owner_item_$continue'(Continue, _acc) -> - [encode_muc_admin_continue(Continue, - [{<<"xmlns">>, - <<"http://jabber.org/protocol/muc#admin">>}]) +'encode_muc_owner_item_$continue'(Continue, __TopXMLNS, + _acc) -> + [encode_muc_admin_continue(Continue, __TopXMLNS) | _acc]. -'encode_muc_owner_item_$reason'(<<>>, _acc) -> _acc; -'encode_muc_owner_item_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_owner_item_$reason'(<<>>, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_owner_item_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_owner_item_attr_affiliation(__TopXMLNS, undefined) -> @@ -11002,28 +14019,39 @@ decode_muc_owner_els(__TopXMLNS, __IgnoreEls, Items, Config, Destroy). encode_muc_owner({muc_owner, Destroy, Config, Items}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#owner">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_owner_$items'(Items, + __NewTopXMLNS, 'encode_muc_owner_$config'(Config, + __NewTopXMLNS, 'encode_muc_owner_$destroy'(Destroy, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_muc_owner_$items'([], _acc) -> _acc; -'encode_muc_owner_$items'([Items | _els], _acc) -> - 'encode_muc_owner_$items'(_els, - [encode_muc_owner_item(Items, []) | _acc]). +'encode_muc_owner_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_muc_owner_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_muc_owner_$items'(_els, __TopXMLNS, + [encode_muc_owner_item(Items, __TopXMLNS) + | _acc]). -'encode_muc_owner_$config'(undefined, _acc) -> _acc; -'encode_muc_owner_$config'(Config, _acc) -> - [encode_xdata(Config, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_muc_owner_$config'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_owner_$config'(Config, __TopXMLNS, _acc) -> + [encode_xdata(Config, __TopXMLNS) | _acc]. -'encode_muc_owner_$destroy'(undefined, _acc) -> _acc; -'encode_muc_owner_$destroy'(Destroy, _acc) -> - [encode_muc_destroy(Destroy, []) | _acc]. +'encode_muc_owner_$destroy'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_owner_$destroy'(Destroy, __TopXMLNS, + _acc) -> + [encode_muc_destroy(Destroy, __TopXMLNS) | _acc]. decode_muc_password(__TopXMLNS, __IgnoreEls, {xmlel, <<"password">>, _attrs, _els}) -> @@ -11043,9 +14071,14 @@ decode_muc_password_els(__TopXMLNS, __IgnoreEls, decode_muc_password_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_muc_password(Cdata, _xmlns_attrs) -> +encode_muc_password(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/muc#owner">>, + <<"http://jabber.org/protocol/muc#user">>, + <<"http://jabber.org/protocol/muc">>], + __TopXMLNS), _els = encode_muc_password_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"password">>, _attrs, _els}. decode_muc_password_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -11246,46 +14279,68 @@ decode_muc_user_els(__TopXMLNS, __IgnoreEls, [_ | _els], encode_muc_user({muc_user, Decline, Destroy, Invites, Items, Status_codes, Password}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_user_$status_codes'(Status_codes, + __NewTopXMLNS, 'encode_muc_user_$items'(Items, + __NewTopXMLNS, 'encode_muc_user_$invites'(Invites, + __NewTopXMLNS, 'encode_muc_user_$password'(Password, + __NewTopXMLNS, 'encode_muc_user_$decline'(Decline, + __NewTopXMLNS, 'encode_muc_user_$destroy'(Destroy, + __NewTopXMLNS, []))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"x">>, _attrs, _els}. -'encode_muc_user_$status_codes'([], _acc) -> _acc; +'encode_muc_user_$status_codes'([], __TopXMLNS, _acc) -> + _acc; 'encode_muc_user_$status_codes'([Status_codes | _els], - _acc) -> - 'encode_muc_user_$status_codes'(_els, - [encode_muc_user_status(Status_codes, []) + __TopXMLNS, _acc) -> + 'encode_muc_user_$status_codes'(_els, __TopXMLNS, + [encode_muc_user_status(Status_codes, + __TopXMLNS) | _acc]). -'encode_muc_user_$items'([], _acc) -> _acc; -'encode_muc_user_$items'([Items | _els], _acc) -> - 'encode_muc_user_$items'(_els, - [encode_muc_user_item(Items, []) | _acc]). +'encode_muc_user_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_muc_user_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_muc_user_$items'(_els, __TopXMLNS, + [encode_muc_user_item(Items, __TopXMLNS) | _acc]). -'encode_muc_user_$invites'([], _acc) -> _acc; -'encode_muc_user_$invites'([Invites | _els], _acc) -> - 'encode_muc_user_$invites'(_els, - [encode_muc_user_invite(Invites, []) | _acc]). +'encode_muc_user_$invites'([], __TopXMLNS, _acc) -> + _acc; +'encode_muc_user_$invites'([Invites | _els], __TopXMLNS, + _acc) -> + 'encode_muc_user_$invites'(_els, __TopXMLNS, + [encode_muc_user_invite(Invites, __TopXMLNS) + | _acc]). -'encode_muc_user_$password'(undefined, _acc) -> _acc; -'encode_muc_user_$password'(Password, _acc) -> - [encode_muc_password(Password, []) | _acc]. +'encode_muc_user_$password'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_$password'(Password, __TopXMLNS, + _acc) -> + [encode_muc_password(Password, __TopXMLNS) | _acc]. -'encode_muc_user_$decline'(undefined, _acc) -> _acc; -'encode_muc_user_$decline'(Decline, _acc) -> - [encode_muc_user_decline(Decline, []) | _acc]. +'encode_muc_user_$decline'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_$decline'(Decline, __TopXMLNS, _acc) -> + [encode_muc_user_decline(Decline, __TopXMLNS) | _acc]. -'encode_muc_user_$destroy'(undefined, _acc) -> _acc; -'encode_muc_user_$destroy'(Destroy, _acc) -> - [encode_muc_destroy(Destroy, []) | _acc]. +'encode_muc_user_$destroy'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_$destroy'(Destroy, __TopXMLNS, _acc) -> + [encode_muc_destroy(Destroy, __TopXMLNS) | _acc]. decode_muc_user_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> @@ -11412,31 +14467,46 @@ decode_muc_user_item_attrs(__TopXMLNS, [], Affiliation, encode_muc_user_item({muc_item, Actor, Continue, Reason, Affiliation, Role, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_user_item_$actor'(Actor, + __NewTopXMLNS, 'encode_muc_user_item_$continue'(Continue, + __NewTopXMLNS, 'encode_muc_user_item_$reason'(Reason, + __NewTopXMLNS, [])))), _attrs = encode_muc_user_item_attr_nick(Nick, encode_muc_user_item_attr_jid(Jid, encode_muc_user_item_attr_role(Role, encode_muc_user_item_attr_affiliation(Affiliation, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"item">>, _attrs, _els}. -'encode_muc_user_item_$actor'(undefined, _acc) -> _acc; -'encode_muc_user_item_$actor'(Actor, _acc) -> - [encode_muc_user_actor(Actor, []) | _acc]. +'encode_muc_user_item_$actor'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_item_$actor'(Actor, __TopXMLNS, + _acc) -> + [encode_muc_user_actor(Actor, __TopXMLNS) | _acc]. -'encode_muc_user_item_$continue'(undefined, _acc) -> +'encode_muc_user_item_$continue'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_muc_user_item_$continue'(Continue, _acc) -> - [encode_muc_user_continue(Continue, []) | _acc]. +'encode_muc_user_item_$continue'(Continue, __TopXMLNS, + _acc) -> + [encode_muc_user_continue(Continue, __TopXMLNS) | _acc]. -'encode_muc_user_item_$reason'(<<>>, _acc) -> _acc; -'encode_muc_user_item_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_user_item_$reason'(<<>>, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_item_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_user_item_attr_affiliation(__TopXMLNS, undefined) -> @@ -11513,10 +14583,14 @@ decode_muc_user_status_attrs(__TopXMLNS, [_ | _attrs], decode_muc_user_status_attrs(__TopXMLNS, [], Code) -> decode_muc_user_status_attr_code(__TopXMLNS, Code). -encode_muc_user_status(Code, _xmlns_attrs) -> +encode_muc_user_status(Code, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_user_status_attr_code(Code, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"status">>, _attrs, _els}. decode_muc_user_status_attr_code(__TopXMLNS, @@ -11555,10 +14629,14 @@ decode_muc_user_continue_attrs(__TopXMLNS, [], decode_muc_user_continue_attr_thread(__TopXMLNS, Thread). -encode_muc_user_continue(Thread, _xmlns_attrs) -> +encode_muc_user_continue(Thread, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_user_continue_attr_thread(Thread, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"continue">>, _attrs, _els}. decode_muc_user_continue_attr_thread(__TopXMLNS, @@ -11597,11 +14675,15 @@ decode_muc_user_actor_attrs(__TopXMLNS, [], Jid, decode_muc_user_actor_attr_nick(__TopXMLNS, Nick)}. encode_muc_user_actor({muc_actor, Jid, Nick}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_user_actor_attr_nick(Nick, encode_muc_user_actor_attr_jid(Jid, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"actor">>, _attrs, _els}. decode_muc_user_actor_attr_jid(__TopXMLNS, undefined) -> @@ -11716,24 +14798,35 @@ decode_muc_user_invite_attrs(__TopXMLNS, [], To, encode_muc_user_invite({muc_invite, Reason, From, To, Continue}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_user_invite_$continue'(Continue, + __NewTopXMLNS, 'encode_muc_user_invite_$reason'(Reason, + __NewTopXMLNS, []))), _attrs = encode_muc_user_invite_attr_from(From, encode_muc_user_invite_attr_to(To, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"invite">>, _attrs, _els}. -'encode_muc_user_invite_$continue'(undefined, _acc) -> +'encode_muc_user_invite_$continue'(undefined, + __TopXMLNS, _acc) -> _acc; -'encode_muc_user_invite_$continue'(Continue, _acc) -> - [encode_muc_user_continue(Continue, []) | _acc]. +'encode_muc_user_invite_$continue'(Continue, __TopXMLNS, + _acc) -> + [encode_muc_user_continue(Continue, __TopXMLNS) | _acc]. -'encode_muc_user_invite_$reason'(<<>>, _acc) -> _acc; -'encode_muc_user_invite_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_user_invite_$reason'(<<>>, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_invite_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_user_invite_attr_to(__TopXMLNS, undefined) -> undefined; @@ -11864,23 +14957,34 @@ decode_muc_destroy_attrs(__TopXMLNS, [], Jid, Xmlns) -> encode_muc_destroy({muc_destroy, Xmlns, Jid, Reason, Password}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/muc#user">>, + <<"http://jabber.org/protocol/muc#owner">>], + __TopXMLNS), _els = lists:reverse('encode_muc_destroy_$password'(Password, + __NewTopXMLNS, 'encode_muc_destroy_$reason'(Reason, + __NewTopXMLNS, []))), - _attrs = encode_muc_destroy_attr_xmlns(Xmlns, - encode_muc_destroy_attr_jid(Jid, - _xmlns_attrs)), + _attrs = encode_muc_destroy_attr_jid(Jid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"destroy">>, _attrs, _els}. -'encode_muc_destroy_$password'(undefined, _acc) -> _acc; -'encode_muc_destroy_$password'(Password, _acc) -> - [encode_muc_password(Password, []) | _acc]. +'encode_muc_destroy_$password'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_destroy_$password'(Password, __TopXMLNS, + _acc) -> + [encode_muc_password(Password, __TopXMLNS) | _acc]. -'encode_muc_destroy_$reason'(<<>>, _acc) -> _acc; -'encode_muc_destroy_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_destroy_$reason'(<<>>, __TopXMLNS, _acc) -> + _acc; +'encode_muc_destroy_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_destroy_attr_jid(__TopXMLNS, undefined) -> undefined; @@ -11901,10 +15005,6 @@ decode_muc_destroy_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_muc_destroy_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_muc_destroy_attr_xmlns(<<>>, _acc) -> _acc; -encode_muc_destroy_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_muc_user_decline(__TopXMLNS, __IgnoreEls, {xmlel, <<"decline">>, _attrs, _els}) -> Reason = decode_muc_user_decline_els(__TopXMLNS, @@ -11969,18 +15069,25 @@ decode_muc_user_decline_attrs(__TopXMLNS, [], To, decode_muc_user_decline_attr_from(__TopXMLNS, From)}. encode_muc_user_decline({muc_decline, Reason, From, To}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, + [], __TopXMLNS), _els = lists:reverse('encode_muc_user_decline_$reason'(Reason, - [])), + __NewTopXMLNS, [])), _attrs = encode_muc_user_decline_attr_from(From, encode_muc_user_decline_attr_to(To, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"decline">>, _attrs, _els}. -'encode_muc_user_decline_$reason'(<<>>, _acc) -> _acc; -'encode_muc_user_decline_$reason'(Reason, _acc) -> - [encode_muc_reason(Reason, []) | _acc]. +'encode_muc_user_decline_$reason'(<<>>, __TopXMLNS, + _acc) -> + _acc; +'encode_muc_user_decline_$reason'(Reason, __TopXMLNS, + _acc) -> + [encode_muc_reason(Reason, __TopXMLNS) | _acc]. decode_muc_user_decline_attr_to(__TopXMLNS, undefined) -> @@ -12033,9 +15140,14 @@ decode_muc_reason_els(__TopXMLNS, __IgnoreEls, decode_muc_reason_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_muc_reason(Cdata, _xmlns_attrs) -> +encode_muc_reason(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/muc#user">>, + <<"http://jabber.org/protocol/muc#admin">>, + <<"http://jabber.org/protocol/muc#owner">>], + __TopXMLNS), _els = encode_muc_reason_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"reason">>, _attrs, _els}. decode_muc_reason_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -12086,13 +15198,17 @@ decode_muc_history_attrs(__TopXMLNS, [], Maxchars, encode_muc_history({muc_history, Maxchars, Maxstanzas, Seconds, Since}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/muc">>, + [], __TopXMLNS), _els = [], _attrs = encode_muc_history_attr_since(Since, encode_muc_history_attr_seconds(Seconds, encode_muc_history_attr_maxstanzas(Maxstanzas, encode_muc_history_attr_maxchars(Maxchars, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"history">>, _attrs, _els}. decode_muc_history_attr_maxchars(__TopXMLNS, @@ -12274,30 +15390,47 @@ decode_bytestreams_attrs(__TopXMLNS, [], Dstaddr, Sid, encode_bytestreams({bytestreams, Hosts, Used, Activate, Dstaddr, Mode, Sid}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, + [], __TopXMLNS), _els = lists:reverse('encode_bytestreams_$hosts'(Hosts, + __NewTopXMLNS, 'encode_bytestreams_$used'(Used, + __NewTopXMLNS, 'encode_bytestreams_$activate'(Activate, + __NewTopXMLNS, [])))), _attrs = encode_bytestreams_attr_mode(Mode, encode_bytestreams_attr_sid(Sid, encode_bytestreams_attr_dstaddr(Dstaddr, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"query">>, _attrs, _els}. -'encode_bytestreams_$hosts'([], _acc) -> _acc; -'encode_bytestreams_$hosts'([Hosts | _els], _acc) -> - 'encode_bytestreams_$hosts'(_els, - [encode_bytestreams_streamhost(Hosts, []) +'encode_bytestreams_$hosts'([], __TopXMLNS, _acc) -> + _acc; +'encode_bytestreams_$hosts'([Hosts | _els], __TopXMLNS, + _acc) -> + 'encode_bytestreams_$hosts'(_els, __TopXMLNS, + [encode_bytestreams_streamhost(Hosts, + __TopXMLNS) | _acc]). -'encode_bytestreams_$used'(undefined, _acc) -> _acc; -'encode_bytestreams_$used'(Used, _acc) -> - [encode_bytestreams_streamhost_used(Used, []) | _acc]. +'encode_bytestreams_$used'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_bytestreams_$used'(Used, __TopXMLNS, _acc) -> + [encode_bytestreams_streamhost_used(Used, __TopXMLNS) + | _acc]. -'encode_bytestreams_$activate'(undefined, _acc) -> _acc; -'encode_bytestreams_$activate'(Activate, _acc) -> - [encode_bytestreams_activate(Activate, []) | _acc]. +'encode_bytestreams_$activate'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_bytestreams_$activate'(Activate, __TopXMLNS, + _acc) -> + [encode_bytestreams_activate(Activate, __TopXMLNS) + | _acc]. decode_bytestreams_attr_dstaddr(__TopXMLNS, undefined) -> @@ -12349,9 +15482,12 @@ decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_bytestreams_activate(Cdata, _xmlns_attrs) -> +encode_bytestreams_activate(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, + [], __TopXMLNS), _els = encode_bytestreams_activate_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"activate">>, _attrs, _els}. decode_bytestreams_activate_cdata(__TopXMLNS, <<>>) -> @@ -12391,11 +15527,15 @@ decode_bytestreams_streamhost_used_attrs(__TopXMLNS, [], decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, Jid). -encode_bytestreams_streamhost_used(Jid, _xmlns_attrs) -> +encode_bytestreams_streamhost_used(Jid, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, + [], __TopXMLNS), _els = [], _attrs = encode_bytestreams_streamhost_used_attr_jid(Jid, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"streamhost-used">>, _attrs, _els}. decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, @@ -12454,12 +15594,16 @@ decode_bytestreams_streamhost_attrs(__TopXMLNS, [], Jid, encode_bytestreams_streamhost({streamhost, Jid, Host, Port}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, + [], __TopXMLNS), _els = [], _attrs = encode_bytestreams_streamhost_attr_port(Port, encode_bytestreams_streamhost_attr_host(Host, encode_bytestreams_streamhost_attr_jid(Jid, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"streamhost">>, _attrs, _els}. decode_bytestreams_streamhost_attr_jid(__TopXMLNS, @@ -12541,12 +15685,14 @@ decode_delay_attrs(__TopXMLNS, [], Stamp, From) -> {decode_delay_attr_stamp(__TopXMLNS, Stamp), decode_delay_attr_from(__TopXMLNS, From)}. -encode_delay({delay, Stamp, From, Desc}, - _xmlns_attrs) -> +encode_delay({delay, Stamp, From, Desc}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:delay">>, + [], __TopXMLNS), _els = encode_delay_cdata(Desc, []), _attrs = encode_delay_attr_from(From, encode_delay_attr_stamp(Stamp, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"delay">>, _attrs, _els}. decode_delay_attr_stamp(__TopXMLNS, undefined) -> @@ -12590,9 +15736,12 @@ decode_chatstate_paused(__TopXMLNS, __IgnoreEls, {chatstate, paused}. encode_chatstate_paused({chatstate, paused}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"paused">>, _attrs, _els}. decode_chatstate_inactive(__TopXMLNS, __IgnoreEls, @@ -12600,19 +15749,24 @@ decode_chatstate_inactive(__TopXMLNS, __IgnoreEls, {chatstate, inactive}. encode_chatstate_inactive({chatstate, inactive}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"inactive">>, _attrs, _els}. decode_chatstate_gone(__TopXMLNS, __IgnoreEls, {xmlel, <<"gone">>, _attrs, _els}) -> {chatstate, gone}. -encode_chatstate_gone({chatstate, gone}, - _xmlns_attrs) -> +encode_chatstate_gone({chatstate, gone}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"gone">>, _attrs, _els}. decode_chatstate_composing(__TopXMLNS, __IgnoreEls, @@ -12620,9 +15774,12 @@ decode_chatstate_composing(__TopXMLNS, __IgnoreEls, {chatstate, composing}. encode_chatstate_composing({chatstate, composing}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"composing">>, _attrs, _els}. decode_chatstate_active(__TopXMLNS, __IgnoreEls, @@ -12630,9 +15787,12 @@ decode_chatstate_active(__TopXMLNS, __IgnoreEls, {chatstate, active}. encode_chatstate_active({chatstate, active}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"active">>, _attrs, _els}. decode_shim_headers(__TopXMLNS, __IgnoreEls, @@ -12669,18 +15829,23 @@ decode_shim_headers_els(__TopXMLNS, __IgnoreEls, decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, Headers). -encode_shim_headers({shim, Headers}, _xmlns_attrs) -> +encode_shim_headers({shim, Headers}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/shim">>, + [], __TopXMLNS), _els = lists:reverse('encode_shim_headers_$headers'(Headers, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"headers">>, _attrs, _els}. -'encode_shim_headers_$headers'([], _acc) -> _acc; +'encode_shim_headers_$headers'([], __TopXMLNS, _acc) -> + _acc; 'encode_shim_headers_$headers'([Headers | _els], - _acc) -> - 'encode_shim_headers_$headers'(_els, - [encode_shim_header(Headers, []) | _acc]). + __TopXMLNS, _acc) -> + 'encode_shim_headers_$headers'(_els, __TopXMLNS, + [encode_shim_header(Headers, __TopXMLNS) + | _acc]). decode_shim_header(__TopXMLNS, __IgnoreEls, {xmlel, <<"header">>, _attrs, _els}) -> @@ -12711,10 +15876,14 @@ decode_shim_header_attrs(__TopXMLNS, [_ | _attrs], decode_shim_header_attrs(__TopXMLNS, [], Name) -> decode_shim_header_attr_name(__TopXMLNS, Name). -encode_shim_header({Name, Cdata}, _xmlns_attrs) -> +encode_shim_header({Name, Cdata}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/shim">>, + [], __TopXMLNS), _els = encode_shim_header_cdata(Cdata, []), _attrs = encode_shim_header_attr_name(Name, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"header">>, _attrs, _els}. decode_shim_header_attr_name(__TopXMLNS, undefined) -> @@ -12741,9 +15910,12 @@ decode_pubsub_error_unsupported_access_model(__TopXMLNS, encode_pubsub_error_unsupported_access_model({ps_error, 'unsupported-access-model', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsupported-access-model">>, _attrs, _els}. decode_pubsub_error_unsupported(__TopXMLNS, __IgnoreEls, @@ -12769,11 +15941,15 @@ decode_pubsub_error_unsupported_attrs(__TopXMLNS, [], encode_pubsub_error_unsupported({ps_error, unsupported, Feature}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], _attrs = encode_pubsub_error_unsupported_attr_feature(Feature, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"unsupported">>, _attrs, _els}. decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, @@ -12821,9 +15997,12 @@ decode_pubsub_error_too_many_subscriptions(__TopXMLNS, encode_pubsub_error_too_many_subscriptions({ps_error, 'too-many-subscriptions', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"too-many-subscriptions">>, _attrs, _els}. decode_pubsub_error_subid_required(__TopXMLNS, @@ -12834,9 +16013,12 @@ decode_pubsub_error_subid_required(__TopXMLNS, encode_pubsub_error_subid_required({ps_error, 'subid-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"subid-required">>, _attrs, _els}. decode_pubsub_error_presence_subscription_required(__TopXMLNS, @@ -12849,9 +16031,12 @@ decode_pubsub_error_presence_subscription_required(__TopXMLNS, encode_pubsub_error_presence_subscription_required({ps_error, 'presence-subscription-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"presence-subscription-required">>, _attrs, _els}. @@ -12863,9 +16048,12 @@ decode_pubsub_error_pending_subscription(__TopXMLNS, encode_pubsub_error_pending_subscription({ps_error, 'pending-subscription', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"pending-subscription">>, _attrs, _els}. decode_pubsub_error_payload_required(__TopXMLNS, @@ -12876,9 +16064,12 @@ decode_pubsub_error_payload_required(__TopXMLNS, encode_pubsub_error_payload_required({ps_error, 'payload-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"payload-required">>, _attrs, _els}. decode_pubsub_error_payload_too_big(__TopXMLNS, @@ -12889,9 +16080,12 @@ decode_pubsub_error_payload_too_big(__TopXMLNS, encode_pubsub_error_payload_too_big({ps_error, 'payload-too-big', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"payload-too-big">>, _attrs, _els}. decode_pubsub_error_not_subscribed(__TopXMLNS, @@ -12902,9 +16096,12 @@ decode_pubsub_error_not_subscribed(__TopXMLNS, encode_pubsub_error_not_subscribed({ps_error, 'not-subscribed', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-subscribed">>, _attrs, _els}. decode_pubsub_error_not_in_roster_group(__TopXMLNS, @@ -12915,9 +16112,12 @@ decode_pubsub_error_not_in_roster_group(__TopXMLNS, encode_pubsub_error_not_in_roster_group({ps_error, 'not-in-roster-group', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-in-roster-group">>, _attrs, _els}. decode_pubsub_error_nodeid_required(__TopXMLNS, @@ -12928,9 +16128,12 @@ decode_pubsub_error_nodeid_required(__TopXMLNS, encode_pubsub_error_nodeid_required({ps_error, 'nodeid-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"nodeid-required">>, _attrs, _els}. decode_pubsub_error_max_nodes_exceeded(__TopXMLNS, @@ -12941,9 +16144,12 @@ decode_pubsub_error_max_nodes_exceeded(__TopXMLNS, encode_pubsub_error_max_nodes_exceeded({ps_error, 'max-nodes-exceeded', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"max-nodes-exceeded">>, _attrs, _els}. decode_pubsub_error_max_items_exceeded(__TopXMLNS, @@ -12954,9 +16160,12 @@ decode_pubsub_error_max_items_exceeded(__TopXMLNS, encode_pubsub_error_max_items_exceeded({ps_error, 'max-items-exceeded', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"max-items-exceeded">>, _attrs, _els}. decode_pubsub_error_jid_required(__TopXMLNS, @@ -12966,9 +16175,12 @@ decode_pubsub_error_jid_required(__TopXMLNS, encode_pubsub_error_jid_required({ps_error, 'jid-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"jid-required">>, _attrs, _els}. decode_pubsub_error_item_required(__TopXMLNS, @@ -12978,9 +16190,12 @@ decode_pubsub_error_item_required(__TopXMLNS, encode_pubsub_error_item_required({ps_error, 'item-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"item-required">>, _attrs, _els}. decode_pubsub_error_item_forbidden(__TopXMLNS, @@ -12991,9 +16206,12 @@ decode_pubsub_error_item_forbidden(__TopXMLNS, encode_pubsub_error_item_forbidden({ps_error, 'item-forbidden', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"item-forbidden">>, _attrs, _els}. decode_pubsub_error_invalid_subid(__TopXMLNS, @@ -13003,9 +16221,12 @@ decode_pubsub_error_invalid_subid(__TopXMLNS, encode_pubsub_error_invalid_subid({ps_error, 'invalid-subid', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-subid">>, _attrs, _els}. decode_pubsub_error_invalid_payload(__TopXMLNS, @@ -13016,9 +16237,12 @@ decode_pubsub_error_invalid_payload(__TopXMLNS, encode_pubsub_error_invalid_payload({ps_error, 'invalid-payload', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-payload">>, _attrs, _els}. decode_pubsub_error_invalid_options(__TopXMLNS, @@ -13029,9 +16253,12 @@ decode_pubsub_error_invalid_options(__TopXMLNS, encode_pubsub_error_invalid_options({ps_error, 'invalid-options', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-options">>, _attrs, _els}. decode_pubsub_error_invalid_jid(__TopXMLNS, __IgnoreEls, @@ -13040,9 +16267,12 @@ decode_pubsub_error_invalid_jid(__TopXMLNS, __IgnoreEls, encode_pubsub_error_invalid_jid({ps_error, 'invalid-jid', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-jid">>, _attrs, _els}. decode_pubsub_error_configuration_required(__TopXMLNS, @@ -13053,9 +16283,12 @@ decode_pubsub_error_configuration_required(__TopXMLNS, encode_pubsub_error_configuration_required({ps_error, 'configuration-required', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"configuration-required">>, _attrs, _els}. decode_pubsub_error_closed_node(__TopXMLNS, __IgnoreEls, @@ -13064,9 +16297,12 @@ decode_pubsub_error_closed_node(__TopXMLNS, __IgnoreEls, encode_pubsub_error_closed_node({ps_error, 'closed-node', _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"closed-node">>, _attrs, _els}. decode_pubsub_owner(__TopXMLNS, __IgnoreEls, @@ -13281,47 +16517,70 @@ decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, encode_pubsub_owner({pubsub_owner, Affiliations, Configure, Default, Delete, Purge, Subscriptions}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#owner">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_owner_$subscriptions'(Subscriptions, + __NewTopXMLNS, 'encode_pubsub_owner_$affiliations'(Affiliations, + __NewTopXMLNS, 'encode_pubsub_owner_$default'(Default, + __NewTopXMLNS, 'encode_pubsub_owner_$purge'(Purge, + __NewTopXMLNS, 'encode_pubsub_owner_$delete'(Delete, + __NewTopXMLNS, 'encode_pubsub_owner_$configure'(Configure, + __NewTopXMLNS, []))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"pubsub">>, _attrs, _els}. -'encode_pubsub_owner_$subscriptions'(undefined, _acc) -> +'encode_pubsub_owner_$subscriptions'(undefined, + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_owner_$subscriptions'(Subscriptions, - _acc) -> - [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_pubsub_subscriptions(Subscriptions, __TopXMLNS) + | _acc]. -'encode_pubsub_owner_$affiliations'(undefined, _acc) -> +'encode_pubsub_owner_$affiliations'(undefined, + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_owner_$affiliations'(Affiliations, - _acc) -> - [encode_pubsub_owner_affiliations(Affiliations, []) + __TopXMLNS, _acc) -> + [encode_pubsub_owner_affiliations(Affiliations, + __TopXMLNS) | _acc]. -'encode_pubsub_owner_$default'(undefined, _acc) -> _acc; -'encode_pubsub_owner_$default'(Default, _acc) -> - [encode_pubsub_default(Default, []) | _acc]. +'encode_pubsub_owner_$default'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_owner_$default'(Default, __TopXMLNS, + _acc) -> + [encode_pubsub_default(Default, __TopXMLNS) | _acc]. -'encode_pubsub_owner_$purge'(undefined, _acc) -> _acc; -'encode_pubsub_owner_$purge'(Purge, _acc) -> - [encode_pubsub_purge(Purge, []) | _acc]. +'encode_pubsub_owner_$purge'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_owner_$purge'(Purge, __TopXMLNS, _acc) -> + [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. -'encode_pubsub_owner_$delete'(undefined, _acc) -> _acc; -'encode_pubsub_owner_$delete'(Delete, _acc) -> - [encode_pubsub_delete(Delete, []) | _acc]. +'encode_pubsub_owner_$delete'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_owner_$delete'(Delete, __TopXMLNS, + _acc) -> + [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. -'encode_pubsub_owner_$configure'(undefined, _acc) -> +'encode_pubsub_owner_$configure'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_pubsub_owner_$configure'(Configure, _acc) -> - [encode_pubsub_configure(Configure, []) | _acc]. +'encode_pubsub_owner_$configure'(Configure, __TopXMLNS, + _acc) -> + [encode_pubsub_configure(Configure, __TopXMLNS) | _acc]. decode_pubsub(__TopXMLNS, __IgnoreEls, {xmlel, <<"pubsub">>, _attrs, _els}) -> @@ -13941,97 +17200,147 @@ encode_pubsub({pubsub, Subscriptions, Subscription, Affiliations, Publish, Publish_options, Subscribe, Unsubscribe, Options, Items, Retract, Create, Configure, Default, Delete, Purge, Rsm}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_$publish_options'(Publish_options, + __NewTopXMLNS, 'encode_pubsub_$items'(Items, + __NewTopXMLNS, 'encode_pubsub_$options'(Options, + __NewTopXMLNS, 'encode_pubsub_$affiliations'(Affiliations, + __NewTopXMLNS, 'encode_pubsub_$subscriptions'(Subscriptions, + __NewTopXMLNS, 'encode_pubsub_$default'(Default, + __NewTopXMLNS, 'encode_pubsub_$retract'(Retract, + __NewTopXMLNS, 'encode_pubsub_$purge'(Purge, + __NewTopXMLNS, 'encode_pubsub_$delete'(Delete, + __NewTopXMLNS, 'encode_pubsub_$configure'(Configure, + __NewTopXMLNS, 'encode_pubsub_$create'(Create, + __NewTopXMLNS, 'encode_pubsub_$unsubscribe'(Unsubscribe, + __NewTopXMLNS, 'encode_pubsub_$subscribe'(Subscribe, + __NewTopXMLNS, 'encode_pubsub_$publish'(Publish, + __NewTopXMLNS, 'encode_pubsub_$rsm'(Rsm, + __NewTopXMLNS, 'encode_pubsub_$subscription'(Subscription, + __NewTopXMLNS, []))))))))))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"pubsub">>, _attrs, _els}. -'encode_pubsub_$publish_options'(undefined, _acc) -> +'encode_pubsub_$publish_options'(undefined, __TopXMLNS, + _acc) -> _acc; 'encode_pubsub_$publish_options'(Publish_options, - _acc) -> - [encode_pubsub_publish_options(Publish_options, []) + __TopXMLNS, _acc) -> + [encode_pubsub_publish_options(Publish_options, + __TopXMLNS) | _acc]. -'encode_pubsub_$items'(undefined, _acc) -> _acc; -'encode_pubsub_$items'(Items, _acc) -> - [encode_pubsub_items(Items, []) | _acc]. +'encode_pubsub_$items'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$items'(Items, __TopXMLNS, _acc) -> + [encode_pubsub_items(Items, __TopXMLNS) | _acc]. + +'encode_pubsub_$options'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$options'(Options, __TopXMLNS, _acc) -> + [encode_pubsub_options(Options, __TopXMLNS) | _acc]. -'encode_pubsub_$options'(undefined, _acc) -> _acc; -'encode_pubsub_$options'(Options, _acc) -> - [encode_pubsub_options(Options, []) | _acc]. +'encode_pubsub_$affiliations'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$affiliations'(Affiliations, __TopXMLNS, + _acc) -> + [encode_pubsub_affiliations(Affiliations, __TopXMLNS) + | _acc]. -'encode_pubsub_$affiliations'(undefined, _acc) -> _acc; -'encode_pubsub_$affiliations'(Affiliations, _acc) -> - [encode_pubsub_affiliations(Affiliations, []) | _acc]. +'encode_pubsub_$subscriptions'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$subscriptions'(Subscriptions, + __TopXMLNS, _acc) -> + [encode_pubsub_subscriptions(Subscriptions, __TopXMLNS) + | _acc]. -'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc; -'encode_pubsub_$subscriptions'(Subscriptions, _acc) -> - [encode_pubsub_subscriptions(Subscriptions, []) | _acc]. +'encode_pubsub_$default'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$default'(Default, __TopXMLNS, _acc) -> + [encode_pubsub_default(Default, __TopXMLNS) | _acc]. -'encode_pubsub_$default'(undefined, _acc) -> _acc; -'encode_pubsub_$default'(Default, _acc) -> - [encode_pubsub_default(Default, []) | _acc]. +'encode_pubsub_$retract'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$retract'(Retract, __TopXMLNS, _acc) -> + [encode_pubsub_retract(Retract, __TopXMLNS) | _acc]. -'encode_pubsub_$retract'(undefined, _acc) -> _acc; -'encode_pubsub_$retract'(Retract, _acc) -> - [encode_pubsub_retract(Retract, []) | _acc]. +'encode_pubsub_$purge'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$purge'(Purge, __TopXMLNS, _acc) -> + [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. -'encode_pubsub_$purge'(undefined, _acc) -> _acc; -'encode_pubsub_$purge'(Purge, _acc) -> - [encode_pubsub_purge(Purge, []) | _acc]. +'encode_pubsub_$delete'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$delete'(Delete, __TopXMLNS, _acc) -> + [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. -'encode_pubsub_$delete'(undefined, _acc) -> _acc; -'encode_pubsub_$delete'(Delete, _acc) -> - [encode_pubsub_delete(Delete, []) | _acc]. +'encode_pubsub_$configure'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$configure'(Configure, __TopXMLNS, + _acc) -> + [encode_pubsub_configure(Configure, __TopXMLNS) | _acc]. -'encode_pubsub_$configure'(undefined, _acc) -> _acc; -'encode_pubsub_$configure'(Configure, _acc) -> - [encode_pubsub_configure(Configure, []) | _acc]. +'encode_pubsub_$create'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$create'(Create, __TopXMLNS, _acc) -> + [encode_pubsub_create(Create, __TopXMLNS) | _acc]. -'encode_pubsub_$create'(undefined, _acc) -> _acc; -'encode_pubsub_$create'(Create, _acc) -> - [encode_pubsub_create(Create, []) | _acc]. +'encode_pubsub_$unsubscribe'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$unsubscribe'(Unsubscribe, __TopXMLNS, + _acc) -> + [encode_pubsub_unsubscribe(Unsubscribe, __TopXMLNS) + | _acc]. -'encode_pubsub_$unsubscribe'(undefined, _acc) -> _acc; -'encode_pubsub_$unsubscribe'(Unsubscribe, _acc) -> - [encode_pubsub_unsubscribe(Unsubscribe, []) | _acc]. +'encode_pubsub_$subscribe'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$subscribe'(Subscribe, __TopXMLNS, + _acc) -> + [encode_pubsub_subscribe(Subscribe, __TopXMLNS) | _acc]. -'encode_pubsub_$subscribe'(undefined, _acc) -> _acc; -'encode_pubsub_$subscribe'(Subscribe, _acc) -> - [encode_pubsub_subscribe(Subscribe, []) | _acc]. +'encode_pubsub_$publish'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$publish'(Publish, __TopXMLNS, _acc) -> + [encode_pubsub_publish(Publish, __TopXMLNS) | _acc]. -'encode_pubsub_$publish'(undefined, _acc) -> _acc; -'encode_pubsub_$publish'(Publish, _acc) -> - [encode_pubsub_publish(Publish, []) | _acc]. +'encode_pubsub_$rsm'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_$rsm'(Rsm, __TopXMLNS, _acc) -> + [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. -'encode_pubsub_$rsm'(undefined, _acc) -> _acc; -'encode_pubsub_$rsm'(Rsm, _acc) -> - [encode_rsm_set(Rsm, - [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]) +'encode_pubsub_$subscription'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_$subscription'(Subscription, __TopXMLNS, + _acc) -> + [encode_pubsub_subscription(Subscription, __TopXMLNS) | _acc]. -'encode_pubsub_$subscription'(undefined, _acc) -> _acc; -'encode_pubsub_$subscription'(Subscription, _acc) -> - [encode_pubsub_subscription(Subscription, []) | _acc]. - decode_pubsub_purge(__TopXMLNS, __IgnoreEls, {xmlel, <<"purge">>, _attrs, _els}) -> Node = decode_pubsub_purge_attrs(__TopXMLNS, _attrs, @@ -14047,10 +17356,16 @@ decode_pubsub_purge_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_purge_attrs(__TopXMLNS, [], Node) -> decode_pubsub_purge_attr_node(__TopXMLNS, Node). -encode_pubsub_purge(Node, _xmlns_attrs) -> +encode_pubsub_purge(Node, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_purge_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"purge">>, _attrs, _els}. decode_pubsub_purge_attr_node(__TopXMLNS, undefined) -> @@ -14116,16 +17431,23 @@ decode_pubsub_delete_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_delete_attrs(__TopXMLNS, [], Node) -> decode_pubsub_delete_attr_node(__TopXMLNS, Node). -encode_pubsub_delete({Node, Uri}, _xmlns_attrs) -> +encode_pubsub_delete({Node, Uri}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = lists:reverse('encode_pubsub_delete_$uri'(Uri, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_delete_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"delete">>, _attrs, _els}. -'encode_pubsub_delete_$uri'(<<>>, _acc) -> _acc; -'encode_pubsub_delete_$uri'(Uri, _acc) -> - [encode_pubsub_redirect(Uri, []) | _acc]. +'encode_pubsub_delete_$uri'(<<>>, __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_delete_$uri'(Uri, __TopXMLNS, _acc) -> + [encode_pubsub_redirect(Uri, __TopXMLNS) | _acc]. decode_pubsub_delete_attr_node(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -14151,10 +17473,16 @@ decode_pubsub_redirect_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_redirect_attrs(__TopXMLNS, [], Uri) -> decode_pubsub_redirect_attr_uri(__TopXMLNS, Uri). -encode_pubsub_redirect(Uri, _xmlns_attrs) -> +encode_pubsub_redirect(Uri, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_redirect_attr_uri(Uri, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"redirect">>, _attrs, _els}. decode_pubsub_redirect_attr_uri(__TopXMLNS, @@ -14203,19 +17531,25 @@ decode_pubsub_default_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_default_attrs(__TopXMLNS, [], Node) -> decode_pubsub_default_attr_node(__TopXMLNS, Node). -encode_pubsub_default({Node, Xdata}, _xmlns_attrs) -> +encode_pubsub_default({Node, Xdata}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>], + __TopXMLNS), _els = lists:reverse('encode_pubsub_default_$xdata'(Xdata, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_default_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"default">>, _attrs, _els}. -'encode_pubsub_default_$xdata'(undefined, _acc) -> _acc; -'encode_pubsub_default_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_pubsub_default_$xdata'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_default_$xdata'(Xdata, __TopXMLNS, + _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_pubsub_default_attr_node(__TopXMLNS, undefined) -> @@ -14255,20 +17589,23 @@ decode_pubsub_publish_options_els(__TopXMLNS, decode_pubsub_publish_options_els(__TopXMLNS, __IgnoreEls, _els, Xdata). -encode_pubsub_publish_options(Xdata, _xmlns_attrs) -> +encode_pubsub_publish_options(Xdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_publish_options_$xdata'(Xdata, + __NewTopXMLNS, [])), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"publish-options">>, _attrs, _els}. 'encode_pubsub_publish_options_$xdata'(undefined, - _acc) -> + __TopXMLNS, _acc) -> _acc; -'encode_pubsub_publish_options_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_pubsub_publish_options_$xdata'(Xdata, + __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_pubsub_configure(__TopXMLNS, __IgnoreEls, {xmlel, <<"configure">>, _attrs, _els}) -> @@ -14308,20 +17645,25 @@ decode_pubsub_configure_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_configure_attrs(__TopXMLNS, [], Node) -> decode_pubsub_configure_attr_node(__TopXMLNS, Node). -encode_pubsub_configure({Node, Xdata}, _xmlns_attrs) -> +encode_pubsub_configure({Node, Xdata}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>], + __TopXMLNS), _els = lists:reverse('encode_pubsub_configure_$xdata'(Xdata, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_configure_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"configure">>, _attrs, _els}. -'encode_pubsub_configure_$xdata'(undefined, _acc) -> +'encode_pubsub_configure_$xdata'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_pubsub_configure_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_pubsub_configure_$xdata'(Xdata, __TopXMLNS, + _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_pubsub_configure_attr_node(__TopXMLNS, undefined) -> @@ -14348,10 +17690,15 @@ decode_pubsub_create_attrs(__TopXMLNS, [_ | _attrs], decode_pubsub_create_attrs(__TopXMLNS, [], Node) -> decode_pubsub_create_attr_node(__TopXMLNS, Node). -encode_pubsub_create(Node, _xmlns_attrs) -> +encode_pubsub_create(Node, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_create_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"create">>, _attrs, _els}. decode_pubsub_create_attr_node(__TopXMLNS, undefined) -> @@ -14422,19 +17769,26 @@ decode_pubsub_retract_attrs(__TopXMLNS, [], Node, decode_pubsub_retract_attr_notify(__TopXMLNS, Notify)}. encode_pubsub_retract({ps_retract, Node, Notify, Items}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_retract_$items'(Items, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_retract_attr_notify(Notify, encode_pubsub_retract_attr_node(Node, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"retract">>, _attrs, _els}. -'encode_pubsub_retract_$items'([], _acc) -> _acc; -'encode_pubsub_retract_$items'([Items | _els], _acc) -> - 'encode_pubsub_retract_$items'(_els, - [encode_pubsub_item(Items, []) | _acc]). +'encode_pubsub_retract_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_retract_$items'([Items | _els], + __TopXMLNS, _acc) -> + 'encode_pubsub_retract_$items'(_els, __TopXMLNS, + [encode_pubsub_item(Items, __TopXMLNS) + | _acc]). decode_pubsub_retract_attr_node(__TopXMLNS, undefined) -> @@ -14515,21 +17869,26 @@ decode_pubsub_options_attrs(__TopXMLNS, [], Node, Subid, encode_pubsub_options({ps_options, Node, Jid, Subid, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_options_$xdata'(Xdata, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_options_attr_jid(Jid, encode_pubsub_options_attr_subid(Subid, encode_pubsub_options_attr_node(Node, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"options">>, _attrs, _els}. -'encode_pubsub_options_$xdata'(undefined, _acc) -> _acc; -'encode_pubsub_options_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_pubsub_options_$xdata'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_options_$xdata'(Xdata, __TopXMLNS, + _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_pubsub_options_attr_node(__TopXMLNS, undefined) -> @@ -14617,18 +17976,25 @@ decode_pubsub_publish_attrs(__TopXMLNS, [], Node) -> decode_pubsub_publish_attr_node(__TopXMLNS, Node). encode_pubsub_publish({ps_publish, Node, Items}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_publish_$items'(Items, - [])), + __NewTopXMLNS, [])), _attrs = encode_pubsub_publish_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"publish">>, _attrs, _els}. -'encode_pubsub_publish_$items'([], _acc) -> _acc; -'encode_pubsub_publish_$items'([Items | _els], _acc) -> - 'encode_pubsub_publish_$items'(_els, - [encode_pubsub_item(Items, []) | _acc]). +'encode_pubsub_publish_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_publish_$items'([Items | _els], + __TopXMLNS, _acc) -> + 'encode_pubsub_publish_$items'(_els, __TopXMLNS, + [encode_pubsub_item(Items, __TopXMLNS) + | _acc]). decode_pubsub_publish_attr_node(__TopXMLNS, undefined) -> @@ -14674,12 +18040,16 @@ decode_pubsub_unsubscribe_attrs(__TopXMLNS, [], Node, encode_pubsub_unsubscribe({ps_unsubscribe, Node, Jid, Subid}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = [], _attrs = encode_pubsub_unsubscribe_attr_jid(Jid, encode_pubsub_unsubscribe_attr_subid(Subid, encode_pubsub_unsubscribe_attr_node(Node, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"unsubscribe">>, _attrs, _els}. decode_pubsub_unsubscribe_attr_node(__TopXMLNS, @@ -14745,11 +18115,15 @@ decode_pubsub_subscribe_attrs(__TopXMLNS, [], Node, decode_pubsub_subscribe_attr_jid(__TopXMLNS, Jid)}. encode_pubsub_subscribe({ps_subscribe, Node, Jid}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = [], _attrs = encode_pubsub_subscribe_attr_jid(Jid, encode_pubsub_subscribe_attr_node(Node, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"subscribe">>, _attrs, _els}. decode_pubsub_subscribe_attr_node(__TopXMLNS, @@ -14839,24 +18213,30 @@ decode_pubsub_owner_affiliations_attrs(__TopXMLNS, [], Node). encode_pubsub_owner_affiliations({Node, Affiliations}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#owner">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_owner_affiliations_$affiliations'(Affiliations, + __NewTopXMLNS, [])), _attrs = encode_pubsub_owner_affiliations_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"affiliations">>, _attrs, _els}. 'encode_pubsub_owner_affiliations_$affiliations'([], - _acc) -> + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_owner_affiliations_$affiliations'([Affiliations | _els], - _acc) -> + __TopXMLNS, _acc) -> 'encode_pubsub_owner_affiliations_$affiliations'(_els, + __TopXMLNS, [encode_pubsub_owner_affiliation(Affiliations, - []) + __TopXMLNS) | _acc]). decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, @@ -14928,22 +18308,29 @@ decode_pubsub_affiliations_attrs(__TopXMLNS, [], decode_pubsub_affiliations_attr_node(__TopXMLNS, Node). encode_pubsub_affiliations({Node, Affiliations}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_affiliations_$affiliations'(Affiliations, + __NewTopXMLNS, [])), _attrs = encode_pubsub_affiliations_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"affiliations">>, _attrs, _els}. -'encode_pubsub_affiliations_$affiliations'([], _acc) -> +'encode_pubsub_affiliations_$affiliations'([], + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_affiliations_$affiliations'([Affiliations | _els], - _acc) -> + __TopXMLNS, _acc) -> 'encode_pubsub_affiliations_$affiliations'(_els, + __TopXMLNS, [encode_pubsub_affiliation(Affiliations, - []) + __TopXMLNS) | _acc]). decode_pubsub_affiliations_attr_node(__TopXMLNS, @@ -15029,23 +18416,30 @@ decode_pubsub_subscriptions_attrs(__TopXMLNS, [], decode_pubsub_subscriptions_attr_node(__TopXMLNS, Node). encode_pubsub_subscriptions({Node, Subscriptions}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>], + __TopXMLNS), _els = lists:reverse('encode_pubsub_subscriptions_$subscriptions'(Subscriptions, + __NewTopXMLNS, [])), _attrs = encode_pubsub_subscriptions_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"subscriptions">>, _attrs, _els}. 'encode_pubsub_subscriptions_$subscriptions'([], - _acc) -> + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_subscriptions_$subscriptions'([Subscriptions | _els], - _acc) -> + __TopXMLNS, _acc) -> 'encode_pubsub_subscriptions_$subscriptions'(_els, + __TopXMLNS, [encode_pubsub_subscription(Subscriptions, - []) + __TopXMLNS) | _acc]). decode_pubsub_subscriptions_attr_node(__TopXMLNS, @@ -15270,45 +18664,68 @@ decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, encode_pubsub_event({ps_event, Items, Purge, Subscription, Delete, Create, Configuration}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_event_$items'(Items, + __NewTopXMLNS, 'encode_pubsub_event_$create'(Create, + __NewTopXMLNS, 'encode_pubsub_event_$delete'(Delete, + __NewTopXMLNS, 'encode_pubsub_event_$purge'(Purge, + __NewTopXMLNS, 'encode_pubsub_event_$configuration'(Configuration, + __NewTopXMLNS, 'encode_pubsub_event_$subscription'(Subscription, + __NewTopXMLNS, []))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"event">>, _attrs, _els}. -'encode_pubsub_event_$items'(undefined, _acc) -> _acc; -'encode_pubsub_event_$items'(Items, _acc) -> - [encode_pubsub_items(Items, []) | _acc]. +'encode_pubsub_event_$items'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_event_$items'(Items, __TopXMLNS, _acc) -> + [encode_pubsub_items(Items, __TopXMLNS) | _acc]. -'encode_pubsub_event_$create'(undefined, _acc) -> _acc; -'encode_pubsub_event_$create'(Create, _acc) -> - [encode_pubsub_create(Create, []) | _acc]. +'encode_pubsub_event_$create'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_event_$create'(Create, __TopXMLNS, + _acc) -> + [encode_pubsub_create(Create, __TopXMLNS) | _acc]. -'encode_pubsub_event_$delete'(undefined, _acc) -> _acc; -'encode_pubsub_event_$delete'(Delete, _acc) -> - [encode_pubsub_delete(Delete, []) | _acc]. +'encode_pubsub_event_$delete'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_event_$delete'(Delete, __TopXMLNS, + _acc) -> + [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. -'encode_pubsub_event_$purge'(undefined, _acc) -> _acc; -'encode_pubsub_event_$purge'(Purge, _acc) -> - [encode_pubsub_purge(Purge, []) | _acc]. +'encode_pubsub_event_$purge'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_event_$purge'(Purge, __TopXMLNS, _acc) -> + [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. -'encode_pubsub_event_$configuration'(undefined, _acc) -> +'encode_pubsub_event_$configuration'(undefined, + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_event_$configuration'(Configuration, - _acc) -> - [encode_pubsub_event_configuration(Configuration, []) + __TopXMLNS, _acc) -> + [encode_pubsub_event_configuration(Configuration, + __TopXMLNS) | _acc]. -'encode_pubsub_event_$subscription'(undefined, _acc) -> +'encode_pubsub_event_$subscription'(undefined, + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_event_$subscription'(Subscription, - _acc) -> - [encode_pubsub_subscription(Subscription, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_pubsub_subscription(Subscription, __TopXMLNS) + | _acc]. decode_pubsub_items(__TopXMLNS, __IgnoreEls, {xmlel, <<"items">>, _attrs, _els}) -> @@ -15415,35 +18832,44 @@ decode_pubsub_items_attrs(__TopXMLNS, [], Xmlns, encode_pubsub_items({ps_items, Xmlns, Node, Items, Max_items, Subid, Retract}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = lists:reverse('encode_pubsub_items_$items'(Items, + __NewTopXMLNS, 'encode_pubsub_items_$retract'(Retract, + __NewTopXMLNS, []))), _attrs = encode_pubsub_items_attr_subid(Subid, encode_pubsub_items_attr_node(Node, encode_pubsub_items_attr_max_items(Max_items, - encode_pubsub_items_attr_xmlns(Xmlns, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"items">>, _attrs, _els}. -'encode_pubsub_items_$items'([], _acc) -> _acc; -'encode_pubsub_items_$items'([Items | _els], _acc) -> - 'encode_pubsub_items_$items'(_els, - [encode_pubsub_item(Items, []) | _acc]). +'encode_pubsub_items_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_pubsub_items_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_pubsub_items_$items'(_els, __TopXMLNS, + [encode_pubsub_item(Items, __TopXMLNS) + | _acc]). -'encode_pubsub_items_$retract'(undefined, _acc) -> _acc; -'encode_pubsub_items_$retract'(Retract, _acc) -> - [encode_pubsub_event_retract(Retract, []) | _acc]. +'encode_pubsub_items_$retract'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_pubsub_items_$retract'(Retract, __TopXMLNS, + _acc) -> + [encode_pubsub_event_retract(Retract, __TopXMLNS) + | _acc]. decode_pubsub_items_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_pubsub_items_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_pubsub_items_attr_xmlns(<<>>, _acc) -> _acc; -encode_pubsub_items_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_pubsub_items_attr_max_items(__TopXMLNS, undefined) -> undefined; @@ -15533,13 +18959,17 @@ decode_pubsub_item_attrs(__TopXMLNS, [], Id, Xmlns, encode_pubsub_item({ps_item, Xmlns, Id, __Xmls, Node, Publisher}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = __Xmls, _attrs = encode_pubsub_item_attr_publisher(Publisher, encode_pubsub_item_attr_node(Node, - encode_pubsub_item_attr_xmlns(Xmlns, - encode_pubsub_item_attr_id(Id, - _xmlns_attrs)))), + encode_pubsub_item_attr_id(Id, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"item">>, _attrs, _els}. decode_pubsub_item_attr_id(__TopXMLNS, undefined) -> @@ -15554,10 +18984,6 @@ decode_pubsub_item_attr_xmlns(__TopXMLNS, undefined) -> <<>>; decode_pubsub_item_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_pubsub_item_attr_xmlns(<<>>, _acc) -> _acc; -encode_pubsub_item_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_pubsub_item_attr_node(__TopXMLNS, undefined) -> <<>>; decode_pubsub_item_attr_node(__TopXMLNS, _val) -> _val. @@ -15593,10 +19019,14 @@ decode_pubsub_event_retract_attrs(__TopXMLNS, decode_pubsub_event_retract_attrs(__TopXMLNS, [], Id) -> decode_pubsub_event_retract_attr_id(__TopXMLNS, Id). -encode_pubsub_event_retract(Id, _xmlns_attrs) -> +encode_pubsub_event_retract(Id, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, + [], __TopXMLNS), _els = [], _attrs = encode_pubsub_event_retract_attr_id(Id, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"retract">>, _attrs, _els}. decode_pubsub_event_retract_attr_id(__TopXMLNS, @@ -15657,23 +19087,26 @@ decode_pubsub_event_configuration_attrs(__TopXMLNS, [], Node). encode_pubsub_event_configuration({Node, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, + [], __TopXMLNS), _els = lists:reverse('encode_pubsub_event_configuration_$xdata'(Xdata, + __NewTopXMLNS, [])), _attrs = encode_pubsub_event_configuration_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"configuration">>, _attrs, _els}. 'encode_pubsub_event_configuration_$xdata'(undefined, - _acc) -> + __TopXMLNS, _acc) -> _acc; 'encode_pubsub_event_configuration_$xdata'(Xdata, - _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. + __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. decode_pubsub_event_configuration_attr_node(__TopXMLNS, undefined) -> @@ -15726,13 +19159,16 @@ decode_pubsub_owner_affiliation_attrs(__TopXMLNS, [], encode_pubsub_owner_affiliation({ps_affiliation, Xmlns, _, Type, Jid}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/pubsub#owner">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_owner_affiliation_attr_affiliation(Type, - encode_pubsub_owner_affiliation_attr_xmlns(Xmlns, - encode_pubsub_owner_affiliation_attr_jid(Jid, - _xmlns_attrs))), + encode_pubsub_owner_affiliation_attr_jid(Jid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"affiliation">>, _attrs, _els}. decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, @@ -15760,13 +19196,6 @@ decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_pubsub_owner_affiliation_attr_xmlns(<<>>, - _acc) -> - _acc; -encode_pubsub_owner_affiliation_attr_xmlns(_val, - _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -15824,13 +19253,16 @@ decode_pubsub_affiliation_attrs(__TopXMLNS, [], Node, encode_pubsub_affiliation({ps_affiliation, Xmlns, Node, Type, _}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/pubsub">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_affiliation_attr_affiliation(Type, - encode_pubsub_affiliation_attr_xmlns(Xmlns, - encode_pubsub_affiliation_attr_node(Node, - _xmlns_attrs))), + encode_pubsub_affiliation_attr_node(Node, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"affiliation">>, _attrs, _els}. decode_pubsub_affiliation_attr_node(__TopXMLNS, @@ -15851,11 +19283,6 @@ decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_pubsub_affiliation_attr_xmlns(<<>>, _acc) -> - _acc; -encode_pubsub_affiliation_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -15937,15 +19364,20 @@ decode_pubsub_subscription_attrs(__TopXMLNS, [], Xmlns, encode_pubsub_subscription({ps_subscription, Xmlns, Jid, Type, Node, Subid, Expiry}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(Xmlns, + [<<"http://jabber.org/protocol/pubsub">>, + <<"http://jabber.org/protocol/pubsub#owner">>, + <<"http://jabber.org/protocol/pubsub#event">>], + __TopXMLNS), _els = [], _attrs = encode_pubsub_subscription_attr_expiry(Expiry, encode_pubsub_subscription_attr_subscription(Type, encode_pubsub_subscription_attr_subid(Subid, encode_pubsub_subscription_attr_node(Node, encode_pubsub_subscription_attr_jid(Jid, - encode_pubsub_subscription_attr_xmlns(Xmlns, - _xmlns_attrs)))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"subscription">>, _attrs, _els}. decode_pubsub_subscription_attr_xmlns(__TopXMLNS, @@ -15955,11 +19387,6 @@ decode_pubsub_subscription_attr_xmlns(__TopXMLNS, _val) -> _val. -encode_pubsub_subscription_attr_xmlns(<<>>, _acc) -> - _acc; -encode_pubsub_subscription_attr_xmlns(_val, _acc) -> - [{<<"xmlns">>, _val} | _acc]. - decode_pubsub_subscription_attr_jid(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -16167,40 +19594,54 @@ decode_xdata_attrs(__TopXMLNS, [], Type) -> encode_xdata({xdata, Type, Instructions, Title, Reported, Items, Fields}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = lists:reverse('encode_xdata_$fields'(Fields, + __NewTopXMLNS, 'encode_xdata_$items'(Items, + __NewTopXMLNS, 'encode_xdata_$instructions'(Instructions, + __NewTopXMLNS, 'encode_xdata_$reported'(Reported, + __NewTopXMLNS, 'encode_xdata_$title'(Title, + __NewTopXMLNS, [])))))), - _attrs = encode_xdata_attr_type(Type, _xmlns_attrs), + _attrs = encode_xdata_attr_type(Type, + enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), {xmlel, <<"x">>, _attrs, _els}. -'encode_xdata_$fields'([], _acc) -> _acc; -'encode_xdata_$fields'([Fields | _els], _acc) -> - 'encode_xdata_$fields'(_els, - [encode_xdata_field(Fields, []) | _acc]). +'encode_xdata_$fields'([], __TopXMLNS, _acc) -> _acc; +'encode_xdata_$fields'([Fields | _els], __TopXMLNS, + _acc) -> + 'encode_xdata_$fields'(_els, __TopXMLNS, + [encode_xdata_field(Fields, __TopXMLNS) | _acc]). -'encode_xdata_$items'([], _acc) -> _acc; -'encode_xdata_$items'([Items | _els], _acc) -> - 'encode_xdata_$items'(_els, - [encode_xdata_item(Items, []) | _acc]). +'encode_xdata_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_xdata_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_xdata_$items'(_els, __TopXMLNS, + [encode_xdata_item(Items, __TopXMLNS) | _acc]). -'encode_xdata_$instructions'([], _acc) -> _acc; +'encode_xdata_$instructions'([], __TopXMLNS, _acc) -> + _acc; 'encode_xdata_$instructions'([Instructions | _els], - _acc) -> - 'encode_xdata_$instructions'(_els, - [encode_xdata_instructions(Instructions, []) + __TopXMLNS, _acc) -> + 'encode_xdata_$instructions'(_els, __TopXMLNS, + [encode_xdata_instructions(Instructions, + __TopXMLNS) | _acc]). -'encode_xdata_$reported'(undefined, _acc) -> _acc; -'encode_xdata_$reported'(Reported, _acc) -> - [encode_xdata_reported(Reported, []) | _acc]. +'encode_xdata_$reported'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_xdata_$reported'(Reported, __TopXMLNS, _acc) -> + [encode_xdata_reported(Reported, __TopXMLNS) | _acc]. -'encode_xdata_$title'(undefined, _acc) -> _acc; -'encode_xdata_$title'(Title, _acc) -> - [encode_xdata_title(Title, []) | _acc]. +'encode_xdata_$title'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_xdata_$title'(Title, __TopXMLNS, _acc) -> + [encode_xdata_title(Title, __TopXMLNS) | _acc]. decode_xdata_attr_type(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -16250,16 +19691,21 @@ decode_xdata_item_els(__TopXMLNS, __IgnoreEls, decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, Fields). -encode_xdata_item(Fields, _xmlns_attrs) -> +encode_xdata_item(Fields, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = lists:reverse('encode_xdata_item_$fields'(Fields, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"item">>, _attrs, _els}. -'encode_xdata_item_$fields'([], _acc) -> _acc; -'encode_xdata_item_$fields'([Fields | _els], _acc) -> - 'encode_xdata_item_$fields'(_els, - [encode_xdata_field(Fields, []) | _acc]). +'encode_xdata_item_$fields'([], __TopXMLNS, _acc) -> + _acc; +'encode_xdata_item_$fields'([Fields | _els], __TopXMLNS, + _acc) -> + 'encode_xdata_item_$fields'(_els, __TopXMLNS, + [encode_xdata_field(Fields, __TopXMLNS) + | _acc]). decode_xdata_reported(__TopXMLNS, __IgnoreEls, {xmlel, <<"reported">>, _attrs, _els}) -> @@ -16293,18 +19739,22 @@ decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, Fields). -encode_xdata_reported(Fields, _xmlns_attrs) -> +encode_xdata_reported(Fields, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = lists:reverse('encode_xdata_reported_$fields'(Fields, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"reported">>, _attrs, _els}. -'encode_xdata_reported_$fields'([], _acc) -> _acc; +'encode_xdata_reported_$fields'([], __TopXMLNS, _acc) -> + _acc; 'encode_xdata_reported_$fields'([Fields | _els], - _acc) -> - 'encode_xdata_reported_$fields'(_els, - [encode_xdata_field(Fields, []) | _acc]). + __TopXMLNS, _acc) -> + 'encode_xdata_reported_$fields'(_els, __TopXMLNS, + [encode_xdata_field(Fields, __TopXMLNS) + | _acc]). decode_xdata_title(__TopXMLNS, __IgnoreEls, {xmlel, <<"title">>, _attrs, _els}) -> @@ -16324,9 +19774,11 @@ decode_xdata_title_els(__TopXMLNS, __IgnoreEls, decode_xdata_title_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_xdata_title(Cdata, _xmlns_attrs) -> +encode_xdata_title(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = encode_xdata_title_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"title">>, _attrs, _els}. decode_xdata_title_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -16354,9 +19806,11 @@ decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_xdata_instructions(Cdata, _xmlns_attrs) -> +encode_xdata_instructions(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = encode_xdata_instructions_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"instructions">>, _attrs, _els}. decode_xdata_instructions_cdata(__TopXMLNS, <<>>) -> @@ -16473,11 +19927,11 @@ decode_xdata_field_els(__TopXMLNS, __IgnoreEls, Options, Values, Desc, Required, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, Desc, Required, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, Options, Values, Desc, Required, __Els) @@ -16512,37 +19966,56 @@ decode_xdata_field_attrs(__TopXMLNS, [], Label, Type, encode_xdata_field({xdata_field, Label, Type, Var, Required, Desc, Values, Options, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ lists:reverse('encode_xdata_field_$options'(Options, + __NewTopXMLNS, 'encode_xdata_field_$values'(Values, + __NewTopXMLNS, 'encode_xdata_field_$desc'(Desc, + __NewTopXMLNS, 'encode_xdata_field_$required'(Required, + __NewTopXMLNS, []))))), _attrs = encode_xdata_field_attr_var(Var, encode_xdata_field_attr_type(Type, encode_xdata_field_attr_label(Label, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"field">>, _attrs, _els}. -'encode_xdata_field_$options'([], _acc) -> _acc; -'encode_xdata_field_$options'([Options | _els], _acc) -> - 'encode_xdata_field_$options'(_els, - [encode_xdata_field_option(Options, []) +'encode_xdata_field_$options'([], __TopXMLNS, _acc) -> + _acc; +'encode_xdata_field_$options'([Options | _els], + __TopXMLNS, _acc) -> + 'encode_xdata_field_$options'(_els, __TopXMLNS, + [encode_xdata_field_option(Options, + __TopXMLNS) | _acc]). -'encode_xdata_field_$values'([], _acc) -> _acc; -'encode_xdata_field_$values'([Values | _els], _acc) -> - 'encode_xdata_field_$values'(_els, - [encode_xdata_field_value(Values, []) | _acc]). +'encode_xdata_field_$values'([], __TopXMLNS, _acc) -> + _acc; +'encode_xdata_field_$values'([Values | _els], + __TopXMLNS, _acc) -> + 'encode_xdata_field_$values'(_els, __TopXMLNS, + [encode_xdata_field_value(Values, __TopXMLNS) + | _acc]). -'encode_xdata_field_$desc'(undefined, _acc) -> _acc; -'encode_xdata_field_$desc'(Desc, _acc) -> - [encode_xdata_field_desc(Desc, []) | _acc]. +'encode_xdata_field_$desc'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_xdata_field_$desc'(Desc, __TopXMLNS, _acc) -> + [encode_xdata_field_desc(Desc, __TopXMLNS) | _acc]. -'encode_xdata_field_$required'(false, _acc) -> _acc; -'encode_xdata_field_$required'(Required, _acc) -> - [encode_xdata_field_required(Required, []) | _acc]. +'encode_xdata_field_$required'(false, __TopXMLNS, + _acc) -> + _acc; +'encode_xdata_field_$required'(Required, __TopXMLNS, + _acc) -> + [encode_xdata_field_required(Required, __TopXMLNS) + | _acc]. decode_xdata_field_attr_label(__TopXMLNS, undefined) -> <<>>; @@ -16634,16 +20107,20 @@ decode_xdata_field_option_attrs(__TopXMLNS, [], decode_xdata_field_option_attr_label(__TopXMLNS, Label). encode_xdata_field_option({xdata_option, Label, Value}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = lists:reverse('encode_xdata_field_option_$value'(Value, - [])), + __NewTopXMLNS, [])), _attrs = encode_xdata_field_option_attr_label(Label, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"option">>, _attrs, _els}. -'encode_xdata_field_option_$value'(Value, _acc) -> - [encode_xdata_field_value(Value, []) | _acc]. +'encode_xdata_field_option_$value'(Value, __TopXMLNS, + _acc) -> + [encode_xdata_field_value(Value, __TopXMLNS) | _acc]. decode_xdata_field_option_attr_label(__TopXMLNS, undefined) -> @@ -16675,9 +20152,11 @@ decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_xdata_field_value(Cdata, _xmlns_attrs) -> +encode_xdata_field_value(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = encode_xdata_field_value_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"value">>, _attrs, _els}. decode_xdata_field_value_cdata(__TopXMLNS, <<>>) -> @@ -16707,9 +20186,11 @@ decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_xdata_field_desc(Cdata, _xmlns_attrs) -> +encode_xdata_field_desc(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = encode_xdata_field_desc_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"desc">>, _attrs, _els}. decode_xdata_field_desc_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -16723,9 +20204,11 @@ decode_xdata_field_required(__TopXMLNS, __IgnoreEls, {xmlel, <<"required">>, _attrs, _els}) -> true. -encode_xdata_field_required(true, _xmlns_attrs) -> +encode_xdata_field_required(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"required">>, _attrs, _els}. decode_vcard_xupdate(__TopXMLNS, __IgnoreEls, @@ -16761,15 +20244,20 @@ decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, Hash). encode_vcard_xupdate({vcard_xupdate, _, Hash}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"vcard-temp:x:update">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_xupdate_$hash'(Hash, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"x">>, _attrs, _els}. -'encode_vcard_xupdate_$hash'(undefined, _acc) -> _acc; -'encode_vcard_xupdate_$hash'(Hash, _acc) -> - [encode_vcard_xupdate_photo(Hash, []) | _acc]. +'encode_vcard_xupdate_$hash'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_xupdate_$hash'(Hash, __TopXMLNS, _acc) -> + [encode_vcard_xupdate_photo(Hash, __TopXMLNS) | _acc]. decode_vcard_xupdate_photo(__TopXMLNS, __IgnoreEls, {xmlel, <<"photo">>, _attrs, _els}) -> @@ -16789,9 +20277,12 @@ decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_xupdate_photo(Cdata, _xmlns_attrs) -> +encode_vcard_xupdate_photo(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"vcard-temp:x:update">>, [], + __TopXMLNS), _els = encode_vcard_xupdate_photo_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"photo">>, _attrs, _els}. decode_vcard_xupdate_photo_cdata(__TopXMLNS, <<>>) -> @@ -17797,160 +21288,243 @@ encode_vcard_temp({vcard_temp, Version, Fn, N, Nickname, Tz, Geo, Title, Role, Logo, Org, Categories, Note, Prodid, Rev, Sort_string, Sound, Uid, Url, Class, Key, Desc}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_temp_$mailer'(Mailer, + __NewTopXMLNS, 'encode_vcard_temp_$adr'(Adr, + __NewTopXMLNS, 'encode_vcard_temp_$class'(Class, + __NewTopXMLNS, 'encode_vcard_temp_$categories'(Categories, + __NewTopXMLNS, 'encode_vcard_temp_$desc'(Desc, + __NewTopXMLNS, 'encode_vcard_temp_$uid'(Uid, + __NewTopXMLNS, 'encode_vcard_temp_$prodid'(Prodid, + __NewTopXMLNS, 'encode_vcard_temp_$jabberid'(Jabberid, + __NewTopXMLNS, 'encode_vcard_temp_$sound'(Sound, + __NewTopXMLNS, 'encode_vcard_temp_$note'(Note, + __NewTopXMLNS, 'encode_vcard_temp_$role'(Role, + __NewTopXMLNS, 'encode_vcard_temp_$title'(Title, + __NewTopXMLNS, 'encode_vcard_temp_$nickname'(Nickname, + __NewTopXMLNS, 'encode_vcard_temp_$rev'(Rev, + __NewTopXMLNS, 'encode_vcard_temp_$sort_string'(Sort_string, + __NewTopXMLNS, 'encode_vcard_temp_$org'(Org, + __NewTopXMLNS, 'encode_vcard_temp_$bday'(Bday, + __NewTopXMLNS, 'encode_vcard_temp_$key'(Key, + __NewTopXMLNS, 'encode_vcard_temp_$tz'(Tz, + __NewTopXMLNS, 'encode_vcard_temp_$url'(Url, + __NewTopXMLNS, 'encode_vcard_temp_$email'(Email, + __NewTopXMLNS, 'encode_vcard_temp_$tel'(Tel, + __NewTopXMLNS, 'encode_vcard_temp_$label'(Label, + __NewTopXMLNS, 'encode_vcard_temp_$fn'(Fn, + __NewTopXMLNS, 'encode_vcard_temp_$version'(Version, + __NewTopXMLNS, 'encode_vcard_temp_$n'(N, + __NewTopXMLNS, 'encode_vcard_temp_$photo'(Photo, + __NewTopXMLNS, 'encode_vcard_temp_$logo'(Logo, + __NewTopXMLNS, 'encode_vcard_temp_$geo'(Geo, + __NewTopXMLNS, [])))))))))))))))))))))))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"vCard">>, _attrs, _els}. -'encode_vcard_temp_$mailer'(undefined, _acc) -> _acc; -'encode_vcard_temp_$mailer'(Mailer, _acc) -> - [encode_vcard_MAILER(Mailer, []) | _acc]. +'encode_vcard_temp_$mailer'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$mailer'(Mailer, __TopXMLNS, _acc) -> + [encode_vcard_MAILER(Mailer, __TopXMLNS) | _acc]. -'encode_vcard_temp_$adr'([], _acc) -> _acc; -'encode_vcard_temp_$adr'([Adr | _els], _acc) -> - 'encode_vcard_temp_$adr'(_els, - [encode_vcard_ADR(Adr, []) | _acc]). +'encode_vcard_temp_$adr'([], __TopXMLNS, _acc) -> _acc; +'encode_vcard_temp_$adr'([Adr | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_temp_$adr'(_els, __TopXMLNS, + [encode_vcard_ADR(Adr, __TopXMLNS) | _acc]). -'encode_vcard_temp_$class'(undefined, _acc) -> _acc; -'encode_vcard_temp_$class'(Class, _acc) -> - [encode_vcard_CLASS(Class, []) | _acc]. +'encode_vcard_temp_$class'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$class'(Class, __TopXMLNS, _acc) -> + [encode_vcard_CLASS(Class, __TopXMLNS) | _acc]. -'encode_vcard_temp_$categories'([], _acc) -> _acc; -'encode_vcard_temp_$categories'(Categories, _acc) -> - [encode_vcard_CATEGORIES(Categories, []) | _acc]. +'encode_vcard_temp_$categories'([], __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$categories'(Categories, __TopXMLNS, + _acc) -> + [encode_vcard_CATEGORIES(Categories, __TopXMLNS) + | _acc]. -'encode_vcard_temp_$desc'(undefined, _acc) -> _acc; -'encode_vcard_temp_$desc'(Desc, _acc) -> - [encode_vcard_DESC(Desc, []) | _acc]. +'encode_vcard_temp_$desc'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$desc'(Desc, __TopXMLNS, _acc) -> + [encode_vcard_DESC(Desc, __TopXMLNS) | _acc]. -'encode_vcard_temp_$uid'(undefined, _acc) -> _acc; -'encode_vcard_temp_$uid'(Uid, _acc) -> - [encode_vcard_UID(Uid, []) | _acc]. +'encode_vcard_temp_$uid'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$uid'(Uid, __TopXMLNS, _acc) -> + [encode_vcard_UID(Uid, __TopXMLNS) | _acc]. -'encode_vcard_temp_$prodid'(undefined, _acc) -> _acc; -'encode_vcard_temp_$prodid'(Prodid, _acc) -> - [encode_vcard_PRODID(Prodid, []) | _acc]. +'encode_vcard_temp_$prodid'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$prodid'(Prodid, __TopXMLNS, _acc) -> + [encode_vcard_PRODID(Prodid, __TopXMLNS) | _acc]. -'encode_vcard_temp_$jabberid'(undefined, _acc) -> _acc; -'encode_vcard_temp_$jabberid'(Jabberid, _acc) -> - [encode_vcard_JABBERID(Jabberid, []) | _acc]. +'encode_vcard_temp_$jabberid'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$jabberid'(Jabberid, __TopXMLNS, + _acc) -> + [encode_vcard_JABBERID(Jabberid, __TopXMLNS) | _acc]. -'encode_vcard_temp_$sound'(undefined, _acc) -> _acc; -'encode_vcard_temp_$sound'(Sound, _acc) -> - [encode_vcard_SOUND(Sound, []) | _acc]. +'encode_vcard_temp_$sound'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$sound'(Sound, __TopXMLNS, _acc) -> + [encode_vcard_SOUND(Sound, __TopXMLNS) | _acc]. -'encode_vcard_temp_$note'(undefined, _acc) -> _acc; -'encode_vcard_temp_$note'(Note, _acc) -> - [encode_vcard_NOTE(Note, []) | _acc]. +'encode_vcard_temp_$note'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$note'(Note, __TopXMLNS, _acc) -> + [encode_vcard_NOTE(Note, __TopXMLNS) | _acc]. -'encode_vcard_temp_$role'(undefined, _acc) -> _acc; -'encode_vcard_temp_$role'(Role, _acc) -> - [encode_vcard_ROLE(Role, []) | _acc]. +'encode_vcard_temp_$role'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$role'(Role, __TopXMLNS, _acc) -> + [encode_vcard_ROLE(Role, __TopXMLNS) | _acc]. -'encode_vcard_temp_$title'(undefined, _acc) -> _acc; -'encode_vcard_temp_$title'(Title, _acc) -> - [encode_vcard_TITLE(Title, []) | _acc]. +'encode_vcard_temp_$title'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$title'(Title, __TopXMLNS, _acc) -> + [encode_vcard_TITLE(Title, __TopXMLNS) | _acc]. -'encode_vcard_temp_$nickname'(undefined, _acc) -> _acc; -'encode_vcard_temp_$nickname'(Nickname, _acc) -> - [encode_vcard_NICKNAME(Nickname, []) | _acc]. +'encode_vcard_temp_$nickname'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$nickname'(Nickname, __TopXMLNS, + _acc) -> + [encode_vcard_NICKNAME(Nickname, __TopXMLNS) | _acc]. -'encode_vcard_temp_$rev'(undefined, _acc) -> _acc; -'encode_vcard_temp_$rev'(Rev, _acc) -> - [encode_vcard_REV(Rev, []) | _acc]. +'encode_vcard_temp_$rev'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$rev'(Rev, __TopXMLNS, _acc) -> + [encode_vcard_REV(Rev, __TopXMLNS) | _acc]. -'encode_vcard_temp_$sort_string'(undefined, _acc) -> +'encode_vcard_temp_$sort_string'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_vcard_temp_$sort_string'(Sort_string, _acc) -> - [encode_vcard_SORT_STRING(Sort_string, []) | _acc]. +'encode_vcard_temp_$sort_string'(Sort_string, + __TopXMLNS, _acc) -> + [encode_vcard_SORT_STRING(Sort_string, __TopXMLNS) + | _acc]. -'encode_vcard_temp_$org'(undefined, _acc) -> _acc; -'encode_vcard_temp_$org'(Org, _acc) -> - [encode_vcard_ORG(Org, []) | _acc]. +'encode_vcard_temp_$org'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$org'(Org, __TopXMLNS, _acc) -> + [encode_vcard_ORG(Org, __TopXMLNS) | _acc]. -'encode_vcard_temp_$bday'(undefined, _acc) -> _acc; -'encode_vcard_temp_$bday'(Bday, _acc) -> - [encode_vcard_BDAY(Bday, []) | _acc]. +'encode_vcard_temp_$bday'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$bday'(Bday, __TopXMLNS, _acc) -> + [encode_vcard_BDAY(Bday, __TopXMLNS) | _acc]. -'encode_vcard_temp_$key'(undefined, _acc) -> _acc; -'encode_vcard_temp_$key'(Key, _acc) -> - [encode_vcard_KEY(Key, []) | _acc]. +'encode_vcard_temp_$key'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$key'(Key, __TopXMLNS, _acc) -> + [encode_vcard_KEY(Key, __TopXMLNS) | _acc]. -'encode_vcard_temp_$tz'(undefined, _acc) -> _acc; -'encode_vcard_temp_$tz'(Tz, _acc) -> - [encode_vcard_TZ(Tz, []) | _acc]. +'encode_vcard_temp_$tz'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$tz'(Tz, __TopXMLNS, _acc) -> + [encode_vcard_TZ(Tz, __TopXMLNS) | _acc]. -'encode_vcard_temp_$url'(undefined, _acc) -> _acc; -'encode_vcard_temp_$url'(Url, _acc) -> - [encode_vcard_URL(Url, []) | _acc]. +'encode_vcard_temp_$url'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$url'(Url, __TopXMLNS, _acc) -> + [encode_vcard_URL(Url, __TopXMLNS) | _acc]. -'encode_vcard_temp_$email'([], _acc) -> _acc; -'encode_vcard_temp_$email'([Email | _els], _acc) -> - 'encode_vcard_temp_$email'(_els, - [encode_vcard_EMAIL(Email, []) | _acc]). +'encode_vcard_temp_$email'([], __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$email'([Email | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_temp_$email'(_els, __TopXMLNS, + [encode_vcard_EMAIL(Email, __TopXMLNS) | _acc]). -'encode_vcard_temp_$tel'([], _acc) -> _acc; -'encode_vcard_temp_$tel'([Tel | _els], _acc) -> - 'encode_vcard_temp_$tel'(_els, - [encode_vcard_TEL(Tel, []) | _acc]). +'encode_vcard_temp_$tel'([], __TopXMLNS, _acc) -> _acc; +'encode_vcard_temp_$tel'([Tel | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_temp_$tel'(_els, __TopXMLNS, + [encode_vcard_TEL(Tel, __TopXMLNS) | _acc]). -'encode_vcard_temp_$label'([], _acc) -> _acc; -'encode_vcard_temp_$label'([Label | _els], _acc) -> - 'encode_vcard_temp_$label'(_els, - [encode_vcard_LABEL(Label, []) | _acc]). +'encode_vcard_temp_$label'([], __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$label'([Label | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_temp_$label'(_els, __TopXMLNS, + [encode_vcard_LABEL(Label, __TopXMLNS) | _acc]). -'encode_vcard_temp_$fn'(undefined, _acc) -> _acc; -'encode_vcard_temp_$fn'(Fn, _acc) -> - [encode_vcard_FN(Fn, []) | _acc]. +'encode_vcard_temp_$fn'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$fn'(Fn, __TopXMLNS, _acc) -> + [encode_vcard_FN(Fn, __TopXMLNS) | _acc]. -'encode_vcard_temp_$version'(undefined, _acc) -> _acc; -'encode_vcard_temp_$version'(Version, _acc) -> - [encode_vcard_VERSION(Version, []) | _acc]. +'encode_vcard_temp_$version'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$version'(Version, __TopXMLNS, + _acc) -> + [encode_vcard_VERSION(Version, __TopXMLNS) | _acc]. -'encode_vcard_temp_$n'(undefined, _acc) -> _acc; -'encode_vcard_temp_$n'(N, _acc) -> - [encode_vcard_N(N, []) | _acc]. +'encode_vcard_temp_$n'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$n'(N, __TopXMLNS, _acc) -> + [encode_vcard_N(N, __TopXMLNS) | _acc]. -'encode_vcard_temp_$photo'(undefined, _acc) -> _acc; -'encode_vcard_temp_$photo'(Photo, _acc) -> - [encode_vcard_PHOTO(Photo, []) | _acc]. +'encode_vcard_temp_$photo'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$photo'(Photo, __TopXMLNS, _acc) -> + [encode_vcard_PHOTO(Photo, __TopXMLNS) | _acc]. -'encode_vcard_temp_$logo'(undefined, _acc) -> _acc; -'encode_vcard_temp_$logo'(Logo, _acc) -> - [encode_vcard_LOGO(Logo, []) | _acc]. +'encode_vcard_temp_$logo'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_temp_$logo'(Logo, __TopXMLNS, _acc) -> + [encode_vcard_LOGO(Logo, __TopXMLNS) | _acc]. -'encode_vcard_temp_$geo'(undefined, _acc) -> _acc; -'encode_vcard_temp_$geo'(Geo, _acc) -> - [encode_vcard_GEO(Geo, []) | _acc]. +'encode_vcard_temp_$geo'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_temp_$geo'(Geo, __TopXMLNS, _acc) -> + [encode_vcard_GEO(Geo, __TopXMLNS) | _acc]. decode_vcard_CLASS(__TopXMLNS, __IgnoreEls, {xmlel, <<"CLASS">>, _attrs, _els}) -> @@ -18014,20 +21588,26 @@ decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, Class). -encode_vcard_CLASS(Class, _xmlns_attrs) -> +encode_vcard_CLASS(Class, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_CLASS_$class'(Class, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CLASS">>, _attrs, _els}. -'encode_vcard_CLASS_$class'(undefined, _acc) -> _acc; -'encode_vcard_CLASS_$class'(public = Class, _acc) -> - [encode_vcard_PUBLIC(Class, []) | _acc]; -'encode_vcard_CLASS_$class'(private = Class, _acc) -> - [encode_vcard_PRIVATE(Class, []) | _acc]; -'encode_vcard_CLASS_$class'(confidential = Class, +'encode_vcard_CLASS_$class'(undefined, __TopXMLNS, _acc) -> - [encode_vcard_CONFIDENTIAL(Class, []) | _acc]. + _acc; +'encode_vcard_CLASS_$class'(public = Class, __TopXMLNS, + _acc) -> + [encode_vcard_PUBLIC(Class, __TopXMLNS) | _acc]; +'encode_vcard_CLASS_$class'(private = Class, __TopXMLNS, + _acc) -> + [encode_vcard_PRIVATE(Class, __TopXMLNS) | _acc]; +'encode_vcard_CLASS_$class'(confidential = Class, + __TopXMLNS, _acc) -> + [encode_vcard_CONFIDENTIAL(Class, __TopXMLNS) | _acc]. decode_vcard_CATEGORIES(__TopXMLNS, __IgnoreEls, {xmlel, <<"CATEGORIES">>, _attrs, _els}) -> @@ -18063,18 +21643,23 @@ decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, _els, Keywords). -encode_vcard_CATEGORIES(Keywords, _xmlns_attrs) -> +encode_vcard_CATEGORIES(Keywords, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_CATEGORIES_$keywords'(Keywords, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CATEGORIES">>, _attrs, _els}. -'encode_vcard_CATEGORIES_$keywords'([], _acc) -> _acc; -'encode_vcard_CATEGORIES_$keywords'([Keywords | _els], +'encode_vcard_CATEGORIES_$keywords'([], __TopXMLNS, _acc) -> - 'encode_vcard_CATEGORIES_$keywords'(_els, - [encode_vcard_KEYWORD(Keywords, []) + _acc; +'encode_vcard_CATEGORIES_$keywords'([Keywords | _els], + __TopXMLNS, _acc) -> + 'encode_vcard_CATEGORIES_$keywords'(_els, __TopXMLNS, + [encode_vcard_KEYWORD(Keywords, + __TopXMLNS) | _acc]). decode_vcard_KEY(__TopXMLNS, __IgnoreEls, @@ -18126,21 +21711,26 @@ decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, Cred, Type). -encode_vcard_KEY({vcard_key, Type, Cred}, - _xmlns_attrs) -> +encode_vcard_KEY({vcard_key, Type, Cred}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_KEY_$cred'(Cred, + __NewTopXMLNS, 'encode_vcard_KEY_$type'(Type, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"KEY">>, _attrs, _els}. -'encode_vcard_KEY_$cred'(undefined, _acc) -> _acc; -'encode_vcard_KEY_$cred'(Cred, _acc) -> - [encode_vcard_CRED(Cred, []) | _acc]. +'encode_vcard_KEY_$cred'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_KEY_$cred'(Cred, __TopXMLNS, _acc) -> + [encode_vcard_CRED(Cred, __TopXMLNS) | _acc]. -'encode_vcard_KEY_$type'(undefined, _acc) -> _acc; -'encode_vcard_KEY_$type'(Type, _acc) -> - [encode_vcard_TYPE(Type, []) | _acc]. +'encode_vcard_KEY_$type'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_KEY_$type'(Type, __TopXMLNS, _acc) -> + [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. decode_vcard_SOUND(__TopXMLNS, __IgnoreEls, {xmlel, <<"SOUND">>, _attrs, _els}) -> @@ -18215,26 +21805,40 @@ decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, encode_vcard_SOUND({vcard_sound, Phonetic, Binval, Extval}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_SOUND_$phonetic'(Phonetic, + __NewTopXMLNS, 'encode_vcard_SOUND_$extval'(Extval, + __NewTopXMLNS, 'encode_vcard_SOUND_$binval'(Binval, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"SOUND">>, _attrs, _els}. -'encode_vcard_SOUND_$phonetic'(undefined, _acc) -> _acc; -'encode_vcard_SOUND_$phonetic'(Phonetic, _acc) -> - [encode_vcard_PHONETIC(Phonetic, []) | _acc]. +'encode_vcard_SOUND_$phonetic'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_SOUND_$phonetic'(Phonetic, __TopXMLNS, + _acc) -> + [encode_vcard_PHONETIC(Phonetic, __TopXMLNS) | _acc]. -'encode_vcard_SOUND_$extval'(undefined, _acc) -> _acc; -'encode_vcard_SOUND_$extval'(Extval, _acc) -> - [encode_vcard_EXTVAL(Extval, []) | _acc]. +'encode_vcard_SOUND_$extval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_SOUND_$extval'(Extval, __TopXMLNS, + _acc) -> + [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. -'encode_vcard_SOUND_$binval'(undefined, _acc) -> _acc; -'encode_vcard_SOUND_$binval'(Binval, _acc) -> - [encode_vcard_BINVAL(Binval, []) | _acc]. +'encode_vcard_SOUND_$binval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_SOUND_$binval'(Binval, __TopXMLNS, + _acc) -> + [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. decode_vcard_ORG(__TopXMLNS, __IgnoreEls, {xmlel, <<"ORG">>, _attrs, _els}) -> @@ -18289,21 +21893,27 @@ decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, Units, Name). encode_vcard_ORG({vcard_org, Name, Units}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_ORG_$units'(Units, + __NewTopXMLNS, 'encode_vcard_ORG_$name'(Name, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ORG">>, _attrs, _els}. -'encode_vcard_ORG_$units'([], _acc) -> _acc; -'encode_vcard_ORG_$units'([Units | _els], _acc) -> - 'encode_vcard_ORG_$units'(_els, - [encode_vcard_ORGUNIT(Units, []) | _acc]). +'encode_vcard_ORG_$units'([], __TopXMLNS, _acc) -> _acc; +'encode_vcard_ORG_$units'([Units | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_ORG_$units'(_els, __TopXMLNS, + [encode_vcard_ORGUNIT(Units, __TopXMLNS) | _acc]). -'encode_vcard_ORG_$name'(undefined, _acc) -> _acc; -'encode_vcard_ORG_$name'(Name, _acc) -> - [encode_vcard_ORGNAME(Name, []) | _acc]. +'encode_vcard_ORG_$name'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ORG_$name'(Name, __TopXMLNS, _acc) -> + [encode_vcard_ORGNAME(Name, __TopXMLNS) | _acc]. decode_vcard_PHOTO(__TopXMLNS, __IgnoreEls, {xmlel, <<"PHOTO">>, _attrs, _els}) -> @@ -18377,25 +21987,38 @@ decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, Type, Extval, Binval). encode_vcard_PHOTO({vcard_photo, Type, Binval, Extval}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_PHOTO_$type'(Type, + __NewTopXMLNS, 'encode_vcard_PHOTO_$extval'(Extval, + __NewTopXMLNS, 'encode_vcard_PHOTO_$binval'(Binval, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PHOTO">>, _attrs, _els}. -'encode_vcard_PHOTO_$type'(undefined, _acc) -> _acc; -'encode_vcard_PHOTO_$type'(Type, _acc) -> - [encode_vcard_TYPE(Type, []) | _acc]. +'encode_vcard_PHOTO_$type'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_PHOTO_$type'(Type, __TopXMLNS, _acc) -> + [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. -'encode_vcard_PHOTO_$extval'(undefined, _acc) -> _acc; -'encode_vcard_PHOTO_$extval'(Extval, _acc) -> - [encode_vcard_EXTVAL(Extval, []) | _acc]. +'encode_vcard_PHOTO_$extval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_PHOTO_$extval'(Extval, __TopXMLNS, + _acc) -> + [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. -'encode_vcard_PHOTO_$binval'(undefined, _acc) -> _acc; -'encode_vcard_PHOTO_$binval'(Binval, _acc) -> - [encode_vcard_BINVAL(Binval, []) | _acc]. +'encode_vcard_PHOTO_$binval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_PHOTO_$binval'(Binval, __TopXMLNS, + _acc) -> + [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. decode_vcard_LOGO(__TopXMLNS, __IgnoreEls, {xmlel, <<"LOGO">>, _attrs, _els}) -> @@ -18468,25 +22091,36 @@ decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, Type, Extval, Binval). encode_vcard_LOGO({vcard_logo, Type, Binval, Extval}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_LOGO_$type'(Type, + __NewTopXMLNS, 'encode_vcard_LOGO_$extval'(Extval, + __NewTopXMLNS, 'encode_vcard_LOGO_$binval'(Binval, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LOGO">>, _attrs, _els}. -'encode_vcard_LOGO_$type'(undefined, _acc) -> _acc; -'encode_vcard_LOGO_$type'(Type, _acc) -> - [encode_vcard_TYPE(Type, []) | _acc]. +'encode_vcard_LOGO_$type'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_LOGO_$type'(Type, __TopXMLNS, _acc) -> + [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. -'encode_vcard_LOGO_$extval'(undefined, _acc) -> _acc; -'encode_vcard_LOGO_$extval'(Extval, _acc) -> - [encode_vcard_EXTVAL(Extval, []) | _acc]. +'encode_vcard_LOGO_$extval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_LOGO_$extval'(Extval, __TopXMLNS, _acc) -> + [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. -'encode_vcard_LOGO_$binval'(undefined, _acc) -> _acc; -'encode_vcard_LOGO_$binval'(Binval, _acc) -> - [encode_vcard_BINVAL(Binval, []) | _acc]. +'encode_vcard_LOGO_$binval'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_LOGO_$binval'(Binval, __TopXMLNS, _acc) -> + [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, {xmlel, <<"BINVAL">>, _attrs, _els}) -> @@ -18506,9 +22140,11 @@ decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_BINVAL(Cdata, _xmlns_attrs) -> +encode_vcard_BINVAL(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_BINVAL_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"BINVAL">>, _attrs, _els}. decode_vcard_BINVAL_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -18570,20 +22206,26 @@ decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, Lon). -encode_vcard_GEO({vcard_geo, Lat, Lon}, _xmlns_attrs) -> +encode_vcard_GEO({vcard_geo, Lat, Lon}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_GEO_$lat'(Lat, + __NewTopXMLNS, 'encode_vcard_GEO_$lon'(Lon, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"GEO">>, _attrs, _els}. -'encode_vcard_GEO_$lat'(undefined, _acc) -> _acc; -'encode_vcard_GEO_$lat'(Lat, _acc) -> - [encode_vcard_LAT(Lat, []) | _acc]. +'encode_vcard_GEO_$lat'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_GEO_$lat'(Lat, __TopXMLNS, _acc) -> + [encode_vcard_LAT(Lat, __TopXMLNS) | _acc]. -'encode_vcard_GEO_$lon'(undefined, _acc) -> _acc; -'encode_vcard_GEO_$lon'(Lon, _acc) -> - [encode_vcard_LON(Lon, []) | _acc]. +'encode_vcard_GEO_$lon'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_GEO_$lon'(Lon, __TopXMLNS, _acc) -> + [encode_vcard_LON(Lon, __TopXMLNS) | _acc]. decode_vcard_EMAIL(__TopXMLNS, __IgnoreEls, {xmlel, <<"EMAIL">>, _attrs, _els}) -> @@ -18718,40 +22360,58 @@ decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, encode_vcard_EMAIL({vcard_email, Home, Work, Internet, Pref, X400, Userid}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_EMAIL_$x400'(X400, + __NewTopXMLNS, 'encode_vcard_EMAIL_$userid'(Userid, + __NewTopXMLNS, 'encode_vcard_EMAIL_$internet'(Internet, + __NewTopXMLNS, 'encode_vcard_EMAIL_$home'(Home, + __NewTopXMLNS, 'encode_vcard_EMAIL_$pref'(Pref, + __NewTopXMLNS, 'encode_vcard_EMAIL_$work'(Work, + __NewTopXMLNS, []))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"EMAIL">>, _attrs, _els}. -'encode_vcard_EMAIL_$x400'(false, _acc) -> _acc; -'encode_vcard_EMAIL_$x400'(X400, _acc) -> - [encode_vcard_X400(X400, []) | _acc]. +'encode_vcard_EMAIL_$x400'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_EMAIL_$x400'(X400, __TopXMLNS, _acc) -> + [encode_vcard_X400(X400, __TopXMLNS) | _acc]. -'encode_vcard_EMAIL_$userid'(undefined, _acc) -> _acc; -'encode_vcard_EMAIL_$userid'(Userid, _acc) -> - [encode_vcard_USERID(Userid, []) | _acc]. +'encode_vcard_EMAIL_$userid'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_EMAIL_$userid'(Userid, __TopXMLNS, + _acc) -> + [encode_vcard_USERID(Userid, __TopXMLNS) | _acc]. -'encode_vcard_EMAIL_$internet'(false, _acc) -> _acc; -'encode_vcard_EMAIL_$internet'(Internet, _acc) -> - [encode_vcard_INTERNET(Internet, []) | _acc]. +'encode_vcard_EMAIL_$internet'(false, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_EMAIL_$internet'(Internet, __TopXMLNS, + _acc) -> + [encode_vcard_INTERNET(Internet, __TopXMLNS) | _acc]. -'encode_vcard_EMAIL_$home'(false, _acc) -> _acc; -'encode_vcard_EMAIL_$home'(Home, _acc) -> - [encode_vcard_HOME(Home, []) | _acc]. +'encode_vcard_EMAIL_$home'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_EMAIL_$home'(Home, __TopXMLNS, _acc) -> + [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. -'encode_vcard_EMAIL_$pref'(false, _acc) -> _acc; -'encode_vcard_EMAIL_$pref'(Pref, _acc) -> - [encode_vcard_PREF(Pref, []) | _acc]. +'encode_vcard_EMAIL_$pref'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_EMAIL_$pref'(Pref, __TopXMLNS, _acc) -> + [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. -'encode_vcard_EMAIL_$work'(false, _acc) -> _acc; -'encode_vcard_EMAIL_$work'(Work, _acc) -> - [encode_vcard_WORK(Work, []) | _acc]. +'encode_vcard_EMAIL_$work'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_EMAIL_$work'(Work, __TopXMLNS, _acc) -> + [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. decode_vcard_TEL(__TopXMLNS, __IgnoreEls, {xmlel, <<"TEL">>, _attrs, _els}) -> @@ -19091,80 +22751,111 @@ decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, encode_vcard_TEL({vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs, Pref, Number}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_TEL_$number'(Number, + __NewTopXMLNS, 'encode_vcard_TEL_$pager'(Pager, + __NewTopXMLNS, 'encode_vcard_TEL_$pcs'(Pcs, + __NewTopXMLNS, 'encode_vcard_TEL_$bbs'(Bbs, + __NewTopXMLNS, 'encode_vcard_TEL_$voice'(Voice, + __NewTopXMLNS, 'encode_vcard_TEL_$home'(Home, + __NewTopXMLNS, 'encode_vcard_TEL_$pref'(Pref, + __NewTopXMLNS, 'encode_vcard_TEL_$msg'(Msg, + __NewTopXMLNS, 'encode_vcard_TEL_$fax'(Fax, + __NewTopXMLNS, 'encode_vcard_TEL_$work'(Work, + __NewTopXMLNS, 'encode_vcard_TEL_$cell'(Cell, + __NewTopXMLNS, 'encode_vcard_TEL_$modem'(Modem, + __NewTopXMLNS, 'encode_vcard_TEL_$isdn'(Isdn, + __NewTopXMLNS, 'encode_vcard_TEL_$video'(Video, + __NewTopXMLNS, []))))))))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"TEL">>, _attrs, _els}. -'encode_vcard_TEL_$number'(undefined, _acc) -> _acc; -'encode_vcard_TEL_$number'(Number, _acc) -> - [encode_vcard_NUMBER(Number, []) | _acc]. +'encode_vcard_TEL_$number'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_TEL_$number'(Number, __TopXMLNS, _acc) -> + [encode_vcard_NUMBER(Number, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$pager'(false, _acc) -> _acc; -'encode_vcard_TEL_$pager'(Pager, _acc) -> - [encode_vcard_PAGER(Pager, []) | _acc]. +'encode_vcard_TEL_$pager'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$pager'(Pager, __TopXMLNS, _acc) -> + [encode_vcard_PAGER(Pager, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$pcs'(false, _acc) -> _acc; -'encode_vcard_TEL_$pcs'(Pcs, _acc) -> - [encode_vcard_PCS(Pcs, []) | _acc]. +'encode_vcard_TEL_$pcs'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$pcs'(Pcs, __TopXMLNS, _acc) -> + [encode_vcard_PCS(Pcs, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$bbs'(false, _acc) -> _acc; -'encode_vcard_TEL_$bbs'(Bbs, _acc) -> - [encode_vcard_BBS(Bbs, []) | _acc]. +'encode_vcard_TEL_$bbs'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$bbs'(Bbs, __TopXMLNS, _acc) -> + [encode_vcard_BBS(Bbs, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$voice'(false, _acc) -> _acc; -'encode_vcard_TEL_$voice'(Voice, _acc) -> - [encode_vcard_VOICE(Voice, []) | _acc]. +'encode_vcard_TEL_$voice'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$voice'(Voice, __TopXMLNS, _acc) -> + [encode_vcard_VOICE(Voice, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$home'(false, _acc) -> _acc; -'encode_vcard_TEL_$home'(Home, _acc) -> - [encode_vcard_HOME(Home, []) | _acc]. +'encode_vcard_TEL_$home'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$home'(Home, __TopXMLNS, _acc) -> + [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$pref'(false, _acc) -> _acc; -'encode_vcard_TEL_$pref'(Pref, _acc) -> - [encode_vcard_PREF(Pref, []) | _acc]. +'encode_vcard_TEL_$pref'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$pref'(Pref, __TopXMLNS, _acc) -> + [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$msg'(false, _acc) -> _acc; -'encode_vcard_TEL_$msg'(Msg, _acc) -> - [encode_vcard_MSG(Msg, []) | _acc]. +'encode_vcard_TEL_$msg'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$msg'(Msg, __TopXMLNS, _acc) -> + [encode_vcard_MSG(Msg, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$fax'(false, _acc) -> _acc; -'encode_vcard_TEL_$fax'(Fax, _acc) -> - [encode_vcard_FAX(Fax, []) | _acc]. +'encode_vcard_TEL_$fax'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$fax'(Fax, __TopXMLNS, _acc) -> + [encode_vcard_FAX(Fax, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$work'(false, _acc) -> _acc; -'encode_vcard_TEL_$work'(Work, _acc) -> - [encode_vcard_WORK(Work, []) | _acc]. +'encode_vcard_TEL_$work'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$work'(Work, __TopXMLNS, _acc) -> + [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$cell'(false, _acc) -> _acc; -'encode_vcard_TEL_$cell'(Cell, _acc) -> - [encode_vcard_CELL(Cell, []) | _acc]. +'encode_vcard_TEL_$cell'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$cell'(Cell, __TopXMLNS, _acc) -> + [encode_vcard_CELL(Cell, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$modem'(false, _acc) -> _acc; -'encode_vcard_TEL_$modem'(Modem, _acc) -> - [encode_vcard_MODEM(Modem, []) | _acc]. +'encode_vcard_TEL_$modem'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$modem'(Modem, __TopXMLNS, _acc) -> + [encode_vcard_MODEM(Modem, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$isdn'(false, _acc) -> _acc; -'encode_vcard_TEL_$isdn'(Isdn, _acc) -> - [encode_vcard_ISDN(Isdn, []) | _acc]. +'encode_vcard_TEL_$isdn'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$isdn'(Isdn, __TopXMLNS, _acc) -> + [encode_vcard_ISDN(Isdn, __TopXMLNS) | _acc]. -'encode_vcard_TEL_$video'(false, _acc) -> _acc; -'encode_vcard_TEL_$video'(Video, _acc) -> - [encode_vcard_VIDEO(Video, []) | _acc]. +'encode_vcard_TEL_$video'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_TEL_$video'(Video, __TopXMLNS, _acc) -> + [encode_vcard_VIDEO(Video, __TopXMLNS) | _acc]. decode_vcard_LABEL(__TopXMLNS, __IgnoreEls, {xmlel, <<"LABEL">>, _attrs, _els}) -> @@ -19353,51 +23044,72 @@ decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, encode_vcard_LABEL({vcard_label, Home, Work, Postal, Parcel, Dom, Intl, Pref, Line}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_LABEL_$line'(Line, + __NewTopXMLNS, 'encode_vcard_LABEL_$home'(Home, + __NewTopXMLNS, 'encode_vcard_LABEL_$pref'(Pref, + __NewTopXMLNS, 'encode_vcard_LABEL_$work'(Work, + __NewTopXMLNS, 'encode_vcard_LABEL_$intl'(Intl, + __NewTopXMLNS, 'encode_vcard_LABEL_$parcel'(Parcel, + __NewTopXMLNS, 'encode_vcard_LABEL_$postal'(Postal, + __NewTopXMLNS, 'encode_vcard_LABEL_$dom'(Dom, + __NewTopXMLNS, []))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LABEL">>, _attrs, _els}. -'encode_vcard_LABEL_$line'([], _acc) -> _acc; -'encode_vcard_LABEL_$line'([Line | _els], _acc) -> - 'encode_vcard_LABEL_$line'(_els, - [encode_vcard_LINE(Line, []) | _acc]). +'encode_vcard_LABEL_$line'([], __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$line'([Line | _els], __TopXMLNS, + _acc) -> + 'encode_vcard_LABEL_$line'(_els, __TopXMLNS, + [encode_vcard_LINE(Line, __TopXMLNS) | _acc]). -'encode_vcard_LABEL_$home'(false, _acc) -> _acc; -'encode_vcard_LABEL_$home'(Home, _acc) -> - [encode_vcard_HOME(Home, []) | _acc]. +'encode_vcard_LABEL_$home'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$home'(Home, __TopXMLNS, _acc) -> + [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$pref'(false, _acc) -> _acc; -'encode_vcard_LABEL_$pref'(Pref, _acc) -> - [encode_vcard_PREF(Pref, []) | _acc]. +'encode_vcard_LABEL_$pref'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$pref'(Pref, __TopXMLNS, _acc) -> + [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$work'(false, _acc) -> _acc; -'encode_vcard_LABEL_$work'(Work, _acc) -> - [encode_vcard_WORK(Work, []) | _acc]. +'encode_vcard_LABEL_$work'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$work'(Work, __TopXMLNS, _acc) -> + [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$intl'(false, _acc) -> _acc; -'encode_vcard_LABEL_$intl'(Intl, _acc) -> - [encode_vcard_INTL(Intl, []) | _acc]. +'encode_vcard_LABEL_$intl'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$intl'(Intl, __TopXMLNS, _acc) -> + [encode_vcard_INTL(Intl, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$parcel'(false, _acc) -> _acc; -'encode_vcard_LABEL_$parcel'(Parcel, _acc) -> - [encode_vcard_PARCEL(Parcel, []) | _acc]. +'encode_vcard_LABEL_$parcel'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$parcel'(Parcel, __TopXMLNS, + _acc) -> + [encode_vcard_PARCEL(Parcel, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$postal'(false, _acc) -> _acc; -'encode_vcard_LABEL_$postal'(Postal, _acc) -> - [encode_vcard_POSTAL(Postal, []) | _acc]. +'encode_vcard_LABEL_$postal'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$postal'(Postal, __TopXMLNS, + _acc) -> + [encode_vcard_POSTAL(Postal, __TopXMLNS) | _acc]. -'encode_vcard_LABEL_$dom'(false, _acc) -> _acc; -'encode_vcard_LABEL_$dom'(Dom, _acc) -> - [encode_vcard_DOM(Dom, []) | _acc]. +'encode_vcard_LABEL_$dom'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_LABEL_$dom'(Dom, __TopXMLNS, _acc) -> + [encode_vcard_DOM(Dom, __TopXMLNS) | _acc]. decode_vcard_ADR(__TopXMLNS, __IgnoreEls, {xmlel, <<"ADR">>, _attrs, _els}) -> @@ -19762,80 +23474,117 @@ decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, encode_vcard_ADR({vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref, Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_ADR_$street'(Street, + __NewTopXMLNS, 'encode_vcard_ADR_$extadd'(Extadd, + __NewTopXMLNS, 'encode_vcard_ADR_$pcode'(Pcode, + __NewTopXMLNS, 'encode_vcard_ADR_$home'(Home, + __NewTopXMLNS, 'encode_vcard_ADR_$pref'(Pref, + __NewTopXMLNS, 'encode_vcard_ADR_$pobox'(Pobox, + __NewTopXMLNS, 'encode_vcard_ADR_$ctry'(Ctry, + __NewTopXMLNS, 'encode_vcard_ADR_$locality'(Locality, + __NewTopXMLNS, 'encode_vcard_ADR_$work'(Work, + __NewTopXMLNS, 'encode_vcard_ADR_$intl'(Intl, + __NewTopXMLNS, 'encode_vcard_ADR_$parcel'(Parcel, + __NewTopXMLNS, 'encode_vcard_ADR_$postal'(Postal, + __NewTopXMLNS, 'encode_vcard_ADR_$dom'(Dom, + __NewTopXMLNS, 'encode_vcard_ADR_$region'(Region, + __NewTopXMLNS, []))))))))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ADR">>, _attrs, _els}. -'encode_vcard_ADR_$street'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$street'(Street, _acc) -> - [encode_vcard_STREET(Street, []) | _acc]. +'encode_vcard_ADR_$street'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$street'(Street, __TopXMLNS, _acc) -> + [encode_vcard_STREET(Street, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$extadd'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$extadd'(Extadd, _acc) -> - [encode_vcard_EXTADD(Extadd, []) | _acc]. +'encode_vcard_ADR_$extadd'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$extadd'(Extadd, __TopXMLNS, _acc) -> + [encode_vcard_EXTADD(Extadd, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$pcode'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$pcode'(Pcode, _acc) -> - [encode_vcard_PCODE(Pcode, []) | _acc]. +'encode_vcard_ADR_$pcode'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$pcode'(Pcode, __TopXMLNS, _acc) -> + [encode_vcard_PCODE(Pcode, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$home'(false, _acc) -> _acc; -'encode_vcard_ADR_$home'(Home, _acc) -> - [encode_vcard_HOME(Home, []) | _acc]. +'encode_vcard_ADR_$home'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$home'(Home, __TopXMLNS, _acc) -> + [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$pref'(false, _acc) -> _acc; -'encode_vcard_ADR_$pref'(Pref, _acc) -> - [encode_vcard_PREF(Pref, []) | _acc]. +'encode_vcard_ADR_$pref'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$pref'(Pref, __TopXMLNS, _acc) -> + [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$pobox'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$pobox'(Pobox, _acc) -> - [encode_vcard_POBOX(Pobox, []) | _acc]. +'encode_vcard_ADR_$pobox'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$pobox'(Pobox, __TopXMLNS, _acc) -> + [encode_vcard_POBOX(Pobox, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$ctry'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$ctry'(Ctry, _acc) -> - [encode_vcard_CTRY(Ctry, []) | _acc]. +'encode_vcard_ADR_$ctry'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$ctry'(Ctry, __TopXMLNS, _acc) -> + [encode_vcard_CTRY(Ctry, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$locality'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$locality'(Locality, _acc) -> - [encode_vcard_LOCALITY(Locality, []) | _acc]. +'encode_vcard_ADR_$locality'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$locality'(Locality, __TopXMLNS, + _acc) -> + [encode_vcard_LOCALITY(Locality, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$work'(false, _acc) -> _acc; -'encode_vcard_ADR_$work'(Work, _acc) -> - [encode_vcard_WORK(Work, []) | _acc]. +'encode_vcard_ADR_$work'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$work'(Work, __TopXMLNS, _acc) -> + [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$intl'(false, _acc) -> _acc; -'encode_vcard_ADR_$intl'(Intl, _acc) -> - [encode_vcard_INTL(Intl, []) | _acc]. +'encode_vcard_ADR_$intl'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$intl'(Intl, __TopXMLNS, _acc) -> + [encode_vcard_INTL(Intl, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$parcel'(false, _acc) -> _acc; -'encode_vcard_ADR_$parcel'(Parcel, _acc) -> - [encode_vcard_PARCEL(Parcel, []) | _acc]. +'encode_vcard_ADR_$parcel'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$parcel'(Parcel, __TopXMLNS, _acc) -> + [encode_vcard_PARCEL(Parcel, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$postal'(false, _acc) -> _acc; -'encode_vcard_ADR_$postal'(Postal, _acc) -> - [encode_vcard_POSTAL(Postal, []) | _acc]. +'encode_vcard_ADR_$postal'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$postal'(Postal, __TopXMLNS, _acc) -> + [encode_vcard_POSTAL(Postal, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$dom'(false, _acc) -> _acc; -'encode_vcard_ADR_$dom'(Dom, _acc) -> - [encode_vcard_DOM(Dom, []) | _acc]. +'encode_vcard_ADR_$dom'(false, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_ADR_$dom'(Dom, __TopXMLNS, _acc) -> + [encode_vcard_DOM(Dom, __TopXMLNS) | _acc]. -'encode_vcard_ADR_$region'(undefined, _acc) -> _acc; -'encode_vcard_ADR_$region'(Region, _acc) -> - [encode_vcard_REGION(Region, []) | _acc]. +'encode_vcard_ADR_$region'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_vcard_ADR_$region'(Region, __TopXMLNS, _acc) -> + [encode_vcard_REGION(Region, __TopXMLNS) | _acc]. decode_vcard_N(__TopXMLNS, __IgnoreEls, {xmlel, <<"N">>, _attrs, _els}) -> @@ -19946,61 +23695,79 @@ decode_vcard_N_els(__TopXMLNS, __IgnoreEls, [_ | _els], encode_vcard_N({vcard_name, Family, Given, Middle, Prefix, Suffix}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = lists:reverse('encode_vcard_N_$middle'(Middle, + __NewTopXMLNS, 'encode_vcard_N_$suffix'(Suffix, + __NewTopXMLNS, 'encode_vcard_N_$prefix'(Prefix, + __NewTopXMLNS, 'encode_vcard_N_$family'(Family, + __NewTopXMLNS, 'encode_vcard_N_$given'(Given, + __NewTopXMLNS, [])))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"N">>, _attrs, _els}. -'encode_vcard_N_$middle'(undefined, _acc) -> _acc; -'encode_vcard_N_$middle'(Middle, _acc) -> - [encode_vcard_MIDDLE(Middle, []) | _acc]. +'encode_vcard_N_$middle'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_N_$middle'(Middle, __TopXMLNS, _acc) -> + [encode_vcard_MIDDLE(Middle, __TopXMLNS) | _acc]. -'encode_vcard_N_$suffix'(undefined, _acc) -> _acc; -'encode_vcard_N_$suffix'(Suffix, _acc) -> - [encode_vcard_SUFFIX(Suffix, []) | _acc]. +'encode_vcard_N_$suffix'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_N_$suffix'(Suffix, __TopXMLNS, _acc) -> + [encode_vcard_SUFFIX(Suffix, __TopXMLNS) | _acc]. -'encode_vcard_N_$prefix'(undefined, _acc) -> _acc; -'encode_vcard_N_$prefix'(Prefix, _acc) -> - [encode_vcard_PREFIX(Prefix, []) | _acc]. +'encode_vcard_N_$prefix'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_N_$prefix'(Prefix, __TopXMLNS, _acc) -> + [encode_vcard_PREFIX(Prefix, __TopXMLNS) | _acc]. -'encode_vcard_N_$family'(undefined, _acc) -> _acc; -'encode_vcard_N_$family'(Family, _acc) -> - [encode_vcard_FAMILY(Family, []) | _acc]. +'encode_vcard_N_$family'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_N_$family'(Family, __TopXMLNS, _acc) -> + [encode_vcard_FAMILY(Family, __TopXMLNS) | _acc]. -'encode_vcard_N_$given'(undefined, _acc) -> _acc; -'encode_vcard_N_$given'(Given, _acc) -> - [encode_vcard_GIVEN(Given, []) | _acc]. +'encode_vcard_N_$given'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_vcard_N_$given'(Given, __TopXMLNS, _acc) -> + [encode_vcard_GIVEN(Given, __TopXMLNS) | _acc]. decode_vcard_CONFIDENTIAL(__TopXMLNS, __IgnoreEls, {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}) -> confidential. -encode_vcard_CONFIDENTIAL(confidential, _xmlns_attrs) -> +encode_vcard_CONFIDENTIAL(confidential, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}. decode_vcard_PRIVATE(__TopXMLNS, __IgnoreEls, {xmlel, <<"PRIVATE">>, _attrs, _els}) -> private. -encode_vcard_PRIVATE(private, _xmlns_attrs) -> +encode_vcard_PRIVATE(private, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PRIVATE">>, _attrs, _els}. decode_vcard_PUBLIC(__TopXMLNS, __IgnoreEls, {xmlel, <<"PUBLIC">>, _attrs, _els}) -> public. -encode_vcard_PUBLIC(public, _xmlns_attrs) -> +encode_vcard_PUBLIC(public, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PUBLIC">>, _attrs, _els}. decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, @@ -20021,9 +23788,11 @@ decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_EXTVAL(Cdata, _xmlns_attrs) -> +encode_vcard_EXTVAL(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_EXTVAL_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"EXTVAL">>, _attrs, _els}. decode_vcard_EXTVAL_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20051,9 +23820,11 @@ decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_TYPE(Cdata, _xmlns_attrs) -> +encode_vcard_TYPE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_TYPE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"TYPE">>, _attrs, _els}. decode_vcard_TYPE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20081,9 +23852,11 @@ decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_DESC(Cdata, _xmlns_attrs) -> +encode_vcard_DESC(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_DESC_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"DESC">>, _attrs, _els}. decode_vcard_DESC_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20111,9 +23884,11 @@ decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_URL(Cdata, _xmlns_attrs) -> +encode_vcard_URL(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_URL_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"URL">>, _attrs, _els}. decode_vcard_URL_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20141,9 +23916,11 @@ decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_UID(Cdata, _xmlns_attrs) -> +encode_vcard_UID(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_UID_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"UID">>, _attrs, _els}. decode_vcard_UID_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20171,9 +23948,11 @@ decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_SORT_STRING(Cdata, _xmlns_attrs) -> +encode_vcard_SORT_STRING(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_SORT_STRING_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"SORT-STRING">>, _attrs, _els}. decode_vcard_SORT_STRING_cdata(__TopXMLNS, <<>>) -> @@ -20203,9 +23982,11 @@ decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_REV(Cdata, _xmlns_attrs) -> +encode_vcard_REV(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_REV_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"REV">>, _attrs, _els}. decode_vcard_REV_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20233,9 +24014,11 @@ decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_PRODID(Cdata, _xmlns_attrs) -> +encode_vcard_PRODID(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_PRODID_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PRODID">>, _attrs, _els}. decode_vcard_PRODID_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20263,9 +24046,11 @@ decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_NOTE(Cdata, _xmlns_attrs) -> +encode_vcard_NOTE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_NOTE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"NOTE">>, _attrs, _els}. decode_vcard_NOTE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20293,9 +24078,11 @@ decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_KEYWORD(Cdata, _xmlns_attrs) -> +encode_vcard_KEYWORD(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_KEYWORD_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"KEYWORD">>, _attrs, _els}. decode_vcard_KEYWORD_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20323,9 +24110,11 @@ decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_ROLE(Cdata, _xmlns_attrs) -> +encode_vcard_ROLE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_ROLE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ROLE">>, _attrs, _els}. decode_vcard_ROLE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20353,9 +24142,11 @@ decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_TITLE(Cdata, _xmlns_attrs) -> +encode_vcard_TITLE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_TITLE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"TITLE">>, _attrs, _els}. decode_vcard_TITLE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20383,9 +24174,11 @@ decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_TZ(Cdata, _xmlns_attrs) -> +encode_vcard_TZ(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_TZ_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"TZ">>, _attrs, _els}. decode_vcard_TZ_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20413,9 +24206,11 @@ decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_MAILER(Cdata, _xmlns_attrs) -> +encode_vcard_MAILER(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_MAILER_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"MAILER">>, _attrs, _els}. decode_vcard_MAILER_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20443,9 +24238,11 @@ decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_JABBERID(Cdata, _xmlns_attrs) -> +encode_vcard_JABBERID(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_JABBERID_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"JABBERID">>, _attrs, _els}. decode_vcard_JABBERID_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20473,9 +24270,11 @@ decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_BDAY(Cdata, _xmlns_attrs) -> +encode_vcard_BDAY(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_BDAY_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"BDAY">>, _attrs, _els}. decode_vcard_BDAY_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20503,9 +24302,11 @@ decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_NICKNAME(Cdata, _xmlns_attrs) -> +encode_vcard_NICKNAME(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_NICKNAME_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"NICKNAME">>, _attrs, _els}. decode_vcard_NICKNAME_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20533,9 +24334,11 @@ decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_FN(Cdata, _xmlns_attrs) -> +encode_vcard_FN(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_FN_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"FN">>, _attrs, _els}. decode_vcard_FN_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20563,9 +24366,11 @@ decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_VERSION(Cdata, _xmlns_attrs) -> +encode_vcard_VERSION(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_VERSION_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"VERSION">>, _attrs, _els}. decode_vcard_VERSION_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20593,9 +24398,11 @@ decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_CRED(Cdata, _xmlns_attrs) -> +encode_vcard_CRED(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_CRED_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CRED">>, _attrs, _els}. decode_vcard_CRED_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20623,9 +24430,11 @@ decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_PHONETIC(Cdata, _xmlns_attrs) -> +encode_vcard_PHONETIC(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_PHONETIC_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PHONETIC">>, _attrs, _els}. decode_vcard_PHONETIC_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20653,9 +24462,11 @@ decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_ORGUNIT(Cdata, _xmlns_attrs) -> +encode_vcard_ORGUNIT(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_ORGUNIT_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ORGUNIT">>, _attrs, _els}. decode_vcard_ORGUNIT_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20683,9 +24494,11 @@ decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_ORGNAME(Cdata, _xmlns_attrs) -> +encode_vcard_ORGNAME(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_ORGNAME_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ORGNAME">>, _attrs, _els}. decode_vcard_ORGNAME_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20713,9 +24526,11 @@ decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_LON(Cdata, _xmlns_attrs) -> +encode_vcard_LON(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_LON_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LON">>, _attrs, _els}. decode_vcard_LON_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20743,9 +24558,11 @@ decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_LAT(Cdata, _xmlns_attrs) -> +encode_vcard_LAT(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_LAT_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LAT">>, _attrs, _els}. decode_vcard_LAT_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20773,9 +24590,11 @@ decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_USERID(Cdata, _xmlns_attrs) -> +encode_vcard_USERID(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_USERID_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"USERID">>, _attrs, _els}. decode_vcard_USERID_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20803,9 +24622,11 @@ decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_NUMBER(Cdata, _xmlns_attrs) -> +encode_vcard_NUMBER(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_NUMBER_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"NUMBER">>, _attrs, _els}. decode_vcard_NUMBER_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20833,9 +24654,11 @@ decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_LINE(Cdata, _xmlns_attrs) -> +encode_vcard_LINE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_LINE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LINE">>, _attrs, _els}. decode_vcard_LINE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20863,9 +24686,11 @@ decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_CTRY(Cdata, _xmlns_attrs) -> +encode_vcard_CTRY(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_CTRY_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CTRY">>, _attrs, _els}. decode_vcard_CTRY_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20893,9 +24718,11 @@ decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_PCODE(Cdata, _xmlns_attrs) -> +encode_vcard_PCODE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_PCODE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PCODE">>, _attrs, _els}. decode_vcard_PCODE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20923,9 +24750,11 @@ decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_REGION(Cdata, _xmlns_attrs) -> +encode_vcard_REGION(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_REGION_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"REGION">>, _attrs, _els}. decode_vcard_REGION_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20953,9 +24782,11 @@ decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_LOCALITY(Cdata, _xmlns_attrs) -> +encode_vcard_LOCALITY(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_LOCALITY_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"LOCALITY">>, _attrs, _els}. decode_vcard_LOCALITY_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -20983,9 +24814,11 @@ decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_STREET(Cdata, _xmlns_attrs) -> +encode_vcard_STREET(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_STREET_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"STREET">>, _attrs, _els}. decode_vcard_STREET_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21013,9 +24846,11 @@ decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_EXTADD(Cdata, _xmlns_attrs) -> +encode_vcard_EXTADD(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_EXTADD_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"EXTADD">>, _attrs, _els}. decode_vcard_EXTADD_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21043,9 +24878,11 @@ decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_POBOX(Cdata, _xmlns_attrs) -> +encode_vcard_POBOX(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_POBOX_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"POBOX">>, _attrs, _els}. decode_vcard_POBOX_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21073,9 +24910,11 @@ decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_SUFFIX(Cdata, _xmlns_attrs) -> +encode_vcard_SUFFIX(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_SUFFIX_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"SUFFIX">>, _attrs, _els}. decode_vcard_SUFFIX_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21103,9 +24942,11 @@ decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_PREFIX(Cdata, _xmlns_attrs) -> +encode_vcard_PREFIX(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_PREFIX_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PREFIX">>, _attrs, _els}. decode_vcard_PREFIX_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21133,9 +24974,11 @@ decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_MIDDLE(Cdata, _xmlns_attrs) -> +encode_vcard_MIDDLE(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_MIDDLE_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"MIDDLE">>, _attrs, _els}. decode_vcard_MIDDLE_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21163,9 +25006,11 @@ decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_GIVEN(Cdata, _xmlns_attrs) -> +encode_vcard_GIVEN(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_GIVEN_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"GIVEN">>, _attrs, _els}. decode_vcard_GIVEN_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21193,9 +25038,11 @@ decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_vcard_FAMILY(Cdata, _xmlns_attrs) -> +encode_vcard_FAMILY(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = encode_vcard_FAMILY_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"FAMILY">>, _attrs, _els}. decode_vcard_FAMILY_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -21209,171 +25056,209 @@ decode_vcard_X400(__TopXMLNS, __IgnoreEls, {xmlel, <<"X400">>, _attrs, _els}) -> true. -encode_vcard_X400(true, _xmlns_attrs) -> +encode_vcard_X400(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"X400">>, _attrs, _els}. decode_vcard_INTERNET(__TopXMLNS, __IgnoreEls, {xmlel, <<"INTERNET">>, _attrs, _els}) -> true. -encode_vcard_INTERNET(true, _xmlns_attrs) -> +encode_vcard_INTERNET(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"INTERNET">>, _attrs, _els}. decode_vcard_PREF(__TopXMLNS, __IgnoreEls, {xmlel, <<"PREF">>, _attrs, _els}) -> true. -encode_vcard_PREF(true, _xmlns_attrs) -> +encode_vcard_PREF(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PREF">>, _attrs, _els}. decode_vcard_INTL(__TopXMLNS, __IgnoreEls, {xmlel, <<"INTL">>, _attrs, _els}) -> true. -encode_vcard_INTL(true, _xmlns_attrs) -> +encode_vcard_INTL(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"INTL">>, _attrs, _els}. decode_vcard_DOM(__TopXMLNS, __IgnoreEls, {xmlel, <<"DOM">>, _attrs, _els}) -> true. -encode_vcard_DOM(true, _xmlns_attrs) -> +encode_vcard_DOM(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"DOM">>, _attrs, _els}. decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, {xmlel, <<"PARCEL">>, _attrs, _els}) -> true. -encode_vcard_PARCEL(true, _xmlns_attrs) -> +encode_vcard_PARCEL(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PARCEL">>, _attrs, _els}. decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, {xmlel, <<"POSTAL">>, _attrs, _els}) -> true. -encode_vcard_POSTAL(true, _xmlns_attrs) -> +encode_vcard_POSTAL(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"POSTAL">>, _attrs, _els}. decode_vcard_PCS(__TopXMLNS, __IgnoreEls, {xmlel, <<"PCS">>, _attrs, _els}) -> true. -encode_vcard_PCS(true, _xmlns_attrs) -> +encode_vcard_PCS(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PCS">>, _attrs, _els}. decode_vcard_ISDN(__TopXMLNS, __IgnoreEls, {xmlel, <<"ISDN">>, _attrs, _els}) -> true. -encode_vcard_ISDN(true, _xmlns_attrs) -> +encode_vcard_ISDN(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ISDN">>, _attrs, _els}. decode_vcard_MODEM(__TopXMLNS, __IgnoreEls, {xmlel, <<"MODEM">>, _attrs, _els}) -> true. -encode_vcard_MODEM(true, _xmlns_attrs) -> +encode_vcard_MODEM(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"MODEM">>, _attrs, _els}. decode_vcard_BBS(__TopXMLNS, __IgnoreEls, {xmlel, <<"BBS">>, _attrs, _els}) -> true. -encode_vcard_BBS(true, _xmlns_attrs) -> +encode_vcard_BBS(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"BBS">>, _attrs, _els}. decode_vcard_VIDEO(__TopXMLNS, __IgnoreEls, {xmlel, <<"VIDEO">>, _attrs, _els}) -> true. -encode_vcard_VIDEO(true, _xmlns_attrs) -> +encode_vcard_VIDEO(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"VIDEO">>, _attrs, _els}. decode_vcard_CELL(__TopXMLNS, __IgnoreEls, {xmlel, <<"CELL">>, _attrs, _els}) -> true. -encode_vcard_CELL(true, _xmlns_attrs) -> +encode_vcard_CELL(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"CELL">>, _attrs, _els}. decode_vcard_MSG(__TopXMLNS, __IgnoreEls, {xmlel, <<"MSG">>, _attrs, _els}) -> true. -encode_vcard_MSG(true, _xmlns_attrs) -> +encode_vcard_MSG(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"MSG">>, _attrs, _els}. decode_vcard_PAGER(__TopXMLNS, __IgnoreEls, {xmlel, <<"PAGER">>, _attrs, _els}) -> true. -encode_vcard_PAGER(true, _xmlns_attrs) -> +encode_vcard_PAGER(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"PAGER">>, _attrs, _els}. decode_vcard_FAX(__TopXMLNS, __IgnoreEls, {xmlel, <<"FAX">>, _attrs, _els}) -> true. -encode_vcard_FAX(true, _xmlns_attrs) -> +encode_vcard_FAX(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"FAX">>, _attrs, _els}. decode_vcard_VOICE(__TopXMLNS, __IgnoreEls, {xmlel, <<"VOICE">>, _attrs, _els}) -> true. -encode_vcard_VOICE(true, _xmlns_attrs) -> +encode_vcard_VOICE(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"VOICE">>, _attrs, _els}. decode_vcard_WORK(__TopXMLNS, __IgnoreEls, {xmlel, <<"WORK">>, _attrs, _els}) -> true. -encode_vcard_WORK(true, _xmlns_attrs) -> +encode_vcard_WORK(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"WORK">>, _attrs, _els}. decode_vcard_HOME(__TopXMLNS, __IgnoreEls, {xmlel, <<"HOME">>, _attrs, _els}) -> true. -encode_vcard_HOME(true, _xmlns_attrs) -> +encode_vcard_HOME(true, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"HOME">>, _attrs, _els}. decode_stream_error(__TopXMLNS, __IgnoreEls, @@ -21769,184 +25654,153 @@ decode_stream_error_els(__TopXMLNS, __IgnoreEls, Text, Reason). encode_stream_error({stream_error, Reason, Text}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = lists:reverse('encode_stream_error_$text'(Text, + __NewTopXMLNS, 'encode_stream_error_$reason'(Reason, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"stream:error">>, _attrs, _els}. -'encode_stream_error_$text'(undefined, _acc) -> _acc; -'encode_stream_error_$text'(Text, _acc) -> - [encode_stream_error_text(Text, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) - | _acc]. +'encode_stream_error_$text'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_stream_error_$text'(Text, __TopXMLNS, _acc) -> + [encode_stream_error_text(Text, __TopXMLNS) | _acc]. -'encode_stream_error_$reason'(undefined, _acc) -> _acc; -'encode_stream_error_$reason'('bad-format' = Reason, +'encode_stream_error_$reason'(undefined, __TopXMLNS, _acc) -> - [encode_stream_error_bad_format(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + _acc; +'encode_stream_error_$reason'('bad-format' = Reason, + __TopXMLNS, _acc) -> + [encode_stream_error_bad_format(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('bad-namespace-prefix' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_bad_namespace_prefix(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'(conflict = Reason, - _acc) -> - [encode_stream_error_conflict(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_conflict(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('connection-timeout' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_connection_timeout(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('host-gone' = Reason, - _acc) -> - [encode_stream_error_host_gone(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_host_gone(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('host-unknown' = Reason, - _acc) -> - [encode_stream_error_host_unknown(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_host_unknown(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('improper-addressing' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_improper_addressing(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('internal-server-error' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_internal_server_error(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('invalid-from' = Reason, - _acc) -> - [encode_stream_error_invalid_from(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_invalid_from(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('invalid-id' = Reason, - _acc) -> - [encode_stream_error_invalid_id(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_invalid_id(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('invalid-namespace' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_invalid_namespace(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('invalid-xml' = Reason, - _acc) -> - [encode_stream_error_invalid_xml(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_invalid_xml(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('not-authorized' = Reason, - _acc) -> - [encode_stream_error_not_authorized(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_not_authorized(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('not-well-formed' = Reason, - _acc) -> - [encode_stream_error_not_well_formed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_not_well_formed(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('policy-violation' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_policy_violation(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('remote-connection-failed' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_remote_connection_failed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) - | _acc]; -'encode_stream_error_$reason'(reset = Reason, _acc) -> - [encode_stream_error_reset(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; +'encode_stream_error_$reason'(reset = Reason, + __TopXMLNS, _acc) -> + [encode_stream_error_reset(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('resource-constraint' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_resource_constraint(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('restricted-xml' = Reason, - _acc) -> - [encode_stream_error_restricted_xml(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_restricted_xml(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'({'see-other-host', _} = Reason, - _acc) -> - [encode_stream_error_see_other_host(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_see_other_host(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('system-shutdown' = Reason, - _acc) -> - [encode_stream_error_system_shutdown(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS, _acc) -> + [encode_stream_error_system_shutdown(Reason, __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('undefined-condition' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_undefined_condition(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('unsupported-encoding' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_unsupported_encoding(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('unsupported-stanza-type' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_unsupported_stanza_type(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]; 'encode_stream_error_$reason'('unsupported-version' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_stream_error_unsupported_version(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>}]) + __TopXMLNS) | _acc]. decode_stream_error_unsupported_version(__TopXMLNS, @@ -21956,9 +25810,12 @@ decode_stream_error_unsupported_version(__TopXMLNS, 'unsupported-version'. encode_stream_error_unsupported_version('unsupported-version', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsupported-version">>, _attrs, _els}. decode_stream_error_unsupported_stanza_type(__TopXMLNS, @@ -21969,9 +25826,12 @@ decode_stream_error_unsupported_stanza_type(__TopXMLNS, 'unsupported-stanza-type'. encode_stream_error_unsupported_stanza_type('unsupported-stanza-type', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsupported-stanza-type">>, _attrs, _els}. decode_stream_error_unsupported_encoding(__TopXMLNS, @@ -21981,9 +25841,12 @@ decode_stream_error_unsupported_encoding(__TopXMLNS, 'unsupported-encoding'. encode_stream_error_unsupported_encoding('unsupported-encoding', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsupported-encoding">>, _attrs, _els}. decode_stream_error_undefined_condition(__TopXMLNS, @@ -21993,9 +25856,12 @@ decode_stream_error_undefined_condition(__TopXMLNS, 'undefined-condition'. encode_stream_error_undefined_condition('undefined-condition', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"undefined-condition">>, _attrs, _els}. decode_stream_error_system_shutdown(__TopXMLNS, @@ -22005,9 +25871,12 @@ decode_stream_error_system_shutdown(__TopXMLNS, 'system-shutdown'. encode_stream_error_system_shutdown('system-shutdown', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"system-shutdown">>, _attrs, _els}. decode_stream_error_see_other_host(__TopXMLNS, @@ -22036,10 +25905,13 @@ decode_stream_error_see_other_host_els(__TopXMLNS, encode_stream_error_see_other_host({'see-other-host', Host}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = encode_stream_error_see_other_host_cdata(Host, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"see-other-host">>, _attrs, _els}. decode_stream_error_see_other_host_cdata(__TopXMLNS, @@ -22067,9 +25939,12 @@ decode_stream_error_restricted_xml(__TopXMLNS, 'restricted-xml'. encode_stream_error_restricted_xml('restricted-xml', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"restricted-xml">>, _attrs, _els}. decode_stream_error_resource_constraint(__TopXMLNS, @@ -22079,18 +25954,24 @@ decode_stream_error_resource_constraint(__TopXMLNS, 'resource-constraint'. encode_stream_error_resource_constraint('resource-constraint', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"resource-constraint">>, _attrs, _els}. decode_stream_error_reset(__TopXMLNS, __IgnoreEls, {xmlel, <<"reset">>, _attrs, _els}) -> reset. -encode_stream_error_reset(reset, _xmlns_attrs) -> +encode_stream_error_reset(reset, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"reset">>, _attrs, _els}. decode_stream_error_remote_connection_failed(__TopXMLNS, @@ -22101,9 +25982,12 @@ decode_stream_error_remote_connection_failed(__TopXMLNS, 'remote-connection-failed'. encode_stream_error_remote_connection_failed('remote-connection-failed', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"remote-connection-failed">>, _attrs, _els}. decode_stream_error_policy_violation(__TopXMLNS, @@ -22113,9 +25997,12 @@ decode_stream_error_policy_violation(__TopXMLNS, 'policy-violation'. encode_stream_error_policy_violation('policy-violation', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"policy-violation">>, _attrs, _els}. decode_stream_error_not_well_formed(__TopXMLNS, @@ -22125,9 +26012,12 @@ decode_stream_error_not_well_formed(__TopXMLNS, 'not-well-formed'. encode_stream_error_not_well_formed('not-well-formed', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-well-formed">>, _attrs, _els}. decode_stream_error_not_authorized(__TopXMLNS, @@ -22137,9 +26027,12 @@ decode_stream_error_not_authorized(__TopXMLNS, 'not-authorized'. encode_stream_error_not_authorized('not-authorized', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-authorized">>, _attrs, _els}. decode_stream_error_invalid_xml(__TopXMLNS, __IgnoreEls, @@ -22147,9 +26040,12 @@ decode_stream_error_invalid_xml(__TopXMLNS, __IgnoreEls, 'invalid-xml'. encode_stream_error_invalid_xml('invalid-xml', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-xml">>, _attrs, _els}. decode_stream_error_invalid_namespace(__TopXMLNS, @@ -22159,9 +26055,12 @@ decode_stream_error_invalid_namespace(__TopXMLNS, 'invalid-namespace'. encode_stream_error_invalid_namespace('invalid-namespace', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-namespace">>, _attrs, _els}. decode_stream_error_invalid_id(__TopXMLNS, __IgnoreEls, @@ -22169,9 +26068,12 @@ decode_stream_error_invalid_id(__TopXMLNS, __IgnoreEls, 'invalid-id'. encode_stream_error_invalid_id('invalid-id', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-id">>, _attrs, _els}. decode_stream_error_invalid_from(__TopXMLNS, @@ -22180,9 +26082,12 @@ decode_stream_error_invalid_from(__TopXMLNS, 'invalid-from'. encode_stream_error_invalid_from('invalid-from', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-from">>, _attrs, _els}. decode_stream_error_internal_server_error(__TopXMLNS, @@ -22192,9 +26097,12 @@ decode_stream_error_internal_server_error(__TopXMLNS, 'internal-server-error'. encode_stream_error_internal_server_error('internal-server-error', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"internal-server-error">>, _attrs, _els}. decode_stream_error_improper_addressing(__TopXMLNS, @@ -22204,9 +26112,12 @@ decode_stream_error_improper_addressing(__TopXMLNS, 'improper-addressing'. encode_stream_error_improper_addressing('improper-addressing', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"improper-addressing">>, _attrs, _els}. decode_stream_error_host_unknown(__TopXMLNS, @@ -22215,9 +26126,12 @@ decode_stream_error_host_unknown(__TopXMLNS, 'host-unknown'. encode_stream_error_host_unknown('host-unknown', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"host-unknown">>, _attrs, _els}. decode_stream_error_host_gone(__TopXMLNS, __IgnoreEls, @@ -22225,9 +26139,12 @@ decode_stream_error_host_gone(__TopXMLNS, __IgnoreEls, 'host-gone'. encode_stream_error_host_gone('host-gone', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"host-gone">>, _attrs, _els}. decode_stream_error_connection_timeout(__TopXMLNS, @@ -22237,18 +26154,24 @@ decode_stream_error_connection_timeout(__TopXMLNS, 'connection-timeout'. encode_stream_error_connection_timeout('connection-timeout', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"connection-timeout">>, _attrs, _els}. decode_stream_error_conflict(__TopXMLNS, __IgnoreEls, {xmlel, <<"conflict">>, _attrs, _els}) -> conflict. -encode_stream_error_conflict(conflict, _xmlns_attrs) -> +encode_stream_error_conflict(conflict, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"conflict">>, _attrs, _els}. decode_stream_error_bad_namespace_prefix(__TopXMLNS, @@ -22258,9 +26181,12 @@ decode_stream_error_bad_namespace_prefix(__TopXMLNS, 'bad-namespace-prefix'. encode_stream_error_bad_namespace_prefix('bad-namespace-prefix', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"bad-namespace-prefix">>, _attrs, _els}. decode_stream_error_bad_format(__TopXMLNS, __IgnoreEls, @@ -22268,9 +26194,12 @@ decode_stream_error_bad_format(__TopXMLNS, __IgnoreEls, 'bad-format'. encode_stream_error_bad_format('bad-format', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"bad-format">>, _attrs, _els}. decode_stream_error_text(__TopXMLNS, __IgnoreEls, @@ -22306,10 +26235,14 @@ decode_stream_error_text_attrs(__TopXMLNS, [], Lang) -> Lang). encode_stream_error_text({text, Lang, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, + [], __TopXMLNS), _els = encode_stream_error_text_cdata(Data, []), _attrs = 'encode_stream_error_text_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"text">>, _attrs, _els}. 'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, @@ -22376,19 +26309,24 @@ decode_time_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, Tzo). -encode_time({time, Tzo, Utc}, _xmlns_attrs) -> +encode_time({time, Tzo, Utc}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, + [], __TopXMLNS), _els = lists:reverse('encode_time_$utc'(Utc, - 'encode_time_$tzo'(Tzo, []))), - _attrs = _xmlns_attrs, + __NewTopXMLNS, + 'encode_time_$tzo'(Tzo, + __NewTopXMLNS, + []))), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"time">>, _attrs, _els}. -'encode_time_$utc'(undefined, _acc) -> _acc; -'encode_time_$utc'(Utc, _acc) -> - [encode_time_utc(Utc, []) | _acc]. +'encode_time_$utc'(undefined, __TopXMLNS, _acc) -> _acc; +'encode_time_$utc'(Utc, __TopXMLNS, _acc) -> + [encode_time_utc(Utc, __TopXMLNS) | _acc]. -'encode_time_$tzo'(undefined, _acc) -> _acc; -'encode_time_$tzo'(Tzo, _acc) -> - [encode_time_tzo(Tzo, []) | _acc]. +'encode_time_$tzo'(undefined, __TopXMLNS, _acc) -> _acc; +'encode_time_$tzo'(Tzo, __TopXMLNS, _acc) -> + [encode_time_tzo(Tzo, __TopXMLNS) | _acc]. decode_time_tzo(__TopXMLNS, __IgnoreEls, {xmlel, <<"tzo">>, _attrs, _els}) -> @@ -22408,9 +26346,11 @@ decode_time_tzo_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_time_tzo_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_time_tzo(Cdata, _xmlns_attrs) -> +encode_time_tzo(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, + [], __TopXMLNS), _els = encode_time_tzo_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"tzo">>, _attrs, _els}. decode_time_tzo_cdata(__TopXMLNS, <<>>) -> undefined; @@ -22444,9 +26384,11 @@ decode_time_utc_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_time_utc_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_time_utc(Cdata, _xmlns_attrs) -> +encode_time_utc(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, + [], __TopXMLNS), _els = encode_time_utc_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"utc">>, _attrs, _els}. decode_time_utc_cdata(__TopXMLNS, <<>>) -> undefined; @@ -22466,9 +26408,11 @@ decode_ping(__TopXMLNS, __IgnoreEls, {xmlel, <<"ping">>, _attrs, _els}) -> {ping}. -encode_ping({ping}, _xmlns_attrs) -> +encode_ping({ping}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:ping">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ping">>, _attrs, _els}. decode_session(__TopXMLNS, __IgnoreEls, @@ -22503,24 +26447,32 @@ decode_session_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_session_els(__TopXMLNS, __IgnoreEls, _els, Optional). -encode_session({xmpp_session, Optional}, - _xmlns_attrs) -> +encode_session({xmpp_session, Optional}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-session">>, + [], __TopXMLNS), _els = - lists:reverse('encode_session_$optional'(Optional, [])), - _attrs = _xmlns_attrs, + lists:reverse('encode_session_$optional'(Optional, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"session">>, _attrs, _els}. -'encode_session_$optional'(false, _acc) -> _acc; -'encode_session_$optional'(Optional, _acc) -> - [encode_session_optional(Optional, []) | _acc]. +'encode_session_$optional'(false, __TopXMLNS, _acc) -> + _acc; +'encode_session_$optional'(Optional, __TopXMLNS, + _acc) -> + [encode_session_optional(Optional, __TopXMLNS) | _acc]. decode_session_optional(__TopXMLNS, __IgnoreEls, {xmlel, <<"optional">>, _attrs, _els}) -> true. -encode_session_optional(true, _xmlns_attrs) -> +encode_session_optional(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-session">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"optional">>, _attrs, _els}. decode_register(__TopXMLNS, __IgnoreEls, @@ -23159,14 +27111,14 @@ decode_register_els(__TopXMLNS, __IgnoreEls, Name, Username, Remove, Key, City, Nick, Url, Email, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, Last, First, Password, Registered, Date, Phone, State, Name, Username, Remove, Key, City, Nick, Url, Email, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, Xdata, Misc, Address, Instructions, Text, @@ -23188,119 +27140,171 @@ encode_register({register, Registered, Remove, Instructions, Username, Nick, Password, Name, First, Last, Email, Address, City, State, Zip, Phone, Url, Date, Misc, Text, Key, Xdata, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_register_$zip'(Zip, + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ + lists:reverse('encode_register_$zip'(Zip, __NewTopXMLNS, 'encode_register_$xdata'(Xdata, + __NewTopXMLNS, 'encode_register_$misc'(Misc, + __NewTopXMLNS, 'encode_register_$address'(Address, + __NewTopXMLNS, 'encode_register_$instructions'(Instructions, + __NewTopXMLNS, 'encode_register_$text'(Text, + __NewTopXMLNS, 'encode_register_$last'(Last, + __NewTopXMLNS, 'encode_register_$first'(First, + __NewTopXMLNS, 'encode_register_$password'(Password, + __NewTopXMLNS, 'encode_register_$registered'(Registered, + __NewTopXMLNS, 'encode_register_$date'(Date, + __NewTopXMLNS, 'encode_register_$phone'(Phone, + __NewTopXMLNS, 'encode_register_$state'(State, + __NewTopXMLNS, 'encode_register_$name'(Name, + __NewTopXMLNS, 'encode_register_$username'(Username, + __NewTopXMLNS, 'encode_register_$remove'(Remove, + __NewTopXMLNS, 'encode_register_$key'(Key, + __NewTopXMLNS, 'encode_register_$city'(City, + __NewTopXMLNS, 'encode_register_$nick'(Nick, + __NewTopXMLNS, 'encode_register_$url'(Url, + __NewTopXMLNS, 'encode_register_$email'(Email, + __NewTopXMLNS, [])))))))))))))))))))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_register_$zip'(undefined, _acc) -> _acc; -'encode_register_$zip'(Zip, _acc) -> - [encode_register_zip(Zip, []) | _acc]. +'encode_register_$zip'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$zip'(Zip, __TopXMLNS, _acc) -> + [encode_register_zip(Zip, __TopXMLNS) | _acc]. -'encode_register_$xdata'(undefined, _acc) -> _acc; -'encode_register_$xdata'(Xdata, _acc) -> - [encode_xdata(Xdata, - [{<<"xmlns">>, <<"jabber:x:data">>}]) - | _acc]. +'encode_register_$xdata'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$xdata'(Xdata, __TopXMLNS, _acc) -> + [encode_xdata(Xdata, __TopXMLNS) | _acc]. -'encode_register_$misc'(undefined, _acc) -> _acc; -'encode_register_$misc'(Misc, _acc) -> - [encode_register_misc(Misc, []) | _acc]. +'encode_register_$misc'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$misc'(Misc, __TopXMLNS, _acc) -> + [encode_register_misc(Misc, __TopXMLNS) | _acc]. -'encode_register_$address'(undefined, _acc) -> _acc; -'encode_register_$address'(Address, _acc) -> - [encode_register_address(Address, []) | _acc]. +'encode_register_$address'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_register_$address'(Address, __TopXMLNS, _acc) -> + [encode_register_address(Address, __TopXMLNS) | _acc]. -'encode_register_$instructions'(undefined, _acc) -> +'encode_register_$instructions'(undefined, __TopXMLNS, + _acc) -> _acc; -'encode_register_$instructions'(Instructions, _acc) -> - [encode_register_instructions(Instructions, []) | _acc]. +'encode_register_$instructions'(Instructions, + __TopXMLNS, _acc) -> + [encode_register_instructions(Instructions, __TopXMLNS) + | _acc]. -'encode_register_$text'(undefined, _acc) -> _acc; -'encode_register_$text'(Text, _acc) -> - [encode_register_text(Text, []) | _acc]. +'encode_register_$text'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$text'(Text, __TopXMLNS, _acc) -> + [encode_register_text(Text, __TopXMLNS) | _acc]. -'encode_register_$last'(undefined, _acc) -> _acc; -'encode_register_$last'(Last, _acc) -> - [encode_register_last(Last, []) | _acc]. +'encode_register_$last'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$last'(Last, __TopXMLNS, _acc) -> + [encode_register_last(Last, __TopXMLNS) | _acc]. -'encode_register_$first'(undefined, _acc) -> _acc; -'encode_register_$first'(First, _acc) -> - [encode_register_first(First, []) | _acc]. +'encode_register_$first'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$first'(First, __TopXMLNS, _acc) -> + [encode_register_first(First, __TopXMLNS) | _acc]. -'encode_register_$password'(undefined, _acc) -> _acc; -'encode_register_$password'(Password, _acc) -> - [encode_register_password(Password, []) | _acc]. +'encode_register_$password'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_register_$password'(Password, __TopXMLNS, + _acc) -> + [encode_register_password(Password, __TopXMLNS) | _acc]. -'encode_register_$registered'(false, _acc) -> _acc; -'encode_register_$registered'(Registered, _acc) -> - [encode_register_registered(Registered, []) | _acc]. +'encode_register_$registered'(false, __TopXMLNS, + _acc) -> + _acc; +'encode_register_$registered'(Registered, __TopXMLNS, + _acc) -> + [encode_register_registered(Registered, __TopXMLNS) + | _acc]. -'encode_register_$date'(undefined, _acc) -> _acc; -'encode_register_$date'(Date, _acc) -> - [encode_register_date(Date, []) | _acc]. +'encode_register_$date'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$date'(Date, __TopXMLNS, _acc) -> + [encode_register_date(Date, __TopXMLNS) | _acc]. -'encode_register_$phone'(undefined, _acc) -> _acc; -'encode_register_$phone'(Phone, _acc) -> - [encode_register_phone(Phone, []) | _acc]. +'encode_register_$phone'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$phone'(Phone, __TopXMLNS, _acc) -> + [encode_register_phone(Phone, __TopXMLNS) | _acc]. -'encode_register_$state'(undefined, _acc) -> _acc; -'encode_register_$state'(State, _acc) -> - [encode_register_state(State, []) | _acc]. +'encode_register_$state'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$state'(State, __TopXMLNS, _acc) -> + [encode_register_state(State, __TopXMLNS) | _acc]. -'encode_register_$name'(undefined, _acc) -> _acc; -'encode_register_$name'(Name, _acc) -> - [encode_register_name(Name, []) | _acc]. +'encode_register_$name'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$name'(Name, __TopXMLNS, _acc) -> + [encode_register_name(Name, __TopXMLNS) | _acc]. -'encode_register_$username'(undefined, _acc) -> _acc; -'encode_register_$username'(Username, _acc) -> - [encode_register_username(Username, []) | _acc]. +'encode_register_$username'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_register_$username'(Username, __TopXMLNS, + _acc) -> + [encode_register_username(Username, __TopXMLNS) | _acc]. -'encode_register_$remove'(false, _acc) -> _acc; -'encode_register_$remove'(Remove, _acc) -> - [encode_register_remove(Remove, []) | _acc]. +'encode_register_$remove'(false, __TopXMLNS, _acc) -> + _acc; +'encode_register_$remove'(Remove, __TopXMLNS, _acc) -> + [encode_register_remove(Remove, __TopXMLNS) | _acc]. -'encode_register_$key'(undefined, _acc) -> _acc; -'encode_register_$key'(Key, _acc) -> - [encode_register_key(Key, []) | _acc]. +'encode_register_$key'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$key'(Key, __TopXMLNS, _acc) -> + [encode_register_key(Key, __TopXMLNS) | _acc]. -'encode_register_$city'(undefined, _acc) -> _acc; -'encode_register_$city'(City, _acc) -> - [encode_register_city(City, []) | _acc]. +'encode_register_$city'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$city'(City, __TopXMLNS, _acc) -> + [encode_register_city(City, __TopXMLNS) | _acc]. -'encode_register_$nick'(undefined, _acc) -> _acc; -'encode_register_$nick'(Nick, _acc) -> - [encode_register_nick(Nick, []) | _acc]. +'encode_register_$nick'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$nick'(Nick, __TopXMLNS, _acc) -> + [encode_register_nick(Nick, __TopXMLNS) | _acc]. -'encode_register_$url'(undefined, _acc) -> _acc; -'encode_register_$url'(Url, _acc) -> - [encode_register_url(Url, []) | _acc]. +'encode_register_$url'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$url'(Url, __TopXMLNS, _acc) -> + [encode_register_url(Url, __TopXMLNS) | _acc]. -'encode_register_$email'(undefined, _acc) -> _acc; -'encode_register_$email'(Email, _acc) -> - [encode_register_email(Email, []) | _acc]. +'encode_register_$email'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_register_$email'(Email, __TopXMLNS, _acc) -> + [encode_register_email(Email, __TopXMLNS) | _acc]. decode_register_key(__TopXMLNS, __IgnoreEls, {xmlel, <<"key">>, _attrs, _els}) -> @@ -23320,9 +27324,12 @@ decode_register_key_els(__TopXMLNS, __IgnoreEls, decode_register_key_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_key(Cdata, _xmlns_attrs) -> +encode_register_key(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_key_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"key">>, _attrs, _els}. decode_register_key_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23350,9 +27357,12 @@ decode_register_text_els(__TopXMLNS, __IgnoreEls, decode_register_text_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_text(Cdata, _xmlns_attrs) -> +encode_register_text(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_text_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"text">>, _attrs, _els}. decode_register_text_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23380,9 +27390,12 @@ decode_register_misc_els(__TopXMLNS, __IgnoreEls, decode_register_misc_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_misc(Cdata, _xmlns_attrs) -> +encode_register_misc(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_misc_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"misc">>, _attrs, _els}. decode_register_misc_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23410,9 +27423,12 @@ decode_register_date_els(__TopXMLNS, __IgnoreEls, decode_register_date_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_date(Cdata, _xmlns_attrs) -> +encode_register_date(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_date_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"date">>, _attrs, _els}. decode_register_date_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23440,9 +27456,12 @@ decode_register_url_els(__TopXMLNS, __IgnoreEls, decode_register_url_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_url(Cdata, _xmlns_attrs) -> +encode_register_url(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_url_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"url">>, _attrs, _els}. decode_register_url_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23470,9 +27489,12 @@ decode_register_phone_els(__TopXMLNS, __IgnoreEls, decode_register_phone_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_phone(Cdata, _xmlns_attrs) -> +encode_register_phone(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_phone_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"phone">>, _attrs, _els}. decode_register_phone_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23500,9 +27522,12 @@ decode_register_zip_els(__TopXMLNS, __IgnoreEls, decode_register_zip_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_zip(Cdata, _xmlns_attrs) -> +encode_register_zip(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_zip_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"zip">>, _attrs, _els}. decode_register_zip_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23530,9 +27555,12 @@ decode_register_state_els(__TopXMLNS, __IgnoreEls, decode_register_state_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_state(Cdata, _xmlns_attrs) -> +encode_register_state(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_state_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"state">>, _attrs, _els}. decode_register_state_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23560,9 +27588,12 @@ decode_register_city_els(__TopXMLNS, __IgnoreEls, decode_register_city_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_city(Cdata, _xmlns_attrs) -> +encode_register_city(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_city_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"city">>, _attrs, _els}. decode_register_city_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23590,9 +27621,12 @@ decode_register_address_els(__TopXMLNS, __IgnoreEls, decode_register_address_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_address(Cdata, _xmlns_attrs) -> +encode_register_address(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_address_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"address">>, _attrs, _els}. decode_register_address_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23620,9 +27654,12 @@ decode_register_email_els(__TopXMLNS, __IgnoreEls, decode_register_email_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_email(Cdata, _xmlns_attrs) -> +encode_register_email(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_email_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"email">>, _attrs, _els}. decode_register_email_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23650,9 +27687,12 @@ decode_register_last_els(__TopXMLNS, __IgnoreEls, decode_register_last_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_last(Cdata, _xmlns_attrs) -> +encode_register_last(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_last_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"last">>, _attrs, _els}. decode_register_last_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23680,9 +27720,12 @@ decode_register_first_els(__TopXMLNS, __IgnoreEls, decode_register_first_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_first(Cdata, _xmlns_attrs) -> +encode_register_first(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_first_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"first">>, _attrs, _els}. decode_register_first_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23710,9 +27753,12 @@ decode_register_name_els(__TopXMLNS, __IgnoreEls, decode_register_name_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_name(Cdata, _xmlns_attrs) -> +encode_register_name(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_name_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"name">>, _attrs, _els}. decode_register_name_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23740,9 +27786,12 @@ decode_register_password_els(__TopXMLNS, __IgnoreEls, decode_register_password_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_password(Cdata, _xmlns_attrs) -> +encode_register_password(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_password_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"password">>, _attrs, _els}. decode_register_password_cdata(__TopXMLNS, <<>>) -> @@ -23772,9 +27821,12 @@ decode_register_nick_els(__TopXMLNS, __IgnoreEls, decode_register_nick_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_nick(Cdata, _xmlns_attrs) -> +encode_register_nick(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_nick_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"nick">>, _attrs, _els}. decode_register_nick_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -23802,9 +27854,12 @@ decode_register_username_els(__TopXMLNS, __IgnoreEls, decode_register_username_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_username(Cdata, _xmlns_attrs) -> +encode_register_username(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_username_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"username">>, _attrs, _els}. decode_register_username_cdata(__TopXMLNS, <<>>) -> @@ -23836,9 +27891,12 @@ decode_register_instructions_els(__TopXMLNS, decode_register_instructions_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_register_instructions(Cdata, _xmlns_attrs) -> +encode_register_instructions(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = encode_register_instructions_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"instructions">>, _attrs, _els}. decode_register_instructions_cdata(__TopXMLNS, <<>>) -> @@ -23854,18 +27912,24 @@ decode_register_remove(__TopXMLNS, __IgnoreEls, {xmlel, <<"remove">>, _attrs, _els}) -> true. -encode_register_remove(true, _xmlns_attrs) -> +encode_register_remove(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"remove">>, _attrs, _els}. decode_register_registered(__TopXMLNS, __IgnoreEls, {xmlel, <<"registered">>, _attrs, _els}) -> true. -encode_register_registered(true, _xmlns_attrs) -> +encode_register_registered(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:register">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"registered">>, _attrs, _els}. decode_feature_register(__TopXMLNS, __IgnoreEls, @@ -23873,9 +27937,12 @@ decode_feature_register(__TopXMLNS, __IgnoreEls, {feature_register}. encode_feature_register({feature_register}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/features/iq-register">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"register">>, _attrs, _els}. decode_caps(__TopXMLNS, __IgnoreEls, @@ -23917,13 +27984,17 @@ decode_caps_attrs(__TopXMLNS, [], Hash, Node, Exts, decode_caps_attr_ver(__TopXMLNS, Version)}. encode_caps({caps, Node, Version, Hash, Exts}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/caps">>, + [], __TopXMLNS), _els = [], _attrs = encode_caps_attr_ver(Version, encode_caps_attr_ext(Exts, encode_caps_attr_node(Node, encode_caps_attr_hash(Hash, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"c">>, _attrs, _els}. decode_caps_attr_hash(__TopXMLNS, undefined) -> <<>>; @@ -23964,27 +28035,33 @@ decode_p1_ack(__TopXMLNS, __IgnoreEls, {xmlel, <<"ack">>, _attrs, _els}) -> {p1_ack}. -encode_p1_ack({p1_ack}, _xmlns_attrs) -> +encode_p1_ack({p1_ack}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"p1:ack">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ack">>, _attrs, _els}. decode_p1_rebind(__TopXMLNS, __IgnoreEls, {xmlel, <<"rebind">>, _attrs, _els}) -> {p1_rebind}. -encode_p1_rebind({p1_rebind}, _xmlns_attrs) -> +encode_p1_rebind({p1_rebind}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"p1:rebind">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"rebind">>, _attrs, _els}. decode_p1_push(__TopXMLNS, __IgnoreEls, {xmlel, <<"push">>, _attrs, _els}) -> {p1_push}. -encode_p1_push({p1_push}, _xmlns_attrs) -> +encode_p1_push({p1_push}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"p1:push">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"push">>, _attrs, _els}. decode_stream_features(__TopXMLNS, __IgnoreEls, @@ -24002,10 +28079,12 @@ decode_stream_features_els(__TopXMLNS, __IgnoreEls, decode_stream_features_els(__TopXMLNS, __IgnoreEls, _els, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_stream_features_els(__TopXMLNS, __IgnoreEls, - _els, [decode(_el) | __Els]); + _els, + [decode(_el, __TopXMLNS, []) + | __Els]); false -> decode_stream_features_els(__TopXMLNS, __IgnoreEls, _els, __Els) @@ -24017,9 +28096,12 @@ decode_stream_features_els(__TopXMLNS, __IgnoreEls, _els, __Els). encode_stream_features({stream_features, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els], - _attrs = _xmlns_attrs, + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"stream:features">>, _attrs, _els}. decode_compression(__TopXMLNS, __IgnoreEls, @@ -24057,17 +28139,23 @@ decode_compression_els(__TopXMLNS, __IgnoreEls, Methods). encode_compression({compression, Methods}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/features/compress">>, + [], __TopXMLNS), _els = lists:reverse('encode_compression_$methods'(Methods, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"compression">>, _attrs, _els}. -'encode_compression_$methods'([], _acc) -> _acc; -'encode_compression_$methods'([Methods | _els], _acc) -> - 'encode_compression_$methods'(_els, - [encode_compression_method(Methods, []) +'encode_compression_$methods'([], __TopXMLNS, _acc) -> + _acc; +'encode_compression_$methods'([Methods | _els], + __TopXMLNS, _acc) -> + 'encode_compression_$methods'(_els, __TopXMLNS, + [encode_compression_method(Methods, + __TopXMLNS) | _acc]). decode_compression_method(__TopXMLNS, __IgnoreEls, @@ -24088,9 +28176,12 @@ decode_compression_method_els(__TopXMLNS, __IgnoreEls, decode_compression_method_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_compression_method(Cdata, _xmlns_attrs) -> +encode_compression_method(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/features/compress">>, + [], __TopXMLNS), _els = encode_compression_method_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"method">>, _attrs, _els}. decode_compression_method_cdata(__TopXMLNS, <<>>) -> @@ -24106,9 +28197,12 @@ decode_compressed(__TopXMLNS, __IgnoreEls, {xmlel, <<"compressed">>, _attrs, _els}) -> {compressed}. -encode_compressed({compressed}, _xmlns_attrs) -> +encode_compressed({compressed}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"compressed">>, _attrs, _els}. decode_compress(__TopXMLNS, __IgnoreEls, @@ -24145,16 +28239,22 @@ decode_compress_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_compress_els(__TopXMLNS, __IgnoreEls, _els, Methods). -encode_compress({compress, Methods}, _xmlns_attrs) -> +encode_compress({compress, Methods}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = lists:reverse('encode_compress_$methods'(Methods, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"compress">>, _attrs, _els}. -'encode_compress_$methods'([], _acc) -> _acc; -'encode_compress_$methods'([Methods | _els], _acc) -> - 'encode_compress_$methods'(_els, - [encode_compress_method(Methods, []) | _acc]). +'encode_compress_$methods'([], __TopXMLNS, _acc) -> + _acc; +'encode_compress_$methods'([Methods | _els], __TopXMLNS, + _acc) -> + 'encode_compress_$methods'(_els, __TopXMLNS, + [encode_compress_method(Methods, __TopXMLNS) + | _acc]). decode_compress_method(__TopXMLNS, __IgnoreEls, {xmlel, <<"method">>, _attrs, _els}) -> @@ -24174,9 +28274,12 @@ decode_compress_method_els(__TopXMLNS, __IgnoreEls, decode_compress_method_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_compress_method(Cdata, _xmlns_attrs) -> +encode_compress_method(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = encode_compress_method_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"method">>, _attrs, _els}. decode_compress_method_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -24270,29 +28373,36 @@ decode_compress_failure_els(__TopXMLNS, __IgnoreEls, _els, Reason). encode_compress_failure({compress_failure, Reason}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = lists:reverse('encode_compress_failure_$reason'(Reason, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"failure">>, _attrs, _els}. -'encode_compress_failure_$reason'(undefined, _acc) -> +'encode_compress_failure_$reason'(undefined, __TopXMLNS, + _acc) -> _acc; 'encode_compress_failure_$reason'('setup-failed' = Reason, - _acc) -> - [encode_compress_failure_setup_failed(Reason, []) + __TopXMLNS, _acc) -> + [encode_compress_failure_setup_failed(Reason, + __TopXMLNS) | _acc]; 'encode_compress_failure_$reason'('processing-failed' = Reason, - _acc) -> - [encode_compress_failure_processing_failed(Reason, []) + __TopXMLNS, _acc) -> + [encode_compress_failure_processing_failed(Reason, + __TopXMLNS) | _acc]; 'encode_compress_failure_$reason'('unsupported-method' = Reason, - _acc) -> - [encode_compress_failure_unsupported_method(Reason, []) + __TopXMLNS, _acc) -> + [encode_compress_failure_unsupported_method(Reason, + __TopXMLNS) | _acc]. decode_compress_failure_unsupported_method(__TopXMLNS, @@ -24302,9 +28412,12 @@ decode_compress_failure_unsupported_method(__TopXMLNS, 'unsupported-method'. encode_compress_failure_unsupported_method('unsupported-method', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unsupported-method">>, _attrs, _els}. decode_compress_failure_processing_failed(__TopXMLNS, @@ -24314,9 +28427,12 @@ decode_compress_failure_processing_failed(__TopXMLNS, 'processing-failed'. encode_compress_failure_processing_failed('processing-failed', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"processing-failed">>, _attrs, _els}. decode_compress_failure_setup_failed(__TopXMLNS, @@ -24326,9 +28442,12 @@ decode_compress_failure_setup_failed(__TopXMLNS, 'setup-failed'. encode_compress_failure_setup_failed('setup-failed', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"setup-failed">>, _attrs, _els}. decode_starttls_failure(__TopXMLNS, __IgnoreEls, @@ -24336,9 +28455,12 @@ decode_starttls_failure(__TopXMLNS, __IgnoreEls, {starttls_failure}. encode_starttls_failure({starttls_failure}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"failure">>, _attrs, _els}. decode_starttls_proceed(__TopXMLNS, __IgnoreEls, @@ -24346,9 +28468,12 @@ decode_starttls_proceed(__TopXMLNS, __IgnoreEls, {starttls_proceed}. encode_starttls_proceed({starttls_proceed}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"proceed">>, _attrs, _els}. decode_starttls(__TopXMLNS, __IgnoreEls, @@ -24383,24 +28508,32 @@ decode_starttls_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, Required). -encode_starttls({starttls, Required}, _xmlns_attrs) -> +encode_starttls({starttls, Required}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + [], __TopXMLNS), _els = lists:reverse('encode_starttls_$required'(Required, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"starttls">>, _attrs, _els}. -'encode_starttls_$required'(false, _acc) -> _acc; -'encode_starttls_$required'(Required, _acc) -> - [encode_starttls_required(Required, []) | _acc]. +'encode_starttls_$required'(false, __TopXMLNS, _acc) -> + _acc; +'encode_starttls_$required'(Required, __TopXMLNS, + _acc) -> + [encode_starttls_required(Required, __TopXMLNS) | _acc]. decode_starttls_required(__TopXMLNS, __IgnoreEls, {xmlel, <<"required">>, _attrs, _els}) -> true. -encode_starttls_required(true, _xmlns_attrs) -> +encode_starttls_required(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"required">>, _attrs, _els}. decode_sasl_mechanisms(__TopXMLNS, __IgnoreEls, @@ -24440,16 +28573,23 @@ decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, _els, List). encode_sasl_mechanisms({sasl_mechanisms, List}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = - lists:reverse('encode_sasl_mechanisms_$list'(List, [])), - _attrs = _xmlns_attrs, + lists:reverse('encode_sasl_mechanisms_$list'(List, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"mechanisms">>, _attrs, _els}. -'encode_sasl_mechanisms_$list'([], _acc) -> _acc; -'encode_sasl_mechanisms_$list'([List | _els], _acc) -> - 'encode_sasl_mechanisms_$list'(_els, - [encode_sasl_mechanism(List, []) | _acc]). +'encode_sasl_mechanisms_$list'([], __TopXMLNS, _acc) -> + _acc; +'encode_sasl_mechanisms_$list'([List | _els], + __TopXMLNS, _acc) -> + 'encode_sasl_mechanisms_$list'(_els, __TopXMLNS, + [encode_sasl_mechanism(List, __TopXMLNS) + | _acc]). decode_sasl_mechanism(__TopXMLNS, __IgnoreEls, {xmlel, <<"mechanism">>, _attrs, _els}) -> @@ -24469,9 +28609,12 @@ decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_sasl_mechanism(Cdata, _xmlns_attrs) -> +encode_sasl_mechanism(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_mechanism_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"mechanism">>, _attrs, _els}. decode_sasl_mechanism_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -24791,71 +28934,93 @@ decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, Text, Reason). encode_sasl_failure({sasl_failure, Reason, Text}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = lists:reverse('encode_sasl_failure_$text'(Text, + __NewTopXMLNS, 'encode_sasl_failure_$reason'(Reason, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"failure">>, _attrs, _els}. -'encode_sasl_failure_$text'([], _acc) -> _acc; -'encode_sasl_failure_$text'([Text | _els], _acc) -> - 'encode_sasl_failure_$text'(_els, - [encode_sasl_failure_text(Text, []) | _acc]). +'encode_sasl_failure_$text'([], __TopXMLNS, _acc) -> + _acc; +'encode_sasl_failure_$text'([Text | _els], __TopXMLNS, + _acc) -> + 'encode_sasl_failure_$text'(_els, __TopXMLNS, + [encode_sasl_failure_text(Text, __TopXMLNS) + | _acc]). -'encode_sasl_failure_$reason'(undefined, _acc) -> _acc; -'encode_sasl_failure_$reason'(aborted = Reason, _acc) -> - [encode_sasl_failure_aborted(Reason, []) | _acc]; +'encode_sasl_failure_$reason'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_sasl_failure_$reason'(aborted = Reason, + __TopXMLNS, _acc) -> + [encode_sasl_failure_aborted(Reason, __TopXMLNS) + | _acc]; 'encode_sasl_failure_$reason'('account-disabled' = Reason, - _acc) -> - [encode_sasl_failure_account_disabled(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_account_disabled(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('credentials-expired' = Reason, - _acc) -> - [encode_sasl_failure_credentials_expired(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_credentials_expired(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('encryption-required' = Reason, - _acc) -> - [encode_sasl_failure_encryption_required(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_encryption_required(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('incorrect-encoding' = Reason, - _acc) -> - [encode_sasl_failure_incorrect_encoding(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_incorrect_encoding(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('invalid-authzid' = Reason, - _acc) -> - [encode_sasl_failure_invalid_authzid(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_invalid_authzid(Reason, __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('invalid-mechanism' = Reason, - _acc) -> - [encode_sasl_failure_invalid_mechanism(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_invalid_mechanism(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('malformed-request' = Reason, - _acc) -> - [encode_sasl_failure_malformed_request(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_malformed_request(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('mechanism-too-weak' = Reason, - _acc) -> - [encode_sasl_failure_mechanism_too_weak(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_mechanism_too_weak(Reason, + __TopXMLNS) | _acc]; 'encode_sasl_failure_$reason'('not-authorized' = Reason, - _acc) -> - [encode_sasl_failure_not_authorized(Reason, []) | _acc]; + __TopXMLNS, _acc) -> + [encode_sasl_failure_not_authorized(Reason, __TopXMLNS) + | _acc]; 'encode_sasl_failure_$reason'('bad-protocol' = Reason, - _acc) -> - [encode_sasl_failure_bad_protocol(Reason, []) | _acc]; + __TopXMLNS, _acc) -> + [encode_sasl_failure_bad_protocol(Reason, __TopXMLNS) + | _acc]; 'encode_sasl_failure_$reason'('temporary-auth-failure' = Reason, - _acc) -> - [encode_sasl_failure_temporary_auth_failure(Reason, []) + __TopXMLNS, _acc) -> + [encode_sasl_failure_temporary_auth_failure(Reason, + __TopXMLNS) | _acc]. decode_sasl_failure_temporary_auth_failure(__TopXMLNS, @@ -24865,9 +29030,12 @@ decode_sasl_failure_temporary_auth_failure(__TopXMLNS, 'temporary-auth-failure'. encode_sasl_failure_temporary_auth_failure('temporary-auth-failure', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"temporary-auth-failure">>, _attrs, _els}. decode_sasl_failure_bad_protocol(__TopXMLNS, @@ -24876,9 +29044,12 @@ decode_sasl_failure_bad_protocol(__TopXMLNS, 'bad-protocol'. encode_sasl_failure_bad_protocol('bad-protocol', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"bad-protocol">>, _attrs, _els}. decode_sasl_failure_not_authorized(__TopXMLNS, @@ -24888,9 +29059,12 @@ decode_sasl_failure_not_authorized(__TopXMLNS, 'not-authorized'. encode_sasl_failure_not_authorized('not-authorized', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-authorized">>, _attrs, _els}. decode_sasl_failure_mechanism_too_weak(__TopXMLNS, @@ -24900,9 +29074,12 @@ decode_sasl_failure_mechanism_too_weak(__TopXMLNS, 'mechanism-too-weak'. encode_sasl_failure_mechanism_too_weak('mechanism-too-weak', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"mechanism-too-weak">>, _attrs, _els}. decode_sasl_failure_malformed_request(__TopXMLNS, @@ -24912,9 +29089,12 @@ decode_sasl_failure_malformed_request(__TopXMLNS, 'malformed-request'. encode_sasl_failure_malformed_request('malformed-request', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"malformed-request">>, _attrs, _els}. decode_sasl_failure_invalid_mechanism(__TopXMLNS, @@ -24924,9 +29104,12 @@ decode_sasl_failure_invalid_mechanism(__TopXMLNS, 'invalid-mechanism'. encode_sasl_failure_invalid_mechanism('invalid-mechanism', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-mechanism">>, _attrs, _els}. decode_sasl_failure_invalid_authzid(__TopXMLNS, @@ -24936,9 +29119,12 @@ decode_sasl_failure_invalid_authzid(__TopXMLNS, 'invalid-authzid'. encode_sasl_failure_invalid_authzid('invalid-authzid', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"invalid-authzid">>, _attrs, _els}. decode_sasl_failure_incorrect_encoding(__TopXMLNS, @@ -24948,9 +29134,12 @@ decode_sasl_failure_incorrect_encoding(__TopXMLNS, 'incorrect-encoding'. encode_sasl_failure_incorrect_encoding('incorrect-encoding', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"incorrect-encoding">>, _attrs, _els}. decode_sasl_failure_encryption_required(__TopXMLNS, @@ -24960,9 +29149,12 @@ decode_sasl_failure_encryption_required(__TopXMLNS, 'encryption-required'. encode_sasl_failure_encryption_required('encryption-required', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"encryption-required">>, _attrs, _els}. decode_sasl_failure_credentials_expired(__TopXMLNS, @@ -24972,9 +29164,12 @@ decode_sasl_failure_credentials_expired(__TopXMLNS, 'credentials-expired'. encode_sasl_failure_credentials_expired('credentials-expired', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"credentials-expired">>, _attrs, _els}. decode_sasl_failure_account_disabled(__TopXMLNS, @@ -24984,18 +29179,24 @@ decode_sasl_failure_account_disabled(__TopXMLNS, 'account-disabled'. encode_sasl_failure_account_disabled('account-disabled', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"account-disabled">>, _attrs, _els}. decode_sasl_failure_aborted(__TopXMLNS, __IgnoreEls, {xmlel, <<"aborted">>, _attrs, _els}) -> aborted. -encode_sasl_failure_aborted(aborted, _xmlns_attrs) -> +encode_sasl_failure_aborted(aborted, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"aborted">>, _attrs, _els}. decode_sasl_failure_text(__TopXMLNS, __IgnoreEls, @@ -25031,10 +29232,14 @@ decode_sasl_failure_text_attrs(__TopXMLNS, [], Lang) -> Lang). encode_sasl_failure_text({text, Lang, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_failure_text_cdata(Data, []), _attrs = 'encode_sasl_failure_text_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"text">>, _attrs, _els}. 'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, @@ -25076,10 +29281,12 @@ decode_sasl_success_els(__TopXMLNS, __IgnoreEls, decode_sasl_success_els(__TopXMLNS, __IgnoreEls, _els, Text). -encode_sasl_success({sasl_success, Text}, - _xmlns_attrs) -> +encode_sasl_success({sasl_success, Text}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_success_cdata(Text, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"success">>, _attrs, _els}. decode_sasl_success_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -25114,9 +29321,12 @@ decode_sasl_response_els(__TopXMLNS, __IgnoreEls, Text). encode_sasl_response({sasl_response, Text}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_response_cdata(Text, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"response">>, _attrs, _els}. decode_sasl_response_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -25151,9 +29361,12 @@ decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, Text). encode_sasl_challenge({sasl_challenge, Text}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_challenge_cdata(Text, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"challenge">>, _attrs, _els}. decode_sasl_challenge_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -25173,9 +29386,12 @@ decode_sasl_abort(__TopXMLNS, __IgnoreEls, {xmlel, <<"abort">>, _attrs, _els}) -> {sasl_abort}. -encode_sasl_abort({sasl_abort}, _xmlns_attrs) -> +encode_sasl_abort({sasl_abort}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"abort">>, _attrs, _els}. decode_sasl_auth(__TopXMLNS, __IgnoreEls, @@ -25208,10 +29424,14 @@ decode_sasl_auth_attrs(__TopXMLNS, [], Mechanism) -> decode_sasl_auth_attr_mechanism(__TopXMLNS, Mechanism). encode_sasl_auth({sasl_auth, Mechanism, Text}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, + [], __TopXMLNS), _els = encode_sasl_auth_cdata(Text, []), _attrs = encode_sasl_auth_attr_mechanism(Mechanism, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"auth">>, _attrs, _els}. decode_sasl_auth_attr_mechanism(__TopXMLNS, @@ -25331,31 +29551,52 @@ decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, encode_legacy_auth({legacy_auth, Username, Password, Digest, Resource}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, + [], __TopXMLNS), _els = lists:reverse('encode_legacy_auth_$digest'(Digest, + __NewTopXMLNS, 'encode_legacy_auth_$password'(Password, + __NewTopXMLNS, 'encode_legacy_auth_$resource'(Resource, + __NewTopXMLNS, 'encode_legacy_auth_$username'(Username, + __NewTopXMLNS, []))))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_legacy_auth_$digest'(undefined, _acc) -> _acc; -'encode_legacy_auth_$digest'(Digest, _acc) -> - [encode_legacy_auth_digest(Digest, []) | _acc]. +'encode_legacy_auth_$digest'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_legacy_auth_$digest'(Digest, __TopXMLNS, + _acc) -> + [encode_legacy_auth_digest(Digest, __TopXMLNS) | _acc]. -'encode_legacy_auth_$password'(undefined, _acc) -> _acc; -'encode_legacy_auth_$password'(Password, _acc) -> - [encode_legacy_auth_password(Password, []) | _acc]. +'encode_legacy_auth_$password'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_legacy_auth_$password'(Password, __TopXMLNS, + _acc) -> + [encode_legacy_auth_password(Password, __TopXMLNS) + | _acc]. -'encode_legacy_auth_$resource'(undefined, _acc) -> _acc; -'encode_legacy_auth_$resource'(Resource, _acc) -> - [encode_legacy_auth_resource(Resource, []) | _acc]. +'encode_legacy_auth_$resource'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_legacy_auth_$resource'(Resource, __TopXMLNS, + _acc) -> + [encode_legacy_auth_resource(Resource, __TopXMLNS) + | _acc]. -'encode_legacy_auth_$username'(undefined, _acc) -> _acc; -'encode_legacy_auth_$username'(Username, _acc) -> - [encode_legacy_auth_username(Username, []) | _acc]. +'encode_legacy_auth_$username'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_legacy_auth_$username'(Username, __TopXMLNS, + _acc) -> + [encode_legacy_auth_username(Username, __TopXMLNS) + | _acc]. decode_legacy_auth_resource(__TopXMLNS, __IgnoreEls, {xmlel, <<"resource">>, _attrs, _els}) -> @@ -25375,9 +29616,11 @@ decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_legacy_auth_resource(Cdata, _xmlns_attrs) -> +encode_legacy_auth_resource(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, + [], __TopXMLNS), _els = encode_legacy_auth_resource_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"resource">>, _attrs, _els}. decode_legacy_auth_resource_cdata(__TopXMLNS, <<>>) -> @@ -25407,9 +29650,11 @@ decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_legacy_auth_digest(Cdata, _xmlns_attrs) -> +encode_legacy_auth_digest(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, + [], __TopXMLNS), _els = encode_legacy_auth_digest_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"digest">>, _attrs, _els}. decode_legacy_auth_digest_cdata(__TopXMLNS, <<>>) -> @@ -25439,9 +29684,11 @@ decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_legacy_auth_password(Cdata, _xmlns_attrs) -> +encode_legacy_auth_password(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, + [], __TopXMLNS), _els = encode_legacy_auth_password_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"password">>, _attrs, _els}. decode_legacy_auth_password_cdata(__TopXMLNS, <<>>) -> @@ -25471,9 +29718,11 @@ decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_legacy_auth_username(Cdata, _xmlns_attrs) -> +encode_legacy_auth_username(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, + [], __TopXMLNS), _els = encode_legacy_auth_username_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"username">>, _attrs, _els}. decode_legacy_auth_username_cdata(__TopXMLNS, <<>>) -> @@ -25535,20 +29784,26 @@ decode_bind_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, Resource). -encode_bind({bind, Jid, Resource}, _xmlns_attrs) -> +encode_bind({bind, Jid, Resource}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + [], __TopXMLNS), _els = lists:reverse('encode_bind_$jid'(Jid, + __NewTopXMLNS, 'encode_bind_$resource'(Resource, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"bind">>, _attrs, _els}. -'encode_bind_$jid'(undefined, _acc) -> _acc; -'encode_bind_$jid'(Jid, _acc) -> - [encode_bind_jid(Jid, []) | _acc]. +'encode_bind_$jid'(undefined, __TopXMLNS, _acc) -> _acc; +'encode_bind_$jid'(Jid, __TopXMLNS, _acc) -> + [encode_bind_jid(Jid, __TopXMLNS) | _acc]. -'encode_bind_$resource'(undefined, _acc) -> _acc; -'encode_bind_$resource'(Resource, _acc) -> - [encode_bind_resource(Resource, []) | _acc]. +'encode_bind_$resource'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_bind_$resource'(Resource, __TopXMLNS, _acc) -> + [encode_bind_resource(Resource, __TopXMLNS) | _acc]. decode_bind_resource(__TopXMLNS, __IgnoreEls, {xmlel, <<"resource">>, _attrs, _els}) -> @@ -25568,9 +29823,12 @@ decode_bind_resource_els(__TopXMLNS, __IgnoreEls, decode_bind_resource_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_bind_resource(Cdata, _xmlns_attrs) -> +encode_bind_resource(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + [], __TopXMLNS), _els = encode_bind_resource_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"resource">>, _attrs, _els}. decode_bind_resource_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -25604,9 +29862,12 @@ decode_bind_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_bind_jid_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_bind_jid(Cdata, _xmlns_attrs) -> +encode_bind_jid(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, + [], __TopXMLNS), _els = encode_bind_jid_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"jid">>, _attrs, _els}. decode_bind_jid_cdata(__TopXMLNS, <<>>) -> undefined; @@ -25968,10 +30229,11 @@ decode_error_els(__TopXMLNS, __IgnoreEls, decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, Reason, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, [decode(_el) | __Els]); + Reason, + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, Reason, __Els) @@ -26002,158 +30264,118 @@ decode_error_attrs(__TopXMLNS, [], Type, Code, By) -> encode_error({stanza_error, Type, Code, By, Reason, Text, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_error_$text'(Text, + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ + lists:reverse('encode_error_$text'(Text, __NewTopXMLNS, 'encode_error_$reason'(Reason, + __NewTopXMLNS, []))), _attrs = encode_error_attr_by(By, encode_error_attr_code(Code, encode_error_attr_type(Type, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"error">>, _attrs, _els}. -'encode_error_$text'(undefined, _acc) -> _acc; -'encode_error_$text'(Text, _acc) -> - [encode_error_text(Text, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]. +'encode_error_$text'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_error_$text'(Text, __TopXMLNS, _acc) -> + [encode_error_text(Text, __TopXMLNS) | _acc]. -'encode_error_$reason'(undefined, _acc) -> _acc; -'encode_error_$reason'('bad-request' = Reason, _acc) -> - [encode_error_bad_request(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_error_$reason'(conflict = Reason, _acc) -> - [encode_error_conflict(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; +'encode_error_$reason'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_error_$reason'('bad-request' = Reason, + __TopXMLNS, _acc) -> + [encode_error_bad_request(Reason, __TopXMLNS) | _acc]; +'encode_error_$reason'(conflict = Reason, __TopXMLNS, + _acc) -> + [encode_error_conflict(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('feature-not-implemented' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_error_feature_not_implemented(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS) | _acc]; -'encode_error_$reason'(forbidden = Reason, _acc) -> - [encode_error_forbidden(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_error_$reason'({gone, _} = Reason, _acc) -> - [encode_error_gone(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_error_$reason'('internal-server-error' = Reason, +'encode_error_$reason'(forbidden = Reason, __TopXMLNS, + _acc) -> + [encode_error_forbidden(Reason, __TopXMLNS) | _acc]; +'encode_error_$reason'({gone, _} = Reason, __TopXMLNS, _acc) -> - [encode_error_internal_server_error(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + [encode_error_gone(Reason, __TopXMLNS) | _acc]; +'encode_error_$reason'('internal-server-error' = Reason, + __TopXMLNS, _acc) -> + [encode_error_internal_server_error(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('item-not-found' = Reason, - _acc) -> - [encode_error_item_not_found(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_item_not_found(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('jid-malformed' = Reason, - _acc) -> - [encode_error_jid_malformed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; + __TopXMLNS, _acc) -> + [encode_error_jid_malformed(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('not-acceptable' = Reason, - _acc) -> - [encode_error_not_acceptable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_error_$reason'('not-allowed' = Reason, _acc) -> - [encode_error_not_allowed(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_not_acceptable(Reason, __TopXMLNS) | _acc]; +'encode_error_$reason'('not-allowed' = Reason, + __TopXMLNS, _acc) -> + [encode_error_not_allowed(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('not-authorized' = Reason, - _acc) -> - [encode_error_not_authorized(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_not_authorized(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('payment-required' = Reason, - _acc) -> - [encode_error_payment_required(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_payment_required(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('policy-violation' = Reason, - _acc) -> - [encode_error_policy_violation(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_policy_violation(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('recipient-unavailable' = Reason, - _acc) -> - [encode_error_recipient_unavailable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) - | _acc]; -'encode_error_$reason'({redirect, _} = Reason, _acc) -> - [encode_error_redirect(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_recipient_unavailable(Reason, __TopXMLNS) | _acc]; +'encode_error_$reason'({redirect, _} = Reason, + __TopXMLNS, _acc) -> + [encode_error_redirect(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('registration-required' = Reason, - _acc) -> - [encode_error_registration_required(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_registration_required(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('remote-server-not-found' = Reason, - _acc) -> + __TopXMLNS, _acc) -> [encode_error_remote_server_not_found(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS) | _acc]; 'encode_error_$reason'('remote-server-timeout' = Reason, - _acc) -> - [encode_error_remote_server_timeout(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_remote_server_timeout(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('resource-constraint' = Reason, - _acc) -> - [encode_error_resource_constraint(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_resource_constraint(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('service-unavailable' = Reason, - _acc) -> - [encode_error_service_unavailable(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_service_unavailable(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('subscription-required' = Reason, - _acc) -> - [encode_error_subscription_required(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_subscription_required(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('undefined-condition' = Reason, - _acc) -> - [encode_error_undefined_condition(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_undefined_condition(Reason, __TopXMLNS) | _acc]; 'encode_error_$reason'('unexpected-request' = Reason, - _acc) -> - [encode_error_unexpected_request(Reason, - [{<<"xmlns">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]) + __TopXMLNS, _acc) -> + [encode_error_unexpected_request(Reason, __TopXMLNS) | _acc]. decode_error_attr_type(__TopXMLNS, undefined) -> @@ -26222,10 +30444,14 @@ decode_error_text_attrs(__TopXMLNS, [_ | _attrs], decode_error_text_attrs(__TopXMLNS, [], Lang) -> 'decode_error_text_attr_xml:lang'(__TopXMLNS, Lang). -encode_error_text({text, Lang, Data}, _xmlns_attrs) -> +encode_error_text({text, Lang, Data}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = encode_error_text_cdata(Data, []), _attrs = 'encode_error_text_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"text">>, _attrs, _els}. 'decode_error_text_attr_xml:lang'(__TopXMLNS, @@ -26251,9 +30477,12 @@ decode_error_unexpected_request(__TopXMLNS, __IgnoreEls, 'unexpected-request'. encode_error_unexpected_request('unexpected-request', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unexpected-request">>, _attrs, _els}. decode_error_undefined_condition(__TopXMLNS, @@ -26263,9 +30492,12 @@ decode_error_undefined_condition(__TopXMLNS, 'undefined-condition'. encode_error_undefined_condition('undefined-condition', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"undefined-condition">>, _attrs, _els}. decode_error_subscription_required(__TopXMLNS, @@ -26275,9 +30507,12 @@ decode_error_subscription_required(__TopXMLNS, 'subscription-required'. encode_error_subscription_required('subscription-required', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"subscription-required">>, _attrs, _els}. decode_error_service_unavailable(__TopXMLNS, @@ -26287,9 +30522,12 @@ decode_error_service_unavailable(__TopXMLNS, 'service-unavailable'. encode_error_service_unavailable('service-unavailable', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"service-unavailable">>, _attrs, _els}. decode_error_resource_constraint(__TopXMLNS, @@ -26299,9 +30537,12 @@ decode_error_resource_constraint(__TopXMLNS, 'resource-constraint'. encode_error_resource_constraint('resource-constraint', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"resource-constraint">>, _attrs, _els}. decode_error_remote_server_timeout(__TopXMLNS, @@ -26311,9 +30552,12 @@ decode_error_remote_server_timeout(__TopXMLNS, 'remote-server-timeout'. encode_error_remote_server_timeout('remote-server-timeout', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"remote-server-timeout">>, _attrs, _els}. decode_error_remote_server_not_found(__TopXMLNS, @@ -26323,9 +30567,12 @@ decode_error_remote_server_not_found(__TopXMLNS, 'remote-server-not-found'. encode_error_remote_server_not_found('remote-server-not-found', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"remote-server-not-found">>, _attrs, _els}. decode_error_registration_required(__TopXMLNS, @@ -26335,9 +30582,12 @@ decode_error_registration_required(__TopXMLNS, 'registration-required'. encode_error_registration_required('registration-required', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"registration-required">>, _attrs, _els}. decode_error_redirect(__TopXMLNS, __IgnoreEls, @@ -26358,9 +30608,12 @@ decode_error_redirect_els(__TopXMLNS, __IgnoreEls, decode_error_redirect_els(__TopXMLNS, __IgnoreEls, _els, Uri). -encode_error_redirect({redirect, Uri}, _xmlns_attrs) -> +encode_error_redirect({redirect, Uri}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = encode_error_redirect_cdata(Uri, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"redirect">>, _attrs, _els}. decode_error_redirect_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -26377,9 +30630,12 @@ decode_error_recipient_unavailable(__TopXMLNS, 'recipient-unavailable'. encode_error_recipient_unavailable('recipient-unavailable', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"recipient-unavailable">>, _attrs, _els}. decode_error_policy_violation(__TopXMLNS, __IgnoreEls, @@ -26387,9 +30643,12 @@ decode_error_policy_violation(__TopXMLNS, __IgnoreEls, 'policy-violation'. encode_error_policy_violation('policy-violation', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"policy-violation">>, _attrs, _els}. decode_error_payment_required(__TopXMLNS, __IgnoreEls, @@ -26397,9 +30656,12 @@ decode_error_payment_required(__TopXMLNS, __IgnoreEls, 'payment-required'. encode_error_payment_required('payment-required', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"payment-required">>, _attrs, _els}. decode_error_not_authorized(__TopXMLNS, __IgnoreEls, @@ -26407,18 +30669,24 @@ decode_error_not_authorized(__TopXMLNS, __IgnoreEls, 'not-authorized'. encode_error_not_authorized('not-authorized', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-authorized">>, _attrs, _els}. decode_error_not_allowed(__TopXMLNS, __IgnoreEls, {xmlel, <<"not-allowed">>, _attrs, _els}) -> 'not-allowed'. -encode_error_not_allowed('not-allowed', _xmlns_attrs) -> +encode_error_not_allowed('not-allowed', __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-allowed">>, _attrs, _els}. decode_error_not_acceptable(__TopXMLNS, __IgnoreEls, @@ -26426,9 +30694,12 @@ decode_error_not_acceptable(__TopXMLNS, __IgnoreEls, 'not-acceptable'. encode_error_not_acceptable('not-acceptable', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"not-acceptable">>, _attrs, _els}. decode_error_jid_malformed(__TopXMLNS, __IgnoreEls, @@ -26436,9 +30707,12 @@ decode_error_jid_malformed(__TopXMLNS, __IgnoreEls, 'jid-malformed'. encode_error_jid_malformed('jid-malformed', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"jid-malformed">>, _attrs, _els}. decode_error_item_not_found(__TopXMLNS, __IgnoreEls, @@ -26446,9 +30720,12 @@ decode_error_item_not_found(__TopXMLNS, __IgnoreEls, 'item-not-found'. encode_error_item_not_found('item-not-found', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"item-not-found">>, _attrs, _els}. decode_error_internal_server_error(__TopXMLNS, @@ -26458,9 +30735,12 @@ decode_error_internal_server_error(__TopXMLNS, 'internal-server-error'. encode_error_internal_server_error('internal-server-error', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"internal-server-error">>, _attrs, _els}. decode_error_gone(__TopXMLNS, __IgnoreEls, @@ -26481,9 +30761,12 @@ decode_error_gone_els(__TopXMLNS, __IgnoreEls, decode_error_gone_els(__TopXMLNS, __IgnoreEls, _els, Uri). -encode_error_gone({gone, Uri}, _xmlns_attrs) -> +encode_error_gone({gone, Uri}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = encode_error_gone_cdata(Uri, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"gone">>, _attrs, _els}. decode_error_gone_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -26497,9 +30780,12 @@ decode_error_forbidden(__TopXMLNS, __IgnoreEls, {xmlel, <<"forbidden">>, _attrs, _els}) -> forbidden. -encode_error_forbidden(forbidden, _xmlns_attrs) -> +encode_error_forbidden(forbidden, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"forbidden">>, _attrs, _els}. decode_error_feature_not_implemented(__TopXMLNS, @@ -26509,27 +30795,36 @@ decode_error_feature_not_implemented(__TopXMLNS, 'feature-not-implemented'. encode_error_feature_not_implemented('feature-not-implemented', - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"feature-not-implemented">>, _attrs, _els}. decode_error_conflict(__TopXMLNS, __IgnoreEls, {xmlel, <<"conflict">>, _attrs, _els}) -> conflict. -encode_error_conflict(conflict, _xmlns_attrs) -> +encode_error_conflict(conflict, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"conflict">>, _attrs, _els}. decode_error_bad_request(__TopXMLNS, __IgnoreEls, {xmlel, <<"bad-request">>, _attrs, _els}) -> 'bad-request'. -encode_error_bad_request('bad-request', _xmlns_attrs) -> +encode_error_bad_request('bad-request', __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, + [], __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"bad-request">>, _attrs, _els}. decode_presence(__TopXMLNS, __IgnoreEls, @@ -26551,7 +30846,10 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"show">>, _attrs, _} = _el | _els], Status, Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, decode_presence_show(__TopXMLNS, __IgnoreEls, @@ -26563,6 +30861,18 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, decode_presence_show(<<"jabber:client">>, __IgnoreEls, _el), Priority, __Els); + <<"jabber:server">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Status, + decode_presence_show(<<"jabber:server">>, + __IgnoreEls, _el), + Priority, __Els); + <<"jabber:component:accept">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Status, + decode_presence_show(<<"jabber:component:accept">>, + __IgnoreEls, _el), + Priority, __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, __Els) @@ -26571,7 +30881,10 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"status">>, _attrs, _} = _el | _els], Status, Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, [decode_presence_status(__TopXMLNS, __IgnoreEls, _el) @@ -26583,6 +30896,18 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el) | Status], Show, Priority, __Els); + <<"jabber:server">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + [decode_presence_status(<<"jabber:server">>, + __IgnoreEls, _el) + | Status], + Show, Priority, __Els); + <<"jabber:component:accept">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + [decode_presence_status(<<"jabber:component:accept">>, + __IgnoreEls, _el) + | Status], + Show, Priority, __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, __Els) @@ -26591,7 +30916,10 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"priority">>, _attrs, _} = _el | _els], Status, Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, decode_presence_priority(__TopXMLNS, __IgnoreEls, @@ -26603,6 +30931,18 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, decode_presence_priority(<<"jabber:client">>, __IgnoreEls, _el), __Els); + <<"jabber:server">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Status, Show, + decode_presence_priority(<<"jabber:server">>, + __IgnoreEls, _el), + __Els); + <<"jabber:component:accept">> -> + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, + Status, Show, + decode_presence_priority(<<"jabber:component:accept">>, + __IgnoreEls, _el), + __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, __Els) @@ -26614,11 +30954,11 @@ decode_presence_els(__TopXMLNS, __IgnoreEls, decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, Status, Show, Priority, __Els) @@ -26668,32 +31008,46 @@ decode_presence_attrs(__TopXMLNS, [], Id, Type, From, encode_presence({presence, Id, Type, Lang, From, To, Show, Status, Priority, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ lists:reverse('encode_presence_$status'(Status, + __NewTopXMLNS, 'encode_presence_$show'(Show, + __NewTopXMLNS, 'encode_presence_$priority'(Priority, + __NewTopXMLNS, [])))), _attrs = 'encode_presence_attr_xml:lang'(Lang, encode_presence_attr_to(To, encode_presence_attr_from(From, encode_presence_attr_type(Type, encode_presence_attr_id(Id, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"presence">>, _attrs, _els}. -'encode_presence_$status'([], _acc) -> _acc; -'encode_presence_$status'([Status | _els], _acc) -> - 'encode_presence_$status'(_els, - [encode_presence_status(Status, []) | _acc]). +'encode_presence_$status'([], __TopXMLNS, _acc) -> _acc; +'encode_presence_$status'([Status | _els], __TopXMLNS, + _acc) -> + 'encode_presence_$status'(_els, __TopXMLNS, + [encode_presence_status(Status, __TopXMLNS) + | _acc]). -'encode_presence_$show'(undefined, _acc) -> _acc; -'encode_presence_$show'(Show, _acc) -> - [encode_presence_show(Show, []) | _acc]. +'encode_presence_$show'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_presence_$show'(Show, __TopXMLNS, _acc) -> + [encode_presence_show(Show, __TopXMLNS) | _acc]. -'encode_presence_$priority'(undefined, _acc) -> _acc; -'encode_presence_$priority'(Priority, _acc) -> - [encode_presence_priority(Priority, []) | _acc]. +'encode_presence_$priority'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_presence_$priority'(Priority, __TopXMLNS, + _acc) -> + [encode_presence_priority(Priority, __TopXMLNS) | _acc]. decode_presence_attr_id(__TopXMLNS, undefined) -> <<>>; decode_presence_attr_id(__TopXMLNS, _val) -> _val. @@ -26778,9 +31132,13 @@ decode_presence_priority_els(__TopXMLNS, __IgnoreEls, decode_presence_priority_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_presence_priority(Cdata, _xmlns_attrs) -> +encode_presence_priority(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_presence_priority_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"priority">>, _attrs, _els}. decode_presence_priority_cdata(__TopXMLNS, <<>>) -> @@ -26828,10 +31186,15 @@ decode_presence_status_attrs(__TopXMLNS, [], Lang) -> Lang). encode_presence_status({text, Lang, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_presence_status_cdata(Data, []), _attrs = 'encode_presence_status_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"status">>, _attrs, _els}. 'decode_presence_status_attr_xml:lang'(__TopXMLNS, @@ -26871,9 +31234,13 @@ decode_presence_show_els(__TopXMLNS, __IgnoreEls, decode_presence_show_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_presence_show(Cdata, _xmlns_attrs) -> +encode_presence_show(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_presence_show_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"show">>, _attrs, _els}. decode_presence_show_cdata(__TopXMLNS, <<>>) -> @@ -26909,7 +31276,10 @@ decode_message_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"subject">>, _attrs, _} = _el | _els], Thread, Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, [decode_message_subject(__TopXMLNS, __IgnoreEls, @@ -26923,6 +31293,20 @@ decode_message_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el) | Subject], Body, __Els); + <<"jabber:server">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + Thread, + [decode_message_subject(<<"jabber:server">>, + __IgnoreEls, _el) + | Subject], + Body, __Els); + <<"jabber:component:accept">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + Thread, + [decode_message_subject(<<"jabber:component:accept">>, + __IgnoreEls, _el) + | Subject], + Body, __Els); _ -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) @@ -26931,7 +31315,10 @@ decode_message_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"thread">>, _attrs, _} = _el | _els], Thread, Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, decode_message_thread(__TopXMLNS, __IgnoreEls, _el), @@ -26941,6 +31328,16 @@ decode_message_els(__TopXMLNS, __IgnoreEls, decode_message_thread(<<"jabber:client">>, __IgnoreEls, _el), Subject, Body, __Els); + <<"jabber:server">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + decode_message_thread(<<"jabber:server">>, + __IgnoreEls, _el), + Subject, Body, __Els); + <<"jabber:component:accept">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + decode_message_thread(<<"jabber:component:accept">>, + __IgnoreEls, _el), + Subject, Body, __Els); _ -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) @@ -26949,7 +31346,10 @@ decode_message_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"body">>, _attrs, _} = _el | _els], Thread, Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> + <<"">> + when __TopXMLNS == <<"jabber:server">>; + __TopXMLNS == <<"jabber:component:accept">>; + __TopXMLNS == <<"jabber:client">> -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, [decode_message_body(__TopXMLNS, __IgnoreEls, _el) @@ -26962,6 +31362,20 @@ decode_message_els(__TopXMLNS, __IgnoreEls, __IgnoreEls, _el) | Body], __Els); + <<"jabber:server">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + Thread, Subject, + [decode_message_body(<<"jabber:server">>, + __IgnoreEls, _el) + | Body], + __Els); + <<"jabber:component:accept">> -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, + Thread, Subject, + [decode_message_body(<<"jabber:component:accept">>, + __IgnoreEls, _el) + | Body], + __Els); _ -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) @@ -26973,11 +31387,11 @@ decode_message_els(__TopXMLNS, __IgnoreEls, decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) @@ -27027,33 +31441,45 @@ decode_message_attrs(__TopXMLNS, [], Id, Type, From, To, encode_message({message, Id, Type, Lang, From, To, Subject, Body, Thread, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ lists:reverse('encode_message_$thread'(Thread, + __NewTopXMLNS, 'encode_message_$subject'(Subject, + __NewTopXMLNS, 'encode_message_$body'(Body, + __NewTopXMLNS, [])))), _attrs = 'encode_message_attr_xml:lang'(Lang, encode_message_attr_to(To, encode_message_attr_from(From, encode_message_attr_type(Type, encode_message_attr_id(Id, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"message">>, _attrs, _els}. -'encode_message_$thread'(undefined, _acc) -> _acc; -'encode_message_$thread'(Thread, _acc) -> - [encode_message_thread(Thread, []) | _acc]. - -'encode_message_$subject'([], _acc) -> _acc; -'encode_message_$subject'([Subject | _els], _acc) -> - 'encode_message_$subject'(_els, - [encode_message_subject(Subject, []) | _acc]). - -'encode_message_$body'([], _acc) -> _acc; -'encode_message_$body'([Body | _els], _acc) -> - 'encode_message_$body'(_els, - [encode_message_body(Body, []) | _acc]). +'encode_message_$thread'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_message_$thread'(Thread, __TopXMLNS, _acc) -> + [encode_message_thread(Thread, __TopXMLNS) | _acc]. + +'encode_message_$subject'([], __TopXMLNS, _acc) -> _acc; +'encode_message_$subject'([Subject | _els], __TopXMLNS, + _acc) -> + 'encode_message_$subject'(_els, __TopXMLNS, + [encode_message_subject(Subject, __TopXMLNS) + | _acc]). + +'encode_message_$body'([], __TopXMLNS, _acc) -> _acc; +'encode_message_$body'([Body | _els], __TopXMLNS, + _acc) -> + 'encode_message_$body'(_els, __TopXMLNS, + [encode_message_body(Body, __TopXMLNS) | _acc]). decode_message_attr_id(__TopXMLNS, undefined) -> <<>>; decode_message_attr_id(__TopXMLNS, _val) -> _val. @@ -27135,9 +31561,13 @@ decode_message_thread_els(__TopXMLNS, __IgnoreEls, decode_message_thread_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_message_thread(Cdata, _xmlns_attrs) -> +encode_message_thread(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_message_thread_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"thread">>, _attrs, _els}. decode_message_thread_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -27176,10 +31606,15 @@ decode_message_body_attrs(__TopXMLNS, [_ | _attrs], decode_message_body_attrs(__TopXMLNS, [], Lang) -> 'decode_message_body_attr_xml:lang'(__TopXMLNS, Lang). -encode_message_body({text, Lang, Data}, _xmlns_attrs) -> +encode_message_body({text, Lang, Data}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_message_body_cdata(Data, []), _attrs = 'encode_message_body_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"body">>, _attrs, _els}. 'decode_message_body_attr_xml:lang'(__TopXMLNS, @@ -27230,10 +31665,15 @@ decode_message_subject_attrs(__TopXMLNS, [], Lang) -> Lang). encode_message_subject({text, Lang, Data}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), _els = encode_message_subject_cdata(Data, []), _attrs = 'encode_message_subject_attr_xml:lang'(Lang, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"subject">>, _attrs, _els}. 'decode_message_subject_attr_xml:lang'(__TopXMLNS, @@ -27273,10 +31713,10 @@ decode_iq_els(__TopXMLNS, __IgnoreEls, decode_iq_els(__TopXMLNS, __IgnoreEls, _els, [_el | __Els]); true -> - case is_known_tag(_el) of + case is_known_tag(_el, __TopXMLNS) of true -> decode_iq_els(__TopXMLNS, __IgnoreEls, _els, - [decode(_el) | __Els]); + [decode(_el, __TopXMLNS, []) | __Els]); false -> decode_iq_els(__TopXMLNS, __IgnoreEls, _els, __Els) end @@ -27321,14 +31761,19 @@ decode_iq_attrs(__TopXMLNS, [], Id, Type, From, To, 'decode_iq_attr_xml:lang'(__TopXMLNS, Lang)}. encode_iq({iq, Id, Type, Lang, From, To, __Els}, - _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els], + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<>>, + [<<"jabber:client">>, <<"jabber:server">>, + <<"jabber:component:accept">>], + __TopXMLNS), + _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], _attrs = 'encode_iq_attr_xml:lang'(Lang, encode_iq_attr_to(To, encode_iq_attr_from(From, encode_iq_attr_type(Type, encode_iq_attr_id(Id, - _xmlns_attrs))))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))))), {xmlel, <<"iq">>, _attrs, _els}. decode_iq_attr_id(__TopXMLNS, undefined) -> @@ -27425,15 +31870,20 @@ decode_stats_attrs(__TopXMLNS, [_ | _attrs], Node) -> decode_stats_attrs(__TopXMLNS, [], Node) -> decode_stats_attr_node(__TopXMLNS, Node). -encode_stats({stats, List, Node}, _xmlns_attrs) -> - _els = lists:reverse('encode_stats_$list'(List, [])), - _attrs = encode_stats_attr_node(Node, _xmlns_attrs), +encode_stats({stats, List, Node}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, + [], __TopXMLNS), + _els = lists:reverse('encode_stats_$list'(List, + __NewTopXMLNS, [])), + _attrs = encode_stats_attr_node(Node, + enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), {xmlel, <<"query">>, _attrs, _els}. -'encode_stats_$list'([], _acc) -> _acc; -'encode_stats_$list'([List | _els], _acc) -> - 'encode_stats_$list'(_els, - [encode_stat(List, []) | _acc]). +'encode_stats_$list'([], __TopXMLNS, _acc) -> _acc; +'encode_stats_$list'([List | _els], __TopXMLNS, _acc) -> + 'encode_stats_$list'(_els, __TopXMLNS, + [encode_stat(List, __TopXMLNS) | _acc]). decode_stats_attr_node(__TopXMLNS, undefined) -> <<>>; decode_stats_attr_node(__TopXMLNS, _val) -> _val. @@ -27495,17 +31945,23 @@ decode_stat_attrs(__TopXMLNS, [], Name, Units, Value) -> decode_stat_attr_value(__TopXMLNS, Value)}. encode_stat({stat, Name, Units, Value, Error}, - _xmlns_attrs) -> - _els = lists:reverse('encode_stat_$error'(Error, [])), + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, + [], __TopXMLNS), + _els = lists:reverse('encode_stat_$error'(Error, + __NewTopXMLNS, [])), _attrs = encode_stat_attr_value(Value, encode_stat_attr_units(Units, encode_stat_attr_name(Name, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"stat">>, _attrs, _els}. -'encode_stat_$error'(undefined, _acc) -> _acc; -'encode_stat_$error'(Error, _acc) -> - [encode_stat_error(Error, []) | _acc]. +'encode_stat_$error'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_stat_$error'(Error, __TopXMLNS, _acc) -> + [encode_stat_error(Error, __TopXMLNS) | _acc]. decode_stat_attr_name(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -27559,10 +32015,14 @@ decode_stat_error_attrs(__TopXMLNS, [], Code) -> decode_stat_error_attr_code(__TopXMLNS, Code). encode_stat_error({stat_error, Code, Reason}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, + [], __TopXMLNS), _els = encode_stat_error_cdata(Reason, []), _attrs = encode_stat_error_attr_code(Code, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"error">>, _attrs, _els}. decode_stat_error_attr_code(__TopXMLNS, undefined) -> @@ -27648,28 +32108,37 @@ decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, encode_bookmarks_storage({bookmark_storage, Conference, Url}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"storage:bookmarks">>, [], + __TopXMLNS), _els = lists:reverse('encode_bookmarks_storage_$conference'(Conference, + __NewTopXMLNS, 'encode_bookmarks_storage_$url'(Url, + __NewTopXMLNS, []))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"storage">>, _attrs, _els}. -'encode_bookmarks_storage_$conference'([], _acc) -> +'encode_bookmarks_storage_$conference'([], __TopXMLNS, + _acc) -> _acc; 'encode_bookmarks_storage_$conference'([Conference | _els], - _acc) -> - 'encode_bookmarks_storage_$conference'(_els, + __TopXMLNS, _acc) -> + 'encode_bookmarks_storage_$conference'(_els, __TopXMLNS, [encode_bookmark_conference(Conference, - []) + __TopXMLNS) | _acc]). -'encode_bookmarks_storage_$url'([], _acc) -> _acc; -'encode_bookmarks_storage_$url'([Url | _els], _acc) -> - 'encode_bookmarks_storage_$url'(_els, - [encode_bookmark_url(Url, []) | _acc]). +'encode_bookmarks_storage_$url'([], __TopXMLNS, _acc) -> + _acc; +'encode_bookmarks_storage_$url'([Url | _els], + __TopXMLNS, _acc) -> + 'encode_bookmarks_storage_$url'(_els, __TopXMLNS, + [encode_bookmark_url(Url, __TopXMLNS) + | _acc]). decode_bookmark_url(__TopXMLNS, __IgnoreEls, {xmlel, <<"url">>, _attrs, _els}) -> @@ -27694,11 +32163,15 @@ decode_bookmark_url_attrs(__TopXMLNS, [], Name, Url) -> decode_bookmark_url_attr_url(__TopXMLNS, Url)}. encode_bookmark_url({bookmark_url, Name, Url}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"storage:bookmarks">>, [], + __TopXMLNS), _els = [], _attrs = encode_bookmark_url_attr_url(Url, encode_bookmark_url_attr_name(Name, - _xmlns_attrs)), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))), {xmlel, <<"url">>, _attrs, _els}. decode_bookmark_url_attr_name(__TopXMLNS, undefined) -> @@ -27807,29 +32280,38 @@ decode_bookmark_conference_attrs(__TopXMLNS, [], Name, encode_bookmark_conference({bookmark_conference, Name, Jid, Autojoin, Nick, Password}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"storage:bookmarks">>, [], + __TopXMLNS), _els = lists:reverse('encode_bookmark_conference_$password'(Password, + __NewTopXMLNS, 'encode_bookmark_conference_$nick'(Nick, + __NewTopXMLNS, []))), _attrs = encode_bookmark_conference_attr_autojoin(Autojoin, encode_bookmark_conference_attr_jid(Jid, encode_bookmark_conference_attr_name(Name, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"conference">>, _attrs, _els}. 'encode_bookmark_conference_$password'(undefined, - _acc) -> + __TopXMLNS, _acc) -> _acc; 'encode_bookmark_conference_$password'(Password, - _acc) -> - [encode_conference_password(Password, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_conference_password(Password, __TopXMLNS) + | _acc]. -'encode_bookmark_conference_$nick'(undefined, _acc) -> +'encode_bookmark_conference_$nick'(undefined, + __TopXMLNS, _acc) -> _acc; -'encode_bookmark_conference_$nick'(Nick, _acc) -> - [encode_conference_nick(Nick, []) | _acc]. +'encode_bookmark_conference_$nick'(Nick, __TopXMLNS, + _acc) -> + [encode_conference_nick(Nick, __TopXMLNS) | _acc]. decode_bookmark_conference_attr_name(__TopXMLNS, undefined) -> @@ -27896,9 +32378,12 @@ decode_conference_password_els(__TopXMLNS, __IgnoreEls, decode_conference_password_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_conference_password(Cdata, _xmlns_attrs) -> +encode_conference_password(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"storage:bookmarks">>, [], + __TopXMLNS), _els = encode_conference_password_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"password">>, _attrs, _els}. decode_conference_password_cdata(__TopXMLNS, <<>>) -> @@ -27928,9 +32413,12 @@ decode_conference_nick_els(__TopXMLNS, __IgnoreEls, decode_conference_nick_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_conference_nick(Cdata, _xmlns_attrs) -> +encode_conference_nick(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"storage:bookmarks">>, [], + __TopXMLNS), _els = encode_conference_nick_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"nick">>, _attrs, _els}. decode_conference_nick_cdata(__TopXMLNS, <<>>) -> <<>>; @@ -27958,9 +32446,12 @@ decode_private_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_private_els(__TopXMLNS, __IgnoreEls, _els, __Xmls). -encode_private({private, __Xmls}, _xmlns_attrs) -> +encode_private({private, __Xmls}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:private">>, [], + __TopXMLNS), _els = __Xmls, - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. decode_disco_items(__TopXMLNS, __IgnoreEls, @@ -28024,24 +32515,32 @@ decode_disco_items_attrs(__TopXMLNS, [], Node) -> decode_disco_items_attr_node(__TopXMLNS, Node). encode_disco_items({disco_items, Node, Items, Rsm}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/disco#items">>, + [], __TopXMLNS), _els = lists:reverse('encode_disco_items_$items'(Items, + __NewTopXMLNS, 'encode_disco_items_$rsm'(Rsm, + __NewTopXMLNS, []))), _attrs = encode_disco_items_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"query">>, _attrs, _els}. -'encode_disco_items_$items'([], _acc) -> _acc; -'encode_disco_items_$items'([Items | _els], _acc) -> - 'encode_disco_items_$items'(_els, - [encode_disco_item(Items, []) | _acc]). +'encode_disco_items_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_disco_items_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_disco_items_$items'(_els, __TopXMLNS, + [encode_disco_item(Items, __TopXMLNS) | _acc]). -'encode_disco_items_$rsm'(undefined, _acc) -> _acc; -'encode_disco_items_$rsm'(Rsm, _acc) -> - [encode_rsm_set(Rsm, - [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]) - | _acc]. +'encode_disco_items_$rsm'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_disco_items_$rsm'(Rsm, __TopXMLNS, _acc) -> + [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. decode_disco_items_attr_node(__TopXMLNS, undefined) -> <<>>; @@ -28081,12 +32580,16 @@ decode_disco_item_attrs(__TopXMLNS, [], Jid, Name, decode_disco_item_attr_node(__TopXMLNS, Node)}. encode_disco_item({disco_item, Jid, Name, Node}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/disco#items">>, + [], __TopXMLNS), _els = [], _attrs = encode_disco_item_attr_node(Node, encode_disco_item_attr_name(Name, encode_disco_item_attr_jid(Jid, - _xmlns_attrs))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)))), {xmlel, <<"item">>, _attrs, _els}. decode_disco_item_attr_jid(__TopXMLNS, undefined) -> @@ -28208,34 +32711,44 @@ decode_disco_info_attrs(__TopXMLNS, [], Node) -> encode_disco_info({disco_info, Node, Identities, Features, Xdata}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, + [], __TopXMLNS), _els = lists:reverse('encode_disco_info_$xdata'(Xdata, + __NewTopXMLNS, 'encode_disco_info_$features'(Features, + __NewTopXMLNS, 'encode_disco_info_$identities'(Identities, + __NewTopXMLNS, [])))), _attrs = encode_disco_info_attr_node(Node, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"query">>, _attrs, _els}. -'encode_disco_info_$xdata'([], _acc) -> _acc; -'encode_disco_info_$xdata'([Xdata | _els], _acc) -> - 'encode_disco_info_$xdata'(_els, - [encode_xdata(Xdata, - [{<<"xmlns">>, - <<"jabber:x:data">>}]) - | _acc]). +'encode_disco_info_$xdata'([], __TopXMLNS, _acc) -> + _acc; +'encode_disco_info_$xdata'([Xdata | _els], __TopXMLNS, + _acc) -> + 'encode_disco_info_$xdata'(_els, __TopXMLNS, + [encode_xdata(Xdata, __TopXMLNS) | _acc]). -'encode_disco_info_$features'([], _acc) -> _acc; +'encode_disco_info_$features'([], __TopXMLNS, _acc) -> + _acc; 'encode_disco_info_$features'([Features | _els], - _acc) -> - 'encode_disco_info_$features'(_els, - [encode_disco_feature(Features, []) | _acc]). + __TopXMLNS, _acc) -> + 'encode_disco_info_$features'(_els, __TopXMLNS, + [encode_disco_feature(Features, __TopXMLNS) + | _acc]). -'encode_disco_info_$identities'([], _acc) -> _acc; +'encode_disco_info_$identities'([], __TopXMLNS, _acc) -> + _acc; 'encode_disco_info_$identities'([Identities | _els], - _acc) -> - 'encode_disco_info_$identities'(_els, - [encode_disco_identity(Identities, []) + __TopXMLNS, _acc) -> + 'encode_disco_info_$identities'(_els, __TopXMLNS, + [encode_disco_identity(Identities, + __TopXMLNS) | _acc]). decode_disco_info_attr_node(__TopXMLNS, undefined) -> @@ -28261,10 +32774,14 @@ decode_disco_feature_attrs(__TopXMLNS, [_ | _attrs], decode_disco_feature_attrs(__TopXMLNS, [], Var) -> decode_disco_feature_attr_var(__TopXMLNS, Var). -encode_disco_feature(Var, _xmlns_attrs) -> +encode_disco_feature(Var, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, + [], __TopXMLNS), _els = [], _attrs = encode_disco_feature_attr_var(Var, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"feature">>, _attrs, _els}. decode_disco_feature_attr_var(__TopXMLNS, undefined) -> @@ -28316,13 +32833,17 @@ decode_disco_identity_attrs(__TopXMLNS, [], Category, encode_disco_identity({identity, Category, Type, Lang, Name}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, + [], __TopXMLNS), _els = [], _attrs = encode_disco_identity_attr_name(Name, 'encode_disco_identity_attr_xml:lang'(Lang, encode_disco_identity_attr_type(Type, encode_disco_identity_attr_category(Category, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"identity">>, _attrs, _els}. decode_disco_identity_attr_category(__TopXMLNS, @@ -28399,16 +32920,21 @@ decode_block_list_els(__TopXMLNS, __IgnoreEls, decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, Items). -encode_block_list({block_list, Items}, _xmlns_attrs) -> +encode_block_list({block_list, Items}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:blocking">>, [], + __TopXMLNS), _els = lists:reverse('encode_block_list_$items'(Items, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"blocklist">>, _attrs, _els}. -'encode_block_list_$items'([], _acc) -> _acc; -'encode_block_list_$items'([Items | _els], _acc) -> - 'encode_block_list_$items'(_els, - [encode_block_item(Items, []) | _acc]). +'encode_block_list_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_block_list_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_block_list_$items'(_els, __TopXMLNS, + [encode_block_item(Items, __TopXMLNS) | _acc]). decode_unblock(__TopXMLNS, __IgnoreEls, {xmlel, <<"unblock">>, _attrs, _els}) -> @@ -28439,16 +32965,20 @@ decode_unblock_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, Items). -encode_unblock({unblock, Items}, _xmlns_attrs) -> +encode_unblock({unblock, Items}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:blocking">>, [], + __TopXMLNS), _els = lists:reverse('encode_unblock_$items'(Items, - [])), - _attrs = _xmlns_attrs, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"unblock">>, _attrs, _els}. -'encode_unblock_$items'([], _acc) -> _acc; -'encode_unblock_$items'([Items | _els], _acc) -> - 'encode_unblock_$items'(_els, - [encode_block_item(Items, []) | _acc]). +'encode_unblock_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_unblock_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_unblock_$items'(_els, __TopXMLNS, + [encode_block_item(Items, __TopXMLNS) | _acc]). decode_block(__TopXMLNS, __IgnoreEls, {xmlel, <<"block">>, _attrs, _els}) -> @@ -28477,15 +33007,20 @@ decode_block_els(__TopXMLNS, __IgnoreEls, [_ | _els], Items) -> decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items). -encode_block({block, Items}, _xmlns_attrs) -> - _els = lists:reverse('encode_block_$items'(Items, [])), - _attrs = _xmlns_attrs, +encode_block({block, Items}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:blocking">>, [], + __TopXMLNS), + _els = lists:reverse('encode_block_$items'(Items, + __NewTopXMLNS, [])), + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"block">>, _attrs, _els}. -'encode_block_$items'([], _acc) -> _acc; -'encode_block_$items'([Items | _els], _acc) -> - 'encode_block_$items'(_els, - [encode_block_item(Items, []) | _acc]). +'encode_block_$items'([], __TopXMLNS, _acc) -> _acc; +'encode_block_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_block_$items'(_els, __TopXMLNS, + [encode_block_item(Items, __TopXMLNS) | _acc]). decode_block_item(__TopXMLNS, __IgnoreEls, {xmlel, <<"item">>, _attrs, _els}) -> @@ -28502,9 +33037,14 @@ decode_block_item_attrs(__TopXMLNS, [_ | _attrs], decode_block_item_attrs(__TopXMLNS, [], Jid) -> decode_block_item_attr_jid(__TopXMLNS, Jid). -encode_block_item(Jid, _xmlns_attrs) -> +encode_block_item(Jid, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:blocking">>, [], + __TopXMLNS), _els = [], - _attrs = encode_block_item_attr_jid(Jid, _xmlns_attrs), + _attrs = encode_block_item_attr_jid(Jid, + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"item">>, _attrs, _els}. decode_block_item_attr_jid(__TopXMLNS, undefined) -> @@ -28592,26 +33132,37 @@ decode_privacy_els(__TopXMLNS, __IgnoreEls, [_ | _els], Default, Active). encode_privacy({privacy_query, Lists, Default, Active}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = lists:reverse('encode_privacy_$lists'(Lists, + __NewTopXMLNS, 'encode_privacy_$default'(Default, + __NewTopXMLNS, 'encode_privacy_$active'(Active, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_privacy_$lists'([], _acc) -> _acc; -'encode_privacy_$lists'([Lists | _els], _acc) -> - 'encode_privacy_$lists'(_els, - [encode_privacy_list(Lists, []) | _acc]). +'encode_privacy_$lists'([], __TopXMLNS, _acc) -> _acc; +'encode_privacy_$lists'([Lists | _els], __TopXMLNS, + _acc) -> + 'encode_privacy_$lists'(_els, __TopXMLNS, + [encode_privacy_list(Lists, __TopXMLNS) | _acc]). -'encode_privacy_$default'(undefined, _acc) -> _acc; -'encode_privacy_$default'(Default, _acc) -> - [encode_privacy_default_list(Default, []) | _acc]. +'encode_privacy_$default'(undefined, __TopXMLNS, + _acc) -> + _acc; +'encode_privacy_$default'(Default, __TopXMLNS, _acc) -> + [encode_privacy_default_list(Default, __TopXMLNS) + | _acc]. -'encode_privacy_$active'(undefined, _acc) -> _acc; -'encode_privacy_$active'(Active, _acc) -> - [encode_privacy_active_list(Active, []) | _acc]. +'encode_privacy_$active'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_privacy_$active'(Active, __TopXMLNS, _acc) -> + [encode_privacy_active_list(Active, __TopXMLNS) | _acc]. decode_privacy_active_list(__TopXMLNS, __IgnoreEls, {xmlel, <<"active">>, _attrs, _els}) -> @@ -28631,10 +33182,14 @@ decode_privacy_active_list_attrs(__TopXMLNS, [], Name) -> decode_privacy_active_list_attr_name(__TopXMLNS, Name). -encode_privacy_active_list(Name, _xmlns_attrs) -> +encode_privacy_active_list(Name, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], _attrs = encode_privacy_active_list_attr_name(Name, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"active">>, _attrs, _els}. decode_privacy_active_list_attr_name(__TopXMLNS, @@ -28667,10 +33222,14 @@ decode_privacy_default_list_attrs(__TopXMLNS, [], Name) -> decode_privacy_default_list_attr_name(__TopXMLNS, Name). -encode_privacy_default_list(Name, _xmlns_attrs) -> +encode_privacy_default_list(Name, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], _attrs = encode_privacy_default_list_attr_name(Name, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"default">>, _attrs, _els}. decode_privacy_default_list_attr_name(__TopXMLNS, @@ -28728,17 +33287,24 @@ decode_privacy_list_attrs(__TopXMLNS, [], Name) -> decode_privacy_list_attr_name(__TopXMLNS, Name). encode_privacy_list({privacy_list, Name, Items}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = lists:reverse('encode_privacy_list_$items'(Items, - [])), + __NewTopXMLNS, [])), _attrs = encode_privacy_list_attr_name(Name, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"list">>, _attrs, _els}. -'encode_privacy_list_$items'([], _acc) -> _acc; -'encode_privacy_list_$items'([Items | _els], _acc) -> - 'encode_privacy_list_$items'(_els, - [encode_privacy_item(Items, []) | _acc]). +'encode_privacy_list_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_privacy_list_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_privacy_list_$items'(_els, __TopXMLNS, + [encode_privacy_item(Items, __TopXMLNS) + | _acc]). decode_privacy_list_attr_name(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -28876,36 +33442,54 @@ decode_privacy_item_attrs(__TopXMLNS, [], Action, Order, encode_privacy_item({privacy_item, Order, Action, Type, Value, Message, Iq, Presence_in, Presence_out}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = lists:reverse('encode_privacy_item_$iq'(Iq, + __NewTopXMLNS, 'encode_privacy_item_$presence_out'(Presence_out, + __NewTopXMLNS, 'encode_privacy_item_$message'(Message, + __NewTopXMLNS, 'encode_privacy_item_$presence_in'(Presence_in, + __NewTopXMLNS, []))))), _attrs = encode_privacy_item_attr_value(Value, encode_privacy_item_attr_type(Type, encode_privacy_item_attr_order(Order, encode_privacy_item_attr_action(Action, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"item">>, _attrs, _els}. -'encode_privacy_item_$iq'(false, _acc) -> _acc; -'encode_privacy_item_$iq'(Iq, _acc) -> - [encode_privacy_iq(Iq, []) | _acc]. +'encode_privacy_item_$iq'(false, __TopXMLNS, _acc) -> + _acc; +'encode_privacy_item_$iq'(Iq, __TopXMLNS, _acc) -> + [encode_privacy_iq(Iq, __TopXMLNS) | _acc]. -'encode_privacy_item_$presence_out'(false, _acc) -> +'encode_privacy_item_$presence_out'(false, __TopXMLNS, + _acc) -> _acc; 'encode_privacy_item_$presence_out'(Presence_out, - _acc) -> - [encode_privacy_presence_out(Presence_out, []) | _acc]. + __TopXMLNS, _acc) -> + [encode_privacy_presence_out(Presence_out, __TopXMLNS) + | _acc]. -'encode_privacy_item_$message'(false, _acc) -> _acc; -'encode_privacy_item_$message'(Message, _acc) -> - [encode_privacy_message(Message, []) | _acc]. +'encode_privacy_item_$message'(false, __TopXMLNS, + _acc) -> + _acc; +'encode_privacy_item_$message'(Message, __TopXMLNS, + _acc) -> + [encode_privacy_message(Message, __TopXMLNS) | _acc]. -'encode_privacy_item_$presence_in'(false, _acc) -> _acc; -'encode_privacy_item_$presence_in'(Presence_in, _acc) -> - [encode_privacy_presence_in(Presence_in, []) | _acc]. +'encode_privacy_item_$presence_in'(false, __TopXMLNS, + _acc) -> + _acc; +'encode_privacy_item_$presence_in'(Presence_in, + __TopXMLNS, _acc) -> + [encode_privacy_presence_in(Presence_in, __TopXMLNS) + | _acc]. decode_privacy_item_attr_action(__TopXMLNS, undefined) -> @@ -28964,36 +33548,48 @@ decode_privacy_presence_out(__TopXMLNS, __IgnoreEls, {xmlel, <<"presence-out">>, _attrs, _els}) -> true. -encode_privacy_presence_out(true, _xmlns_attrs) -> +encode_privacy_presence_out(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"presence-out">>, _attrs, _els}. decode_privacy_presence_in(__TopXMLNS, __IgnoreEls, {xmlel, <<"presence-in">>, _attrs, _els}) -> true. -encode_privacy_presence_in(true, _xmlns_attrs) -> +encode_privacy_presence_in(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"presence-in">>, _attrs, _els}. decode_privacy_iq(__TopXMLNS, __IgnoreEls, {xmlel, <<"iq">>, _attrs, _els}) -> true. -encode_privacy_iq(true, _xmlns_attrs) -> +encode_privacy_iq(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"iq">>, _attrs, _els}. decode_privacy_message(__TopXMLNS, __IgnoreEls, {xmlel, <<"message">>, _attrs, _els}) -> true. -encode_privacy_message(true, _xmlns_attrs) -> +encode_privacy_message(true, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:privacy">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"message">>, _attrs, _els}. decode_rosterver_feature(__TopXMLNS, __IgnoreEls, @@ -29001,9 +33597,12 @@ decode_rosterver_feature(__TopXMLNS, __IgnoreEls, {rosterver_feature}. encode_rosterver_feature({rosterver_feature}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"urn:xmpp:features:rosterver">>, [], + __TopXMLNS), _els = [], - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"ver">>, _attrs, _els}. decode_roster_query(__TopXMLNS, __IgnoreEls, @@ -29049,17 +33648,23 @@ decode_roster_query_attrs(__TopXMLNS, [], Ver) -> decode_roster_query_attr_ver(__TopXMLNS, Ver). encode_roster_query({roster_query, Items, Ver}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, + [], __TopXMLNS), _els = lists:reverse('encode_roster_query_$items'(Items, - [])), + __NewTopXMLNS, [])), _attrs = encode_roster_query_attr_ver(Ver, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"query">>, _attrs, _els}. -'encode_roster_query_$items'([], _acc) -> _acc; -'encode_roster_query_$items'([Items | _els], _acc) -> - 'encode_roster_query_$items'(_els, - [encode_roster_item(Items, []) | _acc]). +'encode_roster_query_$items'([], __TopXMLNS, _acc) -> + _acc; +'encode_roster_query_$items'([Items | _els], __TopXMLNS, + _acc) -> + 'encode_roster_query_$items'(_els, __TopXMLNS, + [encode_roster_item(Items, __TopXMLNS) + | _acc]). decode_roster_query_attr_ver(__TopXMLNS, undefined) -> undefined; @@ -29138,20 +33743,27 @@ decode_roster_item_attrs(__TopXMLNS, [], Jid, Name, encode_roster_item({roster_item, Jid, Name, Groups, Subscription, Ask}, - _xmlns_attrs) -> + __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, + [], __TopXMLNS), _els = - lists:reverse('encode_roster_item_$groups'(Groups, [])), + lists:reverse('encode_roster_item_$groups'(Groups, + __NewTopXMLNS, [])), _attrs = encode_roster_item_attr_ask(Ask, encode_roster_item_attr_subscription(Subscription, encode_roster_item_attr_name(Name, encode_roster_item_attr_jid(Jid, - _xmlns_attrs)))), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS))))), {xmlel, <<"item">>, _attrs, _els}. -'encode_roster_item_$groups'([], _acc) -> _acc; -'encode_roster_item_$groups'([Groups | _els], _acc) -> - 'encode_roster_item_$groups'(_els, - [encode_roster_group(Groups, []) | _acc]). +'encode_roster_item_$groups'([], __TopXMLNS, _acc) -> + _acc; +'encode_roster_item_$groups'([Groups | _els], + __TopXMLNS, _acc) -> + 'encode_roster_item_$groups'(_els, __TopXMLNS, + [encode_roster_group(Groups, __TopXMLNS) + | _acc]). decode_roster_item_attr_jid(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, @@ -29227,9 +33839,11 @@ decode_roster_group_els(__TopXMLNS, __IgnoreEls, decode_roster_group_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_roster_group(Cdata, _xmlns_attrs) -> +encode_roster_group(Cdata, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, + [], __TopXMLNS), _els = encode_roster_group_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"group">>, _attrs, _els}. decode_roster_group_cdata(__TopXMLNS, <<>>) -> @@ -29306,26 +33920,34 @@ decode_version_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, Os, Name). -encode_version({version, Name, Ver, Os}, - _xmlns_attrs) -> +encode_version({version, Name, Ver, Os}, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:version">>, [], + __TopXMLNS), _els = lists:reverse('encode_version_$ver'(Ver, + __NewTopXMLNS, 'encode_version_$os'(Os, + __NewTopXMLNS, 'encode_version_$name'(Name, + __NewTopXMLNS, [])))), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"query">>, _attrs, _els}. -'encode_version_$ver'(undefined, _acc) -> _acc; -'encode_version_$ver'(Ver, _acc) -> - [encode_version_ver(Ver, []) | _acc]. +'encode_version_$ver'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_version_$ver'(Ver, __TopXMLNS, _acc) -> + [encode_version_ver(Ver, __TopXMLNS) | _acc]. -'encode_version_$os'(undefined, _acc) -> _acc; -'encode_version_$os'(Os, _acc) -> - [encode_version_os(Os, []) | _acc]. +'encode_version_$os'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_version_$os'(Os, __TopXMLNS, _acc) -> + [encode_version_os(Os, __TopXMLNS) | _acc]. -'encode_version_$name'(undefined, _acc) -> _acc; -'encode_version_$name'(Name, _acc) -> - [encode_version_name(Name, []) | _acc]. +'encode_version_$name'(undefined, __TopXMLNS, _acc) -> + _acc; +'encode_version_$name'(Name, __TopXMLNS, _acc) -> + [encode_version_name(Name, __TopXMLNS) | _acc]. decode_version_os(__TopXMLNS, __IgnoreEls, {xmlel, <<"os">>, _attrs, _els}) -> @@ -29345,9 +33967,12 @@ decode_version_os_els(__TopXMLNS, __IgnoreEls, decode_version_os_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_version_os(Cdata, _xmlns_attrs) -> +encode_version_os(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:version">>, [], + __TopXMLNS), _els = encode_version_os_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"os">>, _attrs, _els}. decode_version_os_cdata(__TopXMLNS, <<>>) -> @@ -29376,9 +34001,12 @@ decode_version_ver_els(__TopXMLNS, __IgnoreEls, decode_version_ver_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_version_ver(Cdata, _xmlns_attrs) -> +encode_version_ver(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:version">>, [], + __TopXMLNS), _els = encode_version_ver_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"version">>, _attrs, _els}. decode_version_ver_cdata(__TopXMLNS, <<>>) -> @@ -29407,9 +34035,12 @@ decode_version_name_els(__TopXMLNS, __IgnoreEls, decode_version_name_els(__TopXMLNS, __IgnoreEls, _els, Cdata). -encode_version_name(Cdata, _xmlns_attrs) -> +encode_version_name(Cdata, __TopXMLNS) -> + __NewTopXMLNS = + choose_top_xmlns(<<"jabber:iq:version">>, [], + __TopXMLNS), _els = encode_version_name_cdata(Cdata, []), - _attrs = _xmlns_attrs, + _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), {xmlel, <<"name">>, _attrs, _els}. decode_version_name_cdata(__TopXMLNS, <<>>) -> @@ -29446,10 +34077,13 @@ decode_last_attrs(__TopXMLNS, [_ | _attrs], Seconds) -> decode_last_attrs(__TopXMLNS, [], Seconds) -> decode_last_attr_seconds(__TopXMLNS, Seconds). -encode_last({last, Seconds, Status}, _xmlns_attrs) -> +encode_last({last, Seconds, Status}, __TopXMLNS) -> + __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:last">>, + [], __TopXMLNS), _els = encode_last_cdata(Status, []), _attrs = encode_last_attr_seconds(Seconds, - _xmlns_attrs), + enc_xmlns_attrs(__NewTopXMLNS, + __TopXMLNS)), {xmlel, <<"query">>, _attrs, _els}. decode_last_attr_seconds(__TopXMLNS, undefined) -> -- cgit v1.2.3 From fa31e3ef2321e3901d167d3654693b85313acf08 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 24 Sep 2016 23:34:28 +0300 Subject: Deprecate jlib:integer_to_binary/1 and jlib:binary_to_integer/1 --- src/cyrsasl_anonymous.erl | 2 +- src/ejabberd_c2s.erl | 2 +- src/ejabberd_captcha.erl | 2 +- src/ejabberd_commands_doc.erl | 4 ++-- src/ejabberd_http.erl | 12 ++++++------ src/ejabberd_http_bind.erl | 4 ++-- src/ejabberd_sm_sql.erl | 4 ++-- src/ejabberd_sql.erl | 10 +++++----- src/ejabberd_system_monitor.erl | 2 +- src/ejabberd_web_admin.erl | 8 ++++---- src/jd2ejd.erl | 2 +- src/jlib.erl | 4 +++- src/mod_caps.erl | 2 +- src/mod_caps_sql.erl | 4 ++-- src/mod_configure.erl | 10 +++++----- src/mod_http_api.erl | 2 +- src/mod_http_upload.erl | 8 ++++---- src/mod_last_sql.erl | 2 +- src/mod_mam_mnesia.erl | 4 ++-- src/mod_mam_sql.erl | 18 +++++++++--------- src/mod_muc_admin.erl | 2 +- src/mod_offline.erl | 2 +- src/mod_privacy_sql.erl | 2 +- src/mod_pubsub.erl | 4 ++-- src/mod_shared_roster.erl | 6 +++--- src/mod_vcard_sql.erl | 2 +- src/pubsub_db_sql.erl | 2 +- src/pubsub_subscription.erl | 4 ++-- src/pubsub_subscription_sql.erl | 4 ++-- src/randoms.erl | 2 +- src/xmpp_codec.erl | 4 ++-- 31 files changed, 71 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/cyrsasl_anonymous.erl b/src/cyrsasl_anonymous.erl index 802e1cd7b..15980afc5 100644 --- a/src/cyrsasl_anonymous.erl +++ b/src/cyrsasl_anonymous.erl @@ -45,7 +45,7 @@ mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) -> mech_step(#state{server = Server} = S, ClientIn) -> User = iolist_to_binary([randoms:get_string(), - jlib:integer_to_binary(p1_time_compat:unique_integer([positive]))]), + integer_to_binary(p1_time_compat:unique_integer([positive]))]), case ejabberd_auth:is_user_exists(User, Server) of true -> mech_step(S, ClientIn); false -> {ok, [{username, User}, {authzid, User}, {auth_module, ejabberd_auth_anonymous}]} diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index d89290d47..02540259a 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1633,7 +1633,7 @@ new_id() -> randoms:get_string(). -spec new_uniq_id() -> binary(). new_uniq_id() -> iolist_to_binary([randoms:get_string(), - jlib:integer_to_binary(p1_time_compat:unique_integer([positive]))]). + integer_to_binary(p1_time_compat:unique_integer([positive]))]). -spec get_conn_type(state()) -> c2s | c2s_tls | c2s_compressed | websocket | c2s_compressed_tls | http_bind. diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index df74a68b1..9650f3773 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -392,7 +392,7 @@ get_url(Str) -> end. get_transfer_protocol(PortString) -> - PortNumber = jlib:binary_to_integer(PortString), + PortNumber = binary_to_integer(PortString), PortListeners = get_port_listeners(PortNumber), get_captcha_transfer_protocol(PortListeners). diff --git a/src/ejabberd_commands_doc.erl b/src/ejabberd_commands_doc.erl index dc00c5d2a..477e4f5d5 100644 --- a/src/ejabberd_commands_doc.erl +++ b/src/ejabberd_commands_doc.erl @@ -41,7 +41,7 @@ -define(SPAN(N, V), ?TAG_R(span, ??N, V)). -define(STR(A), ?SPAN(str,[<<"\"">>, A, <<"\"">>])). --define(NUM(A), ?SPAN(num,jlib:integer_to_binary(A))). +-define(NUM(A), ?SPAN(num,integer_to_binary(A))). -define(FIELD(A), ?SPAN(field,A)). -define(ID(A), ?SPAN(id,A)). -define(OP(A), ?SPAN(op,A)). @@ -171,7 +171,7 @@ xml_gen({Name, integer}, Int, Indent, HTMLOutput) -> [?XML(member, Indent, [?XML_L(name, Indent, 1, ?ID_A(Name)), ?XML(value, Indent, 1, - [?XML_L(integer, Indent, 2, ?ID(jlib:integer_to_binary(Int)))])])]; + [?XML_L(integer, Indent, 2, ?ID(integer_to_binary(Int)))])])]; xml_gen({Name, string}, Str, Indent, HTMLOutput) -> [?XML(member, Indent, [?XML_L(name, Indent, 1, ?ID_A(Name)), diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index 1c8de2fbf..35679ccd3 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -252,7 +252,7 @@ process_header(State, Data) -> request_headers = add_header(Name, Auth, State)}; {ok, {http_header, _, 'Content-Length' = Name, _, SLen}} -> - case catch jlib:binary_to_integer(SLen) of + case catch binary_to_integer(SLen) of Len when is_integer(Len) -> State#state{request_content_length = Len, request_headers = add_header(Name, SLen, State)}; @@ -327,10 +327,10 @@ get_transfer_protocol(SockMod, HostPort) -> case {SockMod, PortList} of {gen_tcp, []} -> {Host, 80, http}; {gen_tcp, [Port]} -> - {Host, jlib:binary_to_integer(Port), http}; + {Host, binary_to_integer(Port), http}; {fast_tls, []} -> {Host, 443, https}; {fast_tls, [Port]} -> - {Host, jlib:binary_to_integer(Port), https} + {Host, binary_to_integer(Port), https} end. %% XXX bard: search through request handlers looking for one that @@ -587,12 +587,12 @@ make_text_output(State, Status, Reason, Headers, Text) -> of {value, _} -> [{<<"Content-Length">>, - jlib:integer_to_binary(byte_size(Data))} + integer_to_binary(byte_size(Data))} | Headers]; _ -> [{<<"Content-Type">>, <<"text/html; charset=utf-8">>}, {<<"Content-Length">>, - jlib:integer_to_binary(byte_size(Data))} + integer_to_binary(byte_size(Data))} | Headers] end, HeadersOut = case {State#state.request_version, @@ -617,7 +617,7 @@ make_text_output(State, Status, Reason, Headers, Text) -> _ -> Reason end, SL = [Version, - jlib:integer_to_binary(Status), <<" ">>, + integer_to_binary(Status), <<" ">>, NewReason, <<"\r\n">>], Data2 = case State#state.request_method of 'HEAD' -> <<"">>; diff --git a/src/ejabberd_http_bind.erl b/src/ejabberd_http_bind.erl index 1a238607a..20edaa178 100644 --- a/src/ejabberd_http_bind.erl +++ b/src/ejabberd_http_bind.erl @@ -853,7 +853,7 @@ rid_allow(OldRid, NewRid, Attrs, Hold, MaxPause) -> %% We did not miss any packet, we can process it immediately: NewRid == OldRid + 1 -> case catch - jlib:binary_to_integer(fxml:get_attr_s(<<"pause">>, + binary_to_integer(fxml:get_attr_s(<<"pause">>, Attrs)) of {'EXIT', _} -> {true, 0}; @@ -1119,7 +1119,7 @@ parse_request(Data, PayloadSize, MaxStanzaSize) -> if Xmlns /= (?NS_HTTP_BIND) -> {error, bad_request}; true -> case catch - jlib:binary_to_integer(fxml:get_attr_s(<<"rid">>, + binary_to_integer(fxml:get_attr_s(<<"rid">>, Attrs)) of {'EXIT', _} -> {error, bad_request}; diff --git a/src/ejabberd_sm_sql.erl b/src/ejabberd_sm_sql.erl index 28796aca0..2a7b80c19 100644 --- a/src/ejabberd_sm_sql.erl +++ b/src/ejabberd_sm_sql.erl @@ -147,7 +147,7 @@ timestamp_to_now(I) -> {MSec, Sec, USec}. dec_priority(Prio) -> - case catch jlib:binary_to_integer(Prio) of + case catch binary_to_integer(Prio) of {'EXIT', _} -> undefined; Int -> @@ -157,7 +157,7 @@ dec_priority(Prio) -> enc_priority(undefined) -> <<"">>; enc_priority(Int) when is_integer(Int) -> - jlib:integer_to_binary(Int). + integer_to_binary(Int). row_to_session(LServer, {USec, PidS, User, Resource, PrioS, InfoS}) -> Now = timestamp_to_now(USec), diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index a480a1bd3..8116d617f 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -768,7 +768,7 @@ sqlite_to_odbc(Host, {rowid, _}) -> sqlite_to_odbc(_Host, [{columns, Columns}, {rows, TRows}]) -> Rows = [lists:map( fun(I) when is_integer(I) -> - jlib:integer_to_binary(I); + integer_to_binary(I); (B) -> B end, tuple_to_list(Row)) || Row <- TRows], @@ -813,11 +813,11 @@ pgsql_item_to_odbc({<<"FETCH", _/binary>>, Rows, {selected, [element(1, Row) || Row <- Rows], Recs}; pgsql_item_to_odbc(<<"INSERT ", OIDN/binary>>) -> [_OID, N] = str:tokens(OIDN, <<" ">>), - {updated, jlib:binary_to_integer(N)}; + {updated, binary_to_integer(N)}; pgsql_item_to_odbc(<<"DELETE ", N/binary>>) -> - {updated, jlib:binary_to_integer(N)}; + {updated, binary_to_integer(N)}; pgsql_item_to_odbc(<<"UPDATE ", N/binary>>) -> - {updated, jlib:binary_to_integer(N)}; + {updated, binary_to_integer(N)}; pgsql_item_to_odbc({error, Error}) -> {error, Error}; pgsql_item_to_odbc(_) -> {updated, undefined}. @@ -875,7 +875,7 @@ mysql_item_to_odbc(Columns, Recs) -> to_odbc({selected, Columns, Recs}) -> Rows = [lists:map( fun(I) when is_integer(I) -> - jlib:integer_to_binary(I); + integer_to_binary(I); (B) -> B end, Row) || Row <- Recs], diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index 7f815a57e..df6af1c95 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -300,7 +300,7 @@ process_command2([<<"showlh">>, SNode], From, To) -> process_command2([<<"setlh">>, SNode, NewValueString], From, To) -> Node = jlib:binary_to_atom(SNode), - NewValue = jlib:binary_to_integer(NewValueString), + NewValue = binary_to_integer(NewValueString), remote_command(Node, [setlh, NewValue], From, To); process_command2([<<"help">>], From, To) -> send_message(To, From, help()); diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 2740e2879..498fcf9b0 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -1458,8 +1458,8 @@ list_users_in_diapason(Host, Diap, Lang, URLFunc) -> Users = ejabberd_auth:get_vh_registered_users(Host), SUsers = lists:sort([{S, U} || {U, S} <- Users]), [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>), - N1 = jlib:binary_to_integer(S1), - N2 = jlib:binary_to_integer(S2), + N1 = binary_to_integer(S1), + N2 = binary_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), [list_given_users(Host, Sub, <<"../../">>, Lang, URLFunc)]. @@ -1648,7 +1648,7 @@ user_info(User, Server, Query, Lang) -> "://", (jlib:ip_to_list(IP))/binary, ":", - (jlib:integer_to_binary(Port))/binary, + (integer_to_binary(Port))/binary, "#", (jlib:atom_to_binary(Node))/binary>> end, @@ -2520,7 +2520,7 @@ make_netprot_html(NetProt) -> get_port_data(PortIP, Opts) -> {Port, IPT, IPS, _IPV, NetProt, OptsClean} = ejabberd_listener:parse_listener_portip(PortIP, Opts), - SPort = jlib:integer_to_binary(Port), + SPort = integer_to_binary(Port), SSPort = list_to_binary( lists:map(fun (N) -> io_lib:format("~.16b", [N]) diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl index 037d6d63a..fd70f8b1e 100644 --- a/src/jd2ejd.erl +++ b/src/jd2ejd.erl @@ -126,7 +126,7 @@ xdb_data(User, Server, #xmlel{attrs = Attrs} = El) -> TimeStamp = fxml:get_attr_s(<<"last">>, Attrs), Status = fxml:get_tag_cdata(El), catch mod_last:store_last_info(User, Server, - jlib:binary_to_integer(TimeStamp), + binary_to_integer(TimeStamp), Status), ok; ?NS_VCARD -> diff --git a/src/jlib.erl b/src/jlib.erl index 532a74610..b79b8fa7c 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -74,7 +74,9 @@ {resourceprep, 1}, {jid_tolower, 1}, {jid_remove_resource, 1}, - {jid_replace_resource, 2}]). + {jid_replace_resource, 2}, + {integer_to_binary, 1}, + {binary_to_integer, 1}]). -include("ejabberd.hrl"). -include("jlib.hrl"). diff --git a/src/mod_caps.erl b/src/mod_caps.erl index ae11ab651..4d9bdd61f 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -546,7 +546,7 @@ import_start(LServer, DBType) -> import(_LServer, {sql, _}, _DBType, <<"caps_features">>, [Node, SubNode, Feature, _TimeStamp]) -> - Feature1 = case catch jlib:binary_to_integer(Feature) of + Feature1 = case catch binary_to_integer(Feature) of I when is_integer(I), I>0 -> I; _ -> Feature end, diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl index 5faff98b6..dde301575 100644 --- a/src/mod_caps_sql.erl +++ b/src/mod_caps_sql.erl @@ -29,7 +29,7 @@ caps_read(LServer, {Node, SubNode}) -> ?SQL("select @(feature)s from caps_features where" " node=%(Node)s and subnode=%(SubNode)s")) of {selected, [{H}|_] = Fs} -> - case catch jlib:binary_to_integer(H) of + case catch binary_to_integer(H) of Int when is_integer(Int), Int>=0 -> {ok, Int}; _ -> @@ -58,7 +58,7 @@ export(_Server) -> %%%=================================================================== sql_write_features_t({Node, SubNode}, Features) -> NewFeatures = if is_integer(Features) -> - [jlib:integer_to_binary(Features)]; + [integer_to_binary(Features)]; true -> Features end, diff --git a/src/mod_configure.erl b/src/mod_configure.erl index dd361028b..5e2ff351c 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -552,8 +552,8 @@ get_local_items({_, Host}, SUsers = lists:sort([{S, U} || {U, S} <- Users]), try [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>), - N1 = jlib:binary_to_integer(S1), - N2 = jlib:binary_to_integer(S2), + N1 = binary_to_integer(S1), + N2 = binary_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), {result, lists:map( fun({S, U}) -> @@ -1659,11 +1659,11 @@ set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang, IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources], IPs = [<<(jlib:ip_to_list(IP))/binary, ":", - (jlib:integer_to_binary(Port))/binary>> + (integer_to_binary(Port))/binary>> || {IP, Port} <- IPs1], Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]), - Rostersize = jlib:integer_to_binary(erlang:length(Items)), + Rostersize = integer_to_binary(erlang:length(Items)), {result, #xdata{type = form, fields = [?HFIELD(), @@ -1695,7 +1695,7 @@ search_running_node(SNode, [Node | Nodes]) -> end. stop_node(From, Host, ENode, Action, XData) -> - Delay = jlib:binary_to_integer(get_value(<<"delay">>, XData)), + Delay = binary_to_integer(get_value(<<"delay">>, XData)), Subject = case get_value(<<"subject">>, XData) of <<"">> -> []; diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index f3a69aa80..1578be964 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -267,7 +267,7 @@ process(_Path, Request) -> get_api_version(#request{path = Path}) -> get_api_version(lists:reverse(Path)); get_api_version([<<"v", String/binary>> | Tail]) -> - case catch jlib:binary_to_integer(String) of + case catch binary_to_integer(String) of N when is_integer(N) -> N; _ -> diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index f1f5d8173..6ad18531c 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -35,7 +35,7 @@ -define(FORMAT(Error), file:format_error(Error)). -define(URL_ENC(URL), binary_to_list(ejabberd_http:url_encode(URL))). -define(ADDR_TO_STR(IP), ejabberd_config:may_hide_data(jlib:ip_to_list(IP))). --define(STR_TO_INT(Str, B), jlib:binary_to_integer(iolist_to_binary(Str), B)). +-define(STR_TO_INT(Str, B), binary_to_integer(iolist_to_binary(Str), B)). -define(DEFAULT_CONTENT_TYPE, <<"application/octet-stream">>). -define(CONTENT_TYPES, [{<<".avi">>, <<"video/avi">>}, @@ -578,7 +578,7 @@ process_iq(_From, #iq{}, _State) -> create_slot(#state{service_url = undefined, max_size = MaxSize}, JID, File, Size, _ContentType, Lang) when MaxSize /= infinity, Size > MaxSize -> - Text = <<"File larger than ", (jlib:integer_to_binary(MaxSize))/binary, + Text = <<"File larger than ", (integer_to_binary(MaxSize))/binary, " Bytes.">>, ?INFO_MSG("Rejecting file ~s from ~s (too large: ~B bytes)", [File, jid:to_string(JID), Size]), @@ -609,7 +609,7 @@ create_slot(#state{service_url = ServiceURL}, Lang) -> Options = [{body_format, binary}, {full_result, false}], HttpOptions = [{timeout, ?SERVICE_REQUEST_TIMEOUT}], - SizeStr = jlib:integer_to_binary(Size), + SizeStr = integer_to_binary(Size), GetRequest = binary_to_list(ServiceURL) ++ "?jid=" ++ ?URL_ENC(jid:to_string({U, S, <<"">>})) ++ "&name=" ++ ?URL_ENC(File) ++ @@ -727,7 +727,7 @@ iq_disco_info(Host, Lang, Name, AddInfo) -> infinity -> AddInfo; MaxSize -> - MaxSizeStr = jlib:integer_to_binary(MaxSize), + MaxSizeStr = integer_to_binary(MaxSize), Fields = [#xdata_field{type = hidden, var = <<"FORM_TYPE">>, values = [?NS_HTTP_UPLOAD]}, diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl index 13b028c6f..718f01dff 100644 --- a/src/mod_last_sql.erl +++ b/src/mod_last_sql.erl @@ -62,7 +62,7 @@ import(LServer) -> [{<<"select username, seconds, state from last">>, fun([LUser, TimeStamp, State]) -> #last_activity{us = {LUser, LServer}, - timestamp = jlib:binary_to_integer( + timestamp = binary_to_integer( TimeStamp), status = State} end}]. diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl index ecaa4d053..e913d5a45 100644 --- a/src/mod_mam_mnesia.erl +++ b/src/mod_mam_mnesia.erl @@ -97,7 +97,7 @@ store(Pkt, _, {LUser, LServer}, Type, Peer, Nick, _Dir) -> _ -> LPeer = {PUser, PServer, _} = jid:tolower(Peer), TS = p1_time_compat:timestamp(), - ID = jlib:integer_to_binary(now_to_usec(TS)), + ID = integer_to_binary(now_to_usec(TS)), F = fun() -> mnesia:write( #archive_msg{us = {LUser, LServer}, @@ -145,7 +145,7 @@ select(_LServer, JidRequestor, Result = {lists:map( fun(Msg) -> {Msg#archive_msg.id, - jlib:binary_to_integer(Msg#archive_msg.id), + binary_to_integer(Msg#archive_msg.id), mod_mam:msg_to_el(Msg, MsgType, JidRequestor, JidArchive)} end, FilteredMsgs), IsComplete, Count}, diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 2a0dcce95..1491f70f2 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -55,7 +55,7 @@ extended_fields() -> store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir) -> TSinteger = p1_time_compat:system_time(micro_seconds), - ID = jlib:integer_to_binary(TSinteger), + ID = integer_to_binary(TSinteger), SUser = case Type of chat -> LUser; groupchat -> jid:to_string({LUser, LHost, <<>>}) @@ -154,14 +154,14 @@ select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, fun([TS, XML, PeerBin, Kind, Nick]) -> try #xmlel{} = El = fxml_stream:parse_element(XML), - Now = usec_to_now(jlib:binary_to_integer(TS)), + Now = usec_to_now(binary_to_integer(TS)), PeerJid = jid:tolower(jid:from_string(PeerBin)), T = case Kind of <<"">> -> chat; null -> chat; _ -> jlib:binary_to_atom(Kind) end, - [{TS, jlib:binary_to_integer(TS), + [{TS, binary_to_integer(TS), mod_mam:msg_to_el(#archive_msg{timestamp = Now, packet = El, type = T, @@ -176,7 +176,7 @@ select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, [Err, TS, XML, PeerBin, Kind, Nick]), [] end - end, Res1), IsComplete, jlib:binary_to_integer(Count)}; + end, Res1), IsComplete, binary_to_integer(Count)}; _ -> {[], false, 0} end. @@ -208,12 +208,12 @@ make_sql_query(User, LServer, _ -> fun ejabberd_sql:escape/1 end, LimitClause = if is_integer(Max), Max >= 0, ODBCType /= mssql -> - [<<" limit ">>, jlib:integer_to_binary(Max+1)]; + [<<" limit ">>, integer_to_binary(Max+1)]; true -> [] end, TopClause = if is_integer(Max), Max >= 0, ODBCType == mssql -> - [<<" TOP ">>, jlib:integer_to_binary(Max+1)]; + [<<" TOP ">>, integer_to_binary(Max+1)]; true -> [] end, @@ -235,7 +235,7 @@ make_sql_query(User, LServer, _ -> [] end, - PageClause = case catch jlib:binary_to_integer(ID) of + PageClause = case catch binary_to_integer(ID) of I when is_integer(I), I >= 0 -> case Direction of before -> @@ -251,14 +251,14 @@ make_sql_query(User, LServer, StartClause = case Start of {_, _, _} -> [<<" and timestamp >= ">>, - jlib:integer_to_binary(now_to_usec(Start))]; + integer_to_binary(now_to_usec(Start))]; _ -> [] end, EndClause = case End of {_, _, _} -> [<<" and timestamp <= ">>, - jlib:integer_to_binary(now_to_usec(End))]; + integer_to_binary(now_to_usec(End))]; _ -> [] end, diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index a7ba16138..4d56093e1 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -761,7 +761,7 @@ change_room_option(Name, Service, OptionString, ValueString) -> password -> ValueString; subject ->ValueString; subject_author ->ValueString; - max_users -> jlib:binary_to_integer(ValueString); + max_users -> binary_to_integer(ValueString); _ -> jlib:binary_to_atom(ValueString) end, change_room_option(Name, Service, Option, Value). diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 9c062065d..258c97d4f 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -301,7 +301,7 @@ get_sm_items(Acc, _From, _To, _Node, _Lang) -> ([xdata()], jid(), jid(), binary(), binary()) -> [xdata()]. get_info(_Acc, #jid{luser = U, lserver = S, lresource = R}, #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) -> - N = jlib:integer_to_binary(count_offline_messages(U, S)), + N = integer_to_binary(count_offline_messages(U, S)), case ejabberd_sm:get_session_pid(U, S, R) of Pid when is_pid(Pid) -> Pid ! dont_ask_offline; diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index a1f743657..7ca19b5e9 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -198,7 +198,7 @@ export(Server) -> [<<"select id from privacy_list order by " "id desc limit 1;">>]) of {selected, [<<"id">>], [[I]]} -> - put(id, jlib:binary_to_integer(I)); + put(id, binary_to_integer(I)); _ -> put(id, 0) end, diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index f7e1a9834..b55115c9a 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -3279,7 +3279,7 @@ max_items(Host, Options) -> -define(INTEGER_CONFIG_FIELD(Label, Var), ?STRINGXFIELD(Label, <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (jlib:integer_to_binary(get_option(Options, Var))))). + (integer_to_binary(get_option(Options, Var))))). -define(JLIST_CONFIG_FIELD(Label, Var, Opts), ?LISTXFIELD(Label, @@ -3418,7 +3418,7 @@ add_opt(Key, Value, Opts) -> set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). -define(SET_INTEGER_XOPT(Opt, Val, Min, Max), - case catch jlib:binary_to_integer(Val) of + case catch binary_to_integer(Val) of IVal when is_integer(IVal), IVal >= Min -> if (Max =:= undefined) orelse (IVal =< Max) -> set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 8b620514b..45d91bccd 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -907,21 +907,21 @@ shared_roster_group(Host, Group, Query, Lang) -> [?XCT(<<"td">>, <<"Description:">>), ?XE(<<"td">>, [?TEXTAREA(<<"description">>, - jlib:integer_to_binary(lists:max([3, + integer_to_binary(lists:max([3, DescNL])), <<"20">>, Description)])]), ?XE(<<"tr">>, [?XCT(<<"td">>, <<"Members:">>), ?XE(<<"td">>, [?TEXTAREA(<<"members">>, - jlib:integer_to_binary(lists:max([3, + integer_to_binary(lists:max([3, byte_size(FMembers)])), <<"20">>, FMembers)])]), ?XE(<<"tr">>, [?XCT(<<"td">>, <<"Displayed Groups:">>), ?XE(<<"td">>, [?TEXTAREA(<<"dispgroups">>, - jlib:integer_to_binary(lists:max([3, length(FDisplayedGroups)])), + integer_to_binary(lists:max([3, length(FDisplayedGroups)])), <<"20">>, list_to_binary(FDisplayedGroups))])])])])), (?H1GL((?T(<<"Shared Roster Groups">>)), diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index f8ac6be97..129f76b5a 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -82,7 +82,7 @@ search(LServer, Data, AllowReturnAll, MaxMatch) -> infinity -> <<"">>; Val -> - [<<" LIMIT ">>, jlib:integer_to_binary(Val)] + [<<" LIMIT ">>, integer_to_binary(Val)] end, case catch ejabberd_sql:sql_query( LServer, diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index a6f8888a9..69b476539 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -134,7 +134,7 @@ boolean_to_sql(false) -> <<"0">>. timestamp_to_sql(T) -> jlib:now_to_utc_string(T). -sql_to_integer(N) -> jlib:binary_to_integer(N). +sql_to_integer(N) -> binary_to_integer(N). sql_to_boolean(B) -> B == <<"1">>. diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index 33c884afb..de1a363db 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -203,7 +203,7 @@ var_xfield(_) -> {error, badarg}. val_xfield(deliver = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(digest = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(digest_frequency = Opt, [Val]) -> - case catch jlib:binary_to_integer(Val) of + case catch binary_to_integer(Val) of N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, @@ -225,7 +225,7 @@ val_xfield(subscription_type, [<<"items">>]) -> items; val_xfield(subscription_type, [<<"nodes">>]) -> nodes; val_xfield(subscription_depth, [<<"all">>]) -> all; val_xfield(subscription_depth = Opt, [Depth]) -> - case catch jlib:binary_to_integer(Depth) of + case catch binary_to_integer(Depth) of N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index 7c0670957..32aa41a93 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -168,7 +168,7 @@ var_xfield(_) -> {error, badarg}. val_xfield(deliver = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(digest = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(digest_frequency = Opt, [Val]) -> - case catch jlib:binary_to_integer(Val) of + case catch binary_to_integer(Val) of N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, @@ -190,7 +190,7 @@ val_xfield(subscription_type, [<<"items">>]) -> items; val_xfield(subscription_type, [<<"nodes">>]) -> nodes; val_xfield(subscription_depth, [<<"all">>]) -> all; val_xfield(subscription_depth = Opt, [Depth]) -> - case catch jlib:binary_to_integer(Depth) of + case catch binary_to_integer(Depth) of N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, diff --git a/src/randoms.erl b/src/randoms.erl index 52fceef4e..60d0b4e3d 100644 --- a/src/randoms.erl +++ b/src/randoms.erl @@ -36,5 +36,5 @@ start() -> get_string() -> R = crypto:rand_uniform(0, 16#10000000000000000), - jlib:integer_to_binary(R). + integer_to_binary(R). diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index bffe2f1ad..a0181e1e6 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -6686,8 +6686,8 @@ enc_tzo({H, M}) -> dec_tzo(Val) -> [H1, M1] = str:tokens(Val, <<":">>), - H = jlib:binary_to_integer(H1), - M = jlib:binary_to_integer(M1), + H = binary_to_integer(H1), + M = binary_to_integer(M1), if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. decode_thumbnail(__TopXMLNS, __IgnoreEls, -- cgit v1.2.3 From 3112a7187f1d313de424aac157ba4484fc1b506c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 25 Sep 2016 09:57:56 +0300 Subject: Test anonymous auth --- src/ejabberd_c2s.erl | 6 +++++- src/xmpp_codec.erl | 5 ++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 02540259a..f7d8e9dbb 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -907,8 +907,12 @@ wait_for_bind(#sm_resume{} = Pkt, StateData) -> wait_for_bind(Pkt, StateData) when ?IS_STREAM_MGMT_PACKET(Pkt) -> fsm_next_state(wait_for_bind, dispatch_stream_mgmt(Pkt, StateData)); wait_for_bind(#iq{type = set, - sub_els = [#bind{resource = R}]} = IQ, StateData) -> + sub_els = [#bind{resource = R0}]} = IQ, StateData) -> U = StateData#state.user, + R = case R0 of + <<>> -> new_uniq_id(); + _ -> R0 + end, case resource_conflict_action(U, StateData#state.server, R) of closenew -> Err = xmpp:make_error(IQ, xmpp:err_conflict()), diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index a0181e1e6..f8f8b205f 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -29737,7 +29737,7 @@ encode_legacy_auth_username_cdata(_val, _acc) -> decode_bind(__TopXMLNS, __IgnoreEls, {xmlel, <<"bind">>, _attrs, _els}) -> {Jid, Resource} = decode_bind_els(__TopXMLNS, - __IgnoreEls, _els, undefined, undefined), + __IgnoreEls, _els, undefined, <<>>), {bind, Jid, Resource}. decode_bind_els(__TopXMLNS, __IgnoreEls, [], Jid, @@ -29800,8 +29800,7 @@ encode_bind({bind, Jid, Resource}, __TopXMLNS) -> 'encode_bind_$jid'(Jid, __TopXMLNS, _acc) -> [encode_bind_jid(Jid, __TopXMLNS) | _acc]. -'encode_bind_$resource'(undefined, __TopXMLNS, _acc) -> - _acc; +'encode_bind_$resource'(<<>>, __TopXMLNS, _acc) -> _acc; 'encode_bind_$resource'(Resource, __TopXMLNS, _acc) -> [encode_bind_resource(Resource, __TopXMLNS) | _acc]. -- cgit v1.2.3 From 7566e267a757146e0b333429010aed922ad57766 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Thu, 29 Sep 2016 11:20:56 +0200 Subject: PubSub: fix error type on item deletion with insufficient priviledge --- src/node_flat.erl | 10 +++++----- src/node_flat_sql.erl | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/node_flat.erl b/src/node_flat.erl index e80aaad34..e3170a263 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -419,11 +419,11 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> #pubsub_state{affiliation = Affiliation, items = Items} = GenState, Allowed = Affiliation == publisher orelse Affiliation == owner orelse - PublishModel == open orelse - case get_item(Nidx, ItemId) of - {result, #pubsub_item{creation = {_, GenKey}}} -> true; - _ -> false - end, + (PublishModel == open andalso + case get_item(Nidx, ItemId) of + {result, #pubsub_item{creation = {_, GenKey}}} -> true; + _ -> false + end), if not Allowed -> {error, xmpp:err_forbidden()}; true -> diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index 025f6caa8..ac590a1dc 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -276,11 +276,11 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> {result, Affiliation} = get_affiliation(Nidx, GenKey), Allowed = Affiliation == publisher orelse Affiliation == owner orelse - PublishModel == open orelse - case get_item(Nidx, ItemId) of - {result, #pubsub_item{creation = {_, GenKey}}} -> true; - _ -> false - end, + (PublishModel == open andalso + case get_item(Nidx, ItemId) of + {result, #pubsub_item{creation = {_, GenKey}}} -> true; + _ -> false + end), if not Allowed -> {error, xmpp:err_forbidden()}; true -> -- cgit v1.2.3 From 1de0bb83a0bd42af502e0407f185cd6be0fd4a12 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Thu, 29 Sep 2016 16:10:11 +0200 Subject: PubSub: creation jid must be bare jid --- src/node_flat_sql.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index ac590a1dc..bd084333b 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -1036,6 +1036,6 @@ raw_to_item(Nidx, {ItemId, SJID, Creation, Modification, XML}) -> El -> [El] end, #pubsub_item{itemid = {ItemId, Nidx}, - creation = {ToTime(Creation), JID}, + creation = {ToTime(Creation), jid:remove_resource(JID)}, modification = {ToTime(Modification), JID}, payload = Payload}. -- cgit v1.2.3 From 6a3691ef7ce33c17d379ba40fa0c27f21c5ed75d Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 7 Oct 2016 10:31:03 +0300 Subject: Add xdata generator and make some code using it --- src/ejabberd_captcha.erl | 1 + src/flex_offline.erl | 128 +++ src/mod_caps.erl | 13 +- src/mod_mam.erl | 40 +- src/mod_muc.erl | 30 +- src/mod_muc_room.erl | 933 ++++++------------ src/mod_offline.erl | 11 +- src/mod_pubsub.erl | 637 +++++------- src/muc_register.erl | 364 +++++++ src/muc_request.erl | 269 +++++ src/muc_roomconfig.erl | 1675 ++++++++++++++++++++++++++++++++ src/muc_roominfo.erl | 491 ++++++++++ src/node_flat.erl | 3 +- src/node_flat_sql.erl | 2 +- src/pubsub_get_pending.erl | 130 +++ src/pubsub_node_config.erl | 1666 +++++++++++++++++++++++++++++++ src/pubsub_publish_options.erl | 157 +++ src/pubsub_subscribe_authorization.erl | 279 ++++++ src/pubsub_subscribe_options.erl | 508 ++++++++++ src/xdata_codec.erl | 648 ++++++++++++ src/xmpp_codec.erl | 33 +- src/xmpp_util.erl | 60 +- 22 files changed, 6962 insertions(+), 1116 deletions(-) create mode 100644 src/flex_offline.erl create mode 100644 src/muc_register.erl create mode 100644 src/muc_request.erl create mode 100644 src/muc_roomconfig.erl create mode 100644 src/muc_roominfo.erl create mode 100644 src/pubsub_get_pending.erl create mode 100644 src/pubsub_node_config.erl create mode 100644 src/pubsub_publish_options.erl create mode 100644 src/pubsub_subscribe_authorization.erl create mode 100644 src/pubsub_subscribe_options.erl create mode 100644 src/xdata_codec.erl (limited to 'src') diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index 9650f3773..a122eda8e 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -73,6 +73,7 @@ captcha_text(Lang) -> mk_ocr_field(Lang, CID, Type) -> URI = #media_uri{type = Type, uri = <<"cid:", CID/binary>>}, #xdata_field{var = <<"ocr">>, + type = 'text-single', label = captcha_text(Lang), required = true, sub_els = [#media{uri = [URI]}]}. diff --git a/src/flex_offline.erl b/src/flex_offline.erl new file mode 100644 index 000000000..090ab3ddf --- /dev/null +++ b/src/flex_offline.erl @@ -0,0 +1,128 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: flex_offline.xdata +%% Form type: http://jabber.org/protocol/offline +%% Document: XEP-0013 + +-module(flex_offline). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("flex_offline.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> Int; + Int when Int =< Max, Int >= Min -> Int + end. + +enc_int(Int) -> integer_to_binary(Int). + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/offline">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/offline">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {number_of_messages, Val} -> + [encode_number_of_messages(Val, Translate)]; + {number_of_messages, _, _} -> + erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/offline">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"number_of_messages">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{number_of_messages, Result} | Acc], + lists:delete(<<"number_of_messages">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"number_of_messages">>, + <<"http://jabber.org/protocol/offline">>}}) + end; +decode([#xdata_field{var = <<"number_of_messages">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"number_of_messages">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"number_of_messages">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"number_of_messages">>, + <<"http://jabber.org/protocol/offline">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/offline">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/offline">>}}); +decode([], Acc, []) -> Acc. + +encode_number_of_messages(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"number_of_messages">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Number of Offline Messages">>)}. diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 4d9bdd61f..65a745d2d 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -488,14 +488,11 @@ concat_identities(#disco_info{identities = Identities}) -> -spec concat_info(disco_info()) -> iolist(). concat_info(#disco_info{xdata = Xs}) -> lists:sort( - [concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]). - --spec concat_xdata_fields([xdata_field()]) -> iolist(). -concat_xdata_fields(Fields) -> - Form = case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, Fields) of - #xdata_field{values = Values} -> Values; - false -> [] - end, + [concat_xdata_fields(X) || #xdata{type = result} = X <- Xs]). + +-spec concat_xdata_fields(xdata()) -> iolist(). +concat_xdata_fields(#xdata{fields = Fields} = X) -> + Form = xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), Res = [[Var, $<, lists:sort([[Val, $<] || Val <- Values])] || #xdata_field{var = Var, values = Values} <- Fields, is_binary(Var), Var /= <<"FORM_TYPE">>], diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 8569ee020..1daae5aa2 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -37,7 +37,7 @@ process_iq_v0_2/1, process_iq_v0_3/1, disco_sm_features/5, remove_user/2, remove_room/3, mod_opt_type/1, muc_process_iq/2, muc_filter_message/5, message_is_archived/5, delete_old_messages/2, - get_commands_spec/0, msg_to_el/4, get_room_config/4, set_room_option/4]). + get_commands_spec/0, msg_to_el/4, get_room_config/4, set_room_option/3]). -include("xmpp.hrl"). -include("logger.hrl"). @@ -191,39 +191,17 @@ remove_room(LServer, Name, Host) -> Mod:remove_room(LServer, LName, LHost), ok. --spec get_room_config([xdata_field()], mod_muc_room:state(), jid(), binary()) - -> [xdata_field()]. -get_room_config(XFields, RoomState, _From, Lang) -> +-spec get_room_config([muc_roomconfig:property()], mod_muc_room:state(), + jid(), binary()) -> [muc_roomconfig:property()]. +get_room_config(Fields, RoomState, _From, _Lang) -> Config = RoomState#state.config, - Label = <<"Enable message archiving">>, - Var = <<"muc#roomconfig_mam">>, - Val = case Config#config.mam of - true -> <<"1">>; - _ -> <<"0">> - end, - XField = #xdata_field{type = boolean, - label = translate:translate(Lang, Label), - var = Var, - values = [Val]}, - XFields ++ [XField]. + Fields ++ [{mam, Config#config.mam}]. --spec set_room_option({pos_integer(), _}, binary(), [binary()], binary()) +-spec set_room_option({pos_integer(), _}, muc_roomconfig:property(), binary()) -> {pos_integer(), _}. -set_room_option(_Acc, <<"muc#roomconfig_mam">> = Opt, Vals, Lang) -> - try - Val = case Vals of - [<<"0">>|_] -> false; - [<<"false">>|_] -> false; - [<<"1">>|_] -> true; - [<<"true">>|_] -> true - end, - {#config.mam, Val} - catch _:{case_clause, _} -> - Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_bad_request(ErrTxt, Lang)} - end; -set_room_option(Acc, _Opt, _Vals, _Lang) -> +set_room_option(_Acc, {mam, Val}, _Lang) -> + {#config.mam, Val}; +set_room_option(Acc, _Property, _Lang) -> Acc. -spec user_receive_packet(stanza(), ejabberd_c2s:state(), jid(), jid(), jid()) -> stanza(). diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 66604394b..b189508a8 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -668,19 +668,18 @@ get_nick(ServerHost, Host, From) -> Mod:get_nick(LServer, Host, From). iq_get_register_info(ServerHost, Host, From, Lang) -> - {Nick, NickVals, Registered} = case get_nick(ServerHost, Host, From) of - error -> {<<"">>, [], false}; - N -> {N, [N], true} - end, + {Nick, Registered} = case get_nick(ServerHost, Host, From) of + error -> {<<"">>, false}; + N -> {N, true} + end, Title = <<(translate:translate( Lang, <<"Nickname Registration at ">>))/binary, Host/binary>>, Inst = translate:translate(Lang, <<"Enter nickname you want to register">>), - Field = #xdata_field{type = 'text-single', - label = translate:translate(Lang, <<"Nickname">>), - var = <<"nick">>, - values = NickVals}, + Fields = muc_register:encode( + [{roomnick, Nick}], + fun(T) -> translate:translate(Lang, T) end), X = #xdata{type = form, title = Title, - instructions = [Inst], fields = [Field]}, + instructions = [Inst], fields = Fields}, #register{nick = Nick, registered = Registered, instructions = @@ -717,12 +716,13 @@ process_iq_register_set(ServerHost, Host, From, #register{nick = Nick, xdata = XData}, Lang) -> case XData of #xdata{type = submit, fields = Fs} -> - case lists:keyfind(<<"nick">>, #xdata_field.var, Fs) of - #xdata_field{values = [N]} -> - iq_set_register_info(ServerHost, Host, From, N, Lang); - _ -> - ErrText = <<"You must fill in field \"Nickname\" in the form">>, - {error, xmpp:err_not_acceptable(ErrText, Lang)} + try + Options = muc_register:decode(Fs), + N = proplists:get_value(roomnick, Options), + iq_set_register_info(ServerHost, Host, From, N, Lang) + catch _:{muc_register, Why} -> + ErrText = muc_register:format_error(Why), + {error, xmpp:err_bad_request(ErrText, Lang)} end; #xdata{} -> Txt = <<"Incorrect data form">>, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 339b85ecb..52401f835 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -754,100 +754,131 @@ process_groupchat_message(From, #message{lang = Lang} = Packet, StateData) -> -spec process_normal_message(jid(), message(), state()) -> state(). process_normal_message(From, #message{lang = Lang} = Pkt, StateData) -> - IsInvitation = is_invitation(Pkt), - IsVoiceRequest = is_voice_request(Pkt) and - is_visitor(From, StateData), - IsVoiceApprovement = is_voice_approvement(Pkt) and - not is_visitor(From, StateData), - if IsInvitation -> - case check_invitation(From, Pkt, StateData) of - {error, Error} -> - ejabberd_router:route_error(StateData#state.jid, From, Pkt, Error), - StateData; - IJID -> - Config = StateData#state.config, - case Config#config.members_only of - true -> - case get_affiliation(IJID, StateData) of - none -> - NSD = set_affiliation(IJID, member, StateData), - send_affiliation(IJID, member, StateData), - store_room(NSD), - NSD; - _ -> - StateData - end; - false -> - StateData - end - end; - IsVoiceRequest -> - case (StateData#state.config)#config.allow_voice_requests of + Action = lists:foldl( + fun(_, {error, _} = Err) -> + Err; + (#muc_user{invites = [#muc_invite{to = undefined}]}, _) -> + Txt = <<"No 'to' attribute found">>, + {error, xmpp:err_bad_request(Txt, Lang)}; + (#muc_user{invites = [I]}, _) -> + {ok, I}; + (#muc_user{invites = [_|_]}, _) -> + Txt = <<"Multiple elements are not allowed">>, + {error, xmpp:err_resource_constraint(Txt, Lang)}; + (#xdata{type = submit, fields = Fs}, _) -> + try {ok, muc_request:decode(Fs)} + catch _:{muc_request, Why} -> + Txt = muc_request:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)} + end; + (_, Acc) -> + Acc + end, ok, xmpp:get_els(Pkt)), + case Action of + {ok, #muc_invite{} = Invitation} -> + process_invitation(From, Pkt, Invitation, StateData); + {ok, [{role, participant}]} -> + process_voice_request(From, Pkt, StateData); + {ok, VoiceApproval} -> + process_voice_approval(From, Pkt, VoiceApproval, StateData); + {error, Err} -> + ejabberd_router:route_error(StateData#state.jid, From, Pkt, Err), + StateData; + ok -> + StateData + end. + +-spec process_invitation(jid(), message(), muc_invite(), state()) -> state(). +process_invitation(From, Pkt, Invitation, StateData) -> + Lang = xmpp:get_lang(Pkt), + case check_invitation(From, Invitation, Lang, StateData) of + {error, Error} -> + ejabberd_router:route_error(StateData#state.jid, From, Pkt, Error), + StateData; + IJID -> + Config = StateData#state.config, + case Config#config.members_only of true -> - MinInterval = (StateData#state.config)#config.voice_request_min_interval, - BareFrom = jid:remove_resource(jid:tolower(From)), - NowPriority = -p1_time_compat:system_time(micro_seconds), - CleanPriority = NowPriority + MinInterval * 1000000, - Times = clean_treap(StateData#state.last_voice_request_time, - CleanPriority), - case treap:lookup(BareFrom, Times) of - error -> - Times1 = treap:insert(BareFrom, - NowPriority, - true, Times), - NSD = StateData#state{last_voice_request_time = Times1}, - send_voice_request(From, Lang, NSD), + case get_affiliation(IJID, StateData) of + none -> + NSD = set_affiliation(IJID, member, StateData), + send_affiliation(IJID, member, StateData), + store_room(NSD), NSD; - {ok, _, _} -> - ErrText = <<"Please, wait for a while before sending " - "new voice request">>, - Err = xmpp:err_not_acceptable(ErrText, Lang), - ejabberd_router:route_error( - StateData#state.jid, From, Pkt, Err), - StateData#state{last_voice_request_time = Times} + _ -> + StateData end; false -> - ErrText = <<"Voice requests are disabled in this conference">>, - Err = xmpp:err_forbidden(ErrText, Lang), + StateData + end + end. + +-spec process_voice_request(jid(), message(), state()) -> state(). +process_voice_request(From, Pkt, StateData) -> + Lang = xmpp:get_lang(Pkt), + case (StateData#state.config)#config.allow_voice_requests of + true -> + MinInterval = (StateData#state.config)#config.voice_request_min_interval, + BareFrom = jid:remove_resource(jid:tolower(From)), + NowPriority = -p1_time_compat:system_time(micro_seconds), + CleanPriority = NowPriority + MinInterval * 1000000, + Times = clean_treap(StateData#state.last_voice_request_time, + CleanPriority), + case treap:lookup(BareFrom, Times) of + error -> + Times1 = treap:insert(BareFrom, + NowPriority, + true, Times), + NSD = StateData#state{last_voice_request_time = Times1}, + send_voice_request(From, Lang, NSD), + NSD; + {ok, _, _} -> + ErrText = <<"Please, wait for a while before sending " + "new voice request">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), ejabberd_router:route_error( StateData#state.jid, From, Pkt, Err), - StateData + StateData#state{last_voice_request_time = Times} end; - IsVoiceApprovement -> - case is_moderator(From, StateData) of - true -> - case extract_jid_from_voice_approvement(Pkt) of - error -> - ErrText = <<"Failed to extract JID from your voice " - "request approval">>, - Err = xmpp:err_bad_request(ErrText, Lang), - ejabberd_router:route_error( - StateData#state.jid, From, Pkt, Err), - StateData; - TargetJid -> - case is_visitor(TargetJid, StateData) of - true -> - Reason = <<>>, - NSD = set_role(TargetJid, - participant, - StateData), - catch send_new_presence(TargetJid, - Reason, - NSD, - StateData), - NSD; - _ -> - StateData - end + false -> + ErrText = <<"Voice requests are disabled in this conference">>, + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), + StateData + end. + +-spec process_voice_approval(jid(), message(), [muc_request:property()], state()) -> state(). +process_voice_approval(From, Pkt, VoiceApproval, StateData) -> + Lang = xmpp:get_lang(Pkt), + case is_moderator(From, StateData) of + true -> + case lists:keyfind(jid, 1, VoiceApproval) of + {_, TargetJid} -> + Allow = proplists:get_bool(request_allow, VoiceApproval), + case is_visitor(TargetJid, StateData) of + true when Allow -> + Reason = <<>>, + NSD = set_role(TargetJid, participant, StateData), + catch send_new_presence( + TargetJid, Reason, NSD, StateData), + NSD; + _ -> + StateData end; - _ -> - ErrText = <<"Only moderators can approve voice requests">>, - Err = xmpp:err_not_allowed(ErrText, Lang), + false -> + ErrText = <<"Failed to extract JID from your voice " + "request approval">>, + Err = xmpp:err_bad_request(ErrText, Lang), ejabberd_router:route_error( StateData#state.jid, From, Pkt, Err), StateData end; - true -> + false -> + ErrText = <<"Only moderators can approve voice requests">>, + Err = xmpp:err_not_allowed(ErrText, Lang), + ejabberd_router:route_error( + StateData#state.jid, From, Pkt, Err), StateData end. @@ -3090,34 +3121,6 @@ is_password_settings_correct(XData, StateData) -> _ -> true end. --define(XFIELD(Type, Label, Var, Vals), - #xdata_field{type = Type, - label = translate:translate(Lang, Label), - var = Var, - values = Vals}). - --define(BOOLXFIELD(Label, Var, Val), - ?XFIELD(boolean, Label, Var, - case Val of - true -> [<<"1">>]; - _ -> [<<"0">>] - end)). - --define(STRINGXFIELD(Label, Var, Val), - ?XFIELD('text-single', Label, Var, [Val])). - --define(PRIVATEXFIELD(Label, Var, Val), - ?XFIELD('text-private', Label, Var, [Val])). - --define(JIDMULTIXFIELD(Label, Var, JIDList), - ?XFIELD('jid-multi', Label, Var, - [jid:to_string(JID) || JID <- JIDList])). - --spec make_options([{binary(), binary()}], binary()) -> [xdata_option()]. -make_options(Options, Lang) -> - [#xdata_option{label = translate:translate(Lang, Label), - value = Value} || {Label, Value} <- Options]. - -spec get_default_room_maxusers(state()) -> non_neg_integer(). get_default_room_maxusers(RoomState) -> DefRoomOpts = @@ -3138,424 +3141,156 @@ get_config(Lang, StateData, From) -> {MaxUsersRoomInteger, MaxUsersRoomString} = case get_max_users(StateData) of N when is_integer(N) -> - {N, integer_to_binary(N)}; - _ -> {0, <<"none">>} + {N, N}; + _ -> {0, none} end, Title = iolist_to_binary( io_lib:format( translate:translate(Lang, <<"Configuration of room ~s">>), [jid:to_string(StateData#state.jid)])), - Fs = [#xdata_field{type = hidden, - var = <<"FORM_TYPE">>, - values = [<<"http://jabber.org/protocol/muc#roomconfig">>]}, - ?STRINGXFIELD(<<"Room title">>, - <<"muc#roomconfig_roomname">>, (Config#config.title)), - ?STRINGXFIELD(<<"Room description">>, - <<"muc#roomconfig_roomdesc">>, - (Config#config.description))] ++ + Fs = [{roomname, Config#config.title}, + {roomdesc, Config#config.description}] ++ case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of - allow -> - [?BOOLXFIELD(<<"Make room persistent">>, - <<"muc#roomconfig_persistentroom">>, - (Config#config.persistent))]; + allow -> [{persistentroom, Config#config.persistent}]; deny -> [] end ++ - [?BOOLXFIELD(<<"Make room public searchable">>, - <<"muc#roomconfig_publicroom">>, - (Config#config.public)), - ?BOOLXFIELD(<<"Make participants list public">>, - <<"public_list">>, (Config#config.public_list)), - ?BOOLXFIELD(<<"Make room password protected">>, - <<"muc#roomconfig_passwordprotectedroom">>, - (Config#config.password_protected)), - ?PRIVATEXFIELD(<<"Password">>, - <<"muc#roomconfig_roomsecret">>, - case Config#config.password_protected of - true -> Config#config.password; - false -> <<"">> - end), - #xdata_field{type = 'list-single', - label = translate:translate( - Lang, <<"Maximum Number of Occupants">>), - var = <<"muc#roomconfig_maxusers">>, - values = [MaxUsersRoomString], - options = - if is_integer(ServiceMaxUsers) -> []; - true -> make_options( - [{<<"No limit">>, <<"none">>}], - Lang) - end ++ - make_options( - [{integer_to_binary(N), integer_to_binary(N)} - || N <- lists:usort([ServiceMaxUsers, - DefaultRoomMaxUsers, - MaxUsersRoomInteger - | ?MAX_USERS_DEFAULT_LIST]), - N =< ServiceMaxUsers], - Lang)}, - #xdata_field{type = 'list-single', - label = translate:translate( - Lang, <<"Present real Jabber IDs to">>), - var = <<"muc#roomconfig_whois">>, - values = [if Config#config.anonymous -> <<"moderators">>; - true -> <<"anyone">> - end], - options = make_options( - [{<<"moderators only">>, <<"moderators">>}, - {<<"anyone">>, <<"anyone">>}], - Lang)}, - #xdata_field{type = 'list-multi', - label = translate:translate( - Lang, - <<"Roles for which Presence is Broadcasted">>), - var = <<"muc#roomconfig_presencebroadcast">>, - values = [atom_to_binary(Role, utf8) - || Role <- Config#config.presence_broadcast], - options = make_options( - [{<<"Moderator">>, <<"moderator">>}, - {<<"Participant">>, <<"participant">>}, - {<<"Visitor">>, <<"visitor">>}], - Lang)}, - ?BOOLXFIELD(<<"Make room members-only">>, - <<"muc#roomconfig_membersonly">>, - (Config#config.members_only)), - ?BOOLXFIELD(<<"Make room moderated">>, - <<"muc#roomconfig_moderatedroom">>, - (Config#config.moderated)), - ?BOOLXFIELD(<<"Default users as participants">>, - <<"members_by_default">>, - (Config#config.members_by_default)), - ?BOOLXFIELD(<<"Allow users to change the subject">>, - <<"muc#roomconfig_changesubject">>, - (Config#config.allow_change_subj)), - ?BOOLXFIELD(<<"Allow users to send private messages">>, - <<"allow_private_messages">>, - (Config#config.allow_private_messages)), - #xdata_field{type = 'list-single', - label = translate:translate( - Lang, - <<"Allow visitors to send private messages to">>), - var = <<"allow_private_messages_from_visitors">>, - values = [case Config#config.allow_private_messages_from_visitors of - anyone -> <<"anyone">>; - moderators -> <<"moderators">>; - nobody -> <<"nobody">> - end], - options = make_options( - [{<<"nobody">>, <<"nobody">>}, - {<<"moderators only">>, <<"moderators">>}, - {<<"anyone">>, <<"anyone">>}], - Lang)}, - ?BOOLXFIELD(<<"Allow users to query other users">>, - <<"allow_query_users">>, - (Config#config.allow_query_users)), - ?BOOLXFIELD(<<"Allow users to send invites">>, - <<"muc#roomconfig_allowinvites">>, - (Config#config.allow_user_invites)), - ?BOOLXFIELD(<<"Allow visitors to send status text in " - "presence updates">>, - <<"muc#roomconfig_allowvisitorstatus">>, - (Config#config.allow_visitor_status)), - ?BOOLXFIELD(<<"Allow visitors to change nickname">>, - <<"muc#roomconfig_allowvisitornickchange">>, - (Config#config.allow_visitor_nickchange)), - ?BOOLXFIELD(<<"Allow visitors to send voice requests">>, - <<"muc#roomconfig_allowvoicerequests">>, - (Config#config.allow_voice_requests)), - ?BOOLXFIELD(<<"Allow subscription">>, - <<"muc#roomconfig_allow_subscription">>, - (Config#config.allow_subscription)), - ?STRINGXFIELD(<<"Minimum interval between voice requests " - "(in seconds)">>, - <<"muc#roomconfig_voicerequestmininterval">>, - integer_to_binary(Config#config.voice_request_min_interval))] + [{publicroom, Config#config.public}, + {public_list, Config#config.public_list}, + {passwordprotectedroom, Config#config.password_protected}, + {roomsecret, case Config#config.password_protected of + true -> Config#config.password; + false -> <<"">> + end}, + {maxusers, MaxUsersRoomString, + [if is_integer(ServiceMaxUsers) -> []; + true -> [{<<"No limit">>, <<"none">>}] + end] ++ [{integer_to_binary(N), N} + || N <- lists:usort([ServiceMaxUsers, + DefaultRoomMaxUsers, + MaxUsersRoomInteger + | ?MAX_USERS_DEFAULT_LIST]), + N =< ServiceMaxUsers]}, + {whois, if Config#config.anonymous -> moderators; + true -> anyone + end}, + {presencebroadcast, Config#config.presence_broadcast}, + {membersonly, Config#config.members_only}, + {moderatedroom, Config#config.moderated}, + {members_by_default, Config#config.members_by_default}, + {changesubject, Config#config.allow_change_subj}, + {allow_private_messages, Config#config.allow_private_messages}, + {allow_private_messages_from_visitors, + Config#config.allow_private_messages_from_visitors}, + {allow_query_users, Config#config.allow_query_users}, + {allowinvites, Config#config.allow_user_invites}, + {allow_visitor_status, Config#config.allow_visitor_status}, + {allow_visitor_nickchange, Config#config.allow_visitor_nickchange}, + {allow_voice_requests, Config#config.allow_voice_requests}, + {allow_subscription, Config#config.allow_subscription}, + {voice_request_min_interval, Config#config.voice_request_min_interval}] ++ case ejabberd_captcha:is_feature_available() of - true -> - [?BOOLXFIELD(<<"Make room CAPTCHA protected">>, - <<"captcha_protected">>, - (Config#config.captcha_protected))]; + true -> [{captcha_protected, Config#config.captcha_protected}]; false -> [] end ++ - [?JIDMULTIXFIELD(<<"Exclude Jabber IDs from CAPTCHA challenge">>, - <<"muc#roomconfig_captcha_whitelist">>, - ((?SETS):to_list(Config#config.captcha_whitelist)))] + [{captcha_whitelist, + lists:map(fun jid:make/1, ?SETS:to_list(Config#config.captcha_whitelist))}] ++ case mod_muc_log:check_access_log(StateData#state.server_host, From) of - allow -> - [?BOOLXFIELD(<<"Enable logging">>, - <<"muc#roomconfig_enablelogging">>, - (Config#config.logging))]; + allow -> [{enablelogging, Config#config.logging}]; deny -> [] end, Fields = ejabberd_hooks:run_fold(get_room_config, StateData#state.server_host, Fs, [StateData, From, Lang]), - #xdata{type = form, title = Title, fields = Fields}. + #xdata{type = form, title = Title, + fields = muc_roomconfig:encode( + Fields, fun(T) -> translate:translate(Lang, T) end)}. -spec set_config(xdata(), state(), binary()) -> {error, stanza_error()} | {result, undefined, state()}. set_config(#xdata{fields = Fields}, StateData, Lang) -> - Options = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- Fields], - case set_xoption(Options, StateData#state.config, - StateData#state.server_host, Lang) of - #config{} = Config -> - Res = change_config(Config, StateData), - {result, _, NSD} = Res, - Type = case {(StateData#state.config)#config.logging, - Config#config.logging} - of - {true, false} -> roomconfig_change_disabledlogging; - {false, true} -> roomconfig_change_enabledlogging; - {_, _} -> roomconfig_change - end, - Users = [{U#user.jid, U#user.nick, U#user.role} - || {_, U} <- (?DICT):to_list(StateData#state.users)], - add_to_log(Type, Users, NSD), - Res; - Err -> Err + try + Options = muc_roomconfig:decode(Fields), + #config{} = Config = set_config(Options, StateData#state.config, + StateData#state.server_host, Lang), + {result, _, NSD} = Res = change_config(Config, StateData), + Type = case {(StateData#state.config)#config.logging, + Config#config.logging} + of + {true, false} -> roomconfig_change_disabledlogging; + {false, true} -> roomconfig_change_enabledlogging; + {_, _} -> roomconfig_change + end, + Users = [{U#user.jid, U#user.nick, U#user.role} + || {_, U} <- (?DICT):to_list(StateData#state.users)], + add_to_log(Type, Users, NSD), + Res + catch _:{muc_roomconfig, Why} -> + Txt = muc_roomconfig:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)}; + _:{badmatch, {error, #stanza_error{}} = Err} -> + Err end. get_config_opt_name(Pos) -> Fs = [config|record_info(fields, config)], lists:nth(Pos, Fs). --define(SET_BOOL_XOPT(Opt, Val), - case Val of - <<"0">> -> - set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang); - <<"false">> -> - set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang); - <<"1">> -> set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang); - <<"true">> -> - set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang); - _ -> - Txt = <<"Value of '~s' should be boolean">>, - OptName = get_config_opt_name(Opt), - ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])), - {error, xmpp:err_bad_request(ErrTxt, Lang)} - end). - --define(SET_NAT_XOPT(Opt, Val), - case catch binary_to_integer(Val) of - I when is_integer(I), I > 0 -> - set_xoption(Opts, setelement(Opt, Config, I), ServerHost, Lang); - _ -> - Txt = <<"Value of '~s' should be integer">>, - OptName = get_config_opt_name(Opt), - ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])), - {error, xmpp:err_bad_request(ErrTxt, Lang)} - end). - --define(SET_STRING_XOPT(Opt, Vals), - try - V = case Vals of - [] -> <<"">>; - [Val] -> Val; - _ when is_atom(Vals) -> Vals - end, - set_xoption(Opts, setelement(Opt, Config, V), ServerHost, Lang) - catch _:_ -> - Txt = <<"Incorrect value of option '~s'">>, - OptName = get_config_opt_name(Opt), - ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])), - {error, xmpp:err_bad_request(ErrTxt, Lang)} - end). - --define(SET_JIDMULTI_XOPT(Opt, Vals), - begin - Set = lists:foldl(fun ({U, S, R}, Set1) -> - (?SETS):add_element({U, S, R}, Set1); - (#jid{luser = U, lserver = S, lresource = R}, - Set1) -> - (?SETS):add_element({U, S, R}, Set1); - (_, Set1) -> Set1 - end, - (?SETS):empty(), Vals), - set_xoption(Opts, setelement(Opt, Config, Set), ServerHost, Lang) - end). - --spec set_xoption([{binary(), [binary()]}], #config{}, +-spec set_config([muc_roomconfig:property()], #config{}, binary(), binary()) -> #config{} | {error, stanza_error()}. -set_xoption([], Config, _ServerHost, _Lang) -> Config; -set_xoption([{<<"muc#roomconfig_roomname">>, Vals} - | Opts], - Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(#config.title, Vals); -set_xoption([{<<"muc#roomconfig_roomdesc">>, Vals} - | Opts], - Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(#config.description, Vals); -set_xoption([{<<"muc#roomconfig_changesubject">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_change_subj, Val); -set_xoption([{<<"allow_query_users">>, [Val]} | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_query_users, Val); -set_xoption([{<<"allow_private_messages">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_private_messages, Val); -set_xoption([{<<"allow_private_messages_from_visitors">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - case Val of - <<"anyone">> -> - ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors, - anyone); - <<"moderators">> -> - ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors, - moderators); - <<"nobody">> -> - ?SET_STRING_XOPT(#config.allow_private_messages_from_visitors, - nobody); - _ -> - Txt = <<"Value of 'allow_private_messages_from_visitors' " - "should be anyone|moderators|nobody">>, - {error, xmpp:err_bad_request(Txt, Lang)} - end; -set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_visitor_status, Val); -set_xoption([{<<"muc#roomconfig_allowvisitornickchange">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_visitor_nickchange, Val); -set_xoption([{<<"muc#roomconfig_publicroom">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.public, Val); -set_xoption([{<<"public_list">>, [Val]} | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.public_list, Val); -set_xoption([{<<"muc#roomconfig_persistentroom">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.persistent, Val); -set_xoption([{<<"muc#roomconfig_moderatedroom">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.moderated, Val); -set_xoption([{<<"members_by_default">>, [Val]} | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.members_by_default, Val); -set_xoption([{<<"muc#roomconfig_membersonly">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.members_only, Val); -set_xoption([{<<"captcha_protected">>, [Val]} | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.captcha_protected, Val); -set_xoption([{<<"muc#roomconfig_allowinvites">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_user_invites, Val); -set_xoption([{<<"muc#roomconfig_allow_subscription">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_subscription, Val); -set_xoption([{<<"muc#roomconfig_passwordprotectedroom">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.password_protected, Val); -set_xoption([{<<"muc#roomconfig_roomsecret">>, Vals} - | Opts], - Config, ServerHost, Lang) -> - ?SET_STRING_XOPT(#config.password, Vals); -set_xoption([{<<"anonymous">>, [Val]} | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.anonymous, Val); -set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts], - Config, ServerHost, Lang) -> - Roles = - lists:foldl( - fun(_S, error) -> error; - (S, {M, P, V}) -> - case S of - <<"moderator">> -> {true, P, V}; - <<"participant">> -> {M, true, V}; - <<"visitor">> -> {M, P, true}; - _ -> error - end - end, {false, false, false}, Vals), - case Roles of - error -> - Txt = <<"Value of 'muc#roomconfig_presencebroadcast' should " - "be moderator|participant|visitor">>, - {error, xmpp:err_bad_request(Txt, Lang)}; - {M, P, V} -> - Res = - if M -> [moderator]; true -> [] end ++ - if P -> [participant]; true -> [] end ++ - if V -> [visitor]; true -> [] end, - set_xoption(Opts, Config#config{presence_broadcast = Res}, - ServerHost, Lang) - end; -set_xoption([{<<"muc#roomconfig_allowvoicerequests">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.allow_voice_requests, Val); -set_xoption([{<<"muc#roomconfig_voicerequestmininterval">>, - [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_NAT_XOPT(#config.voice_request_min_interval, Val); -set_xoption([{<<"muc#roomconfig_whois">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - case Val of - <<"moderators">> -> - ?SET_BOOL_XOPT(#config.anonymous, - (iolist_to_binary(integer_to_list(1)))); - <<"anyone">> -> - ?SET_BOOL_XOPT(#config.anonymous, - (iolist_to_binary(integer_to_list(0)))); - _ -> - Txt = <<"Value of 'muc#roomconfig_whois' should be " - "moderators|anyone">>, - {error, xmpp:err_bad_request(Txt, Lang)} - end; -set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - case Val of - <<"none">> -> ?SET_STRING_XOPT(#config.max_users, none); - _ -> ?SET_NAT_XOPT(#config.max_users, Val) - end; -set_xoption([{<<"muc#roomconfig_enablelogging">>, [Val]} - | Opts], - Config, ServerHost, Lang) -> - ?SET_BOOL_XOPT(#config.logging, Val); -set_xoption([{<<"muc#roomconfig_captcha_whitelist">>, - Vals} - | Opts], - Config, ServerHost, Lang) -> - JIDs = [jid:from_string(Val) || Val <- Vals], - ?SET_JIDMULTI_XOPT(#config.captcha_whitelist, JIDs); -set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config, ServerHost, Lang) -> - set_xoption(Opts, Config, ServerHost, Lang); -set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) -> - Txt = <<"Unknown option '~s'">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - Err = {error, xmpp:err_bad_request(ErrTxt, Lang)}, - case ejabberd_hooks:run_fold(set_room_option, - ServerHost, - Err, - [Opt, Vals, Lang]) of - {error, Reason} -> - {error, Reason}; - {Pos, Val} -> - set_xoption(Opts, setelement(Pos, Config, Val), ServerHost, Lang) - end. +set_config(Opts, Config, ServerHost, Lang) -> + lists:foldl( + fun(_, {error, _} = Err) -> Err; + ({roomname, Title}, C) -> C#config{title = Title}; + ({roomdesc, Desc}, C) -> C#config{description = Desc}; + ({changesubject, V}, C) -> C#config{allow_change_subj = V}; + ({allow_query_users, V}, C) -> C#config{allow_query_users = V}; + ({allow_private_messages, V}, C) -> + C#config{allow_private_messages = V}; + ({allow_private_messages_from_visitors, V}, C) -> + C#config{allow_private_messages_from_visitors = V}; + ({allow_visitor_status, V}, C) -> C#config{allow_visitor_status = V}; + ({allow_visitor_nickchange, V}, C) -> + C#config{allow_visitor_nickchange = V}; + ({publicroom, V}, C) -> C#config{public = V}; + ({public_list, V}, C) -> C#config{public_list = V}; + ({persistentroom, V}, C) -> C#config{persistent = V}; + ({moderatedroom, V}, C) -> C#config{moderated = V}; + ({members_by_default, V}, C) -> C#config{members_by_default = V}; + ({membersonly, V}, C) -> C#config{members_only = V}; + ({captcha_protected, V}, C) -> C#config{captcha_protected = V}; + ({allowinvites, V}, C) -> C#config{allow_user_invites = V}; + ({allow_subscription, V}, C) -> C#config{allow_subscription = V}; + ({passwordprotectedroom, V}, C) -> C#config{password_protected = V}; + ({roomsecret, V}, C) -> C#config{password = V}; + ({anonymous, V}, C) -> C#config{anonymous = V}; + ({presencebroadcast, V}, C) -> C#config{presence_broadcast = V}; + ({allow_voice_requests, V}, C) -> C#config{allow_voice_requests = V}; + ({voice_request_min_interval, V}, C) -> + C#config{voice_request_min_interval = V}; + ({whois, moderators}, C) -> C#config{anonymous = true}; + ({whois, anyone}, C) -> C#config{anonymous = false}; + ({maxusers, V}, C) -> C#config{max_users = V}; + ({enablelogging, V}, C) -> C#config{logging = V}; + ({captcha_whitelist, Js}, C) -> + LJIDs = [jid:tolower(J) || J <- Js], + C#config{captcha_whitelist = ?SETS:from_list(LJIDs)}; + ({O, V} = Opt, C) -> + case ejabberd_hooks:run_fold(set_room_option, + ServerHost, + {0, undefined}, + [Opt, Lang]) of + {0, undefined} -> + ?ERROR_MSG("set_room_option hook failed for " + "option '~s' with value ~p", [O, V]), + Txt = <<"Failed to process option '", O/binary, "'">>, + {error, xmpp:err_internal_server_error(Txt, Lang)}; + {Pos, Val} -> + setelement(Pos, C, Val) + end + end, Config, Opts). -spec change_config(#config{}, state()) -> {result, undefined, state()}. change_config(Config, StateData) -> @@ -3872,33 +3607,13 @@ process_iq_disco_info(_From, #iq{type = get, lang = Lang}, StateData) -> name = get_title(StateData)}], features = Feats}}. --spec mk_rfieldt('boolean' | 'fixed' | 'hidden' | - 'jid-multi' | 'jid-single' | 'list-multi' | - 'list-single' | 'text-multi' | 'text-private' | - 'text-single', binary(), binary()) -> xdata_field(). -mk_rfieldt(Type, Var, Val) -> - #xdata_field{type = Type, var = Var, values = [Val]}. - --spec mk_rfield(binary(), binary(), binary(), binary()) -> xdata_field(). -mk_rfield(Label, Var, Val, Lang) -> - #xdata_field{type = 'text-single', - label = translate:translate(Lang, Label), - var = Var, - values = [Val]}. - -spec iq_disco_info_extras(binary(), state()) -> xdata(). iq_disco_info_extras(Lang, StateData) -> - Len = (?DICT):size(StateData#state.users), - RoomDescription = (StateData#state.config)#config.description, + Fs = [{description, (StateData#state.config)#config.description}, + {occupants, ?DICT:size(StateData#state.users)}], #xdata{type = result, - fields = [mk_rfieldt(hidden, <<"FORM_TYPE">>, - "http://jabber.org/protocol/muc#roominfo"), - mk_rfield(<<"Room description">>, - <<"muc#roominfo_description">>, - RoomDescription, Lang), - mk_rfield(<<"Number of occupants">>, - <<"muc#roominfo_occupants">>, - integer_to_binary(Len), Lang)]}. + fields = muc_roominfo:encode( + Fs, fun(T) -> translate:translate(Lang, T) end)}. -spec process_iq_disco_items(jid(), iq(), state()) -> {error, stanza_error()} | {result, disco_items()}. @@ -4105,39 +3820,16 @@ get_mucroom_disco_items(StateData) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Voice request support --spec is_voice_request(message()) -> boolean(). -is_voice_request(Packet) -> - Els = xmpp:get_els(Packet), - lists:any( - fun(#xdata{} = X) -> - case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), - xmpp_util:get_xdata_values(<<"muc#role">>, X)} of - {[<<"http://jabber.org/protocol/muc#request">>], - [<<"participant">>]} -> - true; - _ -> - false - end; - (_) -> - false - end, Els). - -spec prepare_request_form(jid(), binary(), binary()) -> message(). prepare_request_form(Requester, Nick, Lang) -> Title = translate:translate(Lang, <<"Voice request">>), Instruction = translate:translate( Lang, <<"Either approve or decline the voice request.">>), - Fs = [#xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = [<<"http://jabber.org/protocol/muc#request">>]}, - #xdata_field{var = <<"muc#role">>, - type = hidden, - values = [<<"participant">>]}, - ?STRINGXFIELD(<<"User JID">>, <<"muc#jid">>, - jid:to_string(Requester)), - ?STRINGXFIELD(<<"Nickname">>, <<"muc#roomnick">>, Nick), - ?BOOLXFIELD(<<"Grant voice to this person?">>, - <<"muc#request_allow">>, false)], + Fs = muc_request:encode([{role, participant}, + {jid, Requester}, + {roomnick, Nick}, + {request_allow, false}], + fun(T) -> translate:translate(Lang, T) end), #message{type = normal, sub_els = [#xdata{type = form, title = Title, @@ -4155,59 +3847,11 @@ send_voice_request(From, Lang, StateData) -> end, Moderators). --spec is_voice_approvement(message()) -> boolean(). -is_voice_approvement(Packet) -> - Els = xmpp:get_els(Packet), - lists:any( - fun(#xdata{} = X) -> - case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), - xmpp_util:get_xdata_values(<<"muc#role">>, X), - xmpp_util:get_xdata_values(<<"muc#request_allow">>, X)} of - {[<<"http://jabber.org/protocol/muc#request">>], - [<<"participant">>], [Flag]} when Flag == <<"true">>; - Flag == <<"1">> -> - true; - _ -> - false - end; - (_) -> - false - end, Els). - --spec extract_jid_from_voice_approvement(message()) -> jid() | error. -extract_jid_from_voice_approvement(Packet) -> - Els = xmpp:get_els(Packet), - lists:foldl( - fun(#xdata{} = X, error) -> - case {xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X), - xmpp_util:get_xdata_values(<<"muc#role">>, X), - xmpp_util:get_xdata_values(<<"muc#request_allow">>, X), - xmpp_util:get_xdata_values(<<"muc#jid">>, X)} of - {[<<"http://jabber.org/protocol/muc#request">>], - [<<"participant">>], [Flag], [J]} when Flag == <<"true">>; - Flag == <<"1">> -> - jid:from_string(J); - _ -> - error - end; - (_, Acc) -> - Acc - end, error, Els). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Invitation support --spec is_invitation(message()) -> boolean(). -is_invitation(Packet) -> - Els = xmpp:get_els(Packet), - lists:any( - fun(#muc_user{invites = [_|_]}) -> true; - (_) -> false - end, Els). - --spec check_invitation(jid(), message(), state()) -> {error, stanza_error()} | jid(). -check_invitation(From, Packet, StateData) -> - Lang = xmpp:get_lang(Packet), +-spec check_invitation(jid(), muc_invite(), binary(), state()) -> {error, stanza_error()} | jid(). +check_invitation(From, Invitation, Lang, StateData) -> FAffiliation = get_affiliation(From, StateData), CanInvite = (StateData#state.config)#config.allow_user_invites orelse @@ -4217,57 +3861,46 @@ check_invitation(From, Packet, StateData) -> Txt = <<"Invitations are not allowed in this conference">>, {error, xmpp:err_not_allowed(Txt, Lang)}; true -> - case xmpp:get_subtag(Packet, #muc_user{}) of - #muc_user{invites = [#muc_invite{to = undefined}]} -> - Txt = <<"No 'to' attribute found">>, - {error, xmpp:err_bad_request(Txt, Lang)}; - #muc_user{invites = [#muc_invite{to = JID, reason = Reason} = I]} -> - Invite = I#muc_invite{to = undefined, from = From}, - Password = case (StateData#state.config)#config.password_protected of - true -> - (StateData#state.config)#config.password; - false -> - undefined - end, - XUser = #muc_user{password = Password, invites = [Invite]}, - XConference = #x_conference{jid = jid:make(StateData#state.room, - StateData#state.host), - reason = Reason}, - Body = iolist_to_binary( - [io_lib:format( - translate:translate( - Lang, - <<"~s invites you to the room ~s">>), - [jid:to_string(From), - jid:to_string({StateData#state.room, - StateData#state.host, - <<"">>})]), - case (StateData#state.config)#config.password_protected of - true -> - <<", ", - (translate:translate( - Lang, <<"the password is">>))/binary, - " '", - ((StateData#state.config)#config.password)/binary, - "'">>; - _ -> <<"">> - end, - case Reason of - <<"">> -> <<"">>; - _ -> <<" (", Reason/binary, ") ">> - end]), - Msg = #message{type = normal, - body = xmpp:mk_text(Body), - sub_els = [XUser, XConference]}, - ejabberd_router:route(StateData#state.jid, JID, Msg), - JID; - #muc_user{invites = [_|_]} -> - Txt = <<"Multiple elements are not allowed">>, - {error, xmpp:err_forbidden(Txt, Lang)}; - _ -> - Txt = <<"No element found">>, - {error, xmpp:err_bad_request(Txt, Lang)} - end + #muc_invite{to = JID, reason = Reason} = Invitation, + Invite = Invitation#muc_invite{to = undefined, from = From}, + Password = case (StateData#state.config)#config.password_protected of + true -> + (StateData#state.config)#config.password; + false -> + undefined + end, + XUser = #muc_user{password = Password, invites = [Invite]}, + XConference = #x_conference{jid = jid:make(StateData#state.room, + StateData#state.host), + reason = Reason}, + Body = iolist_to_binary( + [io_lib:format( + translate:translate( + Lang, + <<"~s invites you to the room ~s">>), + [jid:to_string(From), + jid:to_string({StateData#state.room, + StateData#state.host, + <<"">>})]), + case (StateData#state.config)#config.password_protected of + true -> + <<", ", + (translate:translate( + Lang, <<"the password is">>))/binary, + " '", + ((StateData#state.config)#config.password)/binary, + "'">>; + _ -> <<"">> + end, + case Reason of + <<"">> -> <<"">>; + _ -> <<" (", Reason/binary, ") ">> + end]), + Msg = #message{type = normal, + body = xmpp:mk_text(Body), + sub_els = [XUser, XConference]}, + ejabberd_router:route(StateData#state.jid, JID, Msg), + JID end. %% Handle a message sent to the room by a non-participant. diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 258c97d4f..240650234 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -300,8 +300,7 @@ get_sm_items(Acc, _From, _To, _Node, _Lang) -> -spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()]; ([xdata()], jid(), jid(), binary(), binary()) -> [xdata()]. get_info(_Acc, #jid{luser = U, lserver = S, lresource = R}, - #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) -> - N = integer_to_binary(count_offline_messages(U, S)), + #jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, Lang) -> case ejabberd_sm:get_session_pid(U, S, R) of Pid when is_pid(Pid) -> Pid ! dont_ask_offline; @@ -309,11 +308,9 @@ get_info(_Acc, #jid{luser = U, lserver = S, lresource = R}, ok end, [#xdata{type = result, - fields = [#xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = [?NS_FLEX_OFFLINE]}, - #xdata_field{var = <<"number_of_messages">>, - values = [N]}]}]; + fields = flex_offline:encode( + [{number_of_messages, count_offline_messages(U, S)}], + fun(T) -> translate:translate(Lang, T) end)}]; get_info(Acc, _From, _To, _Node, _Lang) -> Acc. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index b55115c9a..e3fe64c16 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -1028,8 +1028,11 @@ do_route(Host, From, To, Packet) -> case find_authorization_response(Packet) of undefined -> ok; - XData -> - handle_authorization_response(Host, From, To, Packet, XData) + {error, Err} -> + ejabberd_router:route_error(To, From, Packet, Err); + AuthResponse -> + handle_authorization_response( + Host, From, To, Packet, AuthResponse) end; _ -> Err = xmpp:err_service_unavailable(), @@ -1200,19 +1203,28 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, ServerHost = serverhost(Host), Plugins = config(ServerHost, plugins), Config = case Configure of - {_, XData} -> get_xdata_fields(XData); + {_, XData} -> decode_node_config(XData, Host, Lang); undefined -> [] end, Type = hd(Plugins), - create_node(Host, ServerHost, Node, From, Type, Access, Config); + case Config of + {error, _} = Err -> + Err; + _ -> + create_node(Host, ServerHost, Node, From, Type, Access, Config) + end; {set, #pubsub{publish = #ps_publish{node = Node, items = Items}, publish_options = XData, _ = undefined}} -> ServerHost = serverhost(Host), case Items of [#ps_item{id = ItemId, xml_els = Payload}] -> - PubOpts = get_xdata_fields(XData), - publish_item(Host, ServerHost, Node, From, ItemId, - Payload, PubOpts, Access); + case decode_publish_options(XData, Lang) of + {error, _} = Err -> + Err; + PubOpts -> + publish_item(Host, ServerHost, Node, From, ItemId, + Payload, PubOpts, Access) + end; [] -> {error, extended_error(xmpp:err_bad_request(), err_item_required())}; _ -> @@ -1236,10 +1248,17 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, {set, #pubsub{subscribe = #ps_subscribe{node = Node, jid = JID}, options = Options, _ = undefined}} -> Config = case Options of - #ps_options{xdata = XData} -> get_xdata_fields(XData); - _ -> [] + #ps_options{xdata = XData} -> + decode_subscribe_options(XData, Lang); + _ -> + [] end, - subscribe_node(Host, Node, From, JID, Config); + case Config of + {error, _} = Err -> + Err; + _ -> + subscribe_node(Host, Node, From, JID, Config) + end; {set, #pubsub{unsubscribe = #ps_unsubscribe{node = Node, jid = JID, subid = SubId}, _ = undefined}} -> unsubscribe_node(Host, Node, From, JID, SubId); @@ -1262,7 +1281,12 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang, {set, #pubsub{options = #ps_options{node = Node, subid = SubId, jid = JID, xdata = XData}, _ = undefined}} -> - set_options(Host, Node, JID, SubId, get_xdata_fields(XData)); + case decode_subscribe_options(XData, Lang) of + {error, _} = Err -> + Err; + Config -> + set_options(Host, Node, JID, SubId, Config) + end; {set, #pubsub{}} -> {error, xmpp:err_bad_request()}; _ -> @@ -1284,8 +1308,12 @@ iq_pubsub_owner(Host, #iq{type = IQType, from = From, #xdata{type = cancel} -> {result, #pubsub_owner{}}; #xdata{type = submit} -> - Config = get_xdata_fields(XData), - set_configure(Host, Node, From, Config, Lang); + case decode_node_config(XData, Host, Lang) of + {error, _} = Err -> + Err; + Config -> + set_configure(Host, Node, From, Config, Lang) + end; #xdata{} -> {error, xmpp:err_bad_request(<<"Incorrect data form">>, Lang)} end; @@ -1318,19 +1346,20 @@ adhoc_request(Host, _ServerHost, Owner, send_pending_node_form(Host, Owner, Lang, Plugins); adhoc_request(Host, _ServerHost, Owner, #adhoc_command{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, - action = execute, xdata = #xdata{} = XData}, + action = execute, xdata = #xdata{} = XData} = Request, _Access, _Plugins) -> - Config = get_xdata_fields(XData), - case set_xoption(Host, Config, []) of - XForm when is_list(XForm) -> - case lists:keysearch(node, 1, XForm) of - {value, {_, Node}} -> - send_pending_auth_events(Host, Node, Owner, Lang); - false -> - {error, extended_error(xmpp:err_bad_request(), err_invalid_payload())} - end; - Err -> - Err + case decode_get_pending(XData, Lang) of + {error, _} = Err -> + Err; + Config -> + Node = proplists:get_value(node, Config), + case send_pending_auth_events(Host, Node, Owner, Lang) of + ok -> + xmpp_util:make_adhoc_response( + Request, #adhoc_command{action = completed}); + Err -> + Err + end end; adhoc_request(_Host, _ServerHost, _Owner, #adhoc_command{action = cancel}, _Access, _Plugins) -> @@ -1353,12 +1382,9 @@ send_pending_node_form(Host, Owner, _Lang, Plugins) -> Ps -> case get_pending_nodes(Host, Owner, Ps) of {ok, Nodes} -> - XOpts = [#xdata_option{value = Node} || Node <- Nodes], XForm = #xdata{type = form, - fields = [#xdata_field{ - type = 'list-single', - var = <<"pubsub#node">>, - options = lists:usort(XOpts)}]}, + fields = pubsub_get_pending:encode( + [{node, Nodes}])}, #adhoc_command{status = executing, action = execute, xdata = XForm}; Err -> @@ -1423,24 +1449,11 @@ send_authorization_request(#pubsub_node{nodeid = {Host, Node}, Subscriber) -> %% TODO: pass lang to this function Lang = <<"en">>, - Fs = [#xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = [?NS_PUBSUB_SUB_AUTH]}, - #xdata_field{var = <<"pubsub#node">>, - type = 'text-single', - label = translate:translate(Lang, <<"Node ID">>), - values = [Node]}, - #xdata_field{var = <<"pubsub#subscriber_jid">>, - type = 'jid-single', - label = translate:translate(Lang, <<"Subscriber Address">>), - values = [jid:to_string(Subscriber)]}, - #xdata_field{var = <<"pubsub#allow">>, - type = boolean, - label = translate:translate( - Lang, - <<"Allow this Jabber ID to subscribe to " - "this pubsub node?">>), - values = [<<"false">>]}], + Fs = pubsub_subscribe_authorization:encode( + [{node, Node}, + {subscriber_jid, Subscriber}, + {allow, false}], + fun(T) -> translate:translate(Lang, T) end), X = #xdata{type = form, title = translate:translate( Lang, <<"PubSub subscriber request">>), @@ -1455,15 +1468,24 @@ send_authorization_request(#pubsub_node{nodeid = {Host, Node}, ejabberd_router:route(service_jid(Host), jid:make(Owner), Stanza) end, node_owners_action(Host, Type, Nidx, O)). --spec find_authorization_response(message()) -> undefined | xdata(). +-spec find_authorization_response(message()) -> undefined | + pubsub_subscribe_authorization:result() | + {error, stanza_error()}. find_authorization_response(Packet) -> case xmpp:get_subtag(Packet, #xdata{}) of - #xdata{type = submit} = X -> - case xmpp_util:get_xdata_values(<<"FORM_TYPE">>, X) of - [?NS_PUBSUB_SUB_AUTH] -> X; - _ -> undefined + #xdata{type = cancel} -> + undefined; + #xdata{type = submit, fields = Fs} -> + try pubsub_subscribe_authorization:decode(Fs) of + Result -> Result + catch _:{pubsub_subscribe_authorization, Why} -> + Lang = xmpp:get_lang(Packet), + Txt = pubsub_subscribe_authorization:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)} end; - _ -> + #xdata{} -> + {error, xmpp:err_bad_request()}; + false -> undefined end. @@ -1477,43 +1499,33 @@ send_authorization_approval(Host, JID, SNode, Subscription) -> Stanza = #message{sub_els = [Event]}, ejabberd_router:route(service_jid(Host), JID, Stanza). --spec handle_authorization_response(binary(), jid(), jid(), message(), xdata()) -> ok. -handle_authorization_response(Host, From, To, Packet, X) -> +-spec handle_authorization_response(binary(), jid(), jid(), message(), + pubsub_subscribe_authorization:result()) -> ok. +handle_authorization_response(Host, From, To, Packet, Response) -> + Node = proplists:get_value(node, Response), + Subscriber = proplists:get_value(subscriber_jid, Response), + Allow = proplists:get_value(allow, Response), Lang = xmpp:get_lang(Packet), - case {xmpp_util:get_xdata_values(<<"pubsub#node">>, X), - xmpp_util:get_xdata_values(<<"pubsub#subscriber_jid">>, X), - xmpp_util:get_xdata_values(<<"pubsub#allow">>, X)} of - {[Node], [SSubscriber], [SAllow]} -> - FromLJID = jid:tolower(jid:remove_resource(From)), - Subscriber = jid:from_string(SSubscriber), - Allow = case SAllow of - <<"1">> -> true; - <<"true">> -> true; - _ -> false - end, - Action = - fun(#pubsub_node{type = Type, id = Nidx, owners = O}) -> - Owners = node_owners_call(Host, Type, Nidx, O), - case lists:member(FromLJID, Owners) of - true -> - {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), - update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs); - false -> - {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)} - end - end, - case transaction(Host, Node, Action, sync_dirty) of - {error, Error} -> - ejabberd_router:route_error(To, From, Packet, Error); - {result, {_, _NewSubscription}} -> - %% XXX: notify about subscription state change, section 12.11 - ok; - _ -> - Err = xmpp:err_internal_server_error(), - ejabberd_router:route_error(To, From, Packet, Err) - end; + FromLJID = jid:tolower(jid:remove_resource(From)), + Action = + fun(#pubsub_node{type = Type, id = Nidx, owners = O}) -> + Owners = node_owners_call(Host, Type, Nidx, O), + case lists:member(FromLJID, Owners) of + true -> + {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), + update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs); + false -> + {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)} + end + end, + case transaction(Host, Node, Action, sync_dirty) of + {error, Error} -> + ejabberd_router:route_error(To, From, Packet, Error); + {result, {_, _NewSubscription}} -> + %% XXX: notify about subscription state change, section 12.11 + ok; _ -> - Err = xmpp:err_not_acceptable(<<"Incorrect data form">>, Lang), + Err = xmpp:err_internal_server_error(), ejabberd_router:route_error(To, From, Packet, Err) end. @@ -1539,45 +1551,6 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) -> {error, xmpp:err_unexpected_request(Txt, ?MYLANG)} end. --define(XFIELD(Type, Label, Var, Val), - #xdata_field{type = Type, - label = translate:translate(Lang, Label), - var = Var, - values = [Val]}). - --define(BOOLXFIELD(Label, Var, Val), - ?XFIELD(boolean, Label, Var, - case Val of - true -> <<"1">>; - _ -> <<"0">> - end)). - --define(STRINGXFIELD(Label, Var, Val), - ?XFIELD('text-single', Label, Var, Val)). - --define(STRINGMXFIELD(Label, Var, Vals), - #xdata_field{type = 'text-multi', - label = translate:translate(Lang, Label), - var = Var, - values = Vals}). - --define(XFIELDOPT(Type, Label, Var, Val, Opts), - #xdata_field{type = Type, - label = translate:translate(Lang, Label), - var = Var, - options = [#xdata_option{value = Opt} || Opt <- Opts], - values = [Val]}). - --define(LISTXFIELD(Label, Var, Val, Opts), - ?XFIELDOPT('list-single', Label, Var, Val, Opts)). - --define(LISTMXFIELD(Label, Var, Vals, Opts), - #xdata_field{type = 'list-multi', - label = translate:translate(Lang, Label), - var = Var, - options = [#xdata_option{value = Opt} || Opt <- Opts], - values = Vals}). - %% @doc

    Create new pubsub nodes

    %%

    In addition to method-specific error conditions, there are several general reasons why the node creation request might fail:

    %%
      @@ -1617,70 +1590,66 @@ create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) -> end; create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> Type = select_type(ServerHost, Host, Node, GivenType), - case set_xoption(Host, Configuration, node_options(Host, Type)) of - NodeOptions when is_list(NodeOptions) -> - CreateNode = - fun() -> - Parent = case node_call(Host, Type, node_to_path, [Node]) of - {result, [Node]} -> - <<>>; - {result, Path} -> - element(2, node_call(Host, Type, path_to_node, - [lists:sublist(Path, length(Path)-1)])) - end, - Parents = case Parent of - <<>> -> []; - _ -> [Parent] - end, - case node_call(Host, Type, create_node_permission, - [Host, ServerHost, Node, Parent, Owner, Access]) of - {result, true} -> - case tree_call(Host, create_node, - [Host, Node, Type, Owner, NodeOptions, Parents]) - of - {ok, Nidx} -> - SubsByDepth = get_node_subs_by_depth(Host, Node, Owner), - case node_call(Host, Type, create_node, [Nidx, Owner]) of - {result, Result} -> {result, {Nidx, SubsByDepth, Result}}; - Error -> Error - end; - {error, {virtual, Nidx}} -> - case node_call(Host, Type, create_node, [Nidx, Owner]) of - {result, Result} -> {result, {Nidx, [], Result}}; - Error -> Error - end; - Error -> - Error + NodeOptions = merge_config(Configuration, node_options(Host, Type)), + CreateNode = + fun() -> + Parent = case node_call(Host, Type, node_to_path, [Node]) of + {result, [Node]} -> + <<>>; + {result, Path} -> + element(2, node_call(Host, Type, path_to_node, + [lists:sublist(Path, length(Path)-1)])) + end, + Parents = case Parent of + <<>> -> []; + _ -> [Parent] + end, + case node_call(Host, Type, create_node_permission, + [Host, ServerHost, Node, Parent, Owner, Access]) of + {result, true} -> + case tree_call(Host, create_node, + [Host, Node, Type, Owner, NodeOptions, Parents]) + of + {ok, Nidx} -> + SubsByDepth = get_node_subs_by_depth(Host, Node, Owner), + case node_call(Host, Type, create_node, [Nidx, Owner]) of + {result, Result} -> {result, {Nidx, SubsByDepth, Result}}; + Error -> Error end; - _ -> - Txt = <<"You're not allowed to create nodes">>, - {error, xmpp:err_forbidden(Txt, ?MYLANG)} - end - end, - Reply = #pubsub{create = Node}, - case transaction(Host, CreateNode, transaction) of - {result, {Nidx, SubsByDepth, {Result, broadcast}}} -> - broadcast_created_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth), - ejabberd_hooks:run(pubsub_create_node, ServerHost, - [ServerHost, Host, Node, Nidx, NodeOptions]), - case Result of - default -> {result, Reply}; - _ -> {result, Result} - end; - {result, {Nidx, _SubsByDepth, Result}} -> - ejabberd_hooks:run(pubsub_create_node, ServerHost, - [ServerHost, Host, Node, Nidx, NodeOptions]), - case Result of - default -> {result, Reply}; - _ -> {result, Result} - end; - Error -> - %% in case we change transaction to sync_dirty... - %% node_call(Host, Type, delete_node, [Host, Node]), - %% tree_call(Host, delete_node, [Host, Node]), - Error + {error, {virtual, Nidx}} -> + case node_call(Host, Type, create_node, [Nidx, Owner]) of + {result, Result} -> {result, {Nidx, [], Result}}; + Error -> Error + end; + Error -> + Error + end; + _ -> + Txt = <<"You're not allowed to create nodes">>, + {error, xmpp:err_forbidden(Txt, ?MYLANG)} + end + end, + Reply = #pubsub{create = Node}, + case transaction(Host, CreateNode, transaction) of + {result, {Nidx, SubsByDepth, {Result, broadcast}}} -> + broadcast_created_node(Host, Node, Nidx, Type, NodeOptions, SubsByDepth), + ejabberd_hooks:run(pubsub_create_node, ServerHost, + [ServerHost, Host, Node, Nidx, NodeOptions]), + case Result of + default -> {result, Reply}; + _ -> {result, Result} + end; + {result, {Nidx, _SubsByDepth, Result}} -> + ejabberd_hooks:run(pubsub_create_node, ServerHost, + [ServerHost, Host, Node, Nidx, NodeOptions]), + case Result of + default -> {result, Reply}; + _ -> {result, Result} end; Error -> + %% in case we change transaction to sync_dirty... + %% node_call(Host, Type, delete_node, [Host, Node]), + %% tree_call(Host, delete_node, [Host, Node]), Error end. @@ -2636,7 +2605,7 @@ set_subscriptions(Host, Node, From, Entities) -> Owner = jid:tolower(jid:remove_resource(From)), Notify = fun(#ps_subscription{jid = JID, type = Sub}) -> Stanza = #message{ - sub_els = [#pubsub{ + sub_els = [#ps_event{ subscription = #ps_subscription{ jid = JID, type = Sub, @@ -3266,83 +3235,17 @@ max_items(Host, Options) -> end end. --define(BOOL_CONFIG_FIELD(Label, Var), - ?BOOLXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (get_option(Options, Var)))). - --define(STRING_CONFIG_FIELD(Label, Var), - ?STRINGXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (get_option(Options, Var, <<>>)))). - --define(INTEGER_CONFIG_FIELD(Label, Var), - ?STRINGXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (integer_to_binary(get_option(Options, Var))))). - --define(JLIST_CONFIG_FIELD(Label, Var, Opts), - ?LISTXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (jid:to_string(get_option(Options, Var))), - [jid:to_string(O) || O <- Opts])). - --define(ALIST_CONFIG_FIELD(Label, Var, Opts), - ?LISTXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (atom_to_binary(get_option(Options, Var), latin1)), - [atom_to_binary(O, latin1) || O <- Opts])). - --define(LISTM_CONFIG_FIELD(Label, Var, Opts), - ?LISTMXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - (get_option(Options, Var)), Opts)). - --define(NLIST_CONFIG_FIELD(Label, Var), - ?STRINGMXFIELD(Label, - <<"pubsub#", (atom_to_binary(Var, latin1))/binary>>, - get_option(Options, Var, []))). - +-spec get_configure_xfields(_, pubsub_node_config:result(), + binary(), [binary()]) -> [xdata_field()]. get_configure_xfields(_Type, Options, Lang, Groups) -> - [?XFIELD(hidden, <<>>, <<"FORM_TYPE">>, ?NS_PUBSUB_NODE_CONFIG), - ?BOOL_CONFIG_FIELD(<<"Deliver payloads with event notifications">>, - deliver_payloads), - ?BOOL_CONFIG_FIELD(<<"Deliver event notifications">>, - deliver_notifications), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node configuration changes">>, - notify_config), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when the node is deleted">>, - notify_delete), - ?BOOL_CONFIG_FIELD(<<"Notify subscribers when items are removed from the node">>, - notify_retract), - ?BOOL_CONFIG_FIELD(<<"Persist items to storage">>, - persist_items), - ?STRING_CONFIG_FIELD(<<"A friendly name for the node">>, - title), - ?INTEGER_CONFIG_FIELD(<<"Max # of items to persist">>, - max_items), - ?BOOL_CONFIG_FIELD(<<"Whether to allow subscriptions">>, - subscribe), - ?ALIST_CONFIG_FIELD(<<"Specify the access model">>, - access_model, [open, authorize, presence, roster, whitelist]), - ?LISTM_CONFIG_FIELD(<<"Roster groups allowed to subscribe">>, - roster_groups_allowed, Groups), - ?ALIST_CONFIG_FIELD(<<"Specify the publisher model">>, - publish_model, [publishers, subscribers, open]), - ?BOOL_CONFIG_FIELD(<<"Purge all items when the relevant publisher goes offline">>, - purge_offline), - ?ALIST_CONFIG_FIELD(<<"Specify the event message type">>, - notification_type, [headline, normal]), - ?INTEGER_CONFIG_FIELD(<<"Max payload size in bytes">>, - max_payload_size), - ?ALIST_CONFIG_FIELD(<<"When to send the last published item">>, - send_last_published_item, [never, on_sub, on_sub_and_presence]), - ?BOOL_CONFIG_FIELD(<<"Only deliver notifications to available users">>, - presence_based_delivery), - ?NLIST_CONFIG_FIELD(<<"The collections with which a node is affiliated">>, - collection), - ?ALIST_CONFIG_FIELD(<<"Whether owners or publisher should receive replies to items">>, - itemreply, [none, owner, publisher])]. + pubsub_node_config:encode( + lists:map( + fun({roster_groups_allowed, Value}) -> + {roster_groups_allowed, Value, Groups}; + (Opt) -> + Opt + end, Options), + fun(Txt) -> translate:translate(Lang, Txt) end). %%

      There are several reasons why the node configuration request might fail:

      %%
        @@ -3365,18 +3268,13 @@ set_configure(Host, Node, From, Config, Lang) -> [] -> node_options(Host, Type); _ -> Options end, - case set_xoption(Host, Config, OldOpts) of - NewOpts when is_list(NewOpts) -> - case tree_call(Host, - set_node, - [N#pubsub_node{options = NewOpts}]) - of - {result, Nidx} -> {result, ok}; - ok -> {result, ok}; - Err -> Err - end; - Error -> - Error + NewOpts = merge_config(Config, OldOpts), + case tree_call(Host, + set_node, + [N#pubsub_node{options = NewOpts}]) of + {result, Nidx} -> {result, ok}; + ok -> {result, ok}; + Err -> Err end; _ -> {error, xmpp:err_forbidden( @@ -3394,119 +3292,82 @@ set_configure(Host, Node, From, Config, Lang) -> Other end. --spec add_opt(atom(), any(), [{atom(), any()}]) -> [{atom(), any()}]. -add_opt(Key, Value, Opts) -> - lists:keystore(Key, 1, Opts, {Key, Value}). +-spec merge_config([proplists:property()], [proplists:property()]) -> [proplists:property()]. +merge_config(Config1, Config2) -> + lists:foldl( + fun({Opt, Val}, Acc) -> + lists:keystore(Opt, 1, Acc, {Opt, Val}) + end, Config2, Config1). --define(SET_BOOL_XOPT(Opt, Val), - BoolVal = case Val of - <<"0">> -> false; - <<"1">> -> true; - <<"false">> -> false; - <<"true">> -> true; - _ -> error - end, - case BoolVal of - error -> - Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; - _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts)) - end). - --define(SET_STRING_XOPT(Opt, Val), - set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). - --define(SET_INTEGER_XOPT(Opt, Val, Min, Max), - case catch binary_to_integer(Val) of - IVal when is_integer(IVal), IVal >= Min -> - if (Max =:= undefined) orelse (IVal =< Max) -> - set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); - true -> - Txt = <<"Incorrect value of '~s'">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} - end; - _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} - end). +-spec decode_node_config(undefined | xdata(), binary(), binary()) -> + pubsub_node_config:result() | + {error, stanza_error()}. +decode_node_config(undefined, _, _) -> + []; +decode_node_config(#xdata{fields = Fs}, Host, Lang) -> + try + Config = pubsub_node_config:decode(Fs), + Max = get_max_items_node(Host), + case {check_opt_range(max_items, Config, Max), + check_opt_range(max_payload_size, Config, ?MAX_PAYLOAD_SIZE)} of + {true, true} -> + Config; + {true, false} -> + erlang:error( + {pubsub_node_config, + {bad_var_value, <<"pubsub#max_payload_size">>, + ?NS_PUBSUB_NODE_CONFIG}}); + {false, _} -> + erlang:error( + {pubsub_node_config, + {bad_var_value, <<"pubsub#max_items">>, + ?NS_PUBSUB_NODE_CONFIG}}) + end + catch _:{pubsub_node_config, Why} -> + Txt = pubsub_node_config:format_error(Why), + {error, xmpp:err_resource_constraint(Txt, Lang)} + end. + +-spec decode_subscribe_options(undefined | xdata(), binary()) -> + pubsub_subscribe_options:result() | + {error, stanza_error()}. +decode_subscribe_options(undefined, _) -> + []; +decode_subscribe_options(#xdata{fields = Fs}, Lang) -> + try pubsub_subscribe_options:decode(Fs) + catch _:{pubsub_subscribe_options, Why} -> + Txt = pubsub_subscribe_options:format_error(Why), + {error, xmpp:err_resource_constraint(Txt, Lang)} + end. --define(SET_ALIST_XOPT(Opt, Val, Vals), - case lists:member(Val, [atom_to_binary(V, latin1) || V <- Vals]) of - true -> - set_xoption(Host, Opts, add_opt(Opt, jlib:binary_to_atom(Val), NewOpts)); - false -> - Txt = <<"Incorrect value of '~s'">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} - end). - --define(SET_LIST_XOPT(Opt, Val), - set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). - --spec set_xoption(host(), [{binary(), [binary()]}], [{atom(), any()}]) -> [{atom(), any()}]. -set_xoption(_Host, [], NewOpts) -> NewOpts; -set_xoption(Host, [{<<"FORM_TYPE">>, _} | Opts], NewOpts) -> - set_xoption(Host, Opts, NewOpts); -set_xoption(Host, [{<<"pubsub#roster_groups_allowed">>, Value} | Opts], NewOpts) -> - ?SET_LIST_XOPT(roster_groups_allowed, Value); -set_xoption(Host, [{<<"pubsub#deliver_payloads">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(deliver_payloads, Val); -set_xoption(Host, [{<<"pubsub#deliver_notifications">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(deliver_notifications, Val); -set_xoption(Host, [{<<"pubsub#notify_config">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(notify_config, Val); -set_xoption(Host, [{<<"pubsub#notify_delete">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(notify_delete, Val); -set_xoption(Host, [{<<"pubsub#notify_retract">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(notify_retract, Val); -set_xoption(Host, [{<<"pubsub#persist_items">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(persist_items, Val); -set_xoption(Host, [{<<"pubsub#max_items">>, [Val]} | Opts], NewOpts) -> - MaxItems = get_max_items_node(Host), - ?SET_INTEGER_XOPT(max_items, Val, 0, MaxItems); -set_xoption(Host, [{<<"pubsub#subscribe">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(subscribe, Val); -set_xoption(Host, [{<<"pubsub#access_model">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(access_model, Val, [open, authorize, presence, roster, whitelist]); -set_xoption(Host, [{<<"pubsub#publish_model">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(publish_model, Val, [publishers, subscribers, open]); -set_xoption(Host, [{<<"pubsub#notification_type">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(notification_type, Val, [headline, normal]); -set_xoption(Host, [{<<"pubsub#node_type">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(node_type, Val, [leaf, collection]); -set_xoption(Host, [{<<"pubsub#max_payload_size">>, [Val]} | Opts], NewOpts) -> - ?SET_INTEGER_XOPT(max_payload_size, Val, 0, (?MAX_PAYLOAD_SIZE)); -set_xoption(Host, [{<<"pubsub#send_last_published_item">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(send_last_published_item, Val, [never, on_sub, on_sub_and_presence]); -set_xoption(Host, [{<<"pubsub#presence_based_delivery">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(presence_based_delivery, Val); -set_xoption(Host, [{<<"pubsub#purge_offline">>, [Val]} | Opts], NewOpts) -> - ?SET_BOOL_XOPT(purge_offline, Val); -set_xoption(Host, [{<<"pubsub#title">>, Value} | Opts], NewOpts) -> - ?SET_STRING_XOPT(title, Value); -set_xoption(Host, [{<<"pubsub#type">>, Value} | Opts], NewOpts) -> - ?SET_STRING_XOPT(type, Value); -set_xoption(Host, [{<<"pubsub#body_xslt">>, Value} | Opts], NewOpts) -> - ?SET_STRING_XOPT(body_xslt, Value); -set_xoption(Host, [{<<"pubsub#collection">>, Value} | Opts], NewOpts) -> - % NewValue = [string_to_node(V) || V <- Value], - ?SET_LIST_XOPT(collection, Value); -set_xoption(Host, [{<<"pubsub#node">>, [Value]} | Opts], NewOpts) -> - % NewValue = string_to_node(Value), - ?SET_LIST_XOPT(node, Value); -set_xoption(Host, [{<<"pubsub#itemreply">>, [Val]} | Opts], NewOpts) -> - ?SET_ALIST_XOPT(itemreply, Val, [none, owner, publisher]); -set_xoption(Host, [_ | Opts], NewOpts) -> - set_xoption(Host, Opts, NewOpts). - --spec get_xdata_fields(undefined | xdata()) -> [{binary(), [binary()]}]. -get_xdata_fields(undefined) -> +-spec decode_publish_options(undefined | xdata(), binary()) -> + pubsub_publish_options:result() | + {error, stanza_error()}. +decode_publish_options(undefined, _) -> []; -get_xdata_fields(#xdata{fields = Fs}) -> - [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- Fs]. +decode_publish_options(#xdata{fields = Fs}, Lang) -> + try pubsub_publish_options:decode(Fs) + catch _:{pubsub_publish_options, Why} -> + Txt = pubsub_publish_options:format_error(Why), + {error, xmpp:err_resource_constraint(Txt, Lang)} + end. + +-spec decode_get_pending(xdata(), binary()) -> + pubsub_get_pending:result() | + {error, stanza_error()}. +decode_get_pending(#xdata{fields = Fs}, Lang) -> + try pubsub_get_pending:decode(Fs) + catch _:{pubsub_get_pending, Why} -> + Txt = pubsub_get_pending:format_error(Why), + {error, xmpp:err_resource_constraint(Txt, Lang)} + end; +decode_get_pending(undefined, Lang) -> + {error, xmpp:err_bad_request(<<"No data form found">>, Lang)}. + +-spec check_opt_range(atom(), [proplists:property()], non_neg_integer()) -> boolean(). +check_opt_range(Opt, Opts, Max) -> + Val = proplists:get_value(Opt, Opts, Max), + Val =< Max. -spec get_max_items_node(host()) -> undefined | non_neg_integer(). get_max_items_node(Host) -> diff --git a/src/muc_register.erl b/src/muc_register.erl new file mode 100644 index 000000000..cddce2b98 --- /dev/null +++ b/src/muc_register.erl @@ -0,0 +1,364 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: muc_register.xdata +%% Form type: http://jabber.org/protocol/muc#register +%% Document: XEP-0045 + +-module(muc_register). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("muc_register.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, [<<"muc#register_roomnick">>]); + #xdata_field{values = + [<<"http://jabber.org/protocol/muc#register">>]} -> + decode(Fs, Acc, [<<"muc#register_roomnick">>]); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/muc#register">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {allow, Val} -> [encode_allow(Val, Translate)]; + {allow, _, _} -> erlang:error({badarg, Opt}); + {email, Val} -> [encode_email(Val, Translate)]; + {email, _, _} -> erlang:error({badarg, Opt}); + {faqentry, Val} -> [encode_faqentry(Val, Translate)]; + {faqentry, _, _} -> erlang:error({badarg, Opt}); + {first, Val} -> [encode_first(Val, Translate)]; + {first, _, _} -> erlang:error({badarg, Opt}); + {last, Val} -> [encode_last(Val, Translate)]; + {last, _, _} -> erlang:error({badarg, Opt}); + {roomnick, Val} -> [encode_roomnick(Val, Translate)]; + {roomnick, _, _} -> erlang:error({badarg, Opt}); + {url, Val} -> [encode_url(Val, Translate)]; + {url, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/muc#register">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"muc#register_allow">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow, Result} | Acc], + lists:delete(<<"muc#register_allow">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_allow">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_allow">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_allow">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_allow">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_allow">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = <<"muc#register_email">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{email, Result} | Acc], + lists:delete(<<"muc#register_email">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_email">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_email">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_email">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_email">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_email">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = <<"muc#register_faqentry">>, + values = Values} + | Fs], + Acc, Required) -> + try [Value || Value <- Values] of + Result -> + decode(Fs, [{faqentry, Result} | Acc], + lists:delete(<<"muc#register_faqentry">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_faqentry">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_first">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{first, Result} | Acc], + lists:delete(<<"muc#register_first">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_first">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_first">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_first">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_first">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_first">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = <<"muc#register_last">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{last, Result} | Acc], + lists:delete(<<"muc#register_last">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_last">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_last">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_last">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_last">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_last">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = <<"muc#register_roomnick">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{roomnick, Result} | Acc], + lists:delete(<<"muc#register_roomnick">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_roomnick">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_roomnick">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_roomnick">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_roomnick">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_roomnick">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = <<"muc#register_url">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{url, Result} | Acc], + lists:delete(<<"muc#register_url">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#register_url">>, + <<"http://jabber.org/protocol/muc#register">>}}) + end; +decode([#xdata_field{var = <<"muc#register_url">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#register_url">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#register_url">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#register_url">>, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/muc#register">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/muc#register">>}}); +decode([], Acc, []) -> Acc. + +encode_allow(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#register_allow">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow this person to register with the " + "room?">>)}. + +encode_email(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_email">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Email Address">>)}. + +encode_faqentry(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_faqentry">>, + values = Values, required = false, type = 'text-multi', + options = Opts, desc = <<>>, + label = Translate(<<"FAQ Entry">>)}. + +encode_first(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_first">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Given Name">>)}. + +encode_last(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_last">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Family Name">>)}. + +encode_roomnick(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_roomnick">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Nickname">>)}. + +encode_url(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#register_url">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"A Web Page">>)}. diff --git a/src/muc_request.erl b/src/muc_request.erl new file mode 100644 index 000000000..4c7becd2e --- /dev/null +++ b/src/muc_request.erl @@ -0,0 +1,269 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: muc_request.xdata +%% Form type: http://jabber.org/protocol/muc#request +%% Document: XEP-0045 + +-module(muc_request). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("muc_request.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, [<<"muc#role">>]); + #xdata_field{values = + [<<"http://jabber.org/protocol/muc#request">>]} -> + decode(Fs, Acc, [<<"muc#role">>]); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/muc#request">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {role, Val} -> [encode_role(Val, default, Translate)]; + {role, Val, Opts} -> + [encode_role(Val, Opts, Translate)]; + {jid, Val} -> [encode_jid(Val, Translate)]; + {jid, _, _} -> erlang:error({badarg, Opt}); + {roomnick, Val} -> [encode_roomnick(Val, Translate)]; + {roomnick, _, _} -> erlang:error({badarg, Opt}); + {request_allow, Val} -> + [encode_request_allow(Val, Translate)]; + {request_allow, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/muc#request">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"muc#role">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [participant]) of + Result -> + decode(Fs, [{role, Result} | Acc], + lists:delete(<<"muc#role">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#role">>, + <<"http://jabber.org/protocol/muc#request">>}}) + end; +decode([#xdata_field{var = <<"muc#role">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#role">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#role">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#role">>, + <<"http://jabber.org/protocol/muc#request">>}}); +decode([#xdata_field{var = <<"muc#jid">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_jid(Value) of + Result -> + decode(Fs, [{jid, Result} | Acc], + lists:delete(<<"muc#jid">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#jid">>, + <<"http://jabber.org/protocol/muc#request">>}}) + end; +decode([#xdata_field{var = <<"muc#jid">>, values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#jid">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#jid">>} | _], _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#jid">>, + <<"http://jabber.org/protocol/muc#request">>}}); +decode([#xdata_field{var = <<"muc#roomnick">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{roomnick, Result} | Acc], + lists:delete(<<"muc#roomnick">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomnick">>, + <<"http://jabber.org/protocol/muc#request">>}}) + end; +decode([#xdata_field{var = <<"muc#roomnick">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roomnick">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roomnick">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomnick">>, + <<"http://jabber.org/protocol/muc#request">>}}); +decode([#xdata_field{var = <<"muc#request_allow">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{request_allow, Result} | Acc], + lists:delete(<<"muc#request_allow">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#request_allow">>, + <<"http://jabber.org/protocol/muc#request">>}}) + end; +decode([#xdata_field{var = <<"muc#request_allow">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#request_allow">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#request_allow">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#request_allow">>, + <<"http://jabber.org/protocol/muc#request">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/muc#request">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/muc#request">>}}); +decode([], Acc, []) -> Acc. + +encode_role(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"Participant">>), + value = <<"participant">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"muc#role">>, values = Values, + required = false, type = 'list-single', options = Opts, + desc = <<>>, label = Translate(<<"Requested role">>)}. + +encode_jid(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_jid(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#jid">>, values = Values, + required = false, type = 'jid-single', options = Opts, + desc = <<>>, label = Translate(<<"User JID">>)}. + +encode_roomnick(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomnick">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, label = Translate(<<"Nickname">>)}. + +encode_request_allow(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#request_allow">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Grant voice to this person?">>)}. diff --git a/src/muc_roomconfig.erl b/src/muc_roomconfig.erl new file mode 100644 index 000000000..73ceb649e --- /dev/null +++ b/src/muc_roomconfig.erl @@ -0,0 +1,1675 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: muc_roomconfig.xdata +%% Form type: http://jabber.org/protocol/muc#roomconfig +%% Document: XEP-0045 + +-module(muc_roomconfig). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("muc_roomconfig.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> Int; + Int when Int =< Max, Int >= Min -> Int + end. + +enc_int(Int) -> integer_to_binary(Int). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +dec_enum_int(Val, Enums, Min, Max) -> + try dec_int(Val, Min, Max) catch + _:_ -> dec_enum(Val, Enums) + end. + +enc_enum_int(Int) when is_integer(Int) -> enc_int(Int); +enc_enum_int(Atom) -> enc_enum(Atom). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/muc#roomconfig">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {maxhistoryfetch, Val} -> + [encode_maxhistoryfetch(Val, Translate)]; + {maxhistoryfetch, _, _} -> erlang:error({badarg, Opt}); + {allowpm, Val} -> + [encode_allowpm(Val, default, Translate)]; + {allowpm, Val, Opts} -> + [encode_allowpm(Val, Opts, Translate)]; + {allow_private_messages, Val} -> + [encode_allow_private_messages(Val, Translate)]; + {allow_private_messages, _, _} -> + erlang:error({badarg, Opt}); + {allow_private_messages_from_visitors, Val} -> + [encode_allow_private_messages_from_visitors(Val, + default, + Translate)]; + {allow_private_messages_from_visitors, Val, Opts} -> + [encode_allow_private_messages_from_visitors(Val, Opts, + Translate)]; + {allow_visitor_status, Val} -> + [encode_allow_visitor_status(Val, Translate)]; + {allow_visitor_status, _, _} -> + erlang:error({badarg, Opt}); + {allow_visitor_nickchange, Val} -> + [encode_allow_visitor_nickchange(Val, Translate)]; + {allow_visitor_nickchange, _, _} -> + erlang:error({badarg, Opt}); + {allow_voice_requests, Val} -> + [encode_allow_voice_requests(Val, Translate)]; + {allow_voice_requests, _, _} -> + erlang:error({badarg, Opt}); + {allow_subscription, Val} -> + [encode_allow_subscription(Val, Translate)]; + {allow_subscription, _, _} -> + erlang:error({badarg, Opt}); + {voice_request_min_interval, Val} -> + [encode_voice_request_min_interval(Val, Translate)]; + {voice_request_min_interval, _, _} -> + erlang:error({badarg, Opt}); + {captcha_protected, Val} -> + [encode_captcha_protected(Val, Translate)]; + {captcha_protected, _, _} -> + erlang:error({badarg, Opt}); + {captcha_whitelist, Val} -> + [encode_captcha_whitelist(Val, Translate)]; + {captcha_whitelist, _, _} -> + erlang:error({badarg, Opt}); + {allow_query_users, Val} -> + [encode_allow_query_users(Val, Translate)]; + {allow_query_users, _, _} -> + erlang:error({badarg, Opt}); + {allowinvites, Val} -> + [encode_allowinvites(Val, Translate)]; + {allowinvites, _, _} -> erlang:error({badarg, Opt}); + {changesubject, Val} -> + [encode_changesubject(Val, Translate)]; + {changesubject, _, _} -> erlang:error({badarg, Opt}); + {enablelogging, Val} -> + [encode_enablelogging(Val, Translate)]; + {enablelogging, _, _} -> erlang:error({badarg, Opt}); + {getmemberlist, Val} -> + [encode_getmemberlist(Val, default, Translate)]; + {getmemberlist, Val, Opts} -> + [encode_getmemberlist(Val, Opts, Translate)]; + {lang, Val} -> [encode_lang(Val, Translate)]; + {lang, _, _} -> erlang:error({badarg, Opt}); + {pubsub, Val} -> [encode_pubsub(Val, Translate)]; + {pubsub, _, _} -> erlang:error({badarg, Opt}); + {maxusers, Val} -> + [encode_maxusers(Val, default, Translate)]; + {maxusers, Val, Opts} -> + [encode_maxusers(Val, Opts, Translate)]; + {membersonly, Val} -> + [encode_membersonly(Val, Translate)]; + {membersonly, _, _} -> erlang:error({badarg, Opt}); + {moderatedroom, Val} -> + [encode_moderatedroom(Val, Translate)]; + {moderatedroom, _, _} -> erlang:error({badarg, Opt}); + {members_by_default, Val} -> + [encode_members_by_default(Val, Translate)]; + {members_by_default, _, _} -> + erlang:error({badarg, Opt}); + {passwordprotectedroom, Val} -> + [encode_passwordprotectedroom(Val, Translate)]; + {passwordprotectedroom, _, _} -> + erlang:error({badarg, Opt}); + {persistentroom, Val} -> + [encode_persistentroom(Val, Translate)]; + {persistentroom, _, _} -> erlang:error({badarg, Opt}); + {presencebroadcast, Val} -> + [encode_presencebroadcast(Val, default, Translate)]; + {presencebroadcast, Val, Opts} -> + [encode_presencebroadcast(Val, Opts, Translate)]; + {publicroom, Val} -> + [encode_publicroom(Val, Translate)]; + {publicroom, _, _} -> erlang:error({badarg, Opt}); + {public_list, Val} -> + [encode_public_list(Val, Translate)]; + {public_list, _, _} -> erlang:error({badarg, Opt}); + {roomadmins, Val} -> + [encode_roomadmins(Val, Translate)]; + {roomadmins, _, _} -> erlang:error({badarg, Opt}); + {roomdesc, Val} -> [encode_roomdesc(Val, Translate)]; + {roomdesc, _, _} -> erlang:error({badarg, Opt}); + {roomname, Val} -> [encode_roomname(Val, Translate)]; + {roomname, _, _} -> erlang:error({badarg, Opt}); + {roomowners, Val} -> + [encode_roomowners(Val, Translate)]; + {roomowners, _, _} -> erlang:error({badarg, Opt}); + {roomsecret, Val} -> + [encode_roomsecret(Val, Translate)]; + {roomsecret, _, _} -> erlang:error({badarg, Opt}); + {whois, Val} -> [encode_whois(Val, default, Translate)]; + {whois, Val, Opts} -> + [encode_whois(Val, Opts, Translate)]; + {mam, Val} -> [encode_mam(Val, Translate)]; + {mam, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/muc#roomconfig">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{maxhistoryfetch, Result} | Acc], + lists:delete(<<"muc#maxhistoryfetch">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#maxhistoryfetch">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#maxhistoryfetch">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{allowpm, Result} | Acc], + lists:delete(<<"muc#roomconfig_allowpm">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_allowpm">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_allowpm">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_allowpm">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"allow_private_messages">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_private_messages, Result} | Acc], + lists:delete(<<"allow_private_messages">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_private_messages">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_private_messages">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"allow_private_messages">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"allow_private_messages">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_private_messages">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"allow_private_messages_from_visitors">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [nobody, moderators, anyone]) of + Result -> + decode(Fs, + [{allow_private_messages_from_visitors, Result} | Acc], + lists:delete(<<"allow_private_messages_from_visitors">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, + <<"allow_private_messages_from_visitors">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"allow_private_messages_from_visitors">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"allow_private_messages_from_visitors">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"allow_private_messages_from_visitors">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, + <<"allow_private_messages_from_visitors">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"allow_visitor_status">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_visitor_status, Result} | Acc], + lists:delete(<<"allow_visitor_status">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_visitor_status">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_visitor_status">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"allow_visitor_status">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"allow_visitor_status">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_visitor_status">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"allow_visitor_nickchange">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_visitor_nickchange, Result} | Acc], + lists:delete(<<"allow_visitor_nickchange">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_visitor_nickchange">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"allow_visitor_nickchange">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"allow_visitor_nickchange">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"allow_visitor_nickchange">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_visitor_nickchange">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"allow_voice_requests">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_voice_requests, Result} | Acc], + lists:delete(<<"allow_voice_requests">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_voice_requests">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_voice_requests">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"allow_voice_requests">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"allow_voice_requests">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_voice_requests">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"allow_subscription">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_subscription, Result} | Acc], + lists:delete(<<"allow_subscription">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_subscription">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_subscription">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"allow_subscription">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"allow_subscription">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_subscription">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"voice_request_min_interval">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{voice_request_min_interval, Result} | Acc], + lists:delete(<<"voice_request_min_interval">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"voice_request_min_interval">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"voice_request_min_interval">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"voice_request_min_interval">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"voice_request_min_interval">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"voice_request_min_interval">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"captcha_protected">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{captcha_protected, Result} | Acc], + lists:delete(<<"captcha_protected">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"captcha_protected">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"captcha_protected">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"captcha_protected">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"captcha_protected">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"captcha_protected">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"captcha_whitelist">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, [{captcha_whitelist, Result} | Acc], + lists:delete(<<"captcha_whitelist">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"captcha_whitelist">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_query_users">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow_query_users, Result} | Acc], + lists:delete(<<"allow_query_users">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"allow_query_users">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"allow_query_users">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"allow_query_users">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"allow_query_users">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"allow_query_users">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_allowinvites">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allowinvites, Result} | Acc], + lists:delete(<<"muc#roomconfig_allowinvites">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_allowinvites">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_allowinvites">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_allowinvites">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_allowinvites">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_allowinvites">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_changesubject">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{changesubject, Result} | Acc], + lists:delete(<<"muc#roomconfig_changesubject">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_changesubject">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_changesubject">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_changesubject">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_changesubject">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_changesubject">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_enablelogging">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{enablelogging, Result} | Acc], + lists:delete(<<"muc#roomconfig_enablelogging">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_enablelogging">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_enablelogging">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_enablelogging">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_enablelogging">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_enablelogging">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_getmemberlist">>, + values = Values} + | Fs], + Acc, Required) -> + try [Value || Value <- Values] of + Result -> + decode(Fs, [{getmemberlist, Result} | Acc], + lists:delete(<<"muc#roomconfig_getmemberlist">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_getmemberlist">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#roomconfig_lang">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{lang, Result} | Acc], + lists:delete(<<"muc#roomconfig_lang">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_lang">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#roomconfig_lang">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roomconfig_lang">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roomconfig_lang">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_lang">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{pubsub, Result} | Acc], + lists:delete(<<"muc#roomconfig_pubsub">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_pubsub">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roomconfig_pubsub">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_pubsub">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_maxusers">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum_int(Value, [none], 0, infinity) of + Result -> + decode(Fs, [{maxusers, Result} | Acc], + lists:delete(<<"muc#roomconfig_maxusers">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_maxusers">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_maxusers">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_maxusers">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_maxusers">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_maxusers">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_membersonly">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{membersonly, Result} | Acc], + lists:delete(<<"muc#roomconfig_membersonly">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_membersonly">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_membersonly">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_membersonly">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_membersonly">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_membersonly">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_moderatedroom">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{moderatedroom, Result} | Acc], + lists:delete(<<"muc#roomconfig_moderatedroom">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_moderatedroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_moderatedroom">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_moderatedroom">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_moderatedroom">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_moderatedroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"members_by_default">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{members_by_default, Result} | Acc], + lists:delete(<<"members_by_default">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"members_by_default">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"members_by_default">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"members_by_default">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"members_by_default">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"members_by_default">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_passwordprotectedroom">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{passwordprotectedroom, Result} | Acc], + lists:delete(<<"muc#roomconfig_passwordprotectedroom">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, + <<"muc#roomconfig_passwordprotectedroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_passwordprotectedroom">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_passwordprotectedroom">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_passwordprotectedroom">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, + <<"muc#roomconfig_passwordprotectedroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_persistentroom">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{persistentroom, Result} | Acc], + lists:delete(<<"muc#roomconfig_persistentroom">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_persistentroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_persistentroom">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_persistentroom">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_persistentroom">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_persistentroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_presencebroadcast">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_enum(Value, [moderator, participant, visitor]) + || Value <- Values] + of + Result -> + decode(Fs, [{presencebroadcast, Result} | Acc], + lists:delete(<<"muc#roomconfig_presencebroadcast">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_presencebroadcast">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_publicroom">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{publicroom, Result} | Acc], + lists:delete(<<"muc#roomconfig_publicroom">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_publicroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_publicroom">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_publicroom">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_publicroom">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_publicroom">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"public_list">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{public_list, Result} | Acc], + lists:delete(<<"public_list">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"public_list">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"public_list">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"public_list">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"public_list">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"public_list">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_roomadmins">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, [{roomadmins, Result} | Acc], + lists:delete(<<"muc#roomconfig_roomadmins">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_roomadmins">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_roomdesc">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{roomdesc, Result} | Acc], + lists:delete(<<"muc#roomconfig_roomdesc">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_roomdesc">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_roomdesc">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_roomdesc">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_roomdesc">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_roomdesc">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_roomname">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{roomname, Result} | Acc], + lists:delete(<<"muc#roomconfig_roomname">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_roomname">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_roomname">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_roomname">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_roomname">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_roomname">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = + <<"muc#roomconfig_roomowners">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, [{roomowners, Result} | Acc], + lists:delete(<<"muc#roomconfig_roomowners">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_roomowners">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_roomsecret">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{roomsecret, Result} | Acc], + lists:delete(<<"muc#roomconfig_roomsecret">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_roomsecret">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = + <<"muc#roomconfig_roomsecret">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roomconfig_roomsecret">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roomconfig_roomsecret">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_roomsecret">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"muc#roomconfig_whois">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [moderators, anyone]) of + Result -> + decode(Fs, [{whois, Result} | Acc], + lists:delete(<<"muc#roomconfig_whois">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roomconfig_whois">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"muc#roomconfig_whois">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roomconfig_whois">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roomconfig_whois">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roomconfig_whois">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = <<"mam">>, values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{mam, Result} | Acc], + lists:delete(<<"mam">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"mam">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}) + end; +decode([#xdata_field{var = <<"mam">>, values = []} = F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"mam">>, values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"mam">>} | _], _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"mam">>, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/muc#roomconfig">>}}); +decode([], Acc, []) -> Acc. + +encode_maxhistoryfetch(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#maxhistoryfetch">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Maximum Number of History Messages Returned " + "by Room">>)}. + +encode_allowpm(Value, Options, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = if Options == default -> []; + true -> + [#xdata_option{label = Translate(L), value = V} + || {L, V} <- Options] + end, + #xdata_field{var = <<"muc#roomconfig_allowpm">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Roles that May Send Private Messages">>)}. + +encode_allow_private_messages(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_private_messages">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow users to send private messages">>)}. + +encode_allow_private_messages_from_visitors(Value, + Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"nobody">>), + value = <<"nobody">>}, + #xdata_option{label = Translate(<<"moderators only">>), + value = <<"moderators">>}, + #xdata_option{label = Translate(<<"anyone">>), + value = <<"anyone">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = + <<"allow_private_messages_from_visitors">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Allow visitors to send private messages to">>)}. + +encode_allow_visitor_status(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_visitor_status">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow visitors to send status text in " + "presence updates">>)}. + +encode_allow_visitor_nickchange(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_visitor_nickchange">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow visitors to change nickname">>)}. + +encode_allow_voice_requests(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_voice_requests">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow visitors to send voice requests">>)}. + +encode_allow_subscription(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_subscription">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Allow subscription">>)}. + +encode_voice_request_min_interval(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"voice_request_min_interval">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Minimum interval between voice requests " + "(in seconds)">>)}. + +encode_captcha_protected(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"captcha_protected">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room CAPTCHA protected">>)}. + +encode_captcha_whitelist(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = <<"captcha_whitelist">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"Exclude Jabber IDs from CAPTCHA challenge">>)}. + +encode_allow_query_users(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"allow_query_users">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow users to query other users">>)}. + +encode_allowinvites(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_allowinvites">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Allow users to send invites">>)}. + +encode_changesubject(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_changesubject">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Allow users to change the subject">>)}. + +encode_enablelogging(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_enablelogging">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Enable logging">>)}. + +encode_getmemberlist(Value, Options, Translate) -> + Values = case Value of + [] -> []; + Value -> [Value] + end, + Opts = if Options == default -> []; + true -> + [#xdata_option{label = Translate(L), value = V} + || {L, V} <- Options] + end, + #xdata_field{var = <<"muc#roomconfig_getmemberlist">>, + values = Values, required = false, type = 'list-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"Roles and Affiliations that May Retrieve " + "Member List">>)}. + +encode_lang(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_lang">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Natural Language for Room Discussions">>)}. + +encode_pubsub(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_pubsub">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"XMPP URI of Associated Publish-Subscribe " + "Node">>)}. + +encode_maxusers(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum_int(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"No limit">>), + value = <<"none">>}, + #xdata_option{value = <<"5">>}, + #xdata_option{value = <<"10">>}, + #xdata_option{value = <<"20">>}, + #xdata_option{value = <<"30">>}, + #xdata_option{value = <<"50">>}, + #xdata_option{value = <<"100">>}, + #xdata_option{value = <<"200">>}, + #xdata_option{value = <<"500">>}, + #xdata_option{value = <<"1000">>}, + #xdata_option{value = <<"2000">>}, + #xdata_option{value = <<"5000">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum_int(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"muc#roomconfig_maxusers">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = Translate(<<"Maximum Number of Occupants">>)}. + +encode_membersonly(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_membersonly">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room members-only">>)}. + +encode_moderatedroom(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_moderatedroom">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room moderated">>)}. + +encode_members_by_default(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"members_by_default">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Default users as participants">>)}. + +encode_passwordprotectedroom(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = + <<"muc#roomconfig_passwordprotectedroom">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room password protected">>)}. + +encode_persistentroom(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_persistentroom">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room persistent">>)}. + +encode_presencebroadcast(Value, Options, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_enum(V) || V <- Value] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"Moderator">>), + value = <<"moderator">>}, + #xdata_option{label = Translate(<<"Participant">>), + value = <<"participant">>}, + #xdata_option{label = Translate(<<"Visitor">>), + value = <<"visitor">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = + <<"muc#roomconfig_presencebroadcast">>, + values = Values, required = false, type = 'list-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"Roles for which Presence is Broadcasted">>)}. + +encode_publicroom(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_publicroom">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Make room public searchable">>)}. + +encode_public_list(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"public_list">>, values = Values, + required = false, type = boolean, options = Opts, + desc = <<>>, + label = Translate(<<"Make participants list public">>)}. + +encode_roomadmins(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_roomadmins">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = Translate(<<"Full List of Room Admins">>)}. + +encode_roomdesc(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_roomdesc">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Room description">>)}. + +encode_roomname(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_roomname">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Room title">>)}. + +encode_roomowners(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_roomowners">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = Translate(<<"Full List of Room Owners">>)}. + +encode_roomsecret(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roomconfig_roomsecret">>, + values = Values, required = false, + type = 'text-private', options = Opts, desc = <<>>, + label = Translate(<<"Password">>)}. + +encode_whois(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"moderators only">>), + value = <<"moderators">>}, + #xdata_option{label = Translate(<<"anyone">>), + value = <<"anyone">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"muc#roomconfig_whois">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = Translate(<<"Present real Jabber IDs to">>)}. + +encode_mam(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"mam">>, values = Values, + required = false, type = boolean, options = Opts, + desc = <<>>, + label = Translate(<<"Enable message archiving">>)}. diff --git a/src/muc_roominfo.erl b/src/muc_roominfo.erl new file mode 100644 index 000000000..809dcef5b --- /dev/null +++ b/src/muc_roominfo.erl @@ -0,0 +1,491 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: muc_roominfo.xdata +%% Form type: http://jabber.org/protocol/muc#roominfo +%% Document: XEP-0045 + +-module(muc_roominfo). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("muc_roominfo.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> Int; + Int when Int =< Max, Int >= Min -> Int + end. + +enc_int(Int) -> integer_to_binary(Int). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/muc#roominfo">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {maxhistoryfetch, Val} -> + [encode_maxhistoryfetch(Val, Translate)]; + {maxhistoryfetch, _, _} -> erlang:error({badarg, Opt}); + {contactjid, Val} -> + [encode_contactjid(Val, Translate)]; + {contactjid, _, _} -> erlang:error({badarg, Opt}); + {description, Val} -> + [encode_description(Val, Translate)]; + {description, _, _} -> erlang:error({badarg, Opt}); + {lang, Val} -> [encode_lang(Val, Translate)]; + {lang, _, _} -> erlang:error({badarg, Opt}); + {ldapgroup, Val} -> [encode_ldapgroup(Val, Translate)]; + {ldapgroup, _, _} -> erlang:error({badarg, Opt}); + {logs, Val} -> [encode_logs(Val, Translate)]; + {logs, _, _} -> erlang:error({badarg, Opt}); + {occupants, Val} -> [encode_occupants(Val, Translate)]; + {occupants, _, _} -> erlang:error({badarg, Opt}); + {subject, Val} -> [encode_subject(Val, Translate)]; + {subject, _, _} -> erlang:error({badarg, Opt}); + {subjectmod, Val} -> + [encode_subjectmod(Val, Translate)]; + {subjectmod, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/muc#roominfo">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{maxhistoryfetch, Result} | Acc], + lists:delete(<<"muc#maxhistoryfetch">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#maxhistoryfetch">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#maxhistoryfetch">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#maxhistoryfetch">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#maxhistoryfetch">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = + <<"muc#roominfo_contactjid">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, [{contactjid, Result} | Acc], + lists:delete(<<"muc#roominfo_contactjid">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_contactjid">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = + <<"muc#roominfo_description">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{description, Result} | Acc], + lists:delete(<<"muc#roominfo_description">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_description">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = + <<"muc#roominfo_description">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roominfo_description">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roominfo_description">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_description">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = <<"muc#roominfo_lang">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{lang, Result} | Acc], + lists:delete(<<"muc#roominfo_lang">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_lang">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#roominfo_lang">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roominfo_lang">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roominfo_lang">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_lang">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{ldapgroup, Result} | Acc], + lists:delete(<<"muc#roominfo_ldapgroup">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_ldapgroup">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roominfo_ldapgroup">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_ldapgroup">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = <<"muc#roominfo_logs">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{logs, Result} | Acc], + lists:delete(<<"muc#roominfo_logs">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_logs">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#roominfo_logs">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roominfo_logs">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roominfo_logs">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_logs">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = <<"muc#roominfo_occupants">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{occupants, Result} | Acc], + lists:delete(<<"muc#roominfo_occupants">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_occupants">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#roominfo_occupants">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roominfo_occupants">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roominfo_occupants">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_occupants">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = <<"muc#roominfo_subject">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{subject, Result} | Acc], + lists:delete(<<"muc#roominfo_subject">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_subject">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = <<"muc#roominfo_subject">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"muc#roominfo_subject">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"muc#roominfo_subject">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_subject">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = + <<"muc#roominfo_subjectmod">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{subjectmod, Result} | Acc], + lists:delete(<<"muc#roominfo_subjectmod">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"muc#roominfo_subjectmod">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}) + end; +decode([#xdata_field{var = + <<"muc#roominfo_subjectmod">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"muc#roominfo_subjectmod">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"muc#roominfo_subjectmod">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"muc#roominfo_subjectmod">>, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/muc#roominfo">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/muc#roominfo">>}}); +decode([], Acc, []) -> Acc. + +encode_maxhistoryfetch(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#maxhistoryfetch">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Maximum Number of History Messages Returned " + "by Room">>)}. + +encode_contactjid(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_contactjid">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"Contact Addresses (normally, room owner " + "or owners)">>)}. + +encode_description(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_description">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Room description">>)}. + +encode_lang(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_lang">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Natural Language for Room Discussions">>)}. + +encode_ldapgroup(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_ldapgroup">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"An associated LDAP group that defines " + "room membership; this should be an LDAP " + "Distinguished Name according to an implementa" + "tion-specific or deployment-specific " + "definition of a group.">>)}. + +encode_logs(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_logs">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"URL for Archived Discussion Logs">>)}. + +encode_occupants(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_occupants">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Number of occupants">>)}. + +encode_subject(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_subject">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Current Discussion Topic">>)}. + +encode_subjectmod(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"muc#roominfo_subjectmod">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"The room subject can be modified by " + "participants">>)}. diff --git a/src/node_flat.erl b/src/node_flat.erl index e3170a263..3afa49f22 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -84,6 +84,7 @@ options() -> {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, + {title, <<>>}, {presence_based_delivery, false}, {itemreply, none}]. @@ -452,7 +453,7 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) -> end, {error, xmpp:err_item_not_found()}, States); _ -> - {error, xmpp:err_item_not_found()} + {error, xmpp:err_forbidden()} end end end. diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index bd084333b..c1dfd0e81 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -901,7 +901,7 @@ first_in_list(Pred, [H | T]) -> itemids(Nidx, {_U, _S, _R} = JID) -> SJID = encode_jid(JID), - SJIDLike = <<(ejabberd_sql:escape(encode_jid_like(JID)))/binary, "/%">>, + SJIDLike = <<(encode_jid_like(JID))/binary, "/%">>, case catch ejabberd_sql:sql_query_t( ?SQL("select @(itemid)s from pubsub_item where " diff --git a/src/pubsub_get_pending.erl b/src/pubsub_get_pending.erl new file mode 100644 index 000000000..1a7de6a2d --- /dev/null +++ b/src/pubsub_get_pending.erl @@ -0,0 +1,130 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: pubsub_get_pending.xdata +%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization +%% Document: XEP-0060 + +-module(pubsub_get_pending). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("pubsub_get_pending.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, [<<"pubsub#node">>]); + #xdata_field{values = + [<<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>]} -> + decode(Fs, Acc, [<<"pubsub#node">>]); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {node, Val} -> [encode_node(Val, default, Translate)]; + {node, Val, Opts} -> + [encode_node(Val, Opts, Translate)]; + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"pubsub#node">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{node, Result} | Acc], + lists:delete(<<"pubsub#node">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#node">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end; +decode([#xdata_field{var = <<"pubsub#node">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#node">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#node">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#node">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([], Acc, []) -> Acc. + +encode_node(Value, Options, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = if Options == default -> []; + true -> + [#xdata_option{label = Translate(L), value = V} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#node">>, values = Values, + required = false, type = 'list-single', options = Opts, + desc = <<>>, + label = + Translate(<<"The NodeID of the relevant node">>)}. diff --git a/src/pubsub_node_config.erl b/src/pubsub_node_config.erl new file mode 100644 index 000000000..47ed10b49 --- /dev/null +++ b/src/pubsub_node_config.erl @@ -0,0 +1,1666 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: pubsub_node_config.xdata +%% Form type: http://jabber.org/protocol/pubsub#node_config +%% Document: XEP-0060 + +-module(pubsub_node_config). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("pubsub_node_config.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> Int; + Int when Int =< Max, Int >= Min -> Int + end. + +enc_int(Int) -> integer_to_binary(Int). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/pubsub#node_config">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {access_model, Val} -> + [encode_access_model(Val, default, Translate)]; + {access_model, Val, Opts} -> + [encode_access_model(Val, Opts, Translate)]; + {body_xslt, Val} -> [encode_body_xslt(Val, Translate)]; + {body_xslt, _, _} -> erlang:error({badarg, Opt}); + {children_association_policy, Val} -> + [encode_children_association_policy(Val, default, + Translate)]; + {children_association_policy, Val, Opts} -> + [encode_children_association_policy(Val, Opts, + Translate)]; + {children_association_whitelist, Val} -> + [encode_children_association_whitelist(Val, Translate)]; + {children_association_whitelist, _, _} -> + erlang:error({badarg, Opt}); + {children, Val} -> [encode_children(Val, Translate)]; + {children, _, _} -> erlang:error({badarg, Opt}); + {children_max, Val} -> + [encode_children_max(Val, Translate)]; + {children_max, _, _} -> erlang:error({badarg, Opt}); + {collection, Val} -> + [encode_collection(Val, Translate)]; + {collection, _, _} -> erlang:error({badarg, Opt}); + {contact, Val} -> [encode_contact(Val, Translate)]; + {contact, _, _} -> erlang:error({badarg, Opt}); + {dataform_xslt, Val} -> + [encode_dataform_xslt(Val, Translate)]; + {dataform_xslt, _, _} -> erlang:error({badarg, Opt}); + {deliver_notifications, Val} -> + [encode_deliver_notifications(Val, Translate)]; + {deliver_notifications, _, _} -> + erlang:error({badarg, Opt}); + {deliver_payloads, Val} -> + [encode_deliver_payloads(Val, Translate)]; + {deliver_payloads, _, _} -> erlang:error({badarg, Opt}); + {description, Val} -> + [encode_description(Val, Translate)]; + {description, _, _} -> erlang:error({badarg, Opt}); + {item_expire, Val} -> + [encode_item_expire(Val, Translate)]; + {item_expire, _, _} -> erlang:error({badarg, Opt}); + {itemreply, Val} -> + [encode_itemreply(Val, default, Translate)]; + {itemreply, Val, Opts} -> + [encode_itemreply(Val, Opts, Translate)]; + {language, Val} -> + [encode_language(Val, default, Translate)]; + {language, Val, Opts} -> + [encode_language(Val, Opts, Translate)]; + {max_items, Val} -> [encode_max_items(Val, Translate)]; + {max_items, _, _} -> erlang:error({badarg, Opt}); + {max_payload_size, Val} -> + [encode_max_payload_size(Val, Translate)]; + {max_payload_size, _, _} -> erlang:error({badarg, Opt}); + {node_type, Val} -> + [encode_node_type(Val, default, Translate)]; + {node_type, Val, Opts} -> + [encode_node_type(Val, Opts, Translate)]; + {notification_type, Val} -> + [encode_notification_type(Val, default, Translate)]; + {notification_type, Val, Opts} -> + [encode_notification_type(Val, Opts, Translate)]; + {notify_config, Val} -> + [encode_notify_config(Val, Translate)]; + {notify_config, _, _} -> erlang:error({badarg, Opt}); + {notify_delete, Val} -> + [encode_notify_delete(Val, Translate)]; + {notify_delete, _, _} -> erlang:error({badarg, Opt}); + {notify_retract, Val} -> + [encode_notify_retract(Val, Translate)]; + {notify_retract, _, _} -> erlang:error({badarg, Opt}); + {notify_sub, Val} -> + [encode_notify_sub(Val, Translate)]; + {notify_sub, _, _} -> erlang:error({badarg, Opt}); + {persist_items, Val} -> + [encode_persist_items(Val, Translate)]; + {persist_items, _, _} -> erlang:error({badarg, Opt}); + {presence_based_delivery, Val} -> + [encode_presence_based_delivery(Val, Translate)]; + {presence_based_delivery, _, _} -> + erlang:error({badarg, Opt}); + {publish_model, Val} -> + [encode_publish_model(Val, default, Translate)]; + {publish_model, Val, Opts} -> + [encode_publish_model(Val, Opts, Translate)]; + {purge_offline, Val} -> + [encode_purge_offline(Val, Translate)]; + {purge_offline, _, _} -> erlang:error({badarg, Opt}); + {roster_groups_allowed, Val} -> + [encode_roster_groups_allowed(Val, default, Translate)]; + {roster_groups_allowed, Val, Opts} -> + [encode_roster_groups_allowed(Val, Opts, Translate)]; + {send_last_published_item, Val} -> + [encode_send_last_published_item(Val, default, + Translate)]; + {send_last_published_item, Val, Opts} -> + [encode_send_last_published_item(Val, Opts, Translate)]; + {tempsub, Val} -> [encode_tempsub(Val, Translate)]; + {tempsub, _, _} -> erlang:error({badarg, Opt}); + {subscribe, Val} -> [encode_subscribe(Val, Translate)]; + {subscribe, _, _} -> erlang:error({badarg, Opt}); + {title, Val} -> [encode_title(Val, Translate)]; + {title, _, _} -> erlang:error({badarg, Opt}); + {type, Val} -> [encode_type(Val, Translate)]; + {type, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/pubsub#node_config">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"pubsub#access_model">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, + [authorize, open, presence, roster, whitelist]) + of + Result -> + decode(Fs, [{access_model, Result} | Acc], + lists:delete(<<"pubsub#access_model">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#access_model">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#access_model">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#access_model">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#access_model">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#access_model">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#body_xslt">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{body_xslt, Result} | Acc], + lists:delete(<<"pubsub#body_xslt">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#body_xslt">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#body_xslt">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#body_xslt">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#body_xslt">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#body_xslt">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#children_association_policy">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [all, owners, whitelist]) of + Result -> + decode(Fs, + [{children_association_policy, Result} | Acc], + lists:delete(<<"pubsub#children_association_policy">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, + <<"pubsub#children_association_policy">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#children_association_policy">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#children_association_policy">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#children_association_policy">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, + <<"pubsub#children_association_policy">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#children_association_whitelist">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, + [{children_association_whitelist, Result} | Acc], + lists:delete(<<"pubsub#children_association_whitelist">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, + <<"pubsub#children_association_whitelist">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#children">>, + values = Values} + | Fs], + Acc, Required) -> + try [Value || Value <- Values] of + Result -> + decode(Fs, [{children, Result} | Acc], + lists:delete(<<"pubsub#children">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#children">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#children_max">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{children_max, Result} | Acc], + lists:delete(<<"pubsub#children_max">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#children_max">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#children_max">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#children_max">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#children_max">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#children_max">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#collection">>, + values = Values} + | Fs], + Acc, Required) -> + try [Value || Value <- Values] of + Result -> + decode(Fs, [{collection, Result} | Acc], + lists:delete(<<"pubsub#collection">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#collection">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#contact">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_jid(Value) || Value <- Values] of + Result -> + decode(Fs, [{contact, Result} | Acc], + lists:delete(<<"pubsub#contact">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#contact">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#dataform_xslt">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{dataform_xslt, Result} | Acc], + lists:delete(<<"pubsub#dataform_xslt">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#dataform_xslt">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#dataform_xslt">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#dataform_xslt">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#dataform_xslt">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#dataform_xslt">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#deliver_notifications">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{deliver_notifications, Result} | Acc], + lists:delete(<<"pubsub#deliver_notifications">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#deliver_notifications">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#deliver_notifications">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#deliver_notifications">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#deliver_notifications">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#deliver_notifications">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#deliver_payloads">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{deliver_payloads, Result} | Acc], + lists:delete(<<"pubsub#deliver_payloads">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#deliver_payloads">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#deliver_payloads">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#deliver_payloads">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#deliver_payloads">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#deliver_payloads">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#description">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{description, Result} | Acc], + lists:delete(<<"pubsub#description">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#description">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#description">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#description">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#description">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#description">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#item_expire">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{item_expire, Result} | Acc], + lists:delete(<<"pubsub#item_expire">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#item_expire">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#item_expire">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#item_expire">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#item_expire">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#item_expire">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#itemreply">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [owner, publisher, none]) of + Result -> + decode(Fs, [{itemreply, Result} | Acc], + lists:delete(<<"pubsub#itemreply">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#itemreply">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#itemreply">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#itemreply">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#itemreply">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#itemreply">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#language">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{language, Result} | Acc], + lists:delete(<<"pubsub#language">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#language">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#language">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#language">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#language">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#language">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#max_items">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{max_items, Result} | Acc], + lists:delete(<<"pubsub#max_items">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#max_items">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#max_items">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#max_items">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#max_items">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#max_items">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#max_payload_size">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_int(Value, 0, infinity) of + Result -> + decode(Fs, [{max_payload_size, Result} | Acc], + lists:delete(<<"pubsub#max_payload_size">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#max_payload_size">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#max_payload_size">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#max_payload_size">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#max_payload_size">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#max_payload_size">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#node_type">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [leaf, collection]) of + Result -> + decode(Fs, [{node_type, Result} | Acc], + lists:delete(<<"pubsub#node_type">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#node_type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#node_type">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#node_type">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#node_type">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#node_type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#notification_type">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [normal, headline]) of + Result -> + decode(Fs, [{notification_type, Result} | Acc], + lists:delete(<<"pubsub#notification_type">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#notification_type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#notification_type">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#notification_type">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#notification_type">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#notification_type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#notify_config">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{notify_config, Result} | Acc], + lists:delete(<<"pubsub#notify_config">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#notify_config">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#notify_config">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#notify_config">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#notify_config">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#notify_config">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#notify_delete">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{notify_delete, Result} | Acc], + lists:delete(<<"pubsub#notify_delete">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#notify_delete">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#notify_delete">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#notify_delete">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#notify_delete">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#notify_delete">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#notify_retract">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{notify_retract, Result} | Acc], + lists:delete(<<"pubsub#notify_retract">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#notify_retract">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#notify_retract">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#notify_retract">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#notify_retract">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#notify_retract">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#notify_sub">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{notify_sub, Result} | Acc], + lists:delete(<<"pubsub#notify_sub">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#notify_sub">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#notify_sub">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#notify_sub">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#notify_sub">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#notify_sub">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#persist_items">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{persist_items, Result} | Acc], + lists:delete(<<"pubsub#persist_items">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#persist_items">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#persist_items">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#persist_items">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#persist_items">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#persist_items">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#presence_based_delivery">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{presence_based_delivery, Result} | Acc], + lists:delete(<<"pubsub#presence_based_delivery">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#presence_based_delivery">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#presence_based_delivery">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#presence_based_delivery">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#presence_based_delivery">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#presence_based_delivery">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#publish_model">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [publishers, subscribers, open]) of + Result -> + decode(Fs, [{publish_model, Result} | Acc], + lists:delete(<<"pubsub#publish_model">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#publish_model">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#publish_model">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#publish_model">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#publish_model">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#publish_model">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#purge_offline">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{purge_offline, Result} | Acc], + lists:delete(<<"pubsub#purge_offline">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#purge_offline">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#purge_offline">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#purge_offline">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#purge_offline">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#purge_offline">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = + <<"pubsub#roster_groups_allowed">>, + values = Values} + | Fs], + Acc, Required) -> + try [Value || Value <- Values] of + Result -> + decode(Fs, [{roster_groups_allowed, Result} | Acc], + lists:delete(<<"pubsub#roster_groups_allowed">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#roster_groups_allowed">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#send_last_published_item">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, + [never, on_sub, on_sub_and_presence]) + of + Result -> + decode(Fs, [{send_last_published_item, Result} | Acc], + lists:delete(<<"pubsub#send_last_published_item">>, + Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#send_last_published_item">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#send_last_published_item">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#send_last_published_item">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#send_last_published_item">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#send_last_published_item">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#tempsub">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{tempsub, Result} | Acc], + lists:delete(<<"pubsub#tempsub">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#tempsub">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#tempsub">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#tempsub">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#tempsub">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#tempsub">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#subscribe">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{subscribe, Result} | Acc], + lists:delete(<<"pubsub#subscribe">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#subscribe">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#subscribe">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#subscribe">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#subscribe">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#subscribe">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#title">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{title, Result} | Acc], + lists:delete(<<"pubsub#title">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#title">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#title">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#title">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#title">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#title">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = <<"pubsub#type">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{type, Result} | Acc], + lists:delete(<<"pubsub#type">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}) + end; +decode([#xdata_field{var = <<"pubsub#type">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#type">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#type">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#type">>, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/pubsub#node_config">>}}); +decode([], Acc, []) -> Acc. + +encode_access_model(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Subscription requests must be approved " + "and only subscribers may retrieve items">>), + value = <<"authorize">>}, + #xdata_option{label = + Translate(<<"Anyone may subscribe and retrieve items">>), + value = <<"open">>}, + #xdata_option{label = + Translate(<<"Anyone with a presence subscription " + "of both or from may subscribe and retrieve " + "items">>), + value = <<"presence">>}, + #xdata_option{label = + Translate(<<"Anyone in the specified roster group(s) " + "may subscribe and retrieve items">>), + value = <<"roster">>}, + #xdata_option{label = + Translate(<<"Only those on a whitelist may subscribe " + "and retrieve items">>), + value = <<"whitelist">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#access_model">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = Translate(<<"Specify the access model">>)}. + +encode_body_xslt(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#body_xslt">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"The URL of an XSL transformation which " + "can be applied to payloads in order " + "to generate an appropriate message body " + "element.">>)}. + +encode_children_association_policy(Value, Options, + Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Anyone may associate leaf nodes with " + "the collection">>), + value = <<"all">>}, + #xdata_option{label = + Translate(<<"Only collection node owners may associate " + "leaf nodes with the collection">>), + value = <<"owners">>}, + #xdata_option{label = + Translate(<<"Only those on a whitelist may associate " + "leaf nodes with the collection">>), + value = <<"whitelist">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = + <<"pubsub#children_association_policy">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Who may associate leaf nodes with a " + "collection">>)}. + +encode_children_association_whitelist(Value, + Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = + <<"pubsub#children_association_whitelist">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"The list of JIDs that may associate " + "leaf nodes with a collection">>)}. + +encode_children(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#children">>, + values = Values, required = false, type = 'text-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"The child nodes (leaf or collection) " + "associated with a collection">>)}. + +encode_children_max(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#children_max">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"The maximum number of child nodes that " + "can be associated with a collection">>)}. + +encode_collection(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#collection">>, + values = Values, required = false, type = 'text-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"The collections with which a node is " + "affiliated">>)}. + +encode_contact(Value, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_jid(V) || V <- Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#contact">>, + values = Values, required = false, type = 'jid-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"The JIDs of those to contact with questions">>)}. + +encode_dataform_xslt(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#dataform_xslt">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"The URL of an XSL transformation which " + "can be applied to the payload format " + "in order to generate a valid Data Forms " + "result that the client could display " + "using a generic Data Forms rendering " + "engine">>)}. + +encode_deliver_notifications(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#deliver_notifications">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Deliver event notifications">>)}. + +encode_deliver_payloads(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#deliver_payloads">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Deliver payloads with event notifications">>)}. + +encode_description(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#description">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"A description of the node">>)}. + +encode_item_expire(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#item_expire">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Number of seconds after which to automaticall" + "y purge items">>)}. + +encode_itemreply(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Statically specify a replyto of the " + "node owner(s)">>), + value = <<"owner">>}, + #xdata_option{label = + Translate(<<"Dynamically specify a replyto of the " + "item publisher">>), + value = <<"publisher">>}, + #xdata_option{value = <<"none">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#itemreply">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Whether owners or publisher should receive " + "replies to items">>)}. + +encode_language(Value, Options, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = if Options == default -> []; + true -> + [#xdata_option{label = Translate(L), value = V} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#language">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"The default language of the node">>)}. + +encode_max_items(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#max_items">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Max # of items to persist">>)}. + +encode_max_payload_size(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_int(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#max_payload_size">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = Translate(<<"Max payload size in bytes">>)}. + +encode_node_type(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"The node is a leaf node (default)">>), + value = <<"leaf">>}, + #xdata_option{label = + Translate(<<"The node is a collection node">>), + value = <<"collection">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#node_type">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Whether the node is a leaf (default) " + "or a collection">>)}. + +encode_notification_type(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Messages of type normal">>), + value = <<"normal">>}, + #xdata_option{label = + Translate(<<"Messages of type headline">>), + value = <<"headline">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#notification_type">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"Specify the event message type">>)}. + +encode_notify_config(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#notify_config">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Notify subscribers when the node configuratio" + "n changes">>)}. + +encode_notify_delete(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#notify_delete">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Notify subscribers when the node is " + "deleted">>)}. + +encode_notify_retract(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#notify_retract">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Notify subscribers when items are removed " + "from the node">>)}. + +encode_notify_sub(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#notify_sub">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Whether to notify owners about new subscriber" + "s and unsubscribes">>)}. + +encode_persist_items(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#persist_items">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = Translate(<<"Persist items to storage">>)}. + +encode_presence_based_delivery(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#presence_based_delivery">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Only deliver notifications to available " + "users">>)}. + +encode_publish_model(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Only publishers may publish">>), + value = <<"publishers">>}, + #xdata_option{label = + Translate(<<"Subscribers may publish">>), + value = <<"subscribers">>}, + #xdata_option{label = + Translate(<<"Anyone may publish">>), + value = <<"open">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#publish_model">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = Translate(<<"Specify the publisher model">>)}. + +encode_purge_offline(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#purge_offline">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Purge all items when the relevant publisher " + "goes offline">>)}. + +encode_roster_groups_allowed(Value, Options, + Translate) -> + Values = case Value of + [] -> []; + Value -> [Value] + end, + Opts = if Options == default -> []; + true -> + [#xdata_option{label = Translate(L), value = V} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#roster_groups_allowed">>, + values = Values, required = false, type = 'list-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"Roster groups allowed to subscribe">>)}. + +encode_send_last_published_item(Value, Options, + Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = Translate(<<"Never">>), + value = <<"never">>}, + #xdata_option{label = + Translate(<<"When a new subscription is processed">>), + value = <<"on_sub">>}, + #xdata_option{label = + Translate(<<"When a new subscription is processed " + "and whenever a subscriber comes online">>), + value = <<"on_sub_and_presence">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = + <<"pubsub#send_last_published_item">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = + Translate(<<"When to send the last published item">>)}. + +encode_tempsub(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#tempsub">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Whether to make all subscriptions temporary, " + "based on subscriber presence">>)}. + +encode_subscribe(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#subscribe">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Whether to allow subscriptions">>)}. + +encode_title(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#title">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = Translate(<<"A friendly name for the node">>)}. + +encode_type(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#type">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = + Translate(<<"The type of node data, usually specified " + "by the namespace of the payload (if " + "any)">>)}. diff --git a/src/pubsub_publish_options.erl b/src/pubsub_publish_options.erl new file mode 100644 index 000000000..8d0229071 --- /dev/null +++ b/src/pubsub_publish_options.erl @@ -0,0 +1,157 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: pubsub_publish_options.xdata +%% Form type: http://jabber.org/protocol/pubsub#publish-options +%% Document: XEP-0060 + +-module(pubsub_publish_options). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("pubsub_publish_options.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {access_model, Val} -> + [encode_access_model(Val, default, Translate)]; + {access_model, Val, Opts} -> + [encode_access_model(Val, Opts, Translate)]; + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"pubsub#access_model">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, + [authorize, open, presence, roster, whitelist]) + of + Result -> + decode(Fs, [{access_model, Result} | Acc], + lists:delete(<<"pubsub#access_model">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#access_model">>, + <<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>}}) + end; +decode([#xdata_field{var = <<"pubsub#access_model">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#access_model">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#access_model">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#access_model">>, + <<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/pubsub#publish-opt" + "ions">>}}); +decode([], Acc, []) -> Acc. + +encode_access_model(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Access model of authorize">>), + value = <<"authorize">>}, + #xdata_option{label = + Translate(<<"Access model of open">>), + value = <<"open">>}, + #xdata_option{label = + Translate(<<"Access model of presence">>), + value = <<"presence">>}, + #xdata_option{label = + Translate(<<"Access model of roster">>), + value = <<"roster">>}, + #xdata_option{label = + Translate(<<"Access model of whitelist">>), + value = <<"whitelist">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#access_model">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, + label = Translate(<<"Specify the access model">>)}. diff --git a/src/pubsub_subscribe_authorization.erl b/src/pubsub_subscribe_authorization.erl new file mode 100644 index 000000000..e019ed6b9 --- /dev/null +++ b/src/pubsub_subscribe_authorization.erl @@ -0,0 +1,279 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: pubsub_subscribe_authorization.xdata +%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization +%% Document: XEP-0060 + +-module(pubsub_subscribe_authorization). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("pubsub_subscribe_authorization.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> + decode(Fs, Acc, + [<<"pubsub#allow">>, <<"pubsub#node">>, + <<"pubsub#subscriber_jid">>]); + #xdata_field{values = + [<<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>]} -> + decode(Fs, Acc, + [<<"pubsub#allow">>, <<"pubsub#node">>, + <<"pubsub#subscriber_jid">>]); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {allow, Val} -> [encode_allow(Val, Translate)]; + {allow, _, _} -> erlang:error({badarg, Opt}); + {node, Val} -> [encode_node(Val, Translate)]; + {node, _, _} -> erlang:error({badarg, Opt}); + {subscriber_jid, Val} -> + [encode_subscriber_jid(Val, Translate)]; + {subscriber_jid, _, _} -> erlang:error({badarg, Opt}); + {subid, Val} -> [encode_subid(Val, Translate)]; + {subid, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"pubsub#allow">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{allow, Result} | Acc], + lists:delete(<<"pubsub#allow">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#allow">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end; +decode([#xdata_field{var = <<"pubsub#allow">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#allow">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#allow">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#allow">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([#xdata_field{var = <<"pubsub#node">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{node, Result} | Acc], + lists:delete(<<"pubsub#node">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#node">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end; +decode([#xdata_field{var = <<"pubsub#node">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#node">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#node">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#node">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([#xdata_field{var = <<"pubsub#subscriber_jid">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_jid(Value) of + Result -> + decode(Fs, [{subscriber_jid, Result} | Acc], + lists:delete(<<"pubsub#subscriber_jid">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#subscriber_jid">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end; +decode([#xdata_field{var = <<"pubsub#subscriber_jid">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#subscriber_jid">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#subscriber_jid">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#subscriber_jid">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([#xdata_field{var = <<"pubsub#subid">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{subid, Result} | Acc], + lists:delete(<<"pubsub#subid">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#subid">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}) + end; +decode([#xdata_field{var = <<"pubsub#subid">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#subid">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#subid">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#subid">>, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_a" + "uthorization">>}}); +decode([], Acc, []) -> Acc. + +encode_allow(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#allow">>, values = Values, + required = false, type = boolean, options = Opts, + desc = <<>>, + label = + Translate(<<"Allow this Jabber ID to subscribe to " + "this pubsub node?">>)}. + +encode_node(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#node">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, label = Translate(<<"Node ID">>)}. + +encode_subscriber_jid(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_jid(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#subscriber_jid">>, + values = Values, required = false, type = 'jid-single', + options = Opts, desc = <<>>, + label = Translate(<<"Subscriber Address">>)}. + +encode_subid(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#subid">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = + Translate(<<"The subscription identifier associated " + "with the subscription request">>)}. diff --git a/src/pubsub_subscribe_options.erl b/src/pubsub_subscribe_options.erl new file mode 100644 index 000000000..446a84a00 --- /dev/null +++ b/src/pubsub_subscribe_options.erl @@ -0,0 +1,508 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: pubsub_subscribe_options.xdata +%% Form type: http://jabber.org/protocol/pubsub#subscribe_options +%% Document: XEP-0060 + +-module(pubsub_subscribe_options). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("pubsub_subscribe_options.hrl"). + +-export_type([{property, 0}, {result, 0}, {form, 0}]). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> AtomVal + end. + +enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = + [<<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {deliver, Val} -> [encode_deliver(Val, Translate)]; + {deliver, _, _} -> erlang:error({badarg, Opt}); + {digest, Val} -> [encode_digest(Val, Translate)]; + {digest, _, _} -> erlang:error({badarg, Opt}); + {digest_frequency, Val} -> + [encode_digest_frequency(Val, Translate)]; + {digest_frequency, _, _} -> erlang:error({badarg, Opt}); + {expire, Val} -> [encode_expire(Val, Translate)]; + {expire, _, _} -> erlang:error({badarg, Opt}); + {include_body, Val} -> + [encode_include_body(Val, Translate)]; + {include_body, _, _} -> erlang:error({badarg, Opt}); + {'show-values', Val} -> + ['encode_show-values'(Val, default, Translate)]; + {'show-values', Val, Opts} -> + ['encode_show-values'(Val, Opts, Translate)]; + {subscription_type, Val} -> + [encode_subscription_type(Val, default, Translate)]; + {subscription_type, Val, Opts} -> + [encode_subscription_type(Val, Opts, Translate)]; + {subscription_depth, Val} -> + [encode_subscription_depth(Val, default, Translate)]; + {subscription_depth, Val, Opts} -> + [encode_subscription_depth(Val, Opts, Translate)]; + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = + [<<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"pubsub#deliver">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{deliver, Result} | Acc], + lists:delete(<<"pubsub#deliver">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#deliver">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = <<"pubsub#deliver">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#deliver">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#deliver">>} | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#deliver">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = <<"pubsub#digest">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{digest, Result} | Acc], + lists:delete(<<"pubsub#digest">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#digest">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = <<"pubsub#digest">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#digest">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#digest">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#digest">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = + <<"pubsub#digest_frequency">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{digest_frequency, Result} | Acc], + lists:delete(<<"pubsub#digest_frequency">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#digest_frequency">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#digest_frequency">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#digest_frequency">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#digest_frequency">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#digest_frequency">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = <<"pubsub#expire">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{expire, Result} | Acc], + lists:delete(<<"pubsub#expire">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#expire">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = <<"pubsub#expire">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#expire">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#expire">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#expire">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = <<"pubsub#include_body">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_bool(Value) of + Result -> + decode(Fs, [{include_body, Result} | Acc], + lists:delete(<<"pubsub#include_body">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#include_body">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = <<"pubsub#include_body">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"pubsub#include_body">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"pubsub#include_body">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#include_body">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = <<"pubsub#show-values">>, + values = Values} + | Fs], + Acc, Required) -> + try [dec_enum(Value, [away, chat, dnd, online, xa]) + || Value <- Values] + of + Result -> + decode(Fs, [{'show-values', Result} | Acc], + lists:delete(<<"pubsub#show-values">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#show-values">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#subscription_type">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, [items, nodes]) of + Result -> + decode(Fs, [{subscription_type, Result} | Acc], + lists:delete(<<"pubsub#subscription_type">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#subscription_type">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#subscription_type">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#subscription_type">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#subscription_type">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#subscription_type">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = + <<"pubsub#subscription_depth">>, + values = [Value]} + | Fs], + Acc, Required) -> + try dec_enum(Value, ['1', all]) of + Result -> + decode(Fs, [{subscription_depth, Result} | Acc], + lists:delete(<<"pubsub#subscription_depth">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"pubsub#subscription_depth">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}) + end; +decode([#xdata_field{var = + <<"pubsub#subscription_depth">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = + <<"pubsub#subscription_depth">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = + <<"pubsub#subscription_depth">>} + | _], + _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"pubsub#subscription_depth">>, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, + <<"http://jabber.org/protocol/pubsub#subscribe_o" + "ptions">>}}); +decode([], Acc, []) -> Acc. + +encode_deliver(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#deliver">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Whether an entity wants to receive or " + "disable notifications">>)}. + +encode_digest(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#digest">>, values = Values, + required = false, type = boolean, options = Opts, + desc = <<>>, + label = + Translate(<<"Whether an entity wants to receive digests " + "(aggregations) of notifications or all " + "notifications individually">>)}. + +encode_digest_frequency(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#digest_frequency">>, + values = Values, required = false, type = 'text-single', + options = Opts, desc = <<>>, + label = + Translate(<<"The minimum number of milliseconds between " + "sending any two notification digests">>)}. + +encode_expire(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"pubsub#expire">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = + Translate(<<"The DateTime at which a leased subscription " + "will end or has ended">>)}. + +encode_include_body(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_bool(Value)] + end, + Opts = [], + #xdata_field{var = <<"pubsub#include_body">>, + values = Values, required = false, type = boolean, + options = Opts, desc = <<>>, + label = + Translate(<<"Whether an entity wants to receive an " + "XMPP message body in addition to the " + "payload format">>)}. + +'encode_show-values'(Value, Options, Translate) -> + Values = case Value of + [] -> []; + Value -> [enc_enum(V) || V <- Value] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"XMPP Show Value of Away">>), + value = <<"away">>}, + #xdata_option{label = + Translate(<<"XMPP Show Value of Chat">>), + value = <<"chat">>}, + #xdata_option{label = + Translate(<<"XMPP Show Value of DND (Do Not Disturb)">>), + value = <<"dnd">>}, + #xdata_option{label = + Translate(<<"Mere Availability in XMPP (No Show Value)">>), + value = <<"online">>}, + #xdata_option{label = + Translate(<<"XMPP Show Value of XA (Extended Away)">>), + value = <<"xa">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#show-values">>, + values = Values, required = false, type = 'list-multi', + options = Opts, desc = <<>>, + label = + Translate(<<"The presence states for which an entity " + "wants to receive notifications">>)}. + +encode_subscription_type(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Receive notification of new items only">>), + value = <<"items">>}, + #xdata_option{label = + Translate(<<"Receive notification of new nodes only">>), + value = <<"nodes">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#subscription_type">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, label = <<>>}. + +encode_subscription_depth(Value, Options, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_enum(Value)] + end, + Opts = if Options == default -> + [#xdata_option{label = + Translate(<<"Receive notification from direct child " + "nodes only">>), + value = <<"1">>}, + #xdata_option{label = + Translate(<<"Receive notification from all descendent " + "nodes">>), + value = <<"all">>}]; + true -> + [#xdata_option{label = Translate(L), + value = enc_enum(V)} + || {L, V} <- Options] + end, + #xdata_field{var = <<"pubsub#subscription_depth">>, + values = Values, required = false, type = 'list-single', + options = Opts, desc = <<>>, label = <<>>}. diff --git a/src/xdata_codec.erl b/src/xdata_codec.erl new file mode 100644 index 000000000..223f24a1b --- /dev/null +++ b/src/xdata_codec.erl @@ -0,0 +1,648 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 27 Sep 2016 by Evgeny Khramtsov +%%%------------------------------------------------------------------- +-module(xdata_codec). + +%% API +-export([compile/1, compile/2]). +-export([dec_int/1, dec_int/3, dec_enum/2, dec_bool/1, not_empty/1, + dec_enum_int/2, dec_enum_int/4, enc_int/1, enc_enum/1, + enc_bool/1, enc_enum_int/1, format_error/1, enc_jid/1, dec_jid/1]). +-include("xmpp.hrl"). + +-record(state, {mod_name :: atom(), + file_name :: string(), + erl = "" :: string(), + hrl = "" :: string(), + dir = "" :: string(), + ns = <<>> :: binary(), + doc = <<>> :: binary(), + erl_dir = "" :: string(), + hrl_dir = "" :: string(), + prefix = [] :: [binary()], + dec_mfas = [] :: [{binary(), mfa()}], + enc_mfas = [] :: [{binary(), mfa()}], + specs = [] :: [{binary(), string()}], + required = [] :: [{binary(), boolean()} | binary()], + defaults = [] :: [{binary(), any()}]}). + +-define(is_multi_type(T), + ((T == 'list-multi') or (T == 'jid-multi') or (T == 'text-multi'))). + +-define(is_list_type(T), + ((T == 'list-single') or (T == 'list-multi'))). + +%%%=================================================================== +%%% API +%%%=================================================================== +compile(Path) -> + compile(Path, []). + +compile(Path, Opts) -> + case filelib:is_dir(Path) of + true -> + filelib:fold_files( + Path, ".*.xdata", false, + fun(File, ok) -> + compile_file(File, Opts); + (_, Err) -> + Err + end, ok); + false -> + compile_file(Path, Opts) + end. + +compile_file(Path, Opts) -> + try + ok = application:ensure_started(fast_xml), + DirName = filename:dirname(Path), + FileName = filename:basename(Path), + RootName = filename:rootname(FileName), + ConfigPath = filename:join(DirName, RootName) ++ ".cfg", + ModName = list_to_atom(RootName), + {ok, Data} = file:read_file(Path), + Config = case file:consult(ConfigPath) of + {ok, Terms} -> lists:flatten(Terms); + {error, enoent} -> [] + end, + State = #state{mod_name = ModName, + file_name = FileName, + erl = filename:rootname(FileName) ++ ".erl", + hrl = filename:rootname(FileName) ++ ".hrl", + dir = DirName, + prefix = proplists:get_all_values(prefix, Config), + erl_dir = proplists:get_value(erl_dir, Opts, DirName), + hrl_dir = proplists:get_value(hrl_dir, Opts, DirName), + dec_mfas = proplists:get_value(decode, Config, []), + enc_mfas = proplists:get_value(encode, Config, []), + specs = proplists:get_value(specs, Config, []), + required = proplists:get_value(required, Config, []), + defaults = proplists:get_value(defaults, Config, [])}, + #xmlel{} = El = fxml_stream:parse_element(Data), + ok = compile_element(normalize(El), State), + io:format("Compiled ~s~n", [Path]) + catch _:{badmatch, Err} -> + io:format(standard_error, "Failed to compile ~s: ~p~n", + [Path, Err]), + Err + end. + +emit(Format) -> + emit(Format, []). + +emit(Format, Args) -> + put(outbuf, get(outbuf) ++ io_lib:format(Format, Args)). + +dec_int(Val) -> + dec_int(Val, infinity, infinity). + +dec_int(Val, Min, Max) -> + case list_to_integer(binary_to_list(Val)) of + Int when Int =< Max, Min == infinity -> + Int; + Int when Int =< Max, Int >= Min -> + Int + end. + +enc_int(Int) -> + integer_to_binary(Int). + +dec_enum(Val, Enums) -> + AtomVal = erlang:binary_to_existing_atom(Val, utf8), + case lists:member(AtomVal, Enums) of + true -> + AtomVal + end. + +enc_enum(Atom) -> + erlang:atom_to_binary(Atom, utf8). + +dec_enum_int(Val, Enums) -> + try dec_int(Val) + catch _:_ -> dec_enum(Val, Enums) + end. + +dec_enum_int(Val, Enums, Min, Max) -> + try dec_int(Val, Min, Max) + catch _:_ -> dec_enum(Val, Enums) + end. + +enc_enum_int(Int) when is_integer(Int) -> + enc_int(Int); +enc_enum_int(Atom) -> + enc_enum(Atom). + +dec_bool(<<"1">>) -> true; +dec_bool(<<"0">>) -> false; +dec_bool(<<"true">>) -> true; +dec_bool(<<"false">>) -> false. + +enc_bool(true) -> <<"1">>; +enc_bool(false) -> <<"0">>. + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +not_empty(<<_, _/binary>> = Val) -> + Val. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", Type/binary, "'">>. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +compile_element(#xmlel{name = <<"form_type">>, children = Els} = Form, + #state{erl = OutErl, erl_dir = ErlDir, + hrl = OutHrl, hrl_dir = HrlDir} = State0) -> + try + Name = fxml:get_subtag_cdata(Form, <<"name">>), + Doc = fxml:get_subtag_cdata(Form, <<"doc">>), + X = #xmlel{name = <<"x">>, + attrs = [{<<"type">>, <<"form">>}, + {<<"xmlns">>, <<"jabber:x:data">>}], + children = Els}, + State = State0#state{ns = Name, doc = Doc}, + #xdata{fields = Fs} = xmpp_codec:decode(X), + put(outbuf, []), + mk_header(State), + mk_aux_funs(), + mk_top_decoder(Fs, State), + mk_top_encoder(Fs, State), + mk_decoder(Fs, State), + mk_encoders(Fs, State), + ErlData = get(outbuf), + ok = file:write_file(filename:join(ErlDir, OutErl), ErlData), + ok = erl_tidy:file(filename:join(ErlDir, OutErl), [{backups, false}]), + put(outbuf, []), + mk_type_definitions(Fs, State), + HrlData = get(outbuf), + ok = file:write_file(filename:join(HrlDir, OutHrl), HrlData) + catch _:{badmatch, Err} -> + Err + end. + +mk_aux_funs() -> + case get_abstract_code_from_myself() of + {ok, AbsCode} -> + AST = lists:filter( + fun(T) -> + case catch erl_syntax_lib:analyze_function(T) of + {format_error, 1} -> true; + {dec_int, 3} -> true; + {dec_int, 1} -> true; + {dec_enum, 2} -> true; + {dec_enum_int, 2} -> true; + {dec_enum_int, 4} -> true; + {enc_int, 1} -> true; + {enc_enum, 1} -> true; + {enc_enum_int, 1} -> true; + {not_empty, 1} -> true; + {dec_bool, 1} -> true; + {enc_bool, 1} -> true; + {enc_jid, 1} -> true; + {dec_jid, 1} -> true; + _ -> false + end + end, AbsCode), + emit(erl_prettypr:format(erl_syntax:form_list(AST)) ++ io_lib:nl()); + error -> + erlang:error({no_abstract_code_found, ?MODULE}) + end. + +get_abstract_code_from_myself() -> + {file, File} = code:is_loaded(?MODULE), + case beam_lib:chunks(File, [abstract_code]) of + {ok, {_, List}} -> + case lists:keyfind(abstract_code, 1, List) of + {abstract_code, {raw_abstract_v1, Abstr}} -> + {ok, Abstr}; + _ -> + error + end; + _ -> + error + end. + +mk_comment_header(#state{file_name = Source, ns = NS, doc = Doc}) -> + emit("%% Created automatically by xdata generator (xdata_codec.erl)~n" + "%% Source: ~s~n" + "%% Form type: ~s~n", [Source, NS]), + if Doc /= <<>> -> emit("%% Document: ~s~n~n", [Doc]); + true -> emit("~n") + end. + +mk_header(#state{mod_name = Mod, hrl = Include} = State) -> + mk_comment_header(State), + emit("~n-module(~s).~n", [Mod]), + emit("-export([decode/1, decode/2, encode/1, encode/2, format_error/1]).~n"), + emit("-include(\"xmpp_codec.hrl\").~n"), + emit("-include(\"~s\").~n", [Include]), + emit("-export_type([property/0, result/0, form/0]).~n"). + +mk_type_definitions(Fs, State) -> + mk_comment_header(State), + lists:foreach( + fun(#xdata_field{var = Var} = F) -> + Spec = get_typespec(F, State), + case is_complex_type(Spec) of + true -> + emit("-type '~s'() :: ~s.~n", + [var_to_rec_field(Var, State), Spec]); + false -> + ok + end + end, Fs), + emit("~n-type property() :: "), + Fields = lists:map( + fun(#xdata_field{var = Var} = F) -> + RecField = var_to_rec_field(Var, State), + [io_lib:format("{'~s', ~s}", + [RecField, mk_typespec(F, State)])] + end, Fs), + emit(string:join(Fields, " |~n ") ++ ".~n"), + emit("-type result() :: [property()].~n~n"), + VarsWithSpec = lists:flatmap( + fun(#xdata_field{type = T, var = Var} = F) + when ?is_list_type(T) -> + RecName = var_to_rec_field(Var, State), + Spec0 = get_typespec(F, State), + Spec = case is_complex_type(Spec0) of + true -> + io_lib:format("'~s'()", [RecName]); + false -> + Spec0 + end, + [{RecName, mk_typespec(F, State), Spec}]; + (_) -> + [] + end, Fs), + case VarsWithSpec of + [] -> + emit("-type form() :: [property() | xdata_field()].~n"); + _ -> + emit("-type options(T) :: [{binary(), T}].~n"), + emit("-type property_with_options() ::~n "), + Options = [io_lib:format("{'~s', ~s, options(~s)}", + [Var, Spec1, Spec2]) + || {Var, Spec1, Spec2} <- VarsWithSpec], + emit(string:join(Options, " |~n ") ++ ".~n"), + emit("-type form() :: [property() | property_with_options() | xdata_field()].~n") + end. + +mk_top_decoder(Fs, State) -> + Required = [Var || #xdata_field{var = Var} <- Fs, is_required(Var, State)], + emit("decode(Fs) -> decode(Fs, []).~n"), + emit("decode(Fs, Acc) ->" + " case lists:keyfind(<<\"FORM_TYPE\">>, #xdata_field.var, Fs) of" + " false ->" + " decode(Fs, Acc, ~p);" + " #xdata_field{values = [~p]} ->" + " decode(Fs, Acc, ~p);" + " _ ->" + " erlang:error({?MODULE, {form_type_mismatch, ~p}})~n" + " end.~n", + [Required, State#state.ns, Required, State#state.ns]). + +mk_top_encoder(Fs, State) -> + Clauses = string:join( + lists:map( + fun(#xdata_field{var = Var, type = T}) when ?is_list_type(T) -> + Field = var_to_rec_field(Var, State), + io_lib:format( + "{'~s', Val} -> ['encode_~s'(Val, default, Translate)];" + "{'~s', Val, Opts} -> ['encode_~s'(Val, Opts, Translate)]", + [Field, Field, Field, Field]); + (#xdata_field{var = Var}) -> + Field = var_to_rec_field(Var, State), + io_lib:format( + "{'~s', Val} -> ['encode_~s'(Val, Translate)];" + "{'~s', _, _} -> erlang:error({badarg, Opt})", + [Field, Field, Field]) + end, Fs) ++ ["#xdata_field{} -> [Opt]; _ -> []"], + ";"), + emit("encode(Cfg) -> encode(Cfg, fun(Text) -> Text end).~n"), + emit("encode(List, Translate) when is_list(List) ->" + " Fs = [case Opt of ~s end || Opt <- List]," + " FormType = #xdata_field{var = <<\"FORM_TYPE\">>, type = hidden," + " values = [~p]}," + " [FormType|lists:flatten(Fs)].~n", + [Clauses, State#state.ns]). + +mk_decoder([#xdata_field{var = Var, type = Type} = F|Fs], State) -> + ValVar = if ?is_multi_type(Type) -> "Values"; + true -> "[Value]" + end, + DecFun = if ?is_multi_type(Type) -> + ["[", mk_decoding_fun(F, State), " || Value <- Values]"]; + true -> + mk_decoding_fun(F, State) + end, + emit("decode([#xdata_field{var = ~p, values = ~s}|Fs], Acc, Required) ->" + " try ~s of" + " Result -> decode(Fs, [{'~s', Result}|Acc]," + " lists:delete(~p, Required))" + " catch _:_ ->" + " erlang:error({?MODULE, {bad_var_value, ~p, ~p}})" + " end;", + [Var, ValVar, DecFun, var_to_rec_field(Var, State), + Var, Var, State#state.ns]), + if not ?is_multi_type(Type) -> + emit("decode([#xdata_field{var = ~p, values = []} = F|Fs]," + " Acc, Required) ->" + " decode([F#xdata_field{var = ~p, values = [<<>>]}|Fs]," + " Acc, Required);", + [Var, Var]), + emit("decode([#xdata_field{var = ~p}|_], _, _) ->" + " erlang:error({?MODULE, {too_many_values, ~p, ~p}});", + [Var, Var, State#state.ns]); + true -> + ok + end, + mk_decoder(Fs, State); +mk_decoder([], State) -> + emit("decode([#xdata_field{var = Var}|Fs], Acc, Required) ->" + " if Var /= <<\"FORM_TYPE\">> ->" + " erlang:error({?MODULE, {unknown_var, Var, ~p}});" + " true ->" + " decode(Fs, Acc, Required)" + " end;", + [State#state.ns]), + emit("decode([], _, [Var|_]) ->" + " erlang:error({?MODULE, {missing_required_var, Var, ~p}});~n", + [State#state.ns]), + emit("decode([], Acc, []) -> Acc.~n"). + +mk_encoders(Fs, State) -> + lists:foreach( + fun(#xdata_field{var = Var, required = IsRequired, desc = Desc, + label = Label, type = Type} = F) -> + EncVals = mk_encoded_values(F, State), + EncOpts = mk_encoded_options(F, State), + FieldName = var_to_rec_field(Var, State), + DescStr = if Desc == <<>> -> "<<>>"; + true -> io_lib:format("Translate(~p)", [Desc]) + end, + LabelStr = if Label == <<>> -> "<<>>"; + true -> io_lib:format("Translate(~p)", [Label]) + end, + if ?is_list_type(Type) -> + emit("'encode_~s'(Value, Options, Translate) ->", [FieldName]); + true -> + emit("'encode_~s'(Value, Translate) ->", [FieldName]) + end, + emit(" Values = ~s," + " Opts = ~s," + " #xdata_field{var = ~p," + " values = Values," + " required = ~p," + " type = ~p," + " options = Opts," + " desc = ~s," + " label = ~s}.~n", + [EncVals, EncOpts, Var, IsRequired, Type, DescStr, LabelStr]) + end, Fs). + +mk_encoded_values(#xdata_field{var = Var, type = Type, + options = Options}, State) -> + EncFun = + case get_enc_fun(Var, Type, Options, State) of + {M, Fun, Args} -> + Mod = if M == undefined -> ""; + true -> io_lib:format("~s:", [M]) + end, + FArgs = [io_lib:format(", ~p", [A]) || A <- Args], + if ?is_multi_type(Type) -> + "[" ++ io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]) ++ + " || V <- Value]"; + true -> + "[" ++ io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs]) + ++ "]" + end; + undefined -> + "[Value]" + end, + Default = case get_dec_fun(Var, Type, Options, State) of + _ when ?is_multi_type(Type) -> "[]"; + undefined -> "<<>>"; + _MFA -> "undefined" + end, + io_lib:format( + "case Value of" + " ~s -> [];~n" + " Value -> ~s~n" + "end", + [Default, EncFun]). + +mk_encoded_options(#xdata_field{var = Var, type = Type, + options = Options}, State) -> + EncFun = case get_enc_fun(Var, Type, Options, State) of + {M, Fun, Args} -> + Mod = if M == undefined -> ""; + true -> io_lib:format("~s:", [M]) + end, + FArgs = [io_lib:format(", ~p", [A]) || A <- Args], + io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]); + undefined -> + "V" + end, + EncOpts = string:join( + [case L of + <<>> -> + io_lib:format("#xdata_option{value = ~p}", [V]); + _ -> + io_lib:format( + "#xdata_option{label = Translate(~p), value = ~p}", + [L, V]) + end || #xdata_option{label = L, value = V} <- Options], + ","), + if ?is_list_type(Type) -> + io_lib:format( + "if Options == default ->" + " [~s];" + "true ->" + " [#xdata_option{label = Translate(L), value = ~s}" + " || {L, V} <- Options]" + "end", + [EncOpts, EncFun]); + true -> + "[]" + end. + +mk_decoding_fun(#xdata_field{var = Var, type = Type, + options = Options}, State) -> + case get_dec_fun(Var, Type, Options, State) of + {M, Fun, Args} -> + Mod = if M == undefined -> ""; + true -> io_lib:format("~s:", [M]) + end, + FArgs = [io_lib:format(", ~p", [A]) || A <- Args], + io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs]); + undefined -> + "Value" + end. + +var_to_rec_field(Var, #state{prefix = [Prefix|T]} = State) -> + Size = size(Prefix), + case Var of + <<(Prefix):Size/binary, Rest/binary>> -> + binary_to_atom(Rest, utf8); + _ -> + var_to_rec_field(Var, State#state{prefix = T}) + end; +var_to_rec_field(Var, #state{prefix = []}) -> + Var. + +get_dec_fun(Var, Type, Options, State) -> + case lists:keyfind(Var, 1, State#state.dec_mfas) of + false when Type == 'list-multi'; Type == 'list-single' -> + if Options /= [] -> + Variants = [binary_to_atom(V, utf8) + || #xdata_option{value = V} <- Options], + {undefined, dec_enum, [Variants]}; + true -> + undefined + end; + false when Type == 'jid-multi'; Type == 'jid-single' -> + {undefined, dec_jid, []}; + false when Type == boolean -> + {undefined, dec_bool, []}; + false -> + undefined; + {Var, {M, F, A}} -> + {M, F, A}; + {Var, {dec_bool, []}} -> + {undefined, dec_bool, []}; + {Var, {not_empty, []}} -> + {undefined, not_empty, []}; + {Var, {dec_enum, [Variants]}} -> + {undefined, dec_enum, [Variants]}; + {Var, {dec_int, Args}} -> + {undefined, dec_int, Args}; + {Var, {dec_enum_int, Args}} -> + {undefined, dec_enum_int, Args}; + {Var, {dec_jid, []}} -> + {undefined, dec_jid, []} + end. + +get_enc_fun(Var, Type, Options, State) -> + case get_dec_fun(Var, Type, Options, State) of + {undefined, dec_enum, _} -> + {undefined, enc_enum, []}; + {undefined, dec_bool, _} -> + {undefined, enc_bool, []}; + {undefined, dec_int, _} -> + {undefined, enc_int, []}; + {undefined, dec_enum_int, _} -> + {undefined, enc_enum_int, []}; + {undefined, dec_jid, _} -> + {undefined, enc_jid, []}; + _ -> + case lists:keyfind(Var, 1, State#state.enc_mfas) of + false -> + undefined; + {Var, {M, F, A}} -> + {M, F, A}; + {Var, {enc_bool, []}} -> + {undefined, enc_bool, []}; + {Var, {dec_enum, _}} -> + {undefined, enc_enum, []}; + {Var, {enc_int, _}} -> + {undefined, enc_int, []}; + {Var, {dec_enum_int, _}} -> + {undefined, enc_enum_int, []}; + {Var, {enc_jid, _}} -> + {undefined, enc_jid, []} + end + end. + +mk_typespec(#xdata_field{type = Type, var = Var} = Field, State) -> + Spec0 = get_typespec(Field, State), + Spec1 = case is_complex_type(Spec0) of + true -> + io_lib:format("'~s'()", [var_to_rec_field(Var, State)]); + false -> + Spec0 + end, + if ?is_multi_type(Type) -> "[" ++ Spec1 ++ "]"; + true -> Spec1 + end. + +get_typespec(#xdata_field{var = Var, type = Type, options = Options}, State) -> + case lists:keyfind(Var, 1, State#state.specs) of + false -> + case get_dec_fun(Var, Type, Options, State) of + {undefined, dec_enum, Args} -> + enum_spec(Args); + {undefined, dec_bool, _} -> + "boolean()"; + {undefined, dec_jid, _} -> + "jid:jid()"; + {undefined, dec_int, Args} -> + int_spec(Args); + {undefined, dec_enum_int, [Variants|T]} -> + enum_spec([Variants]) ++ " | " ++ int_spec(T); + _ -> + "binary()" + end; + {Var, Spec} -> + Spec + end. + +-spec is_complex_type(string()) -> boolean(). +is_complex_type(Spec) -> + string:chr(Spec, $|) /= 0. + +int_spec([]) -> + "integer()"; +int_spec([From, To]) -> + if From /= infinity, To /= infinity -> + io_lib:format("~p..~p", [From, To]); + From > 0 -> + "pos_integer()"; + From == 0 -> + "non_neg_integer()"; + true -> + "integer()" + end. + +enum_spec([Variants]) -> + string:join([atom_to_list(V) || V <- Variants], " | "). + +is_required(Var, State) -> + lists:member(Var, State#state.required) orelse + proplists:get_bool(Var, State#state.required). + +normalize(#xmlel{name = Name, attrs = Attrs, children = Els}) -> + #xmlel{name = Name, + attrs = [normalize(Attr) || Attr <- Attrs], + children = [normalize(El) || El <- Els]}; +normalize({Key, Data}) -> + {Key, normalize(Data)}; +normalize(Txt) when is_binary(Txt) -> + case re:split(Txt, "[\\s\\r\\n\\t]+", [trim, {return, list}]) of + [""|T] -> + list_to_binary(string:join(T, " ")); + T -> + list_to_binary(string:join(T, " ")) + end. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index f8f8b205f..f230dc489 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -6602,6 +6602,20 @@ pp(upload_slot, 3) -> [get, put, xmlns]; pp(thumbnail, 4) -> [uri, 'media-type', width, height]; pp(_, _) -> no. +enc_ps_aff(member) -> <<"member">>; +enc_ps_aff(none) -> <<"none">>; +enc_ps_aff(outcast) -> <<"outcast">>; +enc_ps_aff(owner) -> <<"owner">>; +enc_ps_aff(publisher) -> <<"publisher">>; +enc_ps_aff(publish_only) -> <<"publish-only">>. + +dec_ps_aff(<<"member">>) -> member; +dec_ps_aff(<<"none">>) -> none; +dec_ps_aff(<<"outcast">>) -> outcast; +dec_ps_aff(<<"owner">>) -> owner; +dec_ps_aff(<<"publisher">>) -> publisher; +dec_ps_aff(<<"publish-only">>) -> publish_only. + enc_version({Maj, Min}) -> <<(integer_to_binary(Maj))/binary, $., (integer_to_binary(Min))/binary>>. @@ -19203,10 +19217,7 @@ decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, __TopXMLNS}}); decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [member, none, outcast, owner, publisher, - 'publish-only']) - of + case catch dec_ps_aff(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_attr_value, <<"affiliation">>, <<"affiliation">>, @@ -19216,7 +19227,7 @@ decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, encode_pubsub_owner_affiliation_attr_affiliation(_val, _acc) -> - [{<<"affiliation">>, enc_enum(_val)} | _acc]. + [{<<"affiliation">>, enc_ps_aff(_val)} | _acc]. decode_pubsub_affiliation(__TopXMLNS, __IgnoreEls, {xmlel, <<"affiliation">>, _attrs, _els}) -> @@ -19290,10 +19301,7 @@ decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, __TopXMLNS}}); decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [member, none, outcast, owner, publisher, - 'publish-only']) - of + case catch dec_ps_aff(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_attr_value, <<"affiliation">>, <<"affiliation">>, @@ -19303,7 +19311,7 @@ decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, encode_pubsub_affiliation_attr_affiliation(_val, _acc) -> - [{<<"affiliation">>, enc_enum(_val)} | _acc]. + [{<<"affiliation">>, enc_ps_aff(_val)} | _acc]. decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, {xmlel, <<"subscription">>, _attrs, _els}) -> @@ -19826,7 +19834,7 @@ decode_xdata_field(__TopXMLNS, __IgnoreEls, {xmlel, <<"field">>, _attrs, _els}) -> {Options, Values, Desc, Required, __Els} = decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - [], [], undefined, false, []), + [], [], <<>>, false, []), {Label, Type, Var} = decode_xdata_field_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), @@ -20003,8 +20011,7 @@ encode_xdata_field({xdata_field, Label, Type, Var, [encode_xdata_field_value(Values, __TopXMLNS) | _acc]). -'encode_xdata_field_$desc'(undefined, __TopXMLNS, - _acc) -> +'encode_xdata_field_$desc'(<<>>, __TopXMLNS, _acc) -> _acc; 'encode_xdata_field_$desc'(Desc, __TopXMLNS, _acc) -> [encode_xdata_field_desc(Desc, __TopXMLNS) | _acc]. diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 43178e86f..102d88412 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -11,7 +11,8 @@ %% API -export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, is_standalone_chat_state/1, get_xdata_values/2, - has_xdata_var/2, make_adhoc_response/1, make_adhoc_response/2]). + has_xdata_var/2, make_adhoc_response/1, make_adhoc_response/2, + decode_timestamp/1, encode_timestamp/1]). -include("xmpp.hrl"). @@ -95,11 +96,66 @@ make_adhoc_response(#adhoc_command{lang = Lang, node = Node, sid = SID}, -spec make_adhoc_response(adhoc_command()) -> adhoc_command(). make_adhoc_response(#adhoc_command{sid = <<"">>} = Command) -> - SID = jlib:now_to_utc_string(p1_time_compat:timestamp()), + SID = encode_timestamp(p1_time_compat:timestamp()), Command#adhoc_command{sid = SID}; make_adhoc_response(Command) -> Command. +-spec decode_timestamp(binary()) -> erlang:timestamp(). +decode_timestamp(S) -> + try try_decode_timestamp(S) + catch _:_ -> erlang:error({bad_timestamp, S}) + end. + +-spec encode_timestamp(erlang:timestamp()) -> binary(). +encode_timestamp({MegaSecs, Secs, MicroSecs}) -> + {{Year, Month, Day}, {Hour, Minute, Second}} = + calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}), + Fraction = if MicroSecs > 0 -> + io_lib:format(".~6..0B", [MicroSecs]); + true -> + "" + end, + list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT" + "~2..0B:~2..0B:~2..0B~sZ", + [Year, Month, Day, Hour, Minute, Second, + Fraction])). + %%%=================================================================== %%% Internal functions %%%=================================================================== +try_decode_timestamp(<>) -> + Date = {to_integer(Y, 1970, 9999), to_integer(Mo, 1, 12), to_integer(D, 1, 31)}, + Time = {to_integer(H, 0, 23), to_integer(Mi, 0, 59), to_integer(S, 0, 59)}, + {MS, {TZH, TZM}} = try_decode_fraction(T), + Seconds = calendar:datetime_to_gregorian_seconds({Date, Time}) - + calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}}) - + TZH * 60 * 60 - TZM * 60, + {Seconds div 1000000, Seconds rem 1000000, MS}; +try_decode_timestamp(<>) -> + try_decode_timestamp(<>). + +try_decode_fraction(<<$., T/binary>>) -> + {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], binary}]), + Size = size(V), + <> = T, + {to_integer(binary:part(V, 0, min(6, Size)), 0, 999999), + try_decode_tzd(TZD)}; +try_decode_fraction(TZD) -> + {0, try_decode_tzd(TZD)}. + +try_decode_tzd(<<$Z>>) -> + {0, 0}; +try_decode_tzd(<<$-, H:2/binary, $:, M:2/binary>>) -> + {-1 * to_integer(H, 0, 12), to_integer(M, 0, 59)}; +try_decode_tzd(<<$+, H:2/binary, $:, M:2/binary>>) -> + {to_integer(H, 0, 12), to_integer(M, 0, 59)}. + +to_integer(S, Min, Max) -> + case binary_to_integer(S) of + I when I >= Min, I =< Max -> + I + end. -- cgit v1.2.3 From a915fd161e0121ce4338a62d3cda7736f7e20dd9 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 7 Sep 2016 11:15:19 +0300 Subject: Create room on configuration request as per XEP-0045, 10.1.3 --- src/mod_muc.erl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mod_muc.erl b/src/mod_muc.erl index b189508a8..6b71d1e1d 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -385,8 +385,8 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, {Room, _, Nick} = jid:tolower(To), case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> - case Packet of - #presence{type = available, lang = Lang} -> + case is_create_request(Packet) of + true -> case check_user_can_create_room( ServerHost, AccessCreate, From, Room) and check_create_roomid(ServerHost, Room) of @@ -399,12 +399,13 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, mod_muc_room:route(Pid, From, Nick, Packet), ok; false -> + Lang = xmpp:get_lang(Packet), ErrText = <<"Room creation is denied by service policy">>, Err = xmpp:make_error( Packet, xmpp:err_forbidden(ErrText, Lang)), ejabberd_router:route(To, From, Err) end; - _ -> + false -> Lang = xmpp:get_lang(Packet), ErrText = <<"Conference room does not exist">>, Err = xmpp:err_item_not_found(ErrText, Lang), @@ -501,6 +502,16 @@ process_mucsub(#iq{type = get, from = From, to = To} = IQ) -> RoomJIDs = get_subscribed_rooms(ServerHost, Host, From), xmpp:make_iq_result(IQ, #muc_subscriptions{list = RoomJIDs}). +-spec is_create_request(stanza()) -> boolean(). +is_create_request(#presence{type = available}) -> + true; +is_create_request(#iq{type = set} = IQ) -> + xmpp:has_subtag(IQ, #muc_subscribe{}); +is_create_request(#iq{type = get} = IQ) -> + #muc_owner{} == xmpp:get_subtag(IQ, #muc_owner{}); +is_create_request(_) -> + false. + check_user_can_create_room(ServerHost, AccessCreate, From, _RoomID) -> case acl:match_rule(ServerHost, AccessCreate, From) of -- cgit v1.2.3 From 67720c77137da2e80907f67dccc96fcbdb44c3bf Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 17 Oct 2016 13:37:23 +0300 Subject: Add more MUC tests --- src/gen_iq_handler.erl | 2 +- src/mod_mam.erl | 34 ++- src/mod_muc.erl | 56 +++-- src/mod_muc_room.erl | 556 +++++++++++++++++++++++-------------------------- src/str.erl | 6 + 5 files changed, 316 insertions(+), 338 deletions(-) (limited to 'src') diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index b8a44c96c..8af2cb028 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -156,7 +156,7 @@ process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) -> %% TODO: move this 'conditional' decoding somewhere %% IQ handler should know *nothing* about vCards. Pkt = case xmpp:get_ns(El) of - ?NS_VCARD -> El; + ?NS_VCARD when Module == mod_vcard -> El; _ -> xmpp:decode(El) end, Module:Function(IQ#iq{sub_els = [Pkt]}) diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 1daae5aa2..cbd23ebde 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -772,28 +772,25 @@ select(_LServer, JidRequestor, JidArchive, {groupchat, _Role, #state{config = #config{mam = false}, history = History}} = MsgType) -> #lqueue{len = L, queue = Q} = History, - {Msgs0, _} = - lists:mapfoldl( - fun({Nick, Pkt, _HaveSubject, UTCDateTime, _Size}, I) -> - Now = datetime_to_now(UTCDateTime, I), + Msgs = + lists:flatmap( + fun({Nick, Pkt, _HaveSubject, Now, _Size}) -> TS = now_to_usec(Now), case match_interval(Now, Start, End) and match_rsm(Now, RSM) of true -> - {[{integer_to_binary(TS), TS, - msg_to_el(#archive_msg{ - type = groupchat, - timestamp = Now, - peer = undefined, - nick = Nick, - packet = Pkt}, - MsgType, JidRequestor, JidArchive)}], - I+1}; + [{integer_to_binary(TS), TS, + msg_to_el(#archive_msg{ + type = groupchat, + timestamp = Now, + peer = undefined, + nick = Nick, + packet = Pkt}, + MsgType, JidRequestor, JidArchive)}]; false -> - {[], I+1} + [] end - end, 0, queue:to_list(Q)), - Msgs = lists:flatten(Msgs0), + end, queue:to_list(Q)), case RSM of #rsm_set{max = Max, before = Before} when is_binary(Before) -> {NewMsgs, IsComplete} = filter_by_max(lists:reverse(Msgs), Max), @@ -960,11 +957,6 @@ usec_to_now(Int) -> Sec = Secs rem 1000000, {MSec, Sec, USec}. -datetime_to_now(DateTime, USecs) -> - Seconds = calendar:datetime_to_gregorian_seconds(DateTime) - - calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}), - {Seconds div 1000000, Seconds rem 1000000, USecs}. - get_jids(undefined) -> []; get_jids(Js) -> diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 6b71d1e1d..9c17643b8 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -377,7 +377,7 @@ do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper, end; do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, From, #jid{luser = <<"">>} = To, Packet, _DefRoomOpts) -> - Err = xmpp:err_item_not_found(), + Err = xmpp:err_service_unavailable(), ejabberd_router:route_error(To, From, Packet, Err); do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> @@ -419,7 +419,7 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, end. -spec process_vcard(iq()) -> iq(). -process_vcard(#iq{type = get, lang = Lang} = IQ) -> +process_vcard(#iq{type = get, lang = Lang, sub_els = [#vcard_temp{}]} = IQ) -> Desc = translate:translate(Lang, <<"ejabberd MUC module">>), Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, xmpp:make_iq_result( @@ -428,15 +428,19 @@ process_vcard(#iq{type = get, lang = Lang} = IQ) -> desc = <>}); process_vcard(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)). + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_vcard(#iq{lang = Lang} = IQ) -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). -spec process_register(iq()) -> iq(). -process_register(#iq{type = get, from = From, to = To, lang = Lang} = IQ) -> +process_register(#iq{type = get, from = From, to = To, lang = Lang, + sub_els = [#register{}]} = IQ) -> Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), xmpp:make_iq_result(IQ, iq_get_register_info(ServerHost, Host, From, Lang)); process_register(#iq{type = set, from = From, to = To, - lang = Lang, sub_els = [El]} = IQ) -> + lang = Lang, sub_els = [El = #register{}]} = IQ) -> Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), case process_iq_register_set(ServerHost, Host, From, El, Lang) of @@ -469,8 +473,12 @@ process_disco_info(#iq{type = get, to = To, lang = Lang, IQ, #disco_info{features = Features, identities = [Identity], xdata = X}); -process_disco_info(#iq{type = get, lang = Lang} = IQ) -> - xmpp:make_error(IQ, xmpp:err_item_not_found(<<"No info available">>, Lang)). +process_disco_info(#iq{type = get, lang = Lang, + sub_els = [#disco_info{}]} = IQ) -> + xmpp:make_error(IQ, xmpp:err_item_not_found(<<"Node not found">>, Lang)); +process_disco_info(#iq{lang = Lang} = IQ) -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). -spec process_disco_items(iq()) -> iq(). process_disco_items(#iq{type = set, lang = Lang} = IQ) -> @@ -481,13 +489,17 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang, Host = To#jid.lserver, xmpp:make_iq_result( IQ, #disco_items{node = Node, - items = iq_disco_items(Host, From, Lang, Node, RSM)}). + items = iq_disco_items(Host, From, Lang, Node, RSM)}); +process_disco_items(#iq{lang = Lang} = IQ) -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). -spec process_muc_unique(iq()) -> iq(). process_muc_unique(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); -process_muc_unique(#iq{from = From, type = get} = IQ) -> +process_muc_unique(#iq{from = From, type = get, + sub_els = [#muc_unique{}]} = IQ) -> Name = p1_sha:sha(term_to_binary([From, p1_time_compat:timestamp(), randoms:get_string()])), xmpp:make_iq_result(IQ, #muc_unique{name = Name}). @@ -496,19 +508,22 @@ process_muc_unique(#iq{from = From, type = get} = IQ) -> process_mucsub(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); -process_mucsub(#iq{type = get, from = From, to = To} = IQ) -> +process_mucsub(#iq{type = get, from = From, to = To, + sub_els = [#muc_subscriptions{}]} = IQ) -> Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), RoomJIDs = get_subscribed_rooms(ServerHost, Host, From), - xmpp:make_iq_result(IQ, #muc_subscriptions{list = RoomJIDs}). + xmpp:make_iq_result(IQ, #muc_subscriptions{list = RoomJIDs}); +process_mucsub(#iq{lang = Lang} = IQ) -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). -spec is_create_request(stanza()) -> boolean(). is_create_request(#presence{type = available}) -> true; -is_create_request(#iq{type = set} = IQ) -> - xmpp:has_subtag(IQ, #muc_subscribe{}); -is_create_request(#iq{type = get} = IQ) -> - #muc_owner{} == xmpp:get_subtag(IQ, #muc_owner{}); +is_create_request(#iq{type = T} = IQ) when T == get; T == set -> + xmpp:has_subtag(IQ, #muc_subscribe{}) orelse + xmpp:has_subtag(IQ, #muc_owner{}); is_create_request(_) -> false. @@ -645,13 +660,12 @@ get_vh_rooms(_, _) -> %% index = NewIndex}} %% end. -get_subscribed_rooms(ServerHost, Host, From) -> - Rooms = get_rooms(ServerHost, Host), +get_subscribed_rooms(_ServerHost, Host, From) -> + Rooms = get_vh_rooms(Host), lists:flatmap( - fun(#muc_room{name_host = {Name, _}, opts = Opts}) -> - Subscribers = proplists:get_value(subscribers, Opts, []), - case lists:keymember(From, 1, Subscribers) of - true -> [jid:make(Name, Host, <<>>)]; + fun(#muc_online_room{name_host = {Name, _}, pid = Pid}) -> + case gen_fsm:sync_send_all_state_event(Pid, {is_subscriber, From}) of + true -> [jid:make(Name, Host)]; false -> [] end; (_) -> diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 52401f835..ce6851bc5 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -76,11 +76,6 @@ -type fsm_stop() :: {stop, normal, state()}. -type fsm_next() :: {next_state, normal_state, state()}. -type fsm_transition() :: fsm_stop() | fsm_next(). --type history_element() :: {binary(), %% nick - message(), %% message itself - boolean(), %% have subject - erlang:timestamp(), - non_neg_integer()}. -export_type([state/0]). @@ -252,7 +247,8 @@ normal_state({route, From, <<"">>, ejabberd_router:route_error(StateData#state.jid, From, Packet, Err), {next_state, normal_state, StateData}; false when Type /= error -> - handle_roommessage_from_nonparticipant(Packet, StateData, From); + handle_roommessage_from_nonparticipant(Packet, StateData, From), + {next_state, normal_state, StateData}; false -> {next_state, normal_state, StateData} end; @@ -279,9 +275,6 @@ normal_state({route, From, <<"">>, process_iq_owner(From, IQ, StateData); ?NS_DISCO_INFO when SubEl#disco_info.node == <<>> -> process_iq_disco_info(From, IQ, StateData); - ?NS_DISCO_INFO -> - Txt = <<"Disco info is not available for this node">>, - {error, xmpp:err_service_unavailable(Txt, Lang)}; ?NS_DISCO_ITEMS -> process_iq_disco_items(From, IQ, StateData); ?NS_VCARD -> @@ -291,7 +284,9 @@ normal_state({route, From, <<"">>, ?NS_CAPTCHA -> process_iq_captcha(From, IQ, StateData); _ -> - {error, xmpp:err_feature_not_implemented()} + Txt = <<"The feature requested is not " + "supported by the conference">>, + {error, xmpp:err_service_unavailable(Txt, Lang)} end, {IQRes, NewStateData} = case Res1 of @@ -312,8 +307,12 @@ normal_state({route, From, <<"">>, ok end, case NewStateData of - stop -> {stop, normal, StateData}; - _ -> {next_state, normal_state, NewStateData} + stop -> + {stop, normal, StateData}; + _ when NewStateData#state.just_created -> + close_room_if_temporary_and_empty(NewStateData); + _ -> + {next_state, normal_state, NewStateData} end end catch _:{xmpp_codec, Why} -> @@ -324,7 +323,10 @@ normal_state({route, From, <<"">>, normal_state({route, From, <<"">>, #iq{} = IQ}, StateData) -> Err = xmpp:err_bad_request(), ejabberd_router:route_error(StateData#state.jid, From, IQ, Err), - {next_state, normal_state, StateData}; + case StateData#state.just_created of + true -> {stop, normal, StateData}; + false -> {next_state, normal_state, StateData} + end; normal_state({route, From, Nick, #presence{} = Packet}, StateData) -> Activity = get_user_activity(From, StateData), Now = p1_time_compat:system_time(micro_seconds), @@ -530,8 +532,14 @@ handle_sync_event({change_state, NewStateData}, _From, StateName, _StateData) -> {reply, {ok, NewStateData}, StateName, NewStateData}; handle_sync_event({process_item_change, Item, UJID}, _From, StateName, StateData) -> - NSD = process_item_change(Item, StateData, UJID), - {reply, {ok, NSD}, StateName, NSD}; + case process_item_change(Item, StateData, UJID) of + {error, _} = Err -> + {reply, Err, StateName, StateData}; + NSD -> + {reply, {ok, NSD}, StateName, NSD} + end; +handle_sync_event({is_subscriber, From}, _From, StateName, StateData) -> + {reply, is_subscriber(From, StateData), StateName, StateData}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. @@ -763,7 +771,7 @@ process_normal_message(From, #message{lang = Lang} = Pkt, StateData) -> (#muc_user{invites = [I]}, _) -> {ok, I}; (#muc_user{invites = [_|_]}, _) -> - Txt = <<"Multiple elements are not allowed">>, + Txt = <<"Multiple invitations are not allowed">>, {error, xmpp:err_resource_constraint(Txt, Lang)}; (#xdata{type = submit, fields = Fs}, _) -> try {ok, muc_request:decode(Fs)} @@ -835,7 +843,7 @@ process_voice_request(From, Pkt, StateData) -> {ok, _, _} -> ErrText = <<"Please, wait for a while before sending " "new voice request">>, - Err = xmpp:err_not_acceptable(ErrText, Lang), + Err = xmpp:err_resource_constraint(ErrText, Lang), ejabberd_router:route_error( StateData#state.jid, From, Pkt, Err), StateData#state{last_voice_request_time = Times} @@ -1147,10 +1155,9 @@ decide_fate_message(#message{type = error} = Msg, PD = case check_error_kick(Err) of %% If this is an error stanza and its condition matches a criteria true -> - Reason = - io_lib:format("This participant is considered a ghost " - "and is expulsed: ~s", - [jid:to_string(From)]), + Reason = str:format("This participant is considered a ghost " + "and is expulsed: ~s", + [jid:to_string(From)]), {expulse_sender, Reason}; false -> continue_delivery end, @@ -1198,7 +1205,7 @@ get_error_condition(undefined) -> make_reason(Packet, From, StateData, Reason1) -> {ok, #user{nick = FromNick}} = (?DICT):find(jid:tolower(From), StateData#state.users), Condition = get_error_condition(xmpp:get_error(Packet)), - iolist_to_binary(io_lib:format(Reason1, [FromNick, Condition])). + str:format(Reason1, [FromNick, Condition]). -spec expulse_participant(stanza(), jid(), state(), binary()) -> state(). @@ -1816,11 +1823,9 @@ add_new_user(From, Nick, Packet, StateData) -> Nodes, StateData)), send_existing_presences(From, NewState), send_initial_presence(From, NewState, StateData), - Shift = count_stanza_shift(Nick, Packet, NewState), - case send_history(From, Shift, NewState) of - true -> ok; - _ -> send_subject(From, StateData) - end, + History = get_history(Nick, Packet, NewState), + send_history(From, History, NewState), + send_subject(From, StateData), NewState; true -> add_online_user(From, Nick, none, @@ -1963,84 +1968,43 @@ extract_password(Packet) -> false end. --spec count_stanza_shift(binary(), stanza(), state()) -> non_neg_integer(). -count_stanza_shift(Nick, Packet, StateData) -> - case xmpp:get_subtag(Packet, #muc_history{}) of - #muc_history{since = Since, - seconds = Seconds, - maxstanzas = MaxStanzas, - maxchars = MaxChars} -> - HL = lqueue_to_list(StateData#state.history), - Shift0 = case Since of - undefined -> 0; - _ -> - Sin = calendar:datetime_to_gregorian_seconds( - calendar:now_to_datetime(Since)), - count_seconds_shift(Sin, HL) - end, - Shift1 = case Seconds of - undefined -> 0; - _ -> - Sec = calendar:datetime_to_gregorian_seconds( - calendar:universal_time()) - Seconds, - count_seconds_shift(Sec, HL) - end, - Shift2 = case MaxStanzas of - undefined -> 0; - _ -> count_maxstanzas_shift(MaxStanzas, HL) - end, - Shift3 = case MaxChars of - undefined -> 0; - _ -> count_maxchars_shift(Nick, MaxChars, HL) - end, - lists:max([Shift0, Shift1, Shift2, Shift3]); - false -> - 0 - end. - --spec count_seconds_shift(non_neg_integer(), - [history_element()]) -> non_neg_integer(). -count_seconds_shift(Seconds, HistoryList) -> - lists:sum(lists:map(fun ({_Nick, _Packet, _HaveSubject, - TimeStamp, _Size}) -> - T = - calendar:datetime_to_gregorian_seconds(TimeStamp), - if T < Seconds -> 1; - true -> 0 - end - end, - HistoryList)). - --spec count_maxstanzas_shift(non_neg_integer(), - [history_element()]) -> non_neg_integer(). -count_maxstanzas_shift(MaxStanzas, HistoryList) -> - S = length(HistoryList) - MaxStanzas, - if S =< 0 -> 0; - true -> S - end. - --spec count_maxchars_shift(binary(), non_neg_integer(), - [history_element()]) -> integer(). -count_maxchars_shift(Nick, MaxSize, HistoryList) -> - NLen = byte_size(Nick) + 1, - Sizes = lists:map(fun ({_Nick, _Packet, _HaveSubject, - _TimeStamp, Size}) -> - Size + NLen - end, - HistoryList), - calc_shift(MaxSize, Sizes). - --spec calc_shift(non_neg_integer(), [non_neg_integer()]) -> integer(). -calc_shift(MaxSize, Sizes) -> - Total = lists:sum(Sizes), - calc_shift(MaxSize, Total, 0, Sizes). - --spec calc_shift(non_neg_integer(), integer(), integer(), - [non_neg_integer()]) -> integer(). -calc_shift(_MaxSize, _Size, Shift, []) -> Shift; -calc_shift(MaxSize, Size, Shift, [S | TSizes]) -> - if MaxSize >= Size -> Shift; - true -> calc_shift(MaxSize, Size - S, Shift + 1, TSizes) +-spec get_history(binary(), stanza(), state()) -> lqueue(). +get_history(Nick, Packet, #state{history = History}) -> + case xmpp:get_subtag(Packet, #muc{}) of + #muc{history = #muc_history{} = MUCHistory} -> + Now = p1_time_compat:timestamp(), + Q = History#lqueue.queue, + {NewQ, Len} = filter_history(Q, MUCHistory, Now, Nick, queue:new(), 0, 0), + History#lqueue{queue = NewQ, len = Len}; + _ -> + History + end. + +-spec filter_history(?TQUEUE, muc_history(), erlang:timestamp(), binary(), + ?TQUEUE, non_neg_integer(), non_neg_integer()) -> + {?TQUEUE, non_neg_integer()}. +filter_history(Queue, #muc_history{since = Since, + seconds = Seconds, + maxstanzas = MaxStanzas, + maxchars = MaxChars} = MUC, + Now, Nick, AccQueue, NumStanzas, NumChars) -> + case queue:out_r(Queue) of + {{value, {_, _, _, TimeStamp, Size} = Elem}, NewQueue} -> + NowDiff = timer:now_diff(Now, TimeStamp) div 1000000, + Chars = Size + byte_size(Nick) + 1, + if (NumStanzas < MaxStanzas) andalso + (TimeStamp > Since) andalso + (NowDiff =< Seconds) andalso + (NumChars + Chars =< MaxChars) -> + filter_history(NewQueue, MUC, Now, Nick, + queue:in_r(Elem, AccQueue), + NumStanzas + 1, + NumChars + Chars); + true -> + {AccQueue, NumStanzas} + end; + {empty, _} -> + {AccQueue, NumStanzas} end. -spec is_room_overcrowded(state()) -> boolean(). @@ -2166,19 +2130,20 @@ send_new_presence1(NJID, Reason, IsInitialPresence, StateData, OldStateData) -> end, lists:foreach( fun({LUJID, Info}) -> - {Role, Presence} = if LNJID == LUJID -> {Role0, Presence0}; + IsSelfPresence = LNJID == LUJID, + {Role, Presence} = if IsSelfPresence -> {Role0, Presence0}; true -> {Role1, Presence1} end, Item0 = #muc_item{affiliation = Affiliation, role = Role}, Item1 = case Info#user.role == moderator orelse (StateData#state.config)#config.anonymous - == false of + == false orelse IsSelfPresence of true -> Item0#muc_item{jid = RealJID}; false -> Item0 end, Item = Item1#muc_item{reason = Reason}, - StatusCodes = status_codes(IsInitialPresence, NJID, Info, + StatusCodes = status_codes(IsInitialPresence, IsSelfPresence, StateData), Pres = if Presence == undefined -> #presence{}; true -> Presence @@ -2303,30 +2268,26 @@ send_nick_changing(JID, OldNick, StateData, StateData#state.users), Affiliation = get_affiliation(JID, StateData), lists:foreach( - fun({_LJID, Info}) when Presence /= undefined -> + fun({LJID, Info}) when Presence /= undefined -> + IsSelfPresence = LJID == jid:tolower(JID), Item0 = #muc_item{affiliation = Affiliation, role = Role}, - Item1 = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false of - true -> Item0#muc_item{jid = RealJID, nick = Nick}; - false -> Item0#muc_item{nick = Nick} - end, - Item2 = case Info#user.role == moderator orelse - (StateData#state.config)#config.anonymous - == false of - true -> Item0#muc_item{jid = RealJID}; - false -> Item0 - end, - Status110 = case JID == Info#user.jid of + Item = case Info#user.role == moderator orelse + (StateData#state.config)#config.anonymous + == false orelse IsSelfPresence of + true -> Item0#muc_item{jid = RealJID}; + false -> Item0 + end, + Status110 = case IsSelfPresence of true -> [110]; false -> [] end, - Packet1 = #presence{type = unavailable, - sub_els = [#muc_user{ - items = [Item1], - status_codes = [303|Status110]}]}, + Packet1 = #presence{ + type = unavailable, + sub_els = [#muc_user{ + items = [Item#muc_item{nick = Nick}], + status_codes = [303|Status110]}]}, Packet2 = xmpp:set_subtag(Presence, - #muc_user{items = [Item2], + #muc_user{items = [Item], status_codes = Status110}), if SendOldUnavailable -> send_wrapped( @@ -2364,12 +2325,12 @@ maybe_send_affiliation(JID, Affiliation, StateData) -> true -> ok; % The new affiliation is published via presence. false -> - send_affiliation(LJID, Affiliation, StateData) + send_affiliation(JID, Affiliation, StateData) end. --spec send_affiliation(ljid(), affiliation(), state()) -> ok. -send_affiliation(LJID, Affiliation, StateData) -> - Item = #muc_item{jid = jid:make(LJID), +-spec send_affiliation(jid(), affiliation(), state()) -> ok. +send_affiliation(JID, Affiliation, StateData) -> + Item = #muc_item{jid = JID, affiliation = Affiliation, role = none}, Message = #message{id = randoms:get_string(), @@ -2388,8 +2349,8 @@ send_affiliation(LJID, Affiliation, StateData) -> StateData#state.server_host, Recipients, Message). --spec status_codes(boolean(), jid(), #user{}, state()) -> [pos_integer()]. -status_codes(IsInitialPresence, JID, #user{jid = JID}, StateData) -> +-spec status_codes(boolean(), boolean(), state()) -> [pos_integer()]. +status_codes(IsInitialPresence, _IsSelfPresence = true, StateData) -> S0 = [110], case IsInitialPresence of true -> @@ -2408,7 +2369,7 @@ status_codes(IsInitialPresence, JID, #user{jid = JID}, StateData) -> S3; false -> S0 end; -status_codes(_IsInitialPresence, _JID, _Info, _StateData) -> []. +status_codes(_IsInitialPresence, _IsSelfPresence = false, _StateData) -> []. -spec lqueue_new(non_neg_integer()) -> lqueue(). lqueue_new(Max) -> @@ -2438,54 +2399,58 @@ lqueue_to_list(#lqueue{queue = Q1}) -> -spec add_message_to_history(binary(), jid(), message(), state()) -> state(). add_message_to_history(FromNick, FromJID, Packet, StateData) -> - HaveSubject = Packet#message.subject /= [], - TimeStamp = p1_time_compat:timestamp(), - AddrPacket = case (StateData#state.config)#config.anonymous of - true -> Packet; - false -> - Addresses = #addresses{ - list = [#address{type = ofrom, - jid = FromJID}]}, - xmpp:set_subtag(Packet, Addresses) - end, - TSPacket = xmpp_util:add_delay_info( - AddrPacket, StateData#state.jid, TimeStamp), - SPacket = xmpp:set_from_to( - TSPacket, - jid:replace_resource(StateData#state.jid, FromNick), - StateData#state.jid), - Size = element_size(SPacket), - Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, - calendar:now_to_universal_time(TimeStamp), Size}, - StateData#state.history), add_to_log(text, {FromNick, Packet}, StateData), - StateData#state{history = Q1}. - --spec send_history(jid(), integer(), state()) -> boolean(). -send_history(JID, Shift, StateData) -> - lists:foldl(fun ({Nick, Packet, HaveSubject, _TimeStamp, - _Size}, - B) -> - ejabberd_router:route(jid:replace_resource(StateData#state.jid, - Nick), - JID, Packet), - B or HaveSubject - end, - false, - lists:nthtail(Shift, - lqueue_to_list(StateData#state.history))). + case check_subject(Packet) of + false -> + TimeStamp = p1_time_compat:timestamp(), + AddrPacket = case (StateData#state.config)#config.anonymous of + true -> Packet; + false -> + Addresses = #addresses{ + list = [#address{type = ofrom, + jid = FromJID}]}, + xmpp:set_subtag(Packet, Addresses) + end, + TSPacket = xmpp_util:add_delay_info( + AddrPacket, StateData#state.jid, TimeStamp), + SPacket = xmpp:set_from_to( + TSPacket, + jid:replace_resource(StateData#state.jid, FromNick), + StateData#state.jid), + Size = element_size(SPacket), + Q1 = lqueue_in({FromNick, TSPacket, false, + TimeStamp, Size}, + StateData#state.history), + StateData#state{history = Q1}; + _ -> + StateData + end. + +-spec send_history(jid(), lqueue(), state()) -> boolean(). +send_history(JID, History, StateData) -> + lists:foreach( + fun({Nick, Packet, _HaveSubject, _TimeStamp, _Size}) -> + ejabberd_router:route( + jid:replace_resource(StateData#state.jid, Nick), + JID, Packet) + end, lqueue_to_list(History)). -spec send_subject(jid(), state()) -> ok. -send_subject(_JID, #state{subject_author = <<"">>}) -> ok; send_subject(JID, #state{subject_author = Nick} = StateData) -> - Subject = StateData#state.subject, - Packet = #message{type = groupchat, subject = xmpp:mk_text(Subject)}, + Subject = case StateData#state.subject of + <<"">> -> [#text{}]; + Subj -> xmpp:mk_text(Subj) + end, + Packet = #message{type = groupchat, subject = Subject}, ejabberd_router:route(jid:replace_resource(StateData#state.jid, Nick), JID, Packet). -spec check_subject(message()) -> false | binary(). -check_subject(#message{subject = []}) -> false; -check_subject(#message{subject = Subj}) -> xmpp:get_text(Subj). +check_subject(#message{subject = [_|_] = Subj, body = [], + thread = undefined}) -> + xmpp:get_text(Subj); +check_subject(_) -> + false. -spec can_change_subject(role(), state()) -> boolean(). can_change_subject(Role, StateData) -> @@ -2552,10 +2517,10 @@ items_with_role(SRole, StateData) -> items_with_affiliation(SAffiliation, StateData) -> lists:map( fun({JID, {Affiliation, Reason}}) -> - #muc_item{affiliation = Affiliation, jid = JID, + #muc_item{affiliation = Affiliation, jid = jid:make(JID), reason = Reason}; ({JID, Affiliation}) -> - #muc_item{affiliation = Affiliation, jid = JID} + #muc_item{affiliation = Affiliation, jid = jid:make(JID)} end, search_affiliation(SAffiliation, StateData)). @@ -2600,23 +2565,29 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> "room ~s:~n ~p", [jid:to_string(UJID), jid:to_string(StateData#state.jid), Res]), - NSD = lists:foldl(process_item_change(UJID), - StateData, lists:flatten(Res)), - store_room(NSD), - {result, undefined, NSD}; - {error, Err} -> {error, Err} + case lists:foldl(process_item_change(UJID), + StateData, lists:flatten(Res)) of + {error, _} = Err -> + Err; + NSD -> + store_room(NSD), + {result, undefined, NSD} + end; + {error, Err} -> {error, Err} end. -spec process_item_change(jid()) -> function(). process_item_change(UJID) -> - fun(E, SD) -> - process_item_change(E, SD, UJID) + fun(_, {error, _} = Err) -> + Err; + (Item, SD) -> + process_item_change(Item, SD, UJID) end. -type admin_action() :: {jid(), affiliation | role, affiliation() | role(), binary()}. --spec process_item_change(admin_action(), state(), jid()) -> state(). +-spec process_item_change(admin_action(), state(), jid()) -> state() | {error, stanza_error()}. process_item_change(Item, SD, UJID) -> try case Item of {JID, affiliation, owner, _} when JID#jid.luser == <<"">> -> @@ -2624,23 +2595,23 @@ process_item_change(Item, SD, UJID) -> %% forget the affiliation completely SD; {JID, role, none, Reason} -> - catch send_kickban_presence(UJID, JID, Reason, 307, SD), + send_kickban_presence(UJID, JID, Reason, 307, SD), set_role(JID, none, SD); {JID, affiliation, none, Reason} -> case (SD#state.config)#config.members_only of true -> - catch send_kickban_presence(UJID, JID, Reason, 321, none, SD), + send_kickban_presence(UJID, JID, Reason, 321, none, SD), maybe_send_affiliation(JID, none, SD), SD1 = set_affiliation(JID, none, SD), set_role(JID, none, SD1); _ -> SD1 = set_affiliation(JID, none, SD), - send_update_presence(JID, SD1, SD), + send_update_presence(JID, Reason, SD1, SD), maybe_send_affiliation(JID, none, SD1), SD1 end; {JID, affiliation, outcast, Reason} -> - catch send_kickban_presence(UJID, JID, Reason, 301, outcast, SD), + send_kickban_presence(UJID, JID, Reason, 301, outcast, SD), maybe_send_affiliation(JID, outcast, SD), set_affiliation(JID, outcast, set_role(JID, none, SD), Reason); {JID, affiliation, A, Reason} when (A == admin) or (A == owner) -> @@ -2657,7 +2628,7 @@ process_item_change(Item, SD, UJID) -> SD2; {JID, role, Role, Reason} -> SD1 = set_role(JID, Role, SD), - catch send_new_presence(JID, Reason, SD1, SD), + send_new_presence(JID, Reason, SD1, SD), SD1; {JID, affiliation, A, _Reason} -> SD1 = set_affiliation(JID, A, SD), @@ -2669,7 +2640,7 @@ process_item_change(Item, SD, UJID) -> ?ERROR_MSG("failed to set item ~p from ~s: ~p", [Item, jid:to_string(UJID), {E, {R, erlang:get_stacktrace()}}]), - SD + {error, xmpp:err_internal_server_error()} end. -spec find_changed_items(jid(), affiliation(), role(), @@ -2698,12 +2669,11 @@ find_changed_items(UJID, UAffiliation, URole, Nick /= <<"">> -> case find_jids_by_nick(Nick, StateData) of [] -> - ErrText = iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"Nickname ~s does not exist in the room">>), - [Nick])), + ErrText = str:format( + translate:translate( + Lang, + <<"Nickname ~s does not exist in the room">>), + [Nick]), throw({error, xmpp:err_not_acceptable(ErrText, Lang)}); JIDList -> JIDList @@ -2740,9 +2710,15 @@ find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, Res); true -> - MoreRes = [{jid:remove_resource(Jidx), - RoleOrAff, RoleOrAffValue, Reason} - || Jidx <- JIDs], + MoreRes = case RoleOrAff of + affiliation -> + [{jid:remove_resource(Jidx), + RoleOrAff, RoleOrAffValue, Reason} + || Jidx <- JIDs]; + role -> + [{Jidx, RoleOrAff, RoleOrAffValue, Reason} + || Jidx <- JIDs] + end, find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, [MoreRes | Res]); @@ -2925,12 +2901,13 @@ send_kickban_presence1(MJID, UJID, Reason, Code, Affiliation, StateData#state.users), ActorNick = get_actor_nick(MJID, StateData), lists:foreach( - fun({_LJID, Info}) -> + fun({LJID, Info}) -> + IsSelfPresence = jid:tolower(UJID) == LJID, Item0 = #muc_item{affiliation = Affiliation, role = none}, Item1 = case Info#user.role == moderator orelse (StateData#state.config)#config.anonymous - == false of + == false orelse IsSelfPresence of true -> Item0#muc_item{jid = RealJID}; false -> Item0 end, @@ -2939,9 +2916,12 @@ send_kickban_presence1(MJID, UJID, Reason, Code, Affiliation, <<"">> -> Item2; _ -> Item2#muc_item{actor = #muc_actor{nick = ActorNick}} end, + Codes = if IsSelfPresence -> [110, Code]; + true -> [Code] + end, Packet = #presence{type = unavailable, sub_els = [#muc_user{items = [Item], - status_codes = [Code]}]}, + status_codes = Codes}]}, RoomJIDNick = jid:replace_resource(StateData#state.jid, Nick), send_wrapped(RoomJIDNick, Info#user.jid, Packet, ?NS_MUCSUB_NODES_AFFILIATIONS, StateData), @@ -2989,13 +2969,21 @@ process_iq_owner(From, #iq{type = set, lang = Lang, case Config of #xdata{type = cancel} -> {result, undefined}; - #xdata{type = submit} -> - case is_allowed_log_change(Config, StateData, From) andalso - is_allowed_persistent_change(Config, StateData, From) andalso - is_allowed_room_name_desc_limits(Config, StateData) andalso - is_password_settings_correct(Config, StateData) of - true -> set_config(Config, StateData, Lang); - false -> {error, xmpp:err_not_acceptable()} + #xdata{type = submit, fields = Fs} -> + try muc_roomconfig:decode(Fs) of + Options -> + case is_allowed_log_change(Options, StateData, From) andalso + is_allowed_persistent_change(Options, StateData, From) andalso + is_allowed_room_name_desc_limits(Options, StateData) andalso + is_password_settings_correct(Options, StateData) of + true -> + set_config(Options, StateData, Lang); + false -> + {error, xmpp:err_not_acceptable()} + end + catch _:{muc_roomconfig, Why} -> + Txt = muc_roomconfig:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)} end; _ -> Txt = <<"Incorrect data form">>, @@ -3034,9 +3022,9 @@ process_iq_owner(From, #iq{type = get, lang = Lang, {error, xmpp:err_bad_request()} end. --spec is_allowed_log_change(xdata(), state(), jid()) -> boolean(). -is_allowed_log_change(X, StateData, From) -> - case xmpp_util:has_xdata_var(<<"muc#roomconfig_enablelogging">>, X) of +-spec is_allowed_log_change(muc_roomconfig:result(), state(), jid()) -> boolean(). +is_allowed_log_change(Options, StateData, From) -> + case proplists:is_defined(enablelogging, Options) of false -> true; true -> allow == @@ -3044,9 +3032,9 @@ is_allowed_log_change(X, StateData, From) -> From) end. --spec is_allowed_persistent_change(xdata(), state(), jid()) -> boolean(). -is_allowed_persistent_change(X, StateData, From) -> - case xmpp_util:has_xdata_var(<<"muc#roomconfig_persistentroom">>, X) of +-spec is_allowed_persistent_change(muc_roomconfig:result(), state(), jid()) -> boolean(). +is_allowed_persistent_change(Options, StateData, From) -> + case proplists:is_defined(persistentroom, Options) of false -> true; true -> {_AccessRoute, _AccessCreate, _AccessAdmin, @@ -3059,66 +3047,43 @@ is_allowed_persistent_change(X, StateData, From) -> %% Check if the Room Name and Room Description defined in the Data Form %% are conformant to the configured limits --spec is_allowed_room_name_desc_limits(xdata(), state()) -> boolean(). -is_allowed_room_name_desc_limits(XData, StateData) -> - IsNameAccepted = case xmpp_util:get_xdata_values( - <<"muc#roomconfig_roomname">>, XData) of - [N] -> - byte_size(N) =< - gen_mod:get_module_opt( - StateData#state.server_host, - mod_muc, max_room_name, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> I - end, infinity); - _ -> - true - end, - IsDescAccepted = case xmpp_util:get_xdata_values( - <<"muc#roomconfig_roomdesc">>, XData) of - [D] -> - byte_size(D) =< - gen_mod:get_module_opt( - StateData#state.server_host, - mod_muc, max_room_desc, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> - I - end, infinity); - _ -> true - end, - IsNameAccepted and IsDescAccepted. +-spec is_allowed_room_name_desc_limits(muc_roomconfig:result(), state()) -> boolean(). +is_allowed_room_name_desc_limits(Options, StateData) -> + RoomName = proplists:get_value(roomname, Options, <<"">>), + RoomDesc = proplists:get_value(roomdesc, Options, <<"">>), + MaxRoomName = gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, max_room_name, + fun(infinity) -> infinity; + (I) when is_integer(I), + I>0 -> I + end, infinity), + MaxRoomDesc = gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, max_room_desc, + fun(infinity) -> infinity; + (I) when is_integer(I), + I>0 -> + I + end, infinity), + (byte_size(RoomName) =< MaxRoomName) + andalso (byte_size(RoomDesc) =< MaxRoomDesc). %% Return false if: %% "the password for a password-protected room is blank" --spec is_password_settings_correct(xdata(), state()) -> boolean(). -is_password_settings_correct(XData, StateData) -> +-spec is_password_settings_correct(muc_roomconfig:result(), state()) -> boolean(). +is_password_settings_correct(Options, StateData) -> Config = StateData#state.config, OldProtected = Config#config.password_protected, OldPassword = Config#config.password, - NewProtected = case xmpp_util:get_xdata_values( - <<"muc#roomconfig_passwordprotectedroom">>, XData) of - [<<"1">>] -> true; - [<<"true">>] -> true; - [<<"0">>] -> false; - [<<"false">>] -> false; - _ -> undefined - end, - NewPassword = case xmpp_util:get_xdata_values( - <<"muc#roomconfig_roomsecret">>, XData) of - [P] -> P; - _ -> undefined - end, - case {OldProtected, NewProtected, OldPassword, - NewPassword} - of - {true, undefined, <<"">>, undefined} -> false; - {true, undefined, _, <<"">>} -> false; - {_, true, <<"">>, undefined} -> false; - {_, true, _, <<"">>} -> false; - _ -> true + NewProtected = proplists:get_value(passwordprotectedroom, Options), + NewPassword = proplists:get_value(roomsecret, Options), + case {OldProtected, NewProtected, OldPassword, NewPassword} of + {true, undefined, <<"">>, undefined} -> false; + {true, undefined, _, <<"">>} -> false; + {_, true, <<"">>, undefined} -> false; + {_, true, _, <<"">>} -> false; + _ -> true end. -spec get_default_room_maxusers(state()) -> non_neg_integer(). @@ -3144,10 +3109,9 @@ get_config(Lang, StateData, From) -> {N, N}; _ -> {0, none} end, - Title = iolist_to_binary( - io_lib:format( - translate:translate(Lang, <<"Configuration of room ~s">>), - [jid:to_string(StateData#state.jid)])), + Title = str:format( + translate:translate(Lang, <<"Configuration of room ~s">>), + [jid:to_string(StateData#state.jid)]), Fs = [{roomname, Config#config.title}, {roomdesc, Config#config.description}] ++ case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of @@ -3208,11 +3172,10 @@ get_config(Lang, StateData, From) -> fields = muc_roomconfig:encode( Fields, fun(T) -> translate:translate(Lang, T) end)}. --spec set_config(xdata(), state(), binary()) -> {error, stanza_error()} | - {result, undefined, state()}. -set_config(#xdata{fields = Fields}, StateData, Lang) -> +-spec set_config(muc_roomconfig:result(), state(), binary()) -> + {error, stanza_error()} | {result, undefined, state()}. +set_config(Options, StateData, Lang) -> try - Options = muc_roomconfig:decode(Fields), #config{} = Config = set_config(Options, StateData#state.config, StateData#state.server_host, Lang), {result, _, NSD} = Res = change_config(Config, StateData), @@ -3227,10 +3190,7 @@ set_config(#xdata{fields = Fields}, StateData, Lang) -> || {_, U} <- (?DICT):to_list(StateData#state.users)], add_to_log(Type, Users, NSD), Res - catch _:{muc_roomconfig, Why} -> - Txt = muc_roomconfig:format_error(Why), - {error, xmpp:err_bad_request(Txt, Lang)}; - _:{badmatch, {error, #stanza_error{}} = Err} -> + catch _:{badmatch, {error, #stanza_error{}} = Err} -> Err end. @@ -3331,18 +3291,23 @@ send_config_change_info(New, #state{config = Old} = StateData) -> end ++ case Old#config{anonymous = New#config.anonymous, + vcard = New#config.vcard, logging = New#config.logging} of New -> []; _ -> [104] end, - Message = #message{type = groupchat, - id = randoms:get_string(), - sub_els = [#muc_user{status_codes = Codes}]}, - send_wrapped_multiple(StateData#state.jid, - StateData#state.users, - Message, - ?NS_MUCSUB_NODES_CONFIG, - StateData). + if Codes /= [] -> + Message = #message{type = groupchat, + id = randoms:get_string(), + sub_els = [#muc_user{status_codes = Codes}]}, + send_wrapped_multiple(StateData#state.jid, + StateData#state.users, + Message, + ?NS_MUCSUB_NODES_CONFIG, + StateData); + true -> + ok + end. -spec remove_nonmembers(state()) -> state(). remove_nonmembers(StateData) -> @@ -3620,7 +3585,7 @@ iq_disco_info_extras(Lang, StateData) -> process_iq_disco_items(_From, #iq{type = set, lang = Lang}, _StateData) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, {error, xmpp:err_not_allowed(Txt, Lang)}; -process_iq_disco_items(From, #iq{type = get, lang = Lang}, StateData) -> +process_iq_disco_items(From, #iq{type = get}, StateData) -> case (StateData#state.config)#config.public_list of true -> {result, get_mucroom_disco_items(StateData)}; @@ -3629,8 +3594,10 @@ process_iq_disco_items(From, #iq{type = get, lang = Lang}, StateData) -> true -> {result, get_mucroom_disco_items(StateData)}; _ -> - Txt = <<"Only occupants or administrators can perform this query">>, - {error, xmpp:err_forbidden(Txt, Lang)} + %% If the list of occupants is private, + %% the room MUST return an empty element + %% (http://xmpp.org/extensions/xep-0045.html#disco-roomitems) + {result, #disco_items{}} end end. @@ -3661,7 +3628,7 @@ process_iq_vcard(_From, #iq{type = get}, StateData) -> #xmlel{} = VCard -> {result, VCard}; {error, _} -> - {result, #vcard_temp{}} + {error, xmpp:err_item_not_found()} end; process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [SubEl]}, StateData) -> @@ -3801,8 +3768,7 @@ get_roomdesc_tail(StateData, Lang) -> _ -> translate:translate(Lang, <<"private, ">>) end, Len = (?DICT):size(StateData#state.users), - <<" (", Desc/binary, - (iolist_to_binary(integer_to_list(Len)))/binary, ")">>. + <<" (", Desc/binary, (integer_to_binary(Len))/binary, ")">>. -spec get_mucroom_disco_items(state()) -> disco_items(). get_mucroom_disco_items(StateData) -> diff --git a/src/str.erl b/src/str.erl index 27d21075a..439ae6a7a 100644 --- a/src/str.erl +++ b/src/str.erl @@ -64,6 +64,7 @@ to_float/1, prefix/2, suffix/2, + format/2, to_integer/1]). %%%=================================================================== @@ -277,6 +278,11 @@ prefix(Prefix, B) -> suffix(B1, B2) -> lists:suffix(binary_to_list(B1), binary_to_list(B2)). +-spec format(io:format(), list()) -> binary(). + +format(Format, Args) -> + iolist_to_binary(io_lib:format(Format, Args)). + %%%=================================================================== %%% Internal functions %%%=================================================================== -- cgit v1.2.3 From f6236d456d599544baed11d51c3e6d7ef7e459eb Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 22 Oct 2016 13:01:45 +0300 Subject: Add more tests for privacy lists and blocking command --- src/ejabberd_c2s.erl | 174 ++++++++++++++++++++++------------------------- src/ejabberd_piefxis.erl | 2 +- src/ejabberd_socket.erl | 9 ++- src/mod_admin_extra.erl | 6 +- src/mod_blocking.erl | 13 ++-- src/mod_privacy.erl | 67 ++++++++++-------- src/mod_roster.erl | 9 ++- 7 files changed, 144 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index f7d8e9dbb..986310546 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -881,18 +881,20 @@ decode_element(#xmlel{} = El, StateName, StateData) -> end catch error:{xmpp_codec, Why} -> NS = xmpp:get_ns(El), - case xmpp:is_stanza(El) of - true -> - Lang = xmpp:get_lang(El), - Txt = xmpp:format_error(Why), - send_error(StateData, El, xmpp:err_bad_request(Txt, Lang)); - false when NS == ?NS_STREAM_MGMT_2; NS == ?NS_STREAM_MGMT_3 -> - Err = #sm_failed{reason = 'bad-request', xmlns = NS}, - send_element(StateData, Err); - false -> - ok - end, - fsm_next_state(StateName, StateData) + fsm_next_state( + StateName, + case xmpp:is_stanza(El) of + true -> + Lang = xmpp:get_lang(El), + Txt = xmpp:format_error(Why), + send_error(StateData, El, xmpp:err_bad_request(Txt, Lang)); + false when NS == ?NS_STREAM_MGMT_2; NS == ?NS_STREAM_MGMT_3 -> + Err = #sm_failed{reason = 'bad-request', xmlns = NS}, + send_element(StateData, Err), + StateData; + false -> + StateData + end) end. wait_for_bind({xmlstreamelement, El}, StateData) -> @@ -957,13 +959,14 @@ wait_for_bind(closed, StateData) -> wait_for_bind(stop, StateData) -> {stop, normal, StateData}; wait_for_bind(Pkt, StateData) -> - case xmpp:is_stanza(Pkt) of - true -> - send_error(StateData, Pkt, xmpp:err_not_acceptable()); - false -> - ok - end, - fsm_next_state(wait_for_bind, StateData). + fsm_next_state( + wait_for_bind, + case xmpp:is_stanza(Pkt) of + true -> + send_error(StateData, Pkt, xmpp:err_not_acceptable()); + false -> + StateData + end). -spec open_session(state()) -> {ok, state()} | {error, stanza_error()}. open_session(StateData) -> @@ -1315,27 +1318,23 @@ handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Pac allow -> {true, StateData}; deny -> - Err = xmpp:make_error( - Packet, - xmpp:err_service_unavailable()), - ejabberd_router:route(To, From, Err), + ejabberd_router:route_error( + To, From, Packet, + xmpp:err_service_unavailable()), {false, StateData} end; _ -> - Err = xmpp:make_error(Packet, xmpp:err_forbidden()), - ejabberd_router:route(To, From, Err), + ejabberd_router:route_error( + To, From, Packet, xmpp:err_forbidden()), {false, StateData} end; _ -> case privacy_check_packet(StateData, From, To, Packet, in) of allow -> {true, StateData}; - deny when T == get; T == set -> - Err = xmpp:make_error( - Packet, xmpp:err_service_unavailable()), - ejabberd_router:route(To, From, Err), - {false, StateData}; deny -> + ejabberd_router:route_error( + To, From, Packet, xmpp:err_service_unavailable()), {false, StateData} end end; @@ -1345,13 +1344,11 @@ handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Pac {true, StateData}; deny -> case T of - error -> ok; groupchat -> ok; headline -> ok; _ -> - Err = xmpp:make_error( - Packet, xmpp:err_service_unavailable()), - ejabberd_router:route(To, From, Err) + ejabberd_router:route_error( + To, From, Packet, xmpp:err_service_unavailable()) end, {false, StateData} end @@ -1572,14 +1569,14 @@ send_element(StateData, #xmlel{} = El) -> send_element(StateData, Pkt) -> send_element(StateData, xmpp:encode(Pkt, ?NS_CLIENT)). --spec send_error(state(), xmlel() | stanza(), stanza_error()) -> ok. +-spec send_error(state(), xmlel() | stanza(), stanza_error()) -> state(). send_error(StateData, Stanza, Error) -> Type = xmpp:get_type(Stanza), if Type == error; Type == result; Type == <<"error">>; Type == <<"result">> -> - ok; + StateData; true -> - send_element(StateData, xmpp:make_error(Stanza, Error)) + send_stanza(StateData, xmpp:make_error(Stanza, Error)) end. -spec send_stanza(state(), xmpp_element()) -> state(). @@ -1754,47 +1751,56 @@ presence_track(From, To, Packet, StateData) -> LTo = jid:tolower(To), User = StateData#state.user, Server = StateData#state.server, - case Type of - unavailable -> - A = ?SETS:del_element(LTo, StateData#state.pres_a), - check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet); - subscribe -> - try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData); - subscribed -> - ejabberd_hooks:run(roster_out_subscription, Server, - [User, Server, To, subscribed]), - check_privacy_route(From, StateData, - jid:remove_resource(From), To, Packet); - unsubscribe -> - try_roster_subscribe(unsubscribe, User, Server, From, To, Packet, StateData); - unsubscribed -> - ejabberd_hooks:run(roster_out_subscription, Server, - [User, Server, To, unsubscribed]), - check_privacy_route(From, StateData, - jid:remove_resource(From), To, Packet); - error -> - check_privacy_route(From, StateData, From, To, Packet); - probe -> - check_privacy_route(From, StateData, From, To, Packet); - _ -> - A = (?SETS):add_element(LTo, StateData#state.pres_a), - check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet) + Lang = StateData#state.lang, + case privacy_check_packet(StateData, From, To, Packet, out) of + deny -> + ErrText = <<"Your active privacy list has denied " + "the routing of this stanza.">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + send_error(StateData, xmpp:set_from_to(Packet, From, To), Err); + allow when Type == subscribe; Type == subscribed; + Type == unsubscribe; Type == unsubscribed -> + Access = gen_mod:get_module_opt(Server, mod_roster, access, + fun(A) when is_atom(A) -> A end, + all), + MyBareJID = jid:make(User, Server, <<"">>), + case acl:match_rule(Server, Access, MyBareJID) of + deny -> + ErrText = <<"Denied by ACL">>, + Err = xmpp:err_forbidden(ErrText, Lang), + send_error(StateData, xmpp:set_from_to(Packet, From, To), Err); + allow -> + ejabberd_hooks:run(roster_out_subscription, + Server, + [User, Server, To, Type]), + ejabberd_router:route(jid:remove_resource(From), To, Packet), + StateData + end; + allow when Type == error; Type == probe -> + ejabberd_router:route(From, To, Packet), + StateData; + allow -> + ejabberd_router:route(From, To, Packet), + A = case Type of + available -> + ?SETS:add_element(LTo, StateData#state.pres_a); + unavailable -> + ?SETS:del_element(LTo, StateData#state.pres_a) + end, + StateData#state{pres_a = A} end. -spec check_privacy_route(jid(), state(), jid(), jid(), stanza()) -> state(). check_privacy_route(From, StateData, FromRoute, To, Packet) -> case privacy_check_packet(StateData, From, To, Packet, - out) - of + out) of deny -> Lang = StateData#state.lang, ErrText = <<"Your active privacy list has denied " - "the routing of this stanza.">>, - Err = xmpp:make_error( - xmpp:set_from_to(Packet, From, To), - xmpp:err_not_acceptable(ErrText, Lang)), - send_stanza(StateData, Err); + "the routing of this stanza.">>, + Err = xmpp:err_not_acceptable(ErrText, Lang), + send_error(StateData, xmpp:set_from_to(Packet, From, To), Err); allow -> ejabberd_router:route(FromRoute, To, Packet), StateData @@ -1815,24 +1821,6 @@ is_privacy_allow(StateData, From, To, Packet, Dir) -> allow == privacy_check_packet(StateData, From, To, Packet, Dir). -%%% Check ACL before allowing to send a subscription stanza --spec try_roster_subscribe(subscribe | unsubscribe, binary(), binary(), - jid(), jid(), presence(), state()) -> state(). -try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) -> - JID1 = jid:make(User, Server, <<"">>), - Access = gen_mod:get_module_opt(Server, mod_roster, access, fun(A) when is_atom(A) -> A end, all), - case acl:match_rule(Server, Access, JID1) of - deny -> - %% Silently drop this (un)subscription request - StateData; - allow -> - ejabberd_hooks:run(roster_out_subscription, - Server, - [User, Server, To, Type]), - check_privacy_route(From, StateData, jid:remove_resource(From), - To, Packet) - end. - %% Send presence when disconnecting -spec presence_broadcast(state(), jid(), ?SETS:set(), presence()) -> ok. presence_broadcast(StateData, From, JIDSet, Packet) -> @@ -1980,7 +1968,7 @@ process_privacy_iq(#iq{from = From, to = To, privacy_iq_set, StateData#state.server, {error, xmpp:err_feature_not_implemented(Txt, Lang)}, - [IQ]) + [IQ, StateData#state.privacy_list]) of {result, R, NewPrivList} -> {{result, R}, @@ -2522,9 +2510,8 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) false -> fun(From, To, El, _Time) -> Txt = <<"User session terminated">>, - Err = xmpp:make_error( - El, xmpp:err_service_unavailable(Txt, Lang)), - ejabberd_router:route(To, From, Err) + ejabberd_router:route_error( + To, From, El, xmpp:err_service_unavailable(Txt, Lang)) end end, F = fun(From, _To, #presence{}, _Time) -> @@ -2532,9 +2519,8 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) [jid:to_string(From)]); (From, To, #iq{} = El, _Time) -> Txt = <<"User session terminated">>, - Err = xmpp:make_error( - El, xmpp:err_service_unavailable(Txt, Lang)), - ejabberd_router:route(To, From, Err); + ejabberd_router:route_error( + To, From, El, xmpp:err_service_unavailable(Txt, Lang)); (From, To, El, Time) -> %% We'll drop the stanza if it was by some %% encapsulating protocol as per XEP-0297. One such protocol is diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index 5e6e1bf58..0e79c9913 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -486,7 +486,7 @@ process_privacy(#privacy_query{lists = Lists, from = JID, to = JID, sub_els = [PrivacyQuery]}, Txt = <<"No module is handling this query">>, Error = {error, xmpp:err_feature_not_implemented(Txt, ?MYLANG)}, - case mod_privacy:process_iq_set(Error, IQ) of + case mod_privacy:process_iq_set(Error, IQ, #userlist{}) of {error, #stanza_error{reason = Reason}} = Err -> if Reason == 'item-not-found', Lists == [], Active == undefined, Default /= undefined -> diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index f8dc84630..b5fa52ded 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -31,6 +31,7 @@ -export([start/4, connect/3, connect/4, + connect/5, starttls/2, starttls/3, compress/1, @@ -125,19 +126,21 @@ start(Module, SockMod, Socket, Opts) -> end. connect(Addr, Port, Opts) -> - connect(Addr, Port, Opts, infinity). + connect(Addr, Port, Opts, infinity, self()). connect(Addr, Port, Opts, Timeout) -> + connect(Addr, Port, Opts, Timeout, self()). + +connect(Addr, Port, Opts, Timeout, Owner) -> case gen_tcp:connect(Addr, Port, Opts, Timeout) of {ok, Socket} -> Receiver = ejabberd_receiver:start(Socket, gen_tcp, none), SocketData = #socket_state{sockmod = gen_tcp, socket = Socket, receiver = Receiver}, - Pid = self(), case gen_tcp:controlling_process(Socket, Receiver) of ok -> - ejabberd_receiver:become_controller(Receiver, Pid), + ejabberd_receiver:become_controller(Receiver, Owner), {ok, SocketData}; {error, _Reason} = Error -> gen_tcp:close(Socket), Error end; diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 627b5b58f..4598805c2 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -53,6 +53,7 @@ -include("ejabberd.hrl"). -include("ejabberd_commands.hrl"). -include("mod_roster.hrl"). +-include("mod_privacy.hrl"). -include("ejabberd_sm.hrl"). -include("xmpp.hrl"). @@ -1380,11 +1381,12 @@ privacy_set(Username, Host, QueryS) -> To = jid:make(Host), QueryEl = fxml_stream:parse_element(QueryS), SubEl = xmpp:decode(QueryEl), - IQ = #iq{type = set, id = <<"push">>, sub_els = [SubEl]}, + IQ = #iq{type = set, id = <<"push">>, sub_els = [SubEl], + from = From, to = To}, ejabberd_hooks:run_fold(privacy_iq_set, Host, {error, xmpp:err_feature_not_implemented()}, - [From, To, IQ]), + [IQ, #userlist{}]), ok. %%% diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index b3bbff96e..d2b187d26 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -30,7 +30,7 @@ -protocol({xep, 191, '1.2'}). -export([start/2, stop/1, process_iq/1, - process_iq_set/2, process_iq_get/3, mod_opt_type/1, depends/2]). + process_iq_set/3, process_iq_get/3, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -85,10 +85,11 @@ process_iq_get(Acc, _, _) -> Acc. -spec process_iq_set({error, stanza_error()} | {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, - iq()) -> {error, stanza_error()} | - {result, xmpp_element() | undefined} | - {result, xmpp_element() | undefined, userlist()}. -process_iq_set(Acc, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> + iq(), userlist()) -> + {error, stanza_error()} | + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}. +process_iq_set(Acc, #iq{from = From, lang = Lang, sub_els = [SubEl]}, _) -> #jid{luser = LUser, lserver = LServer} = From, case SubEl of #block{items = []} -> @@ -105,7 +106,7 @@ process_iq_set(Acc, #iq{from = From, lang = Lang, sub_els = [SubEl]}) -> _ -> Acc end; -process_iq_set(Acc, _) -> Acc. +process_iq_set(Acc, _, _) -> Acc. -spec list_to_blocklist_jids([listitem()], [ljid()]) -> [ljid()]. list_to_blocklist_jids([], JIDs) -> JIDs; diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 2f318deec..d4c8464f1 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -32,7 +32,7 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_iq/1, export/1, import/1, - process_iq_set/2, process_iq_get/3, get_user_list/3, + process_iq_set/3, process_iq_get/3, get_user_list/3, check_packet/6, remove_user/2, encode_list_item/1, is_list_needdb/1, updated_list/3, item_to_xml/1, get_user_lists/2, import/3, @@ -103,6 +103,12 @@ process_iq(IQ) -> -spec process_iq_get({error, stanza_error()} | {result, xmpp_element() | undefined}, iq(), userlist()) -> {error, stanza_error()} | {result, xmpp_element() | undefined}. +process_iq_get(_, #iq{lang = Lang, + sub_els = [#privacy_query{default = Default, + active = Active}]}, + _) when Default /= undefined; Active /= undefined -> + Txt = <<"Only element is allowed in this query">>, + {error, xmpp:err_bad_request(Txt, Lang)}; process_iq_get(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{lists = Lists}]}, #userlist{name = Active}) -> @@ -205,7 +211,7 @@ encode_value(Type, Val) -> listitem_value(). decode_value(Type, Value) -> case Type of - jid -> jid:from_string(Value); + jid -> jid:tolower(jid:from_string(Value)); subscription -> case Value of <<"from">> -> from; @@ -213,35 +219,37 @@ decode_value(Type, Value) -> <<"both">> -> both; <<"none">> -> none end; - group -> Value; + group when Value /= <<"">> -> Value; undefined -> none end. -spec process_iq_set({error, stanza_error()} | {result, xmpp_element() | undefined} | {result, xmpp_element() | undefined, userlist()}, - iq()) -> {error, stanza_error()} | - {result, xmpp_element() | undefined} | - {result, xmpp_element() | undefined, userlist()}. + iq(), #userlist{}) -> + {error, stanza_error()} | + {result, xmpp_element() | undefined} | + {result, xmpp_element() | undefined, userlist()}. process_iq_set(_, #iq{from = From, lang = Lang, sub_els = [#privacy_query{default = Default, active = Active, - lists = Lists}]}) -> + lists = Lists}]}, + #userlist{} = UserList) -> #jid{luser = LUser, lserver = LServer} = From, case Lists of [#privacy_list{items = Items, name = ListName}] when Default == undefined, Active == undefined -> - process_lists_set(LUser, LServer, ListName, Items, Lang); + process_lists_set(LUser, LServer, ListName, Items, UserList, Lang); [] when Default == undefined, Active /= undefined -> process_active_set(LUser, LServer, Active, Lang); [] when Active == undefined, Default /= undefined -> process_default_set(LUser, LServer, Default, Lang); _ -> - Txt = <<"There should be exactly one element in this query: " - ", or ">>, + Txt = <<"The stanza MUST contain only one element, " + "one element, or one element">>, {error, xmpp:err_bad_request(Txt, Lang)} end; -process_iq_set(Acc, _) -> +process_iq_set(Acc, _, _) -> Acc. -spec process_default_set(binary(), binary(), none | binary(), @@ -286,13 +294,20 @@ set_privacy_list(#privacy{us = {_, LServer}} = Privacy) -> Mod:set_privacy_list(Privacy). -spec process_lists_set(binary(), binary(), binary(), [privacy_item()], - binary()) -> {error, stanza_error()} | {result, undefined}. -process_lists_set(LUser, LServer, Name, [], Lang) -> + #userlist{}, binary()) -> {error, stanza_error()} | + {result, undefined}. +process_lists_set(_LUser, _LServer, Name, [], #userlist{name = Name}, Lang) -> + Txt = <<"Cannot remove active list">>, + {error, xmpp:err_conflict(Txt, Lang)}; +process_lists_set(LUser, LServer, Name, [], _UserList, Lang) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:remove_privacy_list(LUser, LServer, Name) of {atomic, conflict} -> Txt = <<"Cannot remove default list">>, {error, xmpp:err_conflict(Txt, Lang)}; + {atomic, not_found} -> + Txt = <<"No privacy list with this name found">>, + {error, xmpp:err_item_not_found(Txt, Lang)}; {atomic, ok} -> ejabberd_sm:route(jid:make(LUser, LServer, <<"">>), @@ -308,7 +323,7 @@ process_lists_set(LUser, LServer, Name, [], Lang) -> Txt = <<"Database failure">>, {error, xmpp:err_internal_server_error(Txt, Lang)} end; -process_lists_set(LUser, LServer, Name, Items, Lang) -> +process_lists_set(LUser, LServer, Name, Items, _UserList, Lang) -> case catch lists:map(fun decode_item/1, Items) of {error, Why} -> Txt = xmpp:format_error(Why), @@ -358,9 +373,7 @@ decode_item(#privacy_item{order = Order, action = Action, type = Type, value = Value}, - if MatchMessage and MatchIQ and MatchPresenceIn and MatchPresenceOut -> - ListItem#listitem{match_all = true}; - not (MatchMessage or MatchIQ or MatchPresenceIn or MatchPresenceOut) -> + if not (MatchMessage or MatchIQ or MatchPresenceIn or MatchPresenceOut) -> ListItem#listitem{match_all = true}; true -> ListItem#listitem{match_iq = MatchIQ, @@ -468,17 +481,11 @@ check_packet_aux([Item | List], PType, JID, Item, case is_ptype_match(Item, PType) of true -> - case Type of - none -> Action; - _ -> - case is_type_match(Type, Value, JID, Subscription, - Groups) - of - true -> Action; - false -> - check_packet_aux(List, PType, JID, Subscription, Groups) - end - end; + case is_type_match(Type, Value, JID, Subscription, Groups) of + true -> Action; + false -> + check_packet_aux(List, PType, JID, Subscription, Groups) + end; false -> check_packet_aux(List, PType, JID, Subscription, Groups) end. @@ -499,8 +506,10 @@ is_ptype_match(Item, PType) -> end end. --spec is_type_match(jid | subscription | group, listitem_value(), +-spec is_type_match(none | jid | subscription | group, listitem_value(), ljid(), none | both | from | to, [binary()]) -> boolean(). +is_type_match(none, _Value, _JID, _Subscription, _Groups) -> + true; is_type_match(Type, Value, JID, Subscription, Groups) -> case Type of jid -> diff --git a/src/mod_roster.erl b/src/mod_roster.erl index feebd3945..423fe9e0e 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -49,7 +49,7 @@ get_jid_info/4, encode_item/1, webadmin_page/3, webadmin_user/4, get_versioning_feature/2, roster_versioning_enabled/1, roster_version/2, - mod_opt_type/1, set_roster/1, depends/2]). + mod_opt_type/1, set_roster/1, del_roster/3, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -297,6 +297,13 @@ set_roster(#roster{us = {LUser, LServer}, jid = LJID} = Item) -> roster_subscribe_t(LUser, LServer, LJID, Item) end). +del_roster(LUser, LServer, LJID) -> + transaction( + LServer, + fun() -> + del_roster_t(LUser, LServer, LJID) + end). + encode_item(Item) -> #roster_item{jid = jid:make(Item#roster.jid), name = Item#roster.name, -- cgit v1.2.3 From 9d977e484a4c9609e19b08bc1235deb88b9a725c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 22 Oct 2016 13:09:11 +0300 Subject: Use base64:mime_decode/1 for SASL packets It will be now possible to accept SASL packets with only single '=' character set as required by RFC6120 --- src/xmpp_codec.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index f230dc489..345de7031 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -29298,7 +29298,7 @@ encode_sasl_success({sasl_success, Text}, __TopXMLNS) -> decode_sasl_success_cdata(__TopXMLNS, <<>>) -> <<>>; decode_sasl_success_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of + case catch base64:mime_decode(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_cdata_value, <<>>, <<"success">>, __TopXMLNS}}); @@ -29338,7 +29338,7 @@ encode_sasl_response({sasl_response, Text}, decode_sasl_response_cdata(__TopXMLNS, <<>>) -> <<>>; decode_sasl_response_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of + case catch base64:mime_decode(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_cdata_value, <<>>, <<"response">>, __TopXMLNS}}); @@ -29378,7 +29378,7 @@ encode_sasl_challenge({sasl_challenge, Text}, decode_sasl_challenge_cdata(__TopXMLNS, <<>>) -> <<>>; decode_sasl_challenge_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of + case catch base64:mime_decode(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_cdata_value, <<>>, <<"challenge">>, __TopXMLNS}}); @@ -29454,7 +29454,7 @@ encode_sasl_auth_attr_mechanism(_val, _acc) -> decode_sasl_auth_cdata(__TopXMLNS, <<>>) -> <<>>; decode_sasl_auth_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of + case catch base64:mime_decode(_val) of {'EXIT', _} -> erlang:error({xmpp_codec, {bad_cdata_value, <<>>, <<"auth">>, __TopXMLNS}}); -- cgit v1.2.3 From 2a63d0e95a0e77261a1b57a816720bef190388b1 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 1 Nov 2016 08:47:08 +0100 Subject: mod_mam: Use user JID for stanza ID 'by' attribute Use the user (or room) JID instead of the server JID for the 'by' attribute of and tags. That's what the examples in XEP-0313 v0.2 and XEP-0359 v0.3.0 suggest. --- src/mod_mam.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mod_mam.erl b/src/mod_mam.erl index cbd23ebde..4c3050df1 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -214,7 +214,7 @@ user_receive_packet(Pkt, C2SState, JID, Peer, To) -> NewPkt = strip_my_archived_tag(Pkt, LServer), case store_msg(C2SState, NewPkt, LUser, LServer, Peer, recv) of {ok, ID} -> - set_stanza_id(NewPkt, LServer, ID); + set_stanza_id(NewPkt, JID, ID); _ -> NewPkt end; @@ -232,7 +232,7 @@ user_send_packet(Pkt, C2SState, JID, Peer) -> case store_msg(C2SState, xmpp:set_from_to(NewPkt, JID, Peer), LUser, LServer, Peer, send) of {ok, ID} -> - set_stanza_id(NewPkt, LServer, ID); + set_stanza_id(NewPkt, JID, ID); _ -> NewPkt end; @@ -256,7 +256,7 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, StorePkt = strip_x_jid_tags(NewPkt), case store_muc(MUCState, StorePkt, RoomJID, From, FromNick) of {ok, ID} -> - set_stanza_id(NewPkt, LServer, ID); + set_stanza_id(NewPkt, RoomJID, ID); _ -> NewPkt end; @@ -264,9 +264,9 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, Pkt end. -set_stanza_id(Pkt, LServer, ID) -> - Archived = #mam_archived{by = jid:make(LServer), id = ID}, - StanzaID = #stanza_id{by = jid:make(LServer), id = ID}, +set_stanza_id(Pkt, JID, ID) -> + Archived = #mam_archived{by = JID, id = ID}, + StanzaID = #stanza_id{by = JID, id = ID}, NewEls = [Archived, StanzaID|xmpp:get_els(Pkt)], xmpp:set_els(Pkt, NewEls). @@ -533,9 +533,9 @@ strip_my_archived_tag(Pkt, LServer) -> end end), NewEls = lists:filter( - fun(#mam_archived{by = #jid{luser = <<>>} = By}) -> + fun(#mam_archived{by = By}) -> By#jid.lserver /= LServer; - (#stanza_id{by = #jid{luser = <<>>} = By}) -> + (#stanza_id{by = By}) -> By#jid.lserver /= LServer; (_) -> true -- cgit v1.2.3 From 56c91d3c58ec5461600f70d2d0413c846767f882 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 7 Nov 2016 10:10:57 +0300 Subject: Add roster tests --- src/ejabberd_sm.erl | 213 +++++++++++++++++++++------------------------------- src/mod_roster.erl | 96 +++++++++++++++-------- 2 files changed, 150 insertions(+), 159 deletions(-) (limited to 'src') diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index f6d0e765d..6f6a196e5 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -442,135 +442,96 @@ online(Sessions) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec do_route(jid(), jid(), stanza() | broadcast()) -> any(). +do_route(From, #jid{lresource = <<"">>} = To, {broadcast, _} = Packet) -> + ?DEBUG("processing broadcast to bare JID: ~p", [Packet]), + lists:foreach( + fun(R) -> + do_route(From, jid:replace_resource(To, R), Packet) + end, get_user_resources(To#jid.user, To#jid.server)); do_route(From, To, {broadcast, _} = Packet) -> - case To#jid.lresource of - <<"">> -> - lists:foreach(fun(R) -> - do_route(From, - jid:replace_resource(To, R), - Packet) - end, - get_user_resources(To#jid.user, To#jid.server)); - _ -> - {U, S, R} = jid:tolower(To), - Mod = get_sm_backend(S), - case online(Mod:get_sessions(U, S, R)) of - [] -> - ?DEBUG("packet dropped~n", []); - Ss -> - Session = lists:max(Ss), - Pid = element(2, Session#session.sid), - ?DEBUG("sending to process ~p~n", [Pid]), - Pid ! {route, From, To, Packet} - end + ?DEBUG("processing broadcast to full JID: ~p", [Packet]), + {U, S, R} = jid:tolower(To), + Mod = get_sm_backend(S), + case online(Mod:get_sessions(U, S, R)) of + [] -> + ?DEBUG("dropping broadcast to unavailable resourse: ~p", [Packet]); + Ss -> + Session = lists:max(Ss), + Pid = element(2, Session#session.sid), + ?DEBUG("sending to process ~p: ~p", [Pid, Packet]), + Pid ! {route, From, To, Packet} end; -do_route(From, To, Packet) -> - ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket " - "~P~n", - [From, To, Packet, 8]), +do_route(From, To, #presence{type = T, status = Status} = Packet) + when T == subscribe; T == subscribed; T == unsubscribe; T == unsubscribed -> + ?DEBUG("processing subscription:~n~s", [xmpp:pp(Packet)]), #jid{user = User, server = Server, - luser = LUser, lserver = LServer, lresource = LResource} = To, - Lang = xmpp:get_lang(Packet), - case LResource of - <<"">> -> - case Packet of - #presence{type = T, status = Status} -> - {Pass, _Subsc} = case T of - subscribe -> - Reason = xmpp:get_text(Status), - {is_privacy_allow(From, To, Packet) - andalso - ejabberd_hooks:run_fold(roster_in_subscription, - LServer, - false, - [User, Server, - From, - subscribe, - Reason]), - true}; - subscribed -> - {is_privacy_allow(From, To, Packet) - andalso - ejabberd_hooks:run_fold(roster_in_subscription, - LServer, - false, - [User, Server, - From, - subscribed, - <<"">>]), - true}; - unsubscribe -> - {is_privacy_allow(From, To, Packet) - andalso - ejabberd_hooks:run_fold(roster_in_subscription, - LServer, - false, - [User, Server, - From, - unsubscribe, - <<"">>]), - true}; - unsubscribed -> - {is_privacy_allow(From, To, Packet) - andalso - ejabberd_hooks:run_fold(roster_in_subscription, - LServer, - false, - [User, Server, - From, - unsubscribed, - <<"">>]), - true}; - _ -> {true, false} - end, - if Pass -> - PResources = get_user_present_resources(LUser, LServer), - lists:foreach(fun ({_, R}) -> - do_route(From, - jid:replace_resource(To, - R), - Packet) - end, - PResources); - true -> ok - end; - #message{type = T} when T == chat; T == headline; T == normal -> - route_message(From, To, Packet, T); - #message{type = groupchat} -> - ErrTxt = <<"User session not found">>, - Err = xmpp:make_error( - Packet, xmpp:err_service_unavailable(ErrTxt, Lang)), - ejabberd_router:route(To, From, Err); - #iq{} -> process_iq(From, To, Packet); - _ -> ok - end; - _ -> - Mod = get_sm_backend(LServer), - case online(Mod:get_sessions(LUser, LServer, LResource)) of - [] -> - case Packet of - #message{type = T} when T == chat; T == normal -> - route_message(From, To, Packet, T); - #message{type = groupchat} -> - ErrTxt = <<"User session not found">>, - Err = xmpp:make_error( - Packet, - xmpp:err_service_unavailable(ErrTxt, Lang)), - ejabberd_router:route(To, From, Err); - #iq{type = T} when T == get; T == set -> - ErrTxt = <<"User session not found">>, - Err = xmpp:make_error( - Packet, - xmpp:err_service_unavailable(ErrTxt, Lang)), - ejabberd_router:route(To, From, Err); - _ -> ?DEBUG("packet dropped~n", []) - end; - Ss -> - Session = lists:max(Ss), - Pid = element(2, Session#session.sid), - ?DEBUG("sending to process ~p~n", [Pid]), - Pid ! {route, From, To, Packet} - end + luser = LUser, lserver = LServer} = To, + Reason = if T == subscribe -> xmpp:get_text(Status); + true -> <<"">> + end, + case is_privacy_allow(From, To, Packet) andalso + ejabberd_hooks:run_fold( + roster_in_subscription, + LServer, false, + [User, Server, From, T, Reason]) of + true -> + Mod = get_sm_backend(LServer), + lists:foreach( + fun(#session{sid = SID, usr = {_, _, R}, + priority = Prio}) when is_integer(Prio) -> + Pid = element(2, SID), + ?DEBUG("sending to process ~p:~n~s", + [Pid, xmpp:pp(Packet)]), + Pid ! {route, From, jid:replace_resource(To, R), Packet}; + (_) -> + ok + end, online(Mod:get_sessions(LUser, LServer))); + false -> + ok + end; +do_route(From, #jid{lresource = <<"">>} = To, #presence{} = Packet) -> + ?DEBUG("processing presence to bare JID:~n~s", [xmpp:pp(Packet)]), + {LUser, LServer, _} = jid:tolower(To), + lists:foreach( + fun({_, R}) -> + do_route(From, jid:replace_resource(To, R), Packet) + end, get_user_present_resources(LUser, LServer)); +do_route(From, #jid{lresource = <<"">>} = To, #message{type = T} = Packet) -> + ?DEBUG("processing message to bare JID:~n~s", [xmpp:pp(Packet)]), + if T == chat; T == headline; T == normal -> + route_message(From, To, Packet, T); + true -> + Lang = xmpp:get_lang(Packet), + ErrTxt = <<"User session not found">>, + Err = xmpp:err_service_unavailable(ErrTxt, Lang), + ejabberd_router:route_error(To, From, Packet, Err) + end; +do_route(From, #jid{lresource = <<"">>} = To, #iq{} = Packet) -> + ?DEBUG("processing IQ to bare JID:~n~s", [xmpp:pp(Packet)]), + process_iq(From, To, Packet); +do_route(From, To, Packet) -> + ?DEBUG("processing packet to full JID:~n~s", [xmpp:pp(Packet)]), + {LUser, LServer, LResource} = jid:tolower(To), + Mod = get_sm_backend(LServer), + case online(Mod:get_sessions(LUser, LServer, LResource)) of + [] -> + case Packet of + #message{type = T} when T == chat; T == normal -> + route_message(From, To, Packet, T); + #presence{} -> + ?DEBUG("dropping presence to unavalable resource:~n~s", + [xmpp:pp(Packet)]); + _ -> + Lang = xmpp:get_lang(Packet), + ErrTxt = <<"User session not found">>, + Err = xmpp:err_service_unavailable(ErrTxt, Lang), + ejabberd_router:route_error(To, From, Packet, Err) + end; + Ss -> + Session = lists:max(Ss), + Pid = element(2, Session#session.sid), + ?DEBUG("sending to process ~p:~n~s", [Pid, xmpp:pp(Packet)]), + Pid ! {route, From, To, Packet} end. %% The default list applies to the user as a whole, diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 423fe9e0e..fa27f866c 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -142,21 +142,54 @@ depends(_Host, _Opts) -> process_iq(#iq{from = #jid{luser = <<"">>}, to = #jid{resource = <<"">>}} = IQ) -> process_iq_manager(IQ); - -process_iq(#iq{from = From, lang = Lang} = IQ) -> - #jid{lserver = LServer} = From, - case lists:member(LServer, ?MYHOSTS) of - true -> process_local_iq(IQ); - _ -> - Txt = <<"The query is only allowed from local users">>, - xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)) - end. - -process_local_iq(#iq{type = Type} = IQ) -> - case Type of - set -> try_process_iq_set(IQ); - get -> process_iq_get(IQ) - end. +process_iq(#iq{from = #jid{luser = U, lserver = S}, + to = #jid{luser = U, lserver = S}} = IQ) -> + process_local_iq(IQ); +process_iq(#iq{lang = Lang} = IQ) -> + Txt = <<"Query to another users is forbidden">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)). + +process_local_iq(#iq{type = set,lang = Lang, + sub_els = [#roster_query{ + items = [#roster_item{ask = Ask}]}]} = IQ) + when Ask /= undefined -> + Txt = <<"Possessing 'ask' attribute is not allowed by RFC6121">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); +process_local_iq(#iq{type = set, from = From, lang = Lang, + sub_els = [#roster_query{ + items = [#roster_item{} = Item]}]} = IQ) -> + case has_duplicated_groups(Item#roster_item.groups) of + true -> + Txt = <<"Duplicated groups are not allowed by RFC6121">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); + false -> + #jid{server = Server} = From, + Access = gen_mod:get_module_opt(Server, ?MODULE, + access, fun(A) -> A end, all), + case acl:match_rule(Server, Access, From) of + deny -> + Txt = <<"Denied by ACL">>, + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); + allow -> + process_iq_set(IQ) + end + end; +process_local_iq(#iq{type = set, lang = Lang, + sub_els = [#roster_query{items = [_|_]}]} = IQ) -> + Txt = <<"Multiple elements are not allowed by RFC6121">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); +process_local_iq(#iq{type = get, lang = Lang, + sub_els = [#roster_query{items = Items}]} = IQ) -> + case Items of + [] -> + process_iq_get(IQ); + [_|_] -> + Txt = <<"The query must not contain elements">>, + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)) + end; +process_local_iq(#iq{lang = Lang} = IQ) -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). roster_hash(Items) -> p1_sha:sha(term_to_binary(lists:sort([R#roster{groups = @@ -315,11 +348,18 @@ encode_item(Item) -> end, groups = Item#roster.groups}. +decode_item(#roster_item{subscription = remove} = Item, R, _) -> + R#roster{jid = jid:tolower(Item#roster_item.jid), + name = <<"">>, + subscription = remove, + ask = none, + groups = [], + askmessage = <<"">>, + xs = []}; decode_item(Item, R, Managed) -> R#roster{jid = jid:tolower(Item#roster_item.jid), name = Item#roster_item.name, subscription = case Item#roster_item.subscription of - remove -> remove; Sub when Managed -> Sub; _ -> R#roster.subscription end, @@ -329,17 +369,6 @@ get_roster_by_jid_t(LUser, LServer, LJID) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:get_roster_by_jid(LUser, LServer, LJID). -try_process_iq_set(#iq{from = From, lang = Lang} = IQ) -> - #jid{server = Server} = From, - Access = gen_mod:get_module_opt(Server, ?MODULE, access, fun(A) -> A end, all), - case acl:match_rule(Server, Access, From) of - deny -> - Txt = <<"Denied by ACL">>, - xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); - allow -> - process_iq_set(IQ) - end. - process_iq_set(#iq{from = From, to = To, id = Id, sub_els = [#roster_query{items = QueryItems}]} = IQ) -> Managed = is_managed_from_id(Id), @@ -515,8 +544,7 @@ process_subscription(Direction, User, Server, JID1, {Subscription, Pending} -> NewItem = Item#roster{subscription = Subscription, ask = Pending, - askmessage = - iolist_to_binary(AskMessage)}, + askmessage = AskMessage}, roster_subscribe_t(LUser, LServer, LJID, NewItem), case roster_version_on_db(LServer) of true -> write_roster_version_t(LUser, LServer); @@ -730,10 +758,8 @@ del_roster_t(LUser, LServer, LJID) -> Mod:del_roster(LUser, LServer, LJID). process_item_set_t(LUser, LServer, #roster_item{jid = JID1} = QueryItem) -> - JID = {JID1#jid.user, JID1#jid.server, - JID1#jid.resource}, - LJID = {JID1#jid.luser, JID1#jid.lserver, - JID1#jid.lresource}, + JID = {JID1#jid.user, JID1#jid.server, <<>>}, + LJID = {JID1#jid.luser, JID1#jid.lserver, <<>>}, Item = #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = JID}, Item2 = decode_item(QueryItem, Item, _Managed = true), @@ -1046,6 +1072,10 @@ is_managed_from_id(<<"roster-remotely-managed">>) -> is_managed_from_id(_Id) -> false. +has_duplicated_groups(Groups) -> + GroupsPrep = lists:usort([jid:resourceprep(G) || G <- Groups]), + not (length(GroupsPrep) == length(Groups)). + export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -- cgit v1.2.3 From e841a6ec34e4b79adbeb070e56edec766adc9987 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 8 Nov 2016 15:15:19 +0300 Subject: Add more tests for offline storage --- src/ejabberd_sm.erl | 29 ++++++-------- src/mod_offline.erl | 98 +++++++++++++++++++++++++++------------------- src/mod_offline_mnesia.erl | 16 +++++--- src/xmpp_util.erl | 2 +- 4 files changed, 82 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 6f6a196e5..0655bbcf3 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -498,7 +498,7 @@ do_route(From, #jid{lresource = <<"">>} = To, #presence{} = Packet) -> end, get_user_present_resources(LUser, LServer)); do_route(From, #jid{lresource = <<"">>} = To, #message{type = T} = Packet) -> ?DEBUG("processing message to bare JID:~n~s", [xmpp:pp(Packet)]), - if T == chat; T == headline; T == normal -> + if T == chat; T == headline; T == normal; T == groupchat -> route_message(From, To, Packet, T); true -> Lang = xmpp:get_lang(Packet), @@ -516,7 +516,8 @@ do_route(From, To, Packet) -> case online(Mod:get_sessions(LUser, LServer, LResource)) of [] -> case Packet of - #message{type = T} when T == chat; T == normal -> + #message{type = T} when T == chat; T == normal; + T == headline; T == groupchat -> route_message(From, To, Packet, T); #presence{} -> ?DEBUG("dropping presence to unavalable resource:~n~s", @@ -586,20 +587,16 @@ route_message(From, To, Packet, Type) -> end, PrioRes); _ -> - case Type of - headline -> ok; - _ -> - case ejabberd_auth:is_user_exists(LUser, LServer) andalso - is_privacy_allow(From, To, Packet) of - true -> - ejabberd_hooks:run(offline_message_hook, LServer, - [From, To, Packet]); - false -> - Err = xmpp:make_error(Packet, - xmpp:err_service_unavailable()), - ejabberd_router:route(To, From, Err) - end - end + case ejabberd_auth:is_user_exists(LUser, LServer) andalso + is_privacy_allow(From, To, Packet) of + true -> + ejabberd_hooks:run(offline_message_hook, LServer, + [From, To, Packet]); + false -> + Err = xmpp:make_error(Packet, + xmpp:err_service_unavailable()), + ejabberd_router:route(To, From, Err) + end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 240650234..6134823c1 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -102,7 +102,7 @@ -callback read_message_headers(binary(), binary()) -> any(). -callback read_message(binary(), binary(), non_neg_integer()) -> {ok, #offline_msg{}} | error. --callback remove_message(binary(), binary(), non_neg_integer()) -> ok. +-callback remove_message(binary(), binary(), non_neg_integer()) -> ok | {error, any()}. -callback read_all_messages(binary(), binary()) -> [#offline_msg{}]. -callback remove_all_messages(binary(), binary()) -> {atomic, any()}. -callback count_messages(binary(), binary()) -> non_neg_integer(). @@ -315,32 +315,52 @@ get_info(Acc, _From, _To, _Node, _Lang) -> Acc. -spec handle_offline_query(iq()) -> iq(). +handle_offline_query(#iq{from = #jid{luser = U1, lserver = S1}, + to = #jid{luser = U2, lserver = S2}, + lang = Lang, + sub_els = [#offline{}]} = IQ) + when {U1, S1} /= {U2, S2} -> + Txt = <<"Query to another users is forbidden">>, + xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)); handle_offline_query(#iq{from = #jid{luser = U, lserver = S} = From, to = #jid{luser = U, lserver = S} = _To, - type = Type, - sub_els = [#offline{purge = Purge, - items = Items, - fetch = Fetch}]} = IQ) -> - case Type of - get -> - if Fetch -> handle_offline_fetch(From); - true -> handle_offline_items_view(From, Items) + type = Type, lang = Lang, + sub_els = [#offline{} = Offline]} = IQ) -> + case {Type, Offline} of + {get, #offline{fetch = true, items = [], purge = false}} -> + %% TODO: report database errors + handle_offline_fetch(From), + xmpp:make_iq_result(IQ); + {get, #offline{fetch = false, items = [_|_] = Items, purge = false}} -> + case handle_offline_items_view(From, Items) of + true -> xmpp:make_iq_result(IQ); + false -> xmpp:make_error(IQ, xmpp:err_item_not_found()) end; - set -> - if Purge -> delete_all_msgs(U, S); - true -> handle_offline_items_remove(From, Items) - end - end, - xmpp:make_iq_result(IQ); + {set, #offline{fetch = false, items = [], purge = true}} -> + case delete_all_msgs(U, S) of + {atomic, ok} -> + xmpp:make_iq_result(IQ); + _Err -> + Txt = <<"Database failure">>, + xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)) + end; + {set, #offline{fetch = false, items = [_|_] = Items, purge = false}} -> + case handle_offline_items_remove(From, Items) of + true -> xmpp:make_iq_result(IQ); + false -> xmpp:make_error(IQ, xmpp:err_item_not_found()) + end; + _ -> + xmpp:make_error(IQ, xmpp:err_bad_request()) + end; handle_offline_query(#iq{lang = Lang} = IQ) -> - Txt = <<"Query to another users is forbidden">>, - xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)). + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). --spec handle_offline_items_view(jid(), [offline_item()]) -> ok. +-spec handle_offline_items_view(jid(), [offline_item()]) -> boolean(). handle_offline_items_view(JID, Items) -> {U, S, R} = jid:tolower(JID), - lists:foreach( - fun(#offline_item{node = Node, action = view}) -> + lists:foldl( + fun(#offline_item{node = Node, action = view}, Acc) -> case fetch_msg_by_node(JID, Node) of {ok, OfflineMsg} -> case offline_msg_to_route(S, OfflineMsg) of @@ -351,25 +371,22 @@ handle_offline_items_view(JID, Items) -> Pid ! {route, From, To, NewEl}; none -> ok - end; + end, + Acc or true; error -> - ok + Acc or false end; error -> - ok - end; - (_) -> - ok - end, Items). + Acc or false + end + end, false, Items). --spec handle_offline_items_remove(jid(), [offline_item()]) -> ok. +-spec handle_offline_items_remove(jid(), [offline_item()]) -> boolean(). handle_offline_items_remove(JID, Items) -> - lists:foreach( - fun(#offline_item{node = Node, action = remove}) -> - remove_msg_by_node(JID, Node); - (_) -> - ok - end, Items). + lists:foldl( + fun(#offline_item{node = Node, action = remove}, Acc) -> + Acc or remove_msg_by_node(JID, Node) + end, false, Items). -spec set_offline_tag(message(), binary()) -> message(). set_offline_tag(Msg, Node) -> @@ -401,23 +418,22 @@ fetch_msg_by_node(To, Seq) -> error end. --spec remove_msg_by_node(jid(), binary()) -> ok. +-spec remove_msg_by_node(jid(), binary()) -> boolean(). remove_msg_by_node(To, Seq) -> case catch binary_to_integer(Seq) of I when is_integer(I), I>= 0 -> LUser = To#jid.luser, LServer = To#jid.lserver, Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:remove_message(LUser, LServer, I); + Mod:remove_message(LUser, LServer, I), + true; _ -> - ok + false end. -spec need_to_store(binary(), message()) -> boolean(). need_to_store(_LServer, #message{type = error}) -> false; -need_to_store(_LServer, #message{type = groupchat}) -> false; -need_to_store(_LServer, #message{type = headline}) -> false; -need_to_store(LServer, Packet) -> +need_to_store(LServer, #message{type = Type} = Packet) -> case xmpp:has_subtag(Packet, #offline{}) of false -> case check_store_hint(Packet) of @@ -425,6 +441,8 @@ need_to_store(LServer, Packet) -> true; no_store -> false; + none when Type == headline; Type == groupchat -> + false; none -> case gen_mod:get_module_opt( LServer, ?MODULE, store_empty_body, diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index e8db08ddf..c9f088fa4 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -127,12 +127,16 @@ read_message(LUser, LServer, I) -> remove_message(LUser, LServer, I) -> US = {LUser, LServer}, TS = integer_to_now(I), - Msgs = mnesia:dirty_match_object( - offline_msg, #offline_msg{us = US, timestamp = TS, _ = '_'}), - lists:foreach( - fun(Msg) -> - mnesia:dirty_delete_object(Msg) - end, Msgs). + case mnesia:dirty_match_object( + offline_msg, #offline_msg{us = US, timestamp = TS, _ = '_'}) of + [] -> + {error, notfound}; + Msgs -> + lists:foreach( + fun(Msg) -> + mnesia:dirty_delete_object(Msg) + end, Msgs) + end. read_all_messages(LUser, LServer) -> US = {LUser, LServer}, diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 102d88412..fb3bbc7ab 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -70,7 +70,7 @@ unwrap_carbon(Stanza) -> Stanza. is_standalone_chat_state(Stanza) -> case unwrap_carbon(Stanza) of #message{body = [], subject = [], sub_els = Els} -> - IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY], + IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY, ?NS_EVENT], Stripped = [El || El <- Els, not lists:member(xmpp:get_ns(El), IgnoreNS)], Stripped == []; -- cgit v1.2.3 From 566ac872fe396a6d41296d9cfbc6ed5859a0eeed Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 10 Nov 2016 20:48:43 +0100 Subject: Support to provide password when subscribing to a room (#1306) --- src/mod_muc_room.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 6010e0bbf..054900399 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -4653,7 +4653,8 @@ process_iq_mucsub(From, Packet, NewStateData = set_subscriber(From, Nick, Nodes, StateData), {result, subscription_nodes_to_events(Nodes), NewStateData}; error -> - add_new_user(From, Nick, Packet, StateData) + Packet2 = copy_password_xelement(Packet), + add_new_user(From, Nick, Packet2, StateData) end; _ -> Err = ?ERRT_NOT_ALLOWED(Lang, <<"Subscriptions are not allowed">>), @@ -4697,6 +4698,11 @@ process_iq_mucsub(_From, _Packet, #iq{lang = Lang}, _StateData) -> Txt = <<"Unrecognized subscription command">>, {error, ?ERRT_BAD_REQUEST(Lang, Txt)}. +copy_password_xelement(Packet) -> + SubsEl = fxml:get_subtag_with_xmlns(Packet, <<"subscribe">>, ?NS_MUCSUB), + XEl = fxml:get_subtag_with_xmlns(SubsEl, <<"x">>, ?NS_MUC), + fxml:append_subtags(Packet, [XEl]). + remove_subscriptions(StateData) -> if not (StateData#state.config)#config.allow_subscription -> StateData#state{subscribers = ?DICT:new(), -- cgit v1.2.3 From de81c501992bc5535ef2b0dbe37547c9f3754a73 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 12 Nov 2016 14:47:29 +0300 Subject: Revert "Support to provide password when subscribing to a room (#1306)" This reverts commit 566ac872fe396a6d41296d9cfbc6ed5859a0eeed. --- src/mod_muc_room.erl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index e31ec6b0f..c83565734 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -3735,8 +3735,7 @@ process_iq_mucsub(From, NewStateData = set_subscriber(From, Nick, Nodes, StateData), {result, subscribe_result(Packet), NewStateData}; error -> - Packet2 = copy_password_xelement(Packet), - add_new_user(From, Nick, Packet2, StateData) + add_new_user(From, Nick, Packet, StateData) end; process_iq_mucsub(From, #iq{type = set, sub_els = [#muc_unsubscribe{}]}, StateData) -> @@ -3771,11 +3770,6 @@ process_iq_mucsub(_From, #iq{type = get, lang = Lang}, _StateData) -> Txt = <<"Value 'get' of 'type' attribute is not allowed">>, {error, xmpp:err_bad_request(Txt, Lang)}. -copy_password_xelement(Packet) -> - SubsEl = fxml:get_subtag_with_xmlns(Packet, <<"subscribe">>, ?NS_MUCSUB), - XEl = fxml:get_subtag_with_xmlns(SubsEl, <<"x">>, ?NS_MUC), - fxml:append_subtags(Packet, [XEl]). - remove_subscriptions(StateData) -> if not (StateData#state.config)#config.allow_subscription -> StateData#state{subscribers = ?DICT:new(), -- cgit v1.2.3 From 534e73f7320effc4cacef78ce7dce153a7bf7a70 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 12 Nov 2016 14:51:43 +0300 Subject: Uncomment forgotten block of code --- src/ejabberd_service.erl | 53 ++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 94cd68ecf..35cfe15af 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -170,37 +170,28 @@ wait_for_stream(closed, StateData) -> wait_for_handshake({xmlstreamelement, El}, StateData) -> decode_element(El, wait_for_handshake, StateData); wait_for_handshake(#handshake{data = Digest}, StateData) -> - send_element(StateData, #handshake{}), - lists:foreach( - fun (H) -> - ejabberd_router:register_route(H, ?MYNAME), - ?INFO_MSG("Route registered for service ~p~n", - [H]), - ejabberd_hooks:run(component_connected, [H]) - end, dict:fetch_keys(StateData#state.host_opts)), - {next_state, stream_established, StateData}; - %% case dict:find(StateData#state.host, StateData#state.host_opts) of - %% {ok, Password} -> - %% case p1_sha:sha(<<(StateData#state.streamid)/binary, - %% Password/binary>>) of - %% Digest -> - %% send_element(StateData, #handshake{}), - %% lists:foreach( - %% fun (H) -> - %% ejabberd_router:register_route(H, ?MYNAME), - %% ?INFO_MSG("Route registered for service ~p~n", - %% [H]), - %% ejabberd_hooks:run(component_connected, [H]) - %% end, dict:fetch_keys(StateData#state.host_opts)), - %% {next_state, stream_established, StateData}; - %% _ -> - %% send_element(StateData, xmpp:serr_not_authorized()), - %% {stop, normal, StateData} - %% end; - %% _ -> - %% send_element(StateData, xmpp:serr_not_authorized()), - %% {stop, normal, StateData} - %% end; + case dict:find(StateData#state.host, StateData#state.host_opts) of + {ok, Password} -> + case p1_sha:sha(<<(StateData#state.streamid)/binary, + Password/binary>>) of + Digest -> + send_element(StateData, #handshake{}), + lists:foreach( + fun (H) -> + ejabberd_router:register_route(H, ?MYNAME), + ?INFO_MSG("Route registered for service ~p~n", + [H]), + ejabberd_hooks:run(component_connected, [H]) + end, dict:fetch_keys(StateData#state.host_opts)), + {next_state, stream_established, StateData}; + _ -> + send_element(StateData, xmpp:serr_not_authorized()), + {stop, normal, StateData} + end; + _ -> + send_element(StateData, xmpp:serr_not_authorized()), + {stop, normal, StateData} + end; wait_for_handshake({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; wait_for_handshake({xmlstreamerror, _}, StateData) -> -- cgit v1.2.3 From b8f22ff538da8297b66010912b3fc91e46ded5c0 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 10:44:53 +0300 Subject: Deprecate most of the functions from jlib.erl --- src/ejabberd_oauth.erl | 4 +- src/jlib.erl | 57 ++++++++++++--- src/mod_admin_extra.erl | 4 +- src/mod_mam.erl | 10 +-- src/mod_muc_admin.erl | 2 +- src/mod_offline.erl | 151 ++++++++++++++++++++++++---------------- src/mod_offline_mnesia.erl | 10 +-- src/mod_offline_riak.erl | 9 +-- src/mod_offline_sql.erl | 70 ++++++++++--------- src/prosody2ejabberd.erl | 8 +-- src/pubsub_db_sql.erl | 4 +- src/pubsub_subscription.erl | 8 +-- src/pubsub_subscription_sql.erl | 8 +-- src/randoms.erl | 2 +- src/xmpp.erl | 7 +- src/xmpp_codec.erl | 5 +- src/xmpp_util.erl | 31 +++------ 17 files changed, 228 insertions(+), 162 deletions(-) (limited to 'src') diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl index 318feb3f8..e03b78fe8 100644 --- a/src/ejabberd_oauth.erl +++ b/src/ejabberd_oauth.erl @@ -494,7 +494,7 @@ process(_Handlers, TTL = proplists:get_value(<<"ttl">>, Q, <<"">>), ExpiresIn = case TTL of <<>> -> undefined; - _ -> jlib:binary_to_integer(TTL) + _ -> binary_to_integer(TTL) end, case oauth2:authorize_password({Username, Server}, ClientId, @@ -556,7 +556,7 @@ process(_Handlers, TTL = proplists:get_value(<<"ttl">>, Q, <<"">>), ExpiresIn = case TTL of <<>> -> undefined; - _ -> jlib:binary_to_integer(TTL) + _ -> binary_to_integer(TTL) end, case oauth2:authorize_password({Username, Server}, Scope, diff --git a/src/jlib.erl b/src/jlib.erl index aca3b0ee8..f7dbebd86 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -35,27 +35,33 @@ binary_to_integer/1, integer_to_binary/1]}). +-export([tolower/1, term_to_base64/1, base64_to_term/1, + decode_base64/1, encode_base64/1, ip_to_list/1, + atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, + l2i/1, i2l/1, i2l/2, queue_drop_while/2, + expr_to_term/1, term_to_expr/1]). + +%% The following functions are used by gen_iq_handler.erl for providing backward +%% compatibility and must not be used in other parts of the code +%% Use xmpp:decode() and xmpp:encode() instead +-export([iq_query_info/1, iq_to_xml/1]). + +%% The following functions are deprecated and will be removed soon +%% Use functions from xmpp.erl and xmpp_util.erl instead -export([make_result_iq_reply/1, make_error_reply/3, make_error_reply/2, make_error_element/2, make_correct_from_to_attrs/3, replace_from_to_attrs/3, replace_from_to/3, replace_from_attrs/2, replace_from/2, - remove_attr/2, tolower/1, - get_iq_namespace/1, iq_query_info/1, + remove_attr/2, get_iq_namespace/1, iq_query_or_response_info/1, is_iq_request_type/1, - iq_to_xml/1, parse_xdata_submit/1, - unwrap_carbon/1, is_standalone_chat_state/1, + parse_xdata_submit/1, unwrap_carbon/1, is_standalone_chat_state/1, add_delay_info/3, add_delay_info/4, timestamp_to_legacy/1, timestamp_to_iso_basic/1, timestamp_to_iso/2, now_to_utc_string/1, now_to_local_string/1, datetime_string_to_timestamp/1, - term_to_base64/1, base64_to_term/1, - decode_base64/1, encode_base64/1, ip_to_list/1, rsm_encode/1, rsm_encode/2, rsm_decode/1, binary_to_integer/1, binary_to_integer/2, - integer_to_binary/1, integer_to_binary/2, - atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, - l2i/1, i2l/1, i2l/2, queue_drop_while/2, - expr_to_term/1, term_to_expr/1]). + integer_to_binary/1, integer_to_binary/2]). %% The following functions are deprecated and will be removed soon %% Use corresponding functions from jid.erl instead @@ -75,8 +81,37 @@ {jid_tolower, 1}, {jid_remove_resource, 1}, {jid_replace_resource, 2}, + {add_delay_info, 3}, + {add_delay_info, 4}, + {make_result_iq_reply, 1}, + {make_error_reply, 3}, + {make_error_reply, 2}, + {make_error_element, 2}, + {make_correct_from_to_attrs, 3}, + {replace_from_to_attrs, 3}, + {replace_from_to, 3}, + {replace_from_attrs, 2}, + {replace_from, 2}, + {remove_attr, 2}, + {get_iq_namespace, 1}, + {iq_query_or_response_info, 1}, + {is_iq_request_type, 1}, + {parse_xdata_submit, 1}, + {unwrap_carbon, 1}, + {is_standalone_chat_state, 1}, + {timestamp_to_legacy, 1}, + {timestamp_to_iso_basic, 1}, + {timestamp_to_iso, 2}, + {now_to_utc_string, 1}, + {now_to_local_string, 1}, + {datetime_string_to_timestamp, 1}, + {rsm_encode, 1}, + {rsm_encode, 2}, + {rsm_decode, 1}, + {binary_to_integer, 1}, + {binary_to_integer, 2}, {integer_to_binary, 1}, - {binary_to_integer, 1}]). + {integer_to_binary, 2}]). -include("ejabberd.hrl"). -include("jlib.hrl"). diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 69fffbd7c..2967e86a0 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -761,7 +761,9 @@ set_random_password(User, Server, Reason) -> set_password_auth(User, Server, NewPass). build_random_password(Reason) -> - Date = jlib:timestamp_to_legacy(calendar:universal_time()), + {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:universal_time(), + Date = str:format("~4..0B~2..0B~2..0BT~2..0B:~2..0B:~2..0B", + [Year, Month, Day, Hour, Minute, Second]), RandomString = randoms:get_string(), <<"BANNED_ACCOUNT--", Date/binary, "--", RandomString/binary, "--", Reason/binary>>. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 3d5c8f64d..8c5422f07 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -312,14 +312,14 @@ parse_query(#mam_query{xdata = #xdata{fields = Fs}} = Query, Lang) -> try lists:foldl( fun(#xdata_field{var = <<"start">>, values = [Data|_]}, Q) -> - case jlib:datetime_string_to_timestamp(Data) of - undefined -> throw({error, <<"start">>}); + try xmpp_util:decode_timestamp(Data) of {_, _, _} = TS -> Q#mam_query{start = TS} + catch _:{bad_timestamp, _} -> throw({error, <<"start">>}) end; (#xdata_field{var = <<"end">>, values = [Data|_]}, Q) -> - case jlib:datetime_string_to_timestamp(Data) of - undefined -> throw({error, <<"end">>}); - {_, _, _} = TS -> Q#mam_query{'end' = TS} + try xmpp_util:decode_timestamp(Data) of + {_, _, _} = TS -> Q#mam_query{start = TS} + catch _:{bad_timestamp, _} -> throw({error, <<"end">>}) end; (#xdata_field{var = <<"with">>, values = [Data|_]}, Q) -> case jid:from_string(Data) of diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 8f1f649d2..91ccce559 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -388,7 +388,7 @@ build_info_room({Name, Host, Pid}) -> false -> Last_message1 = queue:last(History), {_, _, _, Ts_last, _} = Last_message1, - jlib:timestamp_to_legacy(Ts_last) + xmpp_util:encode_timestamp(Ts_last) end, {<>, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index dfe3c9e8e..2f6d52c36 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -285,7 +285,7 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID, BareJID = jid:remove_resource(JID), Pid ! dont_ask_offline, {result, lists:map( - fun({Seq, From, _To, _El}) -> + fun({Seq, From, _To, _TS, _El}) -> Node = integer_to_binary(Seq), #disco_item{jid = BareJID, node = Node, @@ -400,10 +400,10 @@ handle_offline_fetch(#jid{luser = U, lserver = S, lresource = R}) -> Pid when is_pid(Pid) -> Pid ! dont_ask_offline, lists:foreach( - fun({Node, From, To, El}) -> + fun({Node, El}) -> NewEl = set_offline_tag(El, Node), - Pid ! {route, From, To, NewEl} - end, read_message_headers(U, S)) + Pid ! {route, xmpp:get_from(El), xmpp:get_to(El), NewEl} + end, read_messages(U, S)) end. -spec fetch_msg_by_node(jid(), binary()) -> error | {ok, #offline_msg{}}. @@ -476,11 +476,13 @@ store_packet(From, To, Packet) -> NewPacket -> TimeStamp = p1_time_compat:timestamp(), Expire = find_x_expire(TimeStamp, NewPacket), - El = xmpp:encode(NewPacket), gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! #offline_msg{us = {LUser, LServer}, - timestamp = TimeStamp, expire = Expire, - from = From, to = To, packet = El}, + timestamp = TimeStamp, + expire = Expire, + from = From, + to = To, + packet = NewPacket}, stop end; _ -> ok @@ -547,10 +549,13 @@ resend_offline_messages(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:pop_messages(LUser, LServer) of {ok, Rs} -> - lists:foreach(fun (R) -> - ejabberd_sm ! offline_msg_to_route(LServer, R) - end, - lists:keysort(#offline_msg.timestamp, Rs)); + lists:foreach( + fun(R) -> + case offline_msg_to_route(LServer, R) of + error -> ok; + RouteMsg -> ejabberd_sm ! RouteMsg + end + end, lists:keysort(#offline_msg.timestamp, Rs)); _ -> ok end. @@ -565,22 +570,26 @@ pop_offline_messages(Ls, User, Server) -> {ok, Rs} -> TS = p1_time_compat:timestamp(), Ls ++ - lists:map(fun (R) -> - offline_msg_to_route(LServer, R) - end, - lists:filter( - fun(#offline_msg{packet = Pkt} = R) -> - Expire = case R#offline_msg.expire of - undefined -> - find_x_expire(TS, Pkt); - Exp -> - Exp - end, - case Expire of - never -> true; - TimeStamp -> TS < TimeStamp - end - end, Rs)); + lists:flatmap( + fun(R) -> + case offline_msg_to_route(LServer, R) of + error -> []; + RouteMsg -> [RouteMsg] + end + end, + lists:filter( + fun(#offline_msg{packet = Pkt} = R) -> + Expire = case R#offline_msg.expire of + undefined -> + find_x_expire(TS, Pkt); + Exp -> + Exp + end, + case Expire of + never -> true; + TimeStamp -> TS < TimeStamp + end + end, Rs)); _ -> Ls end. @@ -625,52 +634,61 @@ webadmin_page(_, Host, webadmin_page(Acc, _, _) -> Acc. get_offline_els(LUser, LServer) -> - Hdrs = read_message_headers(LUser, LServer), - lists:map( - fun({_Seq, From, To, Packet}) -> - xmpp:set_from_to(Packet, From, To) - end, Hdrs). + [Packet || {_Seq, Packet} <- read_messages(LUser, LServer)]. +-spec offline_msg_to_route(binary(), #offline_msg{}) -> + {route, jid(), jid(), message()} | error. offline_msg_to_route(LServer, #offline_msg{} = R) -> - Pkt = xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]), - Pkt1 = case R#offline_msg.timestamp of - undefined -> - Pkt; - TS -> - xmpp_util:add_delay_info(Pkt, jid:make(LServer), TS, - <<"Offline Storage">>) - end, - {route, R#offline_msg.from, R#offline_msg.to, Pkt1}. - -read_message_headers(LUser, LServer) -> + try xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]) of + Pkt -> + NewPkt = add_delay_info(Pkt, LServer, R#offline_msg.timestamp), + {route, R#offline_msg.from, R#offline_msg.to, NewPkt} + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p of user ~s: ~s", + [R#offline_msg.packet, jid:to_string(R#offline_msg.to), + xmpp:format_error(Why)]), + error + end. + +-spec read_messages(binary(), binary()) -> [{binary(), message()}]. +read_messages(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - lists:map( - fun({Seq, From, To, El}) -> + lists:flatmap( + fun({Seq, From, To, TS, El}) -> Node = integer_to_binary(Seq), - Packet = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), - {Node, From, To, Packet} + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of + Pkt -> + Node = integer_to_binary(Seq), + Pkt1 = add_delay_info(Pkt, LServer, TS), + Pkt2 = xmpp:set_from_to(Pkt1, From, To), + [{Node, Pkt2}] + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p " + "of user ~s: ~s", + [El, jid:to_string(To), + xmpp:format_error(Why)]), + [] + end end, Mod:read_message_headers(LUser, LServer)). format_user_queue(Hdrs) -> lists:map( - fun({Seq, From, To, El}) -> + fun({Seq, From, To, TS, El}) -> ID = integer_to_binary(Seq), FPacket = ejabberd_web_admin:pretty_print_xml(El), SFrom = jid:to_string(From), STo = jid:to_string(To), - Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, - {attr, <<"stamp">>}]), - Time = case jlib:datetime_string_to_timestamp(Stamp) of + Time = case TS of + undefined -> + Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, + {attr, <<"stamp">>}]), + try xmpp_util:decode_timestamp(Stamp) of + {_, _, _} = Now -> format_time(Now) + catch _:_ -> + <<"">> + end; {_, _, _} = Now -> - {{Year, Month, Day}, {Hour, Minute, Second}} = - calendar:now_to_local_time(Now), - iolist_to_binary( - io_lib:format( - "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", - [Year, Month, Day, Hour, Minute, - Second])); - _ -> - <<"">> + format_time(Now) end, ?XE(<<"tr">>, [?XAE(<<"td">>, [{<<"class">>, <<"valign">>}], @@ -682,6 +700,11 @@ format_user_queue(Hdrs) -> [?XC(<<"pre">>, FPacket)])]) end, Hdrs). +format_time(Now) -> + {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(Now), + str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + [Year, Month, Day, Hour, Minute, Second]). + user_queue(User, Server, Query, Lang) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -815,6 +838,14 @@ count_offline_messages(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:count_messages(LUser, LServer). +-spec add_delay_info(message(), binary(), + undefined | erlang:timestamp()) -> message(). +add_delay_info(Packet, _LServer, undefined) -> + Packet; +add_delay_info(Packet, LServer, {_, _, _} = TS) -> + xmpp_util:add_delay_info(Packet, jid:make(LServer), TS, + <<"Offline storage">>). + export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index c9f088fa4..9fec9c4d5 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -42,7 +42,11 @@ store_messages(_Host, US, Msgs, Len, MaxOfflineMsgs) -> mnesia:write_lock_table(offline_msg); true -> ok end, - lists:foreach(fun (M) -> mnesia:write(M) end, Msgs) + lists:foreach( + fun(#offline_msg{packet = Pkt} = M) -> + El = xmpp:encode(Pkt), + mnesia:write(M#offline_msg{packet = El}) + end, Msgs) end end, mnesia:transaction(F). @@ -107,9 +111,7 @@ read_message_headers(LUser, LServer) -> fun(#offline_msg{from = From, to = To, packet = Pkt, timestamp = TS}) -> Seq = now_to_integer(TS), - NewPkt = jlib:add_delay_info(Pkt, LServer, TS, - <<"Offline Storage">>), - {Seq, From, To, NewPkt} + {Seq, From, To, TS, Pkt} end, Msgs), lists:keysort(1, Hdrs). diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl index 647f71dfd..241a8d650 100644 --- a/src/mod_offline_riak.erl +++ b/src/mod_offline_riak.erl @@ -36,9 +36,12 @@ store_messages(Host, {User, _}, Msgs, Len, MaxOfflineMsgs) -> try lists:foreach( fun(#offline_msg{us = US, + packet = Pkt, timestamp = TS} = M) -> + El = xmpp:encode(Pkt), ok = ejabberd_riak:put( - M, offline_msg_schema(), + M#offline_msg{packet = El}, + offline_msg_schema(), [{i, TS}, {'2i', [{<<"us">>, US}]}]) end, Msgs), {atomic, ok} @@ -85,9 +88,7 @@ read_message_headers(LUser, LServer) -> fun(#offline_msg{from = From, to = To, packet = Pkt, timestamp = TS}) -> Seq = now_to_integer(TS), - NewPkt = jlib:add_delay_info( - Pkt, LServer, TS, <<"Offline Storage">>), - {Seq, From, To, NewPkt} + {Seq, From, To, Pkt} end, Rs), lists:keysort(1, Hdrs); _Err -> diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 9459753bc..2b7a40bff 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -41,14 +41,14 @@ store_messages(Host, {User, _Server}, Msgs, Len, MaxOfflineMsgs) -> LUser = (M#offline_msg.to)#jid.luser, From = M#offline_msg.from, To = M#offline_msg.to, - Packet = - jlib:replace_from_to(From, To, - M#offline_msg.packet), - NewPacket = - jlib:add_delay_info(Packet, Host, - M#offline_msg.timestamp, - <<"Offline Storage">>), - XML = fxml:element_to_binary(NewPacket), + Packet = xmpp:set_from_to( + M#offline_msg.packet, From, To), + NewPacket = xmpp_util:add_delay_info( + Packet, jid:make(Host), + M#offline_msg.timestamp, + <<"Offline Storage">>), + XML = fxml:element_to_binary( + xmpp:encode(NewPacket)), sql_queries:add_spool_sql(LUser, XML) end, Msgs), @@ -171,15 +171,23 @@ export(_Server) -> [{offline_msg, fun(Host, #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, from = From, to = To, - packet = Packet}) + packet = El}) when LServer == Host -> - Packet1 = jlib:replace_from_to(From, To, Packet), - Packet2 = jlib:add_delay_info(Packet1, LServer, TimeStamp, - <<"Offline Storage">>), - XML = fxml:element_to_binary(Packet2), - [?SQL("delete from spool where username=%(LUser)s;"), - ?SQL("insert into spool(username, xml) values (" - "%(LUser)s, %(XML)s);")]; + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of + Packet -> + Packet1 = xmpp:set_from_to(Packet, From, To), + Packet2 = xmpp_util:add_delay_info( + Packet1, jid:make(LServer), + TimeStamp, <<"Offline Storage">>), + XML = fxml:element_to_binary(xmpp:encode(Packet2)), + [?SQL("delete from spool where username=%(LUser)s;"), + ?SQL("insert into spool(username, xml) values (" + "%(LUser)s, %(XML)s);")] + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p of user ~s@~s: ~s", + [El, LUser, LServer, xmpp:format_error(Why)]), + [] + end; (_Host, _R) -> [] end}]. @@ -188,23 +196,21 @@ import(LServer) -> [{<<"select username, xml from spool;">>, fun([LUser, XML]) -> El = #xmlel{} = fxml_stream:parse_element(XML), - From = #jid{} = jid:from_string( - fxml:get_attr_s(<<"from">>, El#xmlel.attrs)), - To = #jid{} = jid:from_string( - fxml:get_attr_s(<<"to">>, El#xmlel.attrs)), - Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, - {attr, <<"stamp">>}]), - TS = case jlib:datetime_string_to_timestamp(Stamp) of - {_, _, _} = Now -> - Now; - undefined -> - p1_time_compat:timestamp() - end, - Expire = mod_offline:find_x_expire(TS, El#xmlel.children), - #offline_msg{us = {LUser, LServer}, - from = From, to = To, + #message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), + From = Pkt#message.from, + To = case Pkt#message.to of + undefined -> jid:make(LUser, LServer); + JID -> JID + end, + TS = case xmpp:get_subtag(Pkt, #delay{}) of + #delay{stamp = Stamp} -> Stamp; + false -> p1_time_compat:timestamp() + end, + Expire = mod_offline:find_x_expire(TS, Pkt), + #offline_msg{us = {LUser, LServer}, + from = From, to = To, packet = El, - timestamp = TS, expire = Expire} + timestamp = TS, expire = Expire} end}]. import(_, _) -> diff --git a/src/prosody2ejabberd.erl b/src/prosody2ejabberd.erl index d5eca5ecb..fcc472dce 100644 --- a/src/prosody2ejabberd.erl +++ b/src/prosody2ejabberd.erl @@ -300,8 +300,8 @@ convert_privacy_item({_, Item}) -> match_presence_out = MatchPresOut}. el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) -> - case jlib:datetime_string_to_timestamp( - fxml:get_attr_s(<<"stamp">>, Attrs)) of + try xmpp_util:decode_timestamp( + fxml:get_attr_s(<<"stamp">>, Attrs)) of {_, _, _} = TS -> Attrs1 = lists:filter( fun(<<"stamp">>) -> false; @@ -321,8 +321,8 @@ el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) -> packet = Packet}]; _ -> [] - end; - _ -> + end + catch _:{bad_timestamp, _} -> [] end. diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index 69b476539..713d33970 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -132,10 +132,10 @@ integer_to_sql(N) -> iolist_to_binary(integer_to_list(N)). boolean_to_sql(true) -> <<"1">>; boolean_to_sql(false) -> <<"0">>. -timestamp_to_sql(T) -> jlib:now_to_utc_string(T). +timestamp_to_sql(T) -> xmpp_util:encode_timestamp(T). sql_to_integer(N) -> binary_to_integer(N). sql_to_boolean(B) -> B == <<"1">>. -sql_to_timestamp(T) -> jlib:datetime_string_to_timestamp(T). +sql_to_timestamp(T) -> xmpp_util:decode_timestamp(T). diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index de1a363db..f2c962257 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -211,13 +211,11 @@ val_xfield(digest_frequency = Opt, [Val]) -> {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> - case jlib:datetime_string_to_timestamp(Val) of - undefined -> + try xmpp_util:decode_timestamp(Val) + catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; - Timestamp -> - Timestamp + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index 32aa41a93..922b2a418 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -176,13 +176,11 @@ val_xfield(digest_frequency = Opt, [Val]) -> {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> - case jlib:datetime_string_to_timestamp(Val) of - undefined -> + try xmpp_util:decode_timestamp(Val) + catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; - Timestamp -> - Timestamp + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; diff --git a/src/randoms.erl b/src/randoms.erl index 1353f48af..ae477d27d 100644 --- a/src/randoms.erl +++ b/src/randoms.erl @@ -38,7 +38,7 @@ start() -> get_string() -> R = crypto:rand_uniform(0, ?THRESHOLD), - jlib:integer_to_binary(R). + integer_to_binary(R). uniform() -> crypto:rand_uniform(0, ?THRESHOLD)/?THRESHOLD. diff --git a/src/xmpp.erl b/src/xmpp.erl index 0abcda7ee..2c08c2bcd 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -18,7 +18,7 @@ format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3, pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2, - is_known_tag/1, is_known_tag/2]). + is_known_tag/1, is_known_tag/2, append_subtags/2]). %% XMPP errors -export([err_bad_request/0, err_bad_request/2, @@ -369,6 +369,11 @@ has_subtag([El|Els], TagName, XMLNS) -> has_subtag([], _, _) -> false. +-spec append_subtags(stanza(), [xmpp_element() | xmlel()]) -> stanza(). +append_subtags(Stanza, Tags) -> + Els = get_els(Stanza), + set_els(Stanza, Els ++ Tags). + -spec get_text([text()]) -> binary(). get_text([]) -> <<"">>; get_text([#text{data = Data}|_]) -> Data. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 8713365cc..2931baaa4 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -6782,10 +6782,9 @@ dec_jid(Val) -> J -> J end. -enc_utc(Val) -> jlib:now_to_utc_string(Val). +enc_utc(Val) -> xmpp_util:encode_timestamp(Val). -dec_utc(Val) -> - {_, _, _} = jlib:datetime_string_to_timestamp(Val). +dec_utc(Val) -> xmpp_util:decode_timestamp(Val). enc_tzo({H, M}) -> Sign = if H >= 0 -> <<>>; diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 7b3e0e892..a07dae78b 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -27,28 +27,17 @@ add_delay_info(Stz, From, Time) -> erlang:timestamp(), binary()) -> stanza(). add_delay_info(Stz, From, Time, Desc) -> + NewDelay = #delay{stamp = Time, from = From, desc = Desc}, case xmpp:get_subtag(Stz, #delay{}) of - #delay{from = OldFrom, desc = OldDesc} = Delay -> + #delay{from = OldFrom} -> case jid:tolower(From) == jid:tolower(OldFrom) of - true when Desc == <<"">> -> - Stz; - true when OldDesc == <<"">> -> - xmpp:set_subtag(Stz, Delay#delay{desc = Desc}); - true -> - case binary:match(OldDesc, Desc) of - nomatch -> - NewDesc = <>, - xmpp:set_subtag(Stz, Delay#delay{desc = NewDesc}); - _ -> - Stz - end; false -> - NewDelay = #delay{stamp = Time, from = From, desc = Desc}, - xmpp:set_subtag(Stz, NewDelay) + xmpp:set_subtag(Stz, NewDelay); + true -> + xmpp:append_subtags(Stz, [NewDelay]) end; false -> - Delay = #delay{stamp = Time, from = From, desc = Desc}, - xmpp:set_subtag(Stz, Delay) + xmpp:append_subtags(Stz, [NewDelay]) end. -spec unwrap_carbon(stanza()) -> xmpp_element(). @@ -147,10 +136,10 @@ try_decode_timestamp(<>). try_decode_fraction(<<$., T/binary>>) -> - {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], binary}]), - Size = size(V), - <> = T, - {to_integer(binary:part(V, 0, min(6, Size)), 0, 999999), + {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], list}]), + Size = length(V), + <<_:Size/binary, TZD/binary>> = T, + {list_to_integer(string:left(V, 6, $0)), try_decode_tzd(TZD)}; try_decode_fraction(TZD) -> {0, try_decode_tzd(TZD)}. -- cgit v1.2.3 From 21d78ed7f4f4b6ea404fb990d0d9e12be28d7e84 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 10:56:36 +0300 Subject: Don't use jlib.hrl outside of jlib.erl --- src/ejabberd_oauth_rest.erl | 2 +- src/ejabberd_oauth_sql.erl | 2 +- src/node_mb_sql.erl | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ejabberd_oauth_rest.erl b/src/ejabberd_oauth_rest.erl index aadb97084..c932d16f5 100644 --- a/src/ejabberd_oauth_rest.erl +++ b/src/ejabberd_oauth_rest.erl @@ -35,7 +35,7 @@ -include("ejabberd.hrl"). -include("ejabberd_oauth.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("jid.hrl"). init() -> rest:start(?MYNAME), diff --git a/src/ejabberd_oauth_sql.erl b/src/ejabberd_oauth_sql.erl index 9253335ff..3c09362c2 100644 --- a/src/ejabberd_oauth_sql.erl +++ b/src/ejabberd_oauth_sql.erl @@ -36,7 +36,7 @@ -include("ejabberd_oauth.hrl"). -include("ejabberd.hrl"). -include("ejabberd_sql_pt.hrl"). --include("jlib.hrl"). +-include("jid.hrl"). init() -> ok. diff --git a/src/node_mb_sql.erl b/src/node_mb_sql.erl index 125674316..0f5c409ff 100644 --- a/src/node_mb_sql.erl +++ b/src/node_mb_sql.erl @@ -28,7 +28,6 @@ -author('holger@zedat.fu-berlin.de'). -include("pubsub.hrl"). --include("jlib.hrl"). -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, -- cgit v1.2.3 From 7e9f1a6dc19d9230456fdbae355915ba6ec1e656 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 13:41:04 +0300 Subject: Don't auto-decode forwarded payload --- src/mod_carboncopy.erl | 2 +- src/mod_delegation.erl | 20 +++++++++++--------- src/mod_mam.erl | 2 +- src/mod_privilege.erl | 34 +++++++++++++++++++++------------- src/xmpp_codec.erl | 44 ++++++++++++++++---------------------------- src/xmpp_util.erl | 24 ++++++++++++++---------- 6 files changed, 64 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 023e8dc6f..7d8ca5332 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -198,7 +198,7 @@ send_copies(JID, To, Packet, Direction)-> -spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message(). build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) -> - Forwarded = #forwarded{sub_els = [complete_packet(JID, Msg, Direction)]}, + Forwarded = #forwarded{xml_els = [xmpp:encode(complete_packet(JID, Msg, Direction))]}, Carbon = case Direction of sent -> #carbons_sent{forwarded = Forwarded}; received -> #carbons_received{forwarded = Forwarded} diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index 7fec01dcb..ad57bad44 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -217,7 +217,8 @@ process_iq(#iq{to = To, lang = Lang, sub_els = [SubEl]} = IQ, Type) -> Delegations = get_delegations(LServer), case dict:find({NS, Type}, Delegations) of {ok, {Host, _}} -> - Delegation = #delegation{forwarded = #forwarded{sub_els = [IQ]}}, + Delegation = #delegation{ + forwarded = #forwarded{xml_els = [xmpp:encode(IQ)]}}, NewFrom = jid:make(LServer), NewTo = jid:make(Host), ejabberd_local:route_iq( @@ -236,14 +237,15 @@ process_iq(#iq{to = To, lang = Lang, sub_els = [SubEl]} = IQ, Type) -> -spec process_iq_result(iq(), iq()) -> ok. process_iq_result(#iq{from = From, to = To, id = ID, lang = Lang} = IQ, #iq{type = result} = ResIQ) -> - case xmpp:get_subtag(ResIQ, #delegation{}) of - #delegation{ - forwarded = #forwarded{ - sub_els = [#iq{from = To, to = From, - type = Type, id = ID} = Reply]}} - when Type == error; Type == result -> - ejabberd_router:route(From, To, Reply); - _ -> + try + #delegation{forwarded = #forwarded{xml_els = [SubEl]}} = + xmpp:get_subtag(ResIQ, #delegation{}), + case xmpp:decode(SubEl, ?NS_CLIENT, [ignore_els]) of + #iq{from = To, to = From, type = Type, id = ID} = Reply + when Type == error; Type == result -> + ejabberd_router:route(From, To, Reply) + end + catch _:_ -> ?ERROR_MSG("got iq-result with invalid delegated " "payload:~n~s", [xmpp:pp(ResIQ)]), Txt = <<"External component failure">>, diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 8c5422f07..f9ef104bd 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -794,7 +794,7 @@ msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, MsgType, JidRequestor, #jid{lserver = LServer} = JidArchive) -> Pkt2 = maybe_update_from_to(Pkt1, JidRequestor, JidArchive, Peer, MsgType, Nick), - #forwarded{sub_els = [Pkt2], + #forwarded{xml_els = [xmpp:encode(Pkt2)], delay = #delay{stamp = TS, from = jid:make(LServer)}}. maybe_update_from_to(#xmlel{} = El, JidRequestor, JidArchive, Peer, diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl index 50212b7ae..936c237bd 100644 --- a/src/mod_privilege.erl +++ b/src/mod_privilege.erl @@ -257,25 +257,33 @@ get_permissions(ServerHost) -> end. forward_message(From, To, Msg) -> - Host = From#jid.lserver, ServerHost = To#jid.lserver, + Lang = xmpp:get_lang(Msg), case xmpp:get_subtag(Msg, #privilege{}) of - #privilege{forwarded = #forwarded{sub_els = [#message{} = SubEl]}} -> - case SubEl#message.from of - #jid{lresource = <<"">>, lserver = ServerHost} -> - ejabberd_router:route( - xmpp:get_from(SubEl), xmpp:get_to(SubEl), SubEl); + #privilege{forwarded = #forwarded{xml_els = [SubEl]}} -> + try xmpp:decode(SubEl, ?NS_CLIENT, [ignore_els]) of + #message{} = NewMsg -> + case NewMsg#message.from of + #jid{lresource = <<"">>, lserver = ServerHost} -> + ejabberd_router:route( + xmpp:get_from(NewMsg), xmpp:get_to(NewMsg), NewMsg); + _ -> + Lang = xmpp:get_lang(Msg), + Txt = <<"Invalid 'from' attribute in forwarded message">>, + Err = xmpp:err_forbidden(Txt, Lang), + ejabberd_router:route_error(To, From, Msg, Err) + end; _ -> - Lang = xmpp:get_lang(Msg), - Txt = <<"Invalid 'from' attribute">>, - Err = xmpp:err_forbidden(Txt, Lang), + Txt = <<"Message not found in forwarded payload">>, + Err = xmpp:err_bad_request(Txt, Lang), + ejabberd_router:route_error(To, From, Msg, Err) + catch _:{xmpp_codec, Why} -> + Txt = xmpp:format_error(Why), + Err = xmpp:err_bad_request(Txt, Lang), ejabberd_router:route_error(To, From, Msg, Err) end; _ -> - ?ERROR_MSG("got invalid forwarded payload from external " - "component '~s':~n~s", [Host, xmpp:pp(Msg)]), - Lang = xmpp:get_lang(Msg), - Txt = <<"Invalid forwarded payload">>, + Txt = <<"Invalid element">>, Err = xmpp:err_bad_request(Txt, Lang), ejabberd_router:route_error(To, From, Msg, Err) end. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 2931baaa4..6089f79fc 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -6639,7 +6639,7 @@ 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, 5) -> [xmlns, id, rsm, stable, complete]; -pp(forwarded, 2) -> [delay, sub_els]; +pp(forwarded, 2) -> [delay, xml_els]; pp(carbons_disable, 0) -> []; pp(carbons_enable, 0) -> []; pp(carbons_private, 0) -> []; @@ -11966,53 +11966,41 @@ encode_carbons_disable({carbons_disable}, __TopXMLNS) -> decode_forwarded(__TopXMLNS, __IgnoreEls, {xmlel, <<"forwarded">>, _attrs, _els}) -> - {Delay, __Els} = decode_forwarded_els(__TopXMLNS, - __IgnoreEls, _els, undefined, []), - {forwarded, Delay, __Els}. + {Delay, __Xmls} = decode_forwarded_els(__TopXMLNS, + __IgnoreEls, _els, undefined, []), + {forwarded, Delay, __Xmls}. decode_forwarded_els(__TopXMLNS, __IgnoreEls, [], Delay, - __Els) -> - {Delay, lists:reverse(__Els)}; + __Xmls) -> + {Delay, lists:reverse(__Xmls)}; decode_forwarded_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"delay">>, _attrs, _} = _el | _els], Delay, - __Els) -> + __Xmls) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:xmpp:delay">> -> decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, decode_delay(<<"urn:xmpp:delay">>, __IgnoreEls, _el), - __Els); + __Xmls); _ -> decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, __Els) + Delay, __Xmls) end; decode_forwarded_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Delay, __Els) -> - if __IgnoreEls -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, __Els) - end - end; + [{xmlel, _, _, _} = _el | _els], Delay, __Xmls) -> + decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, + Delay, [_el | __Xmls]); decode_forwarded_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Delay, __Els) -> + [_ | _els], Delay, __Xmls) -> decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, __Els). + Delay, __Xmls). -encode_forwarded({forwarded, Delay, __Els}, +encode_forwarded({forwarded, Delay, __Xmls}, __TopXMLNS) -> __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:forward:0">>, [], __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ + _els = __Xmls ++ lists:reverse('encode_forwarded_$delay'(Delay, __NewTopXMLNS, [])), _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index a07dae78b..57440b50e 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -42,16 +42,20 @@ add_delay_info(Stz, From, Time, Desc) -> -spec unwrap_carbon(stanza()) -> xmpp_element(). unwrap_carbon(#message{} = Msg) -> - case xmpp:get_subtag(Msg, #carbons_sent{}) of - #carbons_sent{forwarded = #forwarded{sub_els = [El]}} -> - El; - _ -> - case xmpp:get_subtag(Msg, #carbons_received{}) of - #carbons_received{forwarded = #forwarded{sub_els = [El]}} -> - El; - _ -> - Msg - end + try + case xmpp:get_subtag(Msg, #carbons_sent{}) of + #carbons_sent{forwarded = #forwarded{xml_els = [El]}} -> + xmpp:decode(El, ?NS_CLIENT, [ignore_els]); + _ -> + case xmpp:get_subtag(Msg, #carbons_received{}) of + #carbons_received{forwarded = #forwarded{xml_els = [El]}} -> + xmpp:decode(El, ?NS_CLIENT, [ignore_els]); + _ -> + Msg + end + end + catch _:{xmpp_codec, _} -> + Msg end; unwrap_carbon(Stanza) -> Stanza. -- cgit v1.2.3 From ebefd0d8d6bd0162f0067f85e565afde83a962ca Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 14:17:21 +0300 Subject: Add more control for decoding IQ payloads --- src/ejabberd_local.erl | 8 +------- src/gen_iq_handler.erl | 8 +++----- src/mod_delegation.erl | 8 +++++++- src/mod_vcard.erl | 10 +++++++++- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 210575e5e..d7849396b 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -96,13 +96,7 @@ process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> Err = xmpp:make_error(Packet, xmpp:err_bad_request()), ejabberd_router:route(To, From, Err); process_iq(From, To, #iq{type = T} = Packet) when T == result; T == error -> - try - NewPacket = xmpp:decode_els(Packet), - process_iq_reply(From, To, NewPacket) - catch _:{xmpp_codec, Why} -> - ?DEBUG("failed to decode iq-result ~p: ~s", - [Packet, xmpp:format_error(Why)]) - end. + process_iq_reply(From, To, Packet). -spec process_iq_reply(jid(), jid(), iq()) -> any(). process_iq_reply(From, To, #iq{id = ID} = IQ) -> diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index 8af2cb028..bcbda1d1e 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -153,11 +153,9 @@ process_iq(_Host, Module, Function, From, To, IQ0) -> -spec process_iq(module(), atom(), iq()) -> ignore | iq(). process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) -> try - %% TODO: move this 'conditional' decoding somewhere - %% IQ handler should know *nothing* about vCards. - Pkt = case xmpp:get_ns(El) of - ?NS_VCARD when Module == mod_vcard -> El; - _ -> xmpp:decode(El) + Pkt = case erlang:function_exported(Module, decode_iq_subel, 1) of + true -> Module:decode_iq_subel(El); + false -> xmpp:decode(El) end, Module:Function(IQ#iq{sub_els = [Pkt]}) catch error:{xmpp_codec, Why} -> diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index ad57bad44..56908d9d1 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -18,7 +18,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([component_connected/1, component_disconnected/2, - ejabberd_local/1, ejabberd_sm/1, + ejabberd_local/1, ejabberd_sm/1, decode_iq_subel/1, disco_local_features/5, disco_sm_features/5, disco_local_identity/5, disco_sm_identity/5]). @@ -56,6 +56,12 @@ mod_opt_type(_) -> depends(_, _) -> []. +-spec decode_iq_subel(xmpp_element()) -> xmpp_element(); + (xmlel()) -> xmlel(). +%% Tell gen_iq_handler not to auto-decode IQ payload +decode_iq_subel(El) -> + El. + -spec component_connected(binary()) -> ok. component_connected(Host) -> lists:foreach( diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 8333d32cf..35b907f95 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -37,7 +37,7 @@ remove_user/2, export/1, import/1, import/3, depends/2, process_search/1, process_vcard/1, get_vcard/2, disco_items/5, disco_features/5, disco_identity/5, - mod_opt_type/1, set_vcard/3, make_vcard_search/4]). + decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -167,6 +167,14 @@ get_sm_features(Acc, _From, _To, Node, _Lang) -> _ -> Acc end. +-spec decode_iq_subel(xmpp_element() | xmlel()) -> xmpp_element() | xmlel(). +%% Tell gen_iq_handler not to decode vcard elements +decode_iq_subel(El) -> + case xmpp:get_ns(El) of + ?NS_VCARD -> xmpp:encode(El); + _ -> xmpp:decode(El) + end. + -spec process_local_iq(iq()) -> iq(). process_local_iq(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, -- cgit v1.2.3 From 13d5da4da6f02b9fc6816083a5b1f615ad45e023 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 16:46:04 +0300 Subject: Add some copyright notices --- src/mod_delegation.erl | 29 ++++++++++++++++++++++++----- src/mod_privilege.erl | 29 ++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index 56908d9d1..5f9fafc45 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -1,13 +1,32 @@ %%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc +%%% File : mod_delegation.erl +%%% Author : Anna Mukharram +%%% Purpose : XEP-0355: Namespace Delegation +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% -%%% @end -%%% Created : 10 Nov 2016 by Evgeny Khramtsov %%%------------------------------------------------------------------- -module(mod_delegation). +-author('amuhar3@gmail.com'). + +-protocol({xep, 0355, '0.3'}). + -behaviour(gen_server). -behaviour(gen_mod). diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl index 936c237bd..c1ac5a3fc 100644 --- a/src/mod_privilege.erl +++ b/src/mod_privilege.erl @@ -1,13 +1,32 @@ %%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc +%%% File : mod_privilege.erl +%%% Author : Anna Mukharram +%%% Purpose : XEP-0356: Privileged Entity +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% -%%% @end -%%% Created : 11 Nov 2016 by Evgeny Khramtsov %%%------------------------------------------------------------------- -module(mod_privilege). +-author('amuhar3@gmail.com'). + +-protocol({xep, 0356, '0.2.1'}). + -behaviour(gen_server). -behaviour(gen_mod). -- cgit v1.2.3 From 3765210698dd55d9996e671bb9874c48f12f37e0 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 16:56:05 +0300 Subject: Fix IQ result processing --- src/mod_delegation.erl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index 5f9fafc45..571817963 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -268,7 +268,7 @@ process_iq_result(#iq{from = From, to = To, id = ID, lang = Lang} = IQ, case xmpp:decode(SubEl, ?NS_CLIENT, [ignore_els]) of #iq{from = To, to = From, type = Type, id = ID} = Reply when Type == error; Type == result -> - ejabberd_router:route(From, To, Reply) + ejabberd_router:route(To, From, Reply) end catch _:_ -> ?ERROR_MSG("got iq-result with invalid delegated " @@ -294,9 +294,17 @@ send_disco_queries(LServer, Host, NS) -> ejabberd_local:route_iq( From, To, #iq{type = get, from = From, to = To, sub_els = [#disco_info{node = Node}]}, - fun(#iq{type = result, sub_els = [#disco_info{} = Info]}) -> - Proc = gen_mod:get_module_proc(LServer, ?MODULE), - gen_server:cast(Proc, {disco_info, Type, Host, NS, Info}); + fun(#iq{type = result, sub_els = [SubEl]}) -> + try xmpp:decode(SubEl) of + #disco_info{} = Info-> + Proc = gen_mod:get_module_proc(LServer, ?MODULE), + gen_server:cast( + Proc, {disco_info, Type, Host, NS, Info}); + _ -> + ok + catch _:{xmpp_codec, _} -> + ok + end; (_) -> ok end) -- cgit v1.2.3 From 309962fb8b70dc42dbfcc98b4e64bd251aad84b9 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Mon, 14 Nov 2016 16:52:03 +0100 Subject: Use p1_http from p1_utils 1.0.6 --- src/ejabberd_app.erl | 1 - src/ext_mod.erl | 4 +- src/http_p1.erl | 358 ----------------------------------------------- src/mod_ip_blacklist.erl | 4 +- src/rest.erl | 6 +- 5 files changed, 7 insertions(+), 366 deletions(-) delete mode 100644 src/http_p1.erl (limited to 'src') diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index e88f24e1e..1791aa790 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -225,7 +225,6 @@ start_apps() -> ejabberd:start_app(fast_tls), ejabberd:start_app(fast_xml), ejabberd:start_app(stringprep), - http_p1:start(), ejabberd:start_app(cache_tab). opt_type(net_ticktime) -> diff --git a/src/ext_mod.erl b/src/ext_mod.erl index 842bb09fc..2f71343a2 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -45,7 +45,7 @@ start() -> [code:add_patha(module_ebin_dir(Module)) || {Module, _} <- installed()], - application:start(inets), + p1_http:start(), ejabberd_commands:register_commands(get_commands_spec()). stop() -> @@ -271,7 +271,7 @@ geturl(Url, Hdrs, UsrOpts) -> [U, Pass] -> [{proxy_user, U}, {proxy_password, Pass}]; _ -> [] end, - case httpc:request(get, {Url, Hdrs}, Host++User++UsrOpts++[{version, "HTTP/1.0"}], []) of + case p1_http:request(get, Url, Hdrs, [], Host++User++UsrOpts++[{version, "HTTP/1.0"}]) of {ok, {{_, 200, _}, Headers, Response}} -> {ok, Headers, Response}; {ok, {{_, Code, _}, _Headers, Response}} -> diff --git a/src/http_p1.erl b/src/http_p1.erl deleted file mode 100644 index f430bbe11..000000000 --- a/src/http_p1.erl +++ /dev/null @@ -1,358 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : http_p1.erl -%%% Author : Emilio Bustos -%%% Purpose : Provide a common API for inets / lhttpc / ibrowse -%%% Created : 29 Jul 2010 by Emilio Bustos -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%---------------------------------------------------------------------- - --module(http_p1). - --author('ebustos@process-one.net'). - --export([start/0, stop/0, get/1, get/2, post/2, post/3, - request/3, request/4, request/5, - get_pool_size/0, set_pool_size/1]). - --include("logger.hrl"). - --define(USE_INETS, 1). -% -define(USE_LHTTPC, 1). -% -define(USE_IBROWSE, 1). -% inets used as default if none specified - --ifdef(USE_IBROWSE). - -start() -> - ejabberd:start_app(ibrowse). - -stop() -> - application:stop(ibrowse). - -request(Method, URL, Hdrs, Body, Opts) -> - TimeOut = proplists:get_value(timeout, Opts, infinity), - Options = [{inactivity_timeout, TimeOut} - | proplists:delete(timeout, Opts)], - case ibrowse:send_req(URL, Hdrs, Method, Body, Options) - of - {ok, Status, Headers, Response} -> - {ok, jlib:binary_to_integer(Status), Headers, - Response}; - {error, Reason} -> {error, Reason} - end. - -get_pool_size() -> - application:get_env(ibrowse, default_max_sessions, 10). - -set_pool_size(Size) -> - application:set_env(ibrowse, default_max_sessions, Size). - --else. - --ifdef(USE_LHTTPC). - -start() -> - ejabberd:start_app(lhttpc). - -stop() -> - application:stop(lhttpc). - -request(Method, URL, Hdrs, Body, Opts) -> - {[TO, SO], Rest} = proplists:split(Opts, [timeout, socket_options]), - TimeOut = proplists:get_value(timeout, TO, infinity), - SockOpt = proplists:get_value(socket_options, SO, []), - Options = [{connect_options, SockOpt} | Rest], - Result = lhttpc:request(URL, Method, Hdrs, Body, TimeOut, Options), - ?DEBUG("HTTP request -> response:~n" - "** Method = ~p~n" - "** URI = ~s~n" - "** Body = ~s~n" - "** Hdrs = ~p~n" - "** Timeout = ~p~n" - "** Options = ~p~n" - "** Response = ~p", - [Method, URL, Body, Hdrs, TimeOut, Options, Result]), - case Result of - {ok, {{Status, _Reason}, Headers, Response}} -> - {ok, Status, Headers, (Response)}; - {error, Reason} -> {error, Reason} - end. - -get_pool_size() -> - Opts = proplists:get_value(lhttpc_manager, lhttpc_manager:list_pools()), - proplists:get_value(max_pool_size,Opts). - -set_pool_size(Size) -> - lhttpc_manager:set_max_pool_size(lhttpc_manager, Size). - --else. - -start() -> - ejabberd:start_app(inets). - -stop() -> - application:stop(inets). - -to_list(Str) when is_binary(Str) -> - binary_to_list(Str); -to_list(Str) -> - Str. - -request(Method, URLRaw, HdrsRaw, Body, Opts) -> - Hdrs = lists:map(fun({N, V}) -> - {to_list(N), to_list(V)} - end, HdrsRaw), - URL = to_list(URLRaw), - - Request = case Method of - get -> {URL, Hdrs}; - head -> {URL, Hdrs}; - delete -> {URL, Hdrs}; - _ -> % post, etc. - {URL, Hdrs, - to_list(proplists:get_value(<<"content-type">>, HdrsRaw, [])), - Body} - end, - Options = case proplists:get_value(timeout, Opts, - infinity) - of - infinity -> proplists:delete(timeout, Opts); - _ -> Opts - end, - case httpc:request(Method, Request, Options, []) of - {ok, {{_, Status, _}, Headers, Response}} -> - {ok, Status, Headers, Response}; - {error, Reason} -> {error, Reason} - end. - -get_pool_size() -> - {ok, Size} = httpc:get_option(max_sessions), - Size. - -set_pool_size(Size) -> - httpc:set_option(max_sessions, Size). - --endif. - --endif. - --type({header, - {type, 63, tuple, - [{type, 63, union, - [{type, 63, string, []}, {type, 63, atom, []}]}, - {type, 63, string, []}]}, - []}). - --type({headers, - {type, 64, list, [{type, 64, header, []}]}, []}). - --type({option, - {type, 67, union, - [{type, 67, tuple, - [{atom, 67, connect_timeout}, {type, 67, timeout, []}]}, - {type, 68, tuple, - [{atom, 68, timeout}, {type, 68, timeout, []}]}, - {type, 70, tuple, - [{atom, 70, send_retry}, - {type, 70, non_neg_integer, []}]}, - {type, 71, tuple, - [{atom, 71, partial_upload}, - {type, 71, union, - [{type, 71, non_neg_integer, []}, - {atom, 71, infinity}]}]}, - {type, 72, tuple, - [{atom, 72, partial_download}, {type, 72, pid, []}, - {type, 72, union, - [{type, 72, non_neg_integer, []}, - {atom, 72, infinity}]}]}]}, - []}). - --type({options, - {type, 74, list, [{type, 74, option, []}]}, []}). - --type({result, - {type, 76, union, - [{type, 76, tuple, - [{atom, 76, ok}, - {type, 76, tuple, - [{type, 76, tuple, - [{type, 76, pos_integer, []}, {type, 76, string, []}]}, - {type, 76, headers, []}, {type, 76, string, []}]}]}, - {type, 77, tuple, - [{atom, 77, error}, {type, 77, atom, []}]}]}, - []}). - -%% @spec (URL) -> Result -%% URL = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a GET request. -%% Would be the same as calling `request(get, URL, [])', -%% that is {@link request/3} with an empty header list. -%% @end -%% @see request/3 --spec get(string()) -> result(). -get(URL) -> request(get, URL, []). - -%% @spec (URL, Hdrs) -> Result -%% URL = string() -%% Hdrs = [{Header, Value}] -%% Header = string() -%% Value = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a GET request. -%% Would be the same as calling `request(get, URL, Hdrs)'. -%% @end -%% @see request/3 --spec get(string(), headers()) -> result(). -get(URL, Hdrs) -> request(get, URL, Hdrs). - -%% @spec (URL, RequestBody) -> Result -%% URL = string() -%% RequestBody = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a POST request with form data. -%% Would be the same as calling -%% `request(post, URL, [{"content-type", "x-www-form-urlencoded"}], Body)'. -%% @end -%% @see request/4 --spec post(string(), string()) -> result(). -post(URL, Body) -> - request(post, URL, - [{<<"content-type">>, <<"x-www-form-urlencoded">>}], - Body). - -%% @spec (URL, Hdrs, RequestBody) -> Result -%% URL = string() -%% Hdrs = [{Header, Value}] -%% Header = string() -%% Value = string() -%% RequestBody = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a POST request. -%% Would be the same as calling -%% `request(post, URL, Hdrs, Body)'. -%% @end -%% @see request/4 --spec post(string(), headers(), string()) -> result(). -post(URL, Hdrs, Body) -> - NewHdrs = case [X - || {X, _} <- Hdrs, - str:to_lower(X) == <<"content-type">>] - of - [] -> - [{<<"content-type">>, <<"x-www-form-urlencoded">>} - | Hdrs]; - _ -> Hdrs - end, - request(post, URL, NewHdrs, Body). - -%% @spec (Method, URL, Hdrs) -> Result -%% Method = atom() -%% URL = string() -%% Hdrs = [{Header, Value}] -%% Header = string() -%% Value = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a request without a body. -%% Would be the same as calling `request(Method, URL, Hdrs, [], [])', -%% that is {@link request/5} with an empty body. -%% @end -%% @see request/5 --spec request(atom(), string(), headers()) -> result(). -request(Method, URL, Hdrs) -> - request(Method, URL, Hdrs, [], []). - -%% @spec (Method, URL, Hdrs, RequestBody) -> Result -%% Method = atom() -%% URL = string() -%% Hdrs = [{Header, Value}] -%% Header = string() -%% Value = string() -%% RequestBody = string() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a request with a body. -%% Would be the same as calling -%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5} -%% with no options. -%% @end -%% @see request/5 --spec request(atom(), string(), headers(), string()) -> result(). -request(Method, URL, Hdrs, Body) -> - request(Method, URL, Hdrs, Body, []). - -%% @spec (Method, URL, Hdrs, RequestBody, Options) -> Result -%% Method = atom() -%% URL = string() -%% Hdrs = [{Header, Value}] -%% Header = string() -%% Value = string() -%% RequestBody = string() -%% Options = [Option] -%% Option = {timeout, Milliseconds | infinity} | -%% {connect_timeout, Milliseconds | infinity} | -%% {socket_options, [term()]} | - -%% Milliseconds = integer() -%% Result = {ok, StatusCode, Hdrs, ResponseBody} -%% | {error, Reason} -%% StatusCode = integer() -%% ResponseBody = string() -%% Reason = connection_closed | connect_timeout | timeout -%% @doc Sends a request with a body. -%% Would be the same as calling -%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5} -%% with no options. -%% @end -%% @see request/5 --spec request(atom(), string(), headers(), string(), options()) -> result(). - -% ibrowse {response_format, response_format()} | -% Options - [option()] -% Option - {sync, boolean()} | {stream, StreamTo} | {body_format, body_format()} | {full_result, -% boolean()} | {headers_as_is, boolean()} -%body_format() = string() | binary() -% The body_format option is only valid for the synchronous request and the default is string. -% When making an asynchronous request the body will always be received as a binary. -% lhttpc: always binary - diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl index 897810927..ab17a8891 100644 --- a/src/mod_ip_blacklist.erl +++ b/src/mod_ip_blacklist.erl @@ -89,9 +89,9 @@ loop(_State) -> receive stop -> ok end. %% TODO: Support comment lines starting by % update_bl_c2s() -> ?INFO_MSG("Updating C2S Blacklist", []), - case httpc:request(?BLC2S) of + case p1_http:get(?BLC2S) of {ok, 200, _Headers, Body} -> - IPs = str:tokens(Body, <<"\n">>), + IPs = str:tokens(iolist_to_binary(Body), <<"\n">>), ets:delete_all_objects(bl_c2s), lists:foreach(fun (IP) -> ets:insert(bl_c2s, diff --git a/src/rest.erl b/src/rest.erl index 01b04f66a..e5c6fd963 100644 --- a/src/rest.erl +++ b/src/rest.erl @@ -36,14 +36,14 @@ -define(CONNECT_TIMEOUT, 8000). start(Host) -> - http_p1:start(), + p1_http:start(), Pool_size = ejabberd_config:get_option({ext_api_http_pool_size, Host}, fun(X) when is_integer(X), X > 0-> X end, 100), - http_p1:set_pool_size(Pool_size). + p1_http:set_pool_size(Pool_size). stop(_Host) -> ok. @@ -91,7 +91,7 @@ request(Server, Method, Path, Params, Mime, Data) -> {"content-type", Mime}, {"User-Agent", "ejabberd"}], Begin = os:timestamp(), - Result = case catch http_p1:request(Method, URI, Hdrs, Data, Opts) of + Result = case catch p1_http:request(Method, URI, Hdrs, Data, Opts) of {ok, Code, _, <<>>} -> {ok, Code, []}; {ok, Code, _, <<" ">>} -> -- cgit v1.2.3 From 717159a98fe925260578aeedd4436eb6ae5df4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Thu, 10 Nov 2016 11:15:34 +0100 Subject: Make string args in http_api be list strings --- src/mod_http_api.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 881587ede..a189777b1 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -273,7 +273,7 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) -> fun ({Key, binary}, Acc) -> [{Key, <<>>}|Acc]; ({Key, string}, Acc) -> - [{Key, <<>>}|Acc]; + [{Key, ""}|Acc]; ({Key, integer}, Acc) -> [{Key, 0}|Acc]; ({Key, {list, _}}, Acc) -> @@ -406,10 +406,10 @@ format_arg(Elements, {list, ElementsDef}) format_arg(Arg, integer) when is_integer(Arg) -> Arg; format_arg(Arg, binary) when is_list(Arg) -> process_unicode_codepoints(Arg); format_arg(Arg, binary) when is_binary(Arg) -> Arg; -format_arg(Arg, string) when is_list(Arg) -> process_unicode_codepoints(Arg); -format_arg(Arg, string) when is_binary(Arg) -> Arg; +format_arg(Arg, string) when is_list(Arg) -> Arg; +format_arg(Arg, string) when is_binary(Arg) -> binary_to_list(Arg); format_arg(undefined, binary) -> <<>>; -format_arg(undefined, string) -> <<>>; +format_arg(undefined, string) -> ""; format_arg(Arg, Format) -> ?ERROR_MSG("don't know how to format Arg ~p for format ~p", [Arg, Format]), throw({invalid_parameter, -- cgit v1.2.3 From 5ffc01db5301fddae639701479f5c19ed2267723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Thu, 10 Nov 2016 11:20:57 +0100 Subject: Fix types in check_password_hash --- src/mod_admin_extra.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 2967e86a0..053ce8092 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -176,8 +176,8 @@ get_commands_spec() -> desc = "Check if the password hash is correct", longdesc = "Allowed hash methods: md5, sha.", module = ?MODULE, function = check_password_hash, - args = [{user, binary}, {host, binary}, {passwordhash, string}, - {hashmethod, string}], + args = [{user, binary}, {host, binary}, {passwordhash, binary}, + {hashmethod, binary}], args_example = [<<"peter">>, <<"myserver.com">>, <<"5ebe2294ecd0e0f08eab7690d2a6ee69">>, <<"md5">>], args_desc = ["User name to check", "Server to check", -- cgit v1.2.3 From 2b93de691248629d75e1d2657d09ebd990670924 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Mon, 16 Jun 2014 19:49:08 +0200 Subject: apply string optimizations --- src/str.erl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/str.erl b/src/str.erl index 439ae6a7a..43fd51878 100644 --- a/src/str.erl +++ b/src/str.erl @@ -93,7 +93,10 @@ rchr(B, C) -> -spec str(binary(), binary()) -> non_neg_integer(). str(B1, B2) -> - string:str(binary_to_list(B1), binary_to_list(B2)). + case binary:match(B1, B2) of + {R, _Len} -> R+1; + _ -> 0 + end. -spec rstr(binary(), binary()) -> non_neg_integer(). @@ -113,7 +116,7 @@ cspan(B1, B2) -> -spec copies(binary(), non_neg_integer()) -> binary(). copies(B, N) -> - iolist_to_binary(string:copies(binary_to_list(B), N)). + binary:copy(B, N). -spec words(binary()) -> pos_integer(). @@ -201,7 +204,7 @@ join(L, Sep) -> -spec substr(binary(), pos_integer()) -> binary(). substr(B, N) -> - iolist_to_binary(string:substr(binary_to_list(B), N)). + binary_part(B, N-1, byte_size(B)-N+1). -spec chr(binary(), char()) -> non_neg_integer(). @@ -221,7 +224,7 @@ chars(C, N) -> -spec substr(binary(), pos_integer(), non_neg_integer()) -> binary(). substr(B, S, E) -> - iolist_to_binary(string:substr(binary_to_list(B), S, E)). + binary_part(B, S-1, E). -spec strip(binary(), both | left | right, char()) -> binary(). -- cgit v1.2.3 From 8df68266f2e0bf4cb0d1d51ec8a8372affadc8e5 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 9 Aug 2016 10:53:58 +0200 Subject: Add missing verbs for RESTfull operation --- src/rest.erl | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/rest.erl b/src/rest.erl index e5c6fd963..091002fa5 100644 --- a/src/rest.erl +++ b/src/rest.erl @@ -28,7 +28,7 @@ -behaviour(ejabberd_config). -export([start/1, stop/1, get/2, get/3, post/4, delete/2, - request/6, with_retry/4, opt_type/1]). + put/4, patch/4, request/6, with_retry/4, opt_type/1]). -include("logger.hrl"). @@ -71,18 +71,17 @@ delete(Server, Path) -> request(Server, delete, Path, [], "application/json", <<>>). post(Server, Path, Params, Content) -> - Data = case catch jiffy:encode(Content) of - {'EXIT', Reason} -> - ?ERROR_MSG("HTTP content encodage failed:~n" - "** Content = ~p~n" - "** Err = ~p", - [Content, Reason]), - <<>>; - Encoded -> - Encoded - end, + Data = encode_json(Content), request(Server, post, Path, Params, "application/json", Data). +put(Server, Path, Params, Content) -> + Data = encode_json(Content), + request(Server, put, Path, Params, "application/json", Data). + +patch(Server, Path, Params, Content) -> + Data = encode_json(Content), + request(Server, patch, Path, Params, "application/json", Data). + request(Server, Method, Path, Params, Mime, Data) -> URI = url(Server, Path, Params), Opts = [{connect_timeout, ?CONNECT_TIMEOUT}, @@ -147,6 +146,18 @@ request(Server, Method, Path, Params, Mime, Data) -> %%% HTTP helpers %%%---------------------------------------------------------------------- +encode_json(Content) -> + case catch jiffy:encode(Content) of + {'EXIT', Reason} -> + ?ERROR_MSG("HTTP content encodage failed:~n" + "** Content = ~p~n" + "** Err = ~p", + [Content, Reason]), + <<>>; + Encoded -> + Encoded + end. + base_url(Server, Path) -> Tail = case iolist_to_binary(Path) of <<$/, Ok/binary>> -> Ok; -- cgit v1.2.3 From 4d4ad922a2deaf576bece4389b0ba04cfd1cfe04 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 15 Nov 2016 18:14:21 +0100 Subject: Cosmetic validator changes --- src/mod_proxy65.erl | 6 ++---- src/mod_register.erl | 9 +++------ 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index beea35725..2d0d9ae0a 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -93,12 +93,10 @@ mod_opt_type(auth_type) -> end; mod_opt_type(recbuf) -> fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(shaper) -> - fun (A) when is_atom(A) -> A end; +mod_opt_type(shaper) -> fun acl:shaper_rules_validator/1; mod_opt_type(sndbuf) -> fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(access) -> - fun (A) when is_atom(A) -> A end; +mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hostname) -> fun iolist_to_binary/1; mod_opt_type(ip) -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 44a64539e..dc8ca995c 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -613,14 +613,11 @@ check_ip_access(undefined, _IPAccess) -> check_ip_access(IPAddress, IPAccess) -> acl:match_rule(global, IPAccess, IPAddress). -mod_opt_type(access) -> - fun acl:access_rules_validator/1; -mod_opt_type(access_from) -> - fun (A) when is_atom(A) -> A end; +mod_opt_type(access) -> fun acl:access_rules_validator/1; +mod_opt_type(access_from) -> fun acl:access_rules_validator/1; mod_opt_type(captcha_protected) -> fun (B) when is_boolean(B) -> B end; -mod_opt_type(ip_access) -> - fun acl:access_rules_validator/1; +mod_opt_type(ip_access) -> fun acl:access_rules_validator/1; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(password_strength) -> fun (N) when is_number(N), N >= 0 -> N end; -- cgit v1.2.3 From 2929f5b5bcd27ef825743e2f9db5b1ea122d1a5c Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 15 Nov 2016 18:35:20 +0100 Subject: Minor cosmetic changes on pubsub code --- src/mod_pubsub.erl | 7 +++---- src/node_flat.erl | 2 +- src/node_flat_sql.erl | 2 +- src/pubsub_subscription.erl | 4 ++-- src/pubsub_subscription_sql.erl | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index a586935b8..a138b1896 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -251,7 +251,7 @@ init([ServerHost, Opts]) -> Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), ejabberd_router:register_route(Host, ServerHost), Access = gen_mod:get_opt(access_createnode, Opts, - fun(A) when is_atom(A) -> A end, all), + fun acl:access_rules_validator/1, all), PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, fun(A) when is_boolean(A) -> A end, true), IQDisc = gen_mod:get_opt(iqdisc, Opts, @@ -262,7 +262,7 @@ init([ServerHost, Opts]) -> fun(A) when is_integer(A) andalso A >= 0 -> A end, ?MAXITEMS), MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts, fun(A) when is_integer(A) andalso A >= 0 -> A end, undefined), - pubsub_index:init(Host, ServerHost, Opts), + [pubsub_index:init(Host, ServerHost, Opts) || gen_mod:db_type(ServerHost, ?MODULE)==mnesia], {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), DefaultModule = plugin(Host, hd(Plugins)), BaseOptions = DefaultModule:options(), @@ -3899,8 +3899,7 @@ purge_offline(Host, LJID, Node) -> Error end. -mod_opt_type(access_createnode) -> - fun (A) when is_atom(A) -> A end; +mod_opt_type(access_createnode) -> fun acl:access_rules_validator/1; mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(ignore_pep_from_offline) -> diff --git a/src/node_flat.erl b/src/node_flat.erl index 3afa49f22..9c1bc9b98 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -50,7 +50,7 @@ path_to_node/1, can_fetch_item/2, is_subscribed/1]). init(_Host, _ServerHost, _Opts) -> - %pubsub_subscription:init(), + %pubsub_subscription:init(Host, ServerHost, Opts), mnesia:create_table(pubsub_state, [{disc_copies, [node()]}, {type, ordered_set}, diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index 5adf1e559..7e5ce788f 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -61,7 +61,7 @@ encode_host_like/1]). init(_Host, _ServerHost, _Opts) -> - %%pubsub_subscription_sql:init(), + %%pubsub_subscription_sql:init(Host, ServerHost, Opts), ok. terminate(_Host, _ServerHost) -> diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index f2c962257..297c6627c 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -28,7 +28,7 @@ -author("bjc@kublai.com"). %% API --export([init/0, subscribe_node/3, unsubscribe_node/3, +-export([init/3, subscribe_node/3, unsubscribe_node/3, get_subscription/3, set_subscription/4, make_subid/0, get_options_xform/2, parse_options_xform/1]). @@ -73,7 +73,7 @@ %%==================================================================== %% API %%==================================================================== -init() -> ok = create_table(). +init(_Host, _ServerHost, _Opts) -> ok = create_table(). subscribe_node(JID, NodeId, Options) -> case catch mnesia:sync_dirty(fun add_subscription/3, [JID, NodeId, Options]) diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index 922b2a418..bb7b64112 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -28,7 +28,7 @@ -author("pablo.polvorin@process-one.net"). %% API --export([init/0, subscribe_node/3, unsubscribe_node/3, +-export([init/3, subscribe_node/3, unsubscribe_node/3, get_subscription/3, set_subscription/4, make_subid/0, get_options_xform/2, parse_options_xform/1]). @@ -71,7 +71,7 @@ %% API %%==================================================================== -init() -> ok = create_table(). +init(_Host, _ServerHost, _Opts) -> ok = create_table(). -spec subscribe_node(_JID :: _, _NodeId :: _, Options :: [] | mod_pubsub:subOptions()) -> {result, mod_pubsub:subId()}. -- cgit v1.2.3 From b1723c6e2d83f0d3d65f151a10610f58a54859cf Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 16 Nov 2016 13:11:23 +0100 Subject: Handle correctly p1_http:request result --- src/ext_mod.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ext_mod.erl b/src/ext_mod.erl index 2f71343a2..a2109e569 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -272,9 +272,9 @@ geturl(Url, Hdrs, UsrOpts) -> _ -> [] end, case p1_http:request(get, Url, Hdrs, [], Host++User++UsrOpts++[{version, "HTTP/1.0"}]) of - {ok, {{_, 200, _}, Headers, Response}} -> + {ok, 200, Headers, Response} -> {ok, Headers, Response}; - {ok, {{_, Code, _}, _Headers, Response}} -> + {ok, Code, _Headers, Response} -> {error, {Code, Response}}; {error, Reason} -> {error, Reason} -- cgit v1.2.3 From 3cd174cb56c064e6d4f969677d94cd413003f5e0 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 16 Nov 2016 13:35:50 +0100 Subject: Ensure that presence_broadcast room option is stored (#1380) --- src/mod_muc_room.erl | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index c83565734..060ac2bcd 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -3548,6 +3548,7 @@ make_opts(StateData) -> ?MAKE_CONFIG_OPT(#config.allow_voice_requests), ?MAKE_CONFIG_OPT(#config.allow_subscription), ?MAKE_CONFIG_OPT(#config.mam), + ?MAKE_CONFIG_OPT(#config.presence_broadcast), ?MAKE_CONFIG_OPT(#config.voice_request_min_interval), ?MAKE_CONFIG_OPT(#config.vcard), {captcha_whitelist, -- cgit v1.2.3 From 1c90b19d748c190e3e6cc7361c2de14d686522af Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 16 Nov 2016 18:24:12 +0100 Subject: Fix typo --- src/ejabberd_oauth.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl index e03b78fe8..74e26e8da 100644 --- a/src/ejabberd_oauth.erl +++ b/src/ejabberd_oauth.erl @@ -471,7 +471,7 @@ process(_Handlers, [{<<"href">>, <<"https://www.ejabberd.im">>}, {<<"title">>, <<"ejabberd XMPP server">>}], <<"ejabberd">>), - ?C(" is maintained by "), + ?C(<<" is maintained by ">>), ?XAC(<<"a">>, [{<<"href">>, <<"https://www.process-one.net">>}, {<<"title">>, <<"ProcessOne - Leader in Instant Messaging and Push Solutions">>}], -- cgit v1.2.3 From 995c97671d418264d35aa2308f642bf382832638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Thu, 17 Nov 2016 12:59:27 +0100 Subject: Add auth to mod_http_fileserver --- src/mod_http_fileserver.erl | 88 +++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index 728a2d137..a896cb8b4 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -56,7 +56,7 @@ -record(state, {host, docroot, accesslog, accesslogfd, directory_indices, custom_headers, default_content_type, - content_types = []}). + content_types = [], user_access = none}). -define(PROCNAME, ejabberd_mod_http_fileserver). @@ -133,7 +133,8 @@ start_link(Host, Opts) -> init([Host, Opts]) -> try initialize(Host, Opts) of {DocRoot, AccessLog, AccessLogFD, DirectoryIndices, - CustomHeaders, DefaultContentType, ContentTypes} -> + CustomHeaders, DefaultContentType, ContentTypes, + UserAccess} -> {ok, #state{host = Host, accesslog = AccessLog, accesslogfd = AccessLogFD, @@ -141,7 +142,8 @@ init([Host, Opts]) -> directory_indices = DirectoryIndices, custom_headers = CustomHeaders, default_content_type = DefaultContentType, - content_types = ContentTypes}} + content_types = ContentTypes, + user_access = UserAccess}} catch throw:Reason -> {stop, Reason} @@ -165,7 +167,15 @@ initialize(Host, Opts) -> []), DefaultContentType = gen_mod:get_opt(default_content_type, Opts, fun iolist_to_binary/1, - ?DEFAULT_CONTENT_TYPE), + ?DEFAULT_CONTENT_TYPE), + UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts, + mod_opt_type(must_authenticate_with), + []), + UserAccess = case UserAccess0 of + [] -> none; + _ -> + dict:from_list(UserAccess0) + end, ContentTypes = build_list_content_types( gen_mod:get_opt(content_types, Opts, fun(L) when is_list(L) -> @@ -180,7 +190,7 @@ initialize(Host, Opts) -> [str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes], <<", ">>)]), {DocRoot, AccessLog, AccessLogFD, DirectoryIndices, - CustomHeaders, DefaultContentType, ContentTypes}. + CustomHeaders, DefaultContentType, ContentTypes, UserAccess}. %% @spec (AdminCTs::[CT], Default::[CT]) -> [CT] @@ -246,10 +256,11 @@ try_open_log(FN, Host) -> %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- -handle_call({serve, LocalPath}, _From, State) -> - Reply = serve(LocalPath, State#state.docroot, State#state.directory_indices, +handle_call({serve, LocalPath, Auth}, _From, State) -> + Reply = serve(LocalPath, Auth, State#state.docroot, State#state.directory_indices, State#state.custom_headers, - State#state.default_content_type, State#state.content_types), + State#state.default_content_type, State#state.content_types, + State#state.user_access), {reply, Reply, State}; handle_call(_Request, _From, State) -> {reply, ok, State}. @@ -305,9 +316,9 @@ code_change(_OldVsn, State, _Extra) -> %% @doc Handle an HTTP request. %% LocalPath is the part of the requested URL path that is "local to the module". %% Returns the page to be sent back to the client and/or HTTP status code. -process(LocalPath, Request) -> +process(LocalPath, #request{host = Host, auth = Auth} = Request) -> ?DEBUG("Requested ~p", [LocalPath]), - try gen_server:call(get_proc_name(Request#request.host), {serve, LocalPath}) of + try gen_server:call(get_proc_name(Host), {serve, LocalPath, Auth}) of {FileSize, Code, Headers, Contents} -> add_to_log(FileSize, Code, Request), {Code, Headers, Contents} @@ -318,21 +329,38 @@ process(LocalPath, Request) -> ejabberd_web:error(not_found) end. -serve(LocalPath, DocRoot, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes) -> - FileName = filename:join(filename:split(DocRoot) ++ LocalPath), - case file:read_file_info(FileName) of - {error, enoent} -> ?HTTP_ERR_FILE_NOT_FOUND; - {error, enotdir} -> ?HTTP_ERR_FILE_NOT_FOUND; - {error, eacces} -> ?HTTP_ERR_FORBIDDEN; - {ok, #file_info{type = directory}} -> serve_index(FileName, - DirectoryIndices, - CustomHeaders, - DefaultContentType, - ContentTypes); - {ok, FileInfo} -> serve_file(FileInfo, FileName, - CustomHeaders, - DefaultContentType, - ContentTypes) + +serve(LocalPath, Auth, DocRoot, DirectoryIndices, CustomHeaders, DefaultContentType, + ContentTypes, UserAccess) -> + CanProceed = case {UserAccess, Auth} of + {none, _} -> true; + {_, {User, Pass}} -> + case dict:find(User, UserAccess) of + {ok, Pass} -> true; + _ -> false + end; + _ -> + false + end, + case CanProceed of + true -> + FileName = filename:join(filename:split(DocRoot) ++ LocalPath), + case file:read_file_info(FileName) of + {error, enoent} -> ?HTTP_ERR_FILE_NOT_FOUND; + {error, enotdir} -> ?HTTP_ERR_FILE_NOT_FOUND; + {error, eacces} -> ?HTTP_ERR_FORBIDDEN; + {ok, #file_info{type = directory}} -> serve_index(FileName, + DirectoryIndices, + CustomHeaders, + DefaultContentType, + ContentTypes); + {ok, FileInfo} -> serve_file(FileInfo, FileName, + CustomHeaders, + DefaultContentType, + ContentTypes) + end; + _ -> + ?HTTP_ERR_FORBIDDEN end. %% Troll through the directory indices attempting to find one which @@ -466,6 +494,14 @@ mod_opt_type(default_content_type) -> mod_opt_type(directory_indices) -> fun (L) when is_list(L) -> L end; mod_opt_type(docroot) -> fun (A) -> A end; +mod_opt_type(must_authenticate_with) -> + fun (L) when is_list(L) -> + lists:map(fun(UP) when is_binary(UP) -> + [K, V] = binary:split(UP, <<":">>), + {K, V} + end, L) + end; mod_opt_type(_) -> [accesslog, content_types, custom_headers, - default_content_type, directory_indices, docroot]. + default_content_type, directory_indices, docroot, + must_authenticate_with]. -- cgit v1.2.3 From b8dcc911a3b1e3cc05074d9ac4bd8da80b431388 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 18 Nov 2016 13:38:08 +0300 Subject: Make common tests working again --- src/ejabberd_local.erl | 12 +- src/flex_offline.erl | 2 +- src/mam_query.erl | 220 +++++++++++++++++++++++++++++++++ src/mod_carboncopy.erl | 4 +- src/mod_mam.erl | 197 ++++++++++++++--------------- src/mod_mam_mnesia.erl | 8 +- src/mod_mam_sql.erl | 18 +-- src/mod_offline.erl | 3 +- src/mod_offline_riak.erl | 2 +- src/mod_offline_sql.erl | 3 +- src/mod_roster.erl | 2 +- src/muc_register.erl | 2 +- src/muc_request.erl | 2 +- src/muc_roomconfig.erl | 2 +- src/muc_roominfo.erl | 2 +- src/pubsub_get_pending.erl | 2 +- src/pubsub_node_config.erl | 2 +- src/pubsub_publish_options.erl | 2 +- src/pubsub_subscribe_authorization.erl | 2 +- src/pubsub_subscribe_options.erl | 2 +- src/xmpp_util.erl | 9 +- 21 files changed, 360 insertions(+), 138 deletions(-) create mode 100644 src/mam_query.erl (limited to 'src') diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index d7849396b..74d86945d 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -177,15 +177,19 @@ unregister_iq_handler(Host, XMLNS) -> refresh_iq_handlers() -> ejabberd_local ! refresh_iq_handlers. --spec bounce_resource_packet(jid(), jid(), stanza()) -> ok. -bounce_resource_packet(_From, _To, #presence{}) -> +-spec bounce_resource_packet(jid(), jid(), stanza()) -> stop. +bounce_resource_packet(_From, #jid{lresource = <<"">>}, #presence{}) -> + ok; +bounce_resource_packet(_From, #jid{lresource = <<"">>}, + #message{type = headline}) -> ok; bounce_resource_packet(From, To, Packet) -> Lang = xmpp:get_lang(Packet), Txt = <<"No available resource found">>, Err = xmpp:make_error(Packet, xmpp:err_item_not_found(Txt, Lang)), - ejabberd_router:route(To, From, Err). + ejabberd_router:route(To, From, Err), + stop. %%==================================================================== %% gen_server callbacks @@ -283,7 +287,7 @@ do_route(From, To, Packet) -> ejabberd_sm:route(From, To, Packet); is_record(Packet, iq), To#jid.lresource == <<"">> -> process_iq(From, To, Packet); - Type == result; Type == error; Type == headline -> + Type == result; Type == error -> ok; true -> ejabberd_hooks:run(local_send_to_resource_hook, diff --git a/src/flex_offline.erl b/src/flex_offline.erl index 090ab3ddf..acc57342e 100644 --- a/src/flex_offline.erl +++ b/src/flex_offline.erl @@ -12,7 +12,7 @@ -include("flex_offline.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_int(Val, Min, Max) -> case list_to_integer(binary_to_list(Val)) of diff --git a/src/mam_query.erl b/src/mam_query.erl new file mode 100644 index 000000000..cb5bfe13a --- /dev/null +++ b/src/mam_query.erl @@ -0,0 +1,220 @@ +%% Created automatically by xdata generator (xdata_codec.erl) +%% Source: mam_query.xdata +%% Form type: urn:xmpp:mam:1 +%% Document: XEP-0313 + +-module(mam_query). + +-export([decode/1, decode/2, encode/1, encode/2, + format_error/1]). + +-include("xmpp_codec.hrl"). + +-include("mam_query.hrl"). + +-export_type([property/0, result/0, form/0]). + +enc_jid(J) -> jid:to_string(J). + +dec_jid(Val) -> + case jid:from_string(Val) of + error -> erlang:error(badarg); + J -> J + end. + +format_error({form_type_mismatch, Type}) -> + <<"FORM_TYPE doesn't match '", Type/binary, "'">>; +format_error({bad_var_value, Var, Type}) -> + <<"Bad value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_value, Var, Type}) -> + <<"Missing value of field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({too_many_values, Var, Type}) -> + <<"Too many values for field '", Var/binary, + "' of type '", Type/binary, "'">>; +format_error({unknown_var, Var, Type}) -> + <<"Unknown field '", Var/binary, "' of type '", + Type/binary, "'">>; +format_error({missing_required_var, Var, Type}) -> + <<"Missing required field '", Var/binary, "' of type '", + Type/binary, "'">>. + +decode(Fs) -> decode(Fs, []). + +decode(Fs, Acc) -> + case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, + Fs) + of + false -> decode(Fs, Acc, []); + #xdata_field{values = [<<"urn:xmpp:mam:1">>]} -> + decode(Fs, Acc, []); + _ -> + erlang:error({?MODULE, + {form_type_mismatch, <<"urn:xmpp:mam:1">>}}) + end. + +encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). + +encode(List, Translate) when is_list(List) -> + Fs = [case Opt of + {with, Val} -> [encode_with(Val, Translate)]; + {with, _, _} -> erlang:error({badarg, Opt}); + {start, Val} -> [encode_start(Val, Translate)]; + {start, _, _} -> erlang:error({badarg, Opt}); + {'end', Val} -> [encode_end(Val, Translate)]; + {'end', _, _} -> erlang:error({badarg, Opt}); + {withtext, Val} -> [encode_withtext(Val, Translate)]; + {withtext, _, _} -> erlang:error({badarg, Opt}); + #xdata_field{} -> [Opt]; + _ -> [] + end + || Opt <- List], + FormType = #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, values = [<<"urn:xmpp:mam:1">>]}, + [FormType | lists:flatten(Fs)]. + +decode([#xdata_field{var = <<"with">>, values = [Value]} + | Fs], + Acc, Required) -> + try dec_jid(Value) of + Result -> + decode(Fs, [{with, Result} | Acc], + lists:delete(<<"with">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"with">>, <<"urn:xmpp:mam:1">>}}) + end; +decode([#xdata_field{var = <<"with">>, values = []} = F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"with">>, values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"with">>} | _], _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"with">>, <<"urn:xmpp:mam:1">>}}); +decode([#xdata_field{var = <<"start">>, + values = [Value]} + | Fs], + Acc, Required) -> + try xmpp_util:decode_timestamp(Value) of + Result -> + decode(Fs, [{start, Result} | Acc], + lists:delete(<<"start">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"start">>, <<"urn:xmpp:mam:1">>}}) + end; +decode([#xdata_field{var = <<"start">>, values = []} = F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"start">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"start">>} | _], _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"start">>, <<"urn:xmpp:mam:1">>}}); +decode([#xdata_field{var = <<"end">>, values = [Value]} + | Fs], + Acc, Required) -> + try xmpp_util:decode_timestamp(Value) of + Result -> + decode(Fs, [{'end', Result} | Acc], + lists:delete(<<"end">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"end">>, <<"urn:xmpp:mam:1">>}}) + end; +decode([#xdata_field{var = <<"end">>, values = []} = F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"end">>, values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"end">>} | _], _, _) -> + erlang:error({?MODULE, + {too_many_values, <<"end">>, <<"urn:xmpp:mam:1">>}}); +decode([#xdata_field{var = <<"withtext">>, + values = [Value]} + | Fs], + Acc, Required) -> + try Value of + Result -> + decode(Fs, [{withtext, Result} | Acc], + lists:delete(<<"withtext">>, Required)) + catch + _:_ -> + erlang:error({?MODULE, + {bad_var_value, <<"withtext">>, <<"urn:xmpp:mam:1">>}}) + end; +decode([#xdata_field{var = <<"withtext">>, + values = []} = + F + | Fs], + Acc, Required) -> + decode([F#xdata_field{var = <<"withtext">>, + values = [<<>>]} + | Fs], + Acc, Required); +decode([#xdata_field{var = <<"withtext">>} | _], _, + _) -> + erlang:error({?MODULE, + {too_many_values, <<"withtext">>, + <<"urn:xmpp:mam:1">>}}); +decode([#xdata_field{var = Var} | Fs], Acc, Required) -> + if Var /= <<"FORM_TYPE">> -> + erlang:error({?MODULE, + {unknown_var, Var, <<"urn:xmpp:mam:1">>}}); + true -> decode(Fs, Acc, Required) + end; +decode([], _, [Var | _]) -> + erlang:error({?MODULE, + {missing_required_var, Var, <<"urn:xmpp:mam:1">>}}); +decode([], Acc, []) -> Acc. + +encode_with(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [enc_jid(Value)] + end, + Opts = [], + #xdata_field{var = <<"with">>, values = Values, + required = false, type = 'jid-single', options = Opts, + desc = <<>>, label = Translate(<<"User JID">>)}. + +encode_start(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"start">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = Translate(<<"Search from the date">>)}. + +encode_end(Value, Translate) -> + Values = case Value of + undefined -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"end">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, + label = Translate(<<"Search until the date">>)}. + +encode_withtext(Value, Translate) -> + Values = case Value of + <<>> -> []; + Value -> [Value] + end, + Opts = [], + #xdata_field{var = <<"withtext">>, values = Values, + required = false, type = 'text-single', options = Opts, + desc = <<>>, label = Translate(<<"Search the text">>)}. diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 7d8ca5332..1c8ca1fdc 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -228,8 +228,8 @@ complete_packet(_From, Msg, _Direction) -> -spec is_chat_message(stanza()) -> boolean(). is_chat_message(#message{type = chat}) -> true; -is_chat_message(#message{type = normal, body = Body}) -> - xmpp:get_text(Body) /= <<"">>; +is_chat_message(#message{type = normal, body = [_|_]}) -> + true; is_chat_message(_) -> false. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index f9ef104bd..61754ae59 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -54,12 +54,13 @@ -callback delete_old_messages(binary() | global, erlang:timestamp(), all | chat | groupchat) -> any(). --callback extended_fields() -> [xdata_field()]. +-callback extended_fields() -> [mam_query:property() | #xdata_field{}]. -callback store(xmlel(), binary(), {binary(), binary()}, chat | groupchat, jid(), binary(), recv | send) -> {ok, binary()} | any(). -callback write_prefs(binary(), binary(), #archive_prefs{}, binary()) -> ok | any(). -callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error. --callback select(binary(), jid(), jid(), mam_query(), chat | groupchat) -> +-callback select(binary(), jid(), jid(), mam_query:result(), + #rsm_set{} | undefined, chat | groupchat) -> {[{binary(), non_neg_integer(), xmlel()}], boolean(), non_neg_integer()}. %%%=================================================================== @@ -259,8 +260,9 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, end. set_stanza_id(Pkt, JID, ID) -> - Archived = #mam_archived{by = JID, id = ID}, - StanzaID = #stanza_id{by = JID, id = ID}, + BareJID = jid:remove_resource(JID), + Archived = #mam_archived{by = BareJID, id = ID}, + StanzaID = #stanza_id{by = BareJID, id = ID}, NewEls = [Archived, StanzaID|xmpp:get_els(Pkt)], xmpp:set_els(Pkt, NewEls). @@ -308,43 +310,24 @@ muc_process_iq(#iq{type = get, muc_process_iq(IQ, _MUCState) -> IQ. -parse_query(#mam_query{xdata = #xdata{fields = Fs}} = Query, Lang) -> - try - lists:foldl( - fun(#xdata_field{var = <<"start">>, values = [Data|_]}, Q) -> - try xmpp_util:decode_timestamp(Data) of - {_, _, _} = TS -> Q#mam_query{start = TS} - catch _:{bad_timestamp, _} -> throw({error, <<"start">>}) - end; - (#xdata_field{var = <<"end">>, values = [Data|_]}, Q) -> - try xmpp_util:decode_timestamp(Data) of - {_, _, _} = TS -> Q#mam_query{start = TS} - catch _:{bad_timestamp, _} -> throw({error, <<"end">>}) - end; - (#xdata_field{var = <<"with">>, values = [Data|_]}, Q) -> - case jid:from_string(Data) of - error -> throw({error, <<"with">>}); - J -> Q#mam_query{with = J} - end; - (#xdata_field{var = <<"withtext">>, values = [Data|_]}, Q) -> - case Data of - <<"">> -> throw({error, <<"withtext">>}); - _ -> Q#mam_query{withtext = Data} - end; - (#xdata_field{var = <<"FORM_TYPE">>, values = [NS|_]}, Q) -> - case Query#mam_query.xmlns of - NS -> Q; - _ -> throw({error, <<"FORM_TYPE">>}) - end; - (#xdata_field{}, Acc) -> - Acc - end, Query, Fs) - catch throw:{error, Var} -> - Txt = io_lib:format("Incorrect value of field '~s'", [Var]), - {error, xmpp:err_bad_request(iolist_to_binary(Txt), Lang)} +parse_query(#mam_query{xmlns = ?NS_MAM_TMP, + start = Start, 'end' = End, + with = With, withtext = Text}, _Lang) -> + {ok, [{start, Start}, {'end', End}, + {with, With}, {withtext, Text}]}; +parse_query(#mam_query{xdata = #xdata{}} = Query, Lang) -> + X = xmpp_util:set_xdata_field( + #xdata_field{var = <<"FORM_TYPE">>, + type = hidden, values = [?NS_MAM_1]}, + Query#mam_query.xdata), + try mam_query:decode(X#xdata.fields) of + Form -> {ok, Form} + catch _:{mam_query, Why} -> + Txt = mam_query:format_error(Why), + {error, xmpp:err_bad_request(Txt, Lang)} end; -parse_query(Query, _Lang) -> - Query. +parse_query(#mam_query{}, _Lang) -> + {ok, []}. disco_sm_features(empty, From, To, Node, Lang) -> disco_sm_features({result, []}, From, To, Node, Lang); @@ -402,17 +385,16 @@ delete_old_messages(_TypeBin, _Days) -> %%%=================================================================== process_iq(LServer, #iq{sub_els = [#mam_query{xmlns = NS}]} = IQ) -> - CommonFields = [#xdata_field{type = hidden, - var = <<"FORM_TYPE">>, - values = [NS]}, - #xdata_field{type = 'jid-single', var = <<"with">>}, - #xdata_field{type = 'text-single', var = <<"start">>}, - #xdata_field{type = 'text-single', var = <<"end">>}], Mod = gen_mod:db_mod(LServer, ?MODULE), + CommonFields = [{with, undefined}, + {start, undefined}, + {'end', undefined}], ExtendedFields = Mod:extended_fields(), - Fields = CommonFields ++ ExtendedFields, - Form = #xdata{type = form, fields = Fields}, - xmpp:make_iq_result(IQ, #mam_query{xmlns = NS, xdata = Form}). + Fields = mam_query:encode(CommonFields ++ ExtendedFields), + X = xmpp_util:set_xdata_field( + #xdata_field{var = <<"FORM_TYPE">>, type = hidden, values = [NS]}, + #xdata{type = form, fields = Fields}), + xmpp:make_iq_result(IQ, #mam_query{xmlns = NS, xdata = X}). % Preference setting (both v0.2 & v0.3) process_iq(#iq{type = set, lang = Lang, @@ -457,15 +439,17 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang, {groupchat, _Role, _MUCState} -> ok end, - case parse_query(SubEl, Lang) of + case SubEl of #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) -> xmpp:make_error(IQ, xmpp:err_feature_not_implemented()); - #mam_query{rsm = RSM, xmlns = NS} = Query -> - NewRSM = limit_max(RSM, NS), - NewQuery = Query#mam_query{rsm = NewRSM}, - select_and_send(LServer, NewQuery, IQ, MsgType); - {error, Err} -> - xmpp:make_error(IQ, Err) + #mam_query{rsm = RSM, xmlns = NS} -> + case parse_query(SubEl, Lang) of + {ok, Query} -> + NewRSM = limit_max(RSM, NS), + select_and_send(LServer, Query, NewRSM, IQ, MsgType); + {error, Err} -> + xmpp:make_error(IQ, Err) + end end. should_archive(#message{type = error}, _LServer) -> @@ -493,57 +477,57 @@ should_archive(_, _LServer) -> -spec strip_my_archived_tag(stanza(), binary()) -> stanza(). strip_my_archived_tag(Pkt, LServer) -> - NewPkt = xmpp:decode_els( - Pkt, ?NS_CLIENT, + Els = xmpp:get_els(Pkt), + NewEls = lists:filter( fun(El) -> - case xmpp:get_name(El) of - <<"archived">> -> - xmpp:get_ns(El) == ?NS_MAM_TMP; - <<"stanza-id">> -> - xmpp:get_ns(El) == ?NS_SID_0; - _ -> - false + Name = xmpp:get_name(El), + NS = xmpp:get_ns(El), + if (Name == <<"archived">> andalso NS == ?NS_MAM_TMP); + (Name == <<"stanza-id">> andalso NS == ?NS_SID_0) -> + try xmpp:decode(El) of + #mam_archived{by = By} -> + By#jid.lserver /= LServer; + #stanza_id{by = By} -> + By#jid.lserver /= LServer + catch _:{xmpp_codec, _} -> + false + end; + true -> + true end - end), - NewEls = lists:filter( - fun(#mam_archived{by = By}) -> - By#jid.lserver /= LServer; - (#stanza_id{by = By}) -> - By#jid.lserver /= LServer; - (_) -> - true - end, xmpp:get_els(NewPkt)), - xmpp:set_els(NewPkt, NewEls). + end, Els), + xmpp:set_els(Pkt, NewEls). +-spec strip_x_jid_tags(stanza()) -> stanza(). strip_x_jid_tags(Pkt) -> - NewPkt = xmpp:decode_els( - Pkt, ?NS_CLIENT, + Els = xmpp:get_els(Pkt), + NewEls = lists:filter( fun(El) -> case xmpp:get_name(El) of <<"x">> -> - case xmpp:get_ns(El) of - ?NS_MUC_USER -> true; - ?NS_MUC_ADMIN -> true; - ?NS_MUC_OWNER -> true; - _ -> false - end; + NS = xmpp:get_ns(El), + Items = if NS == ?NS_MUC_USER; + NS == ?NS_MUC_ADMIN; + NS == ?NS_MUC_OWNER -> + try xmpp:decode(El) of + #muc_user{items = Is} -> Is; + #muc_admin{items = Is} -> Is; + #muc_owner{items = Is} -> Is + catch _:{xmpp_codec, _} -> + [] + end; + true -> + [] + end, + not lists:any( + fun(#muc_item{jid = JID}) -> + JID /= undefined + end, Items); _ -> - false + true end - end), - NewEls = lists:filter( - fun(El) -> - Items = case El of - #muc_user{items = Is} -> Is; - #muc_admin{items = Is} -> Is; - #muc_owner{items = Is} -> Is; - _ -> [] - end, - not lists:any(fun(#muc_item{jid = JID}) -> - JID /= undefined - end, Items) - end, xmpp:get_els(NewPkt)), - xmpp:set_els(NewPkt, NewEls). + end, Els), + xmpp:set_els(Pkt, NewEls). should_archive_peer(C2SState, #archive_prefs{default = Default, @@ -625,7 +609,7 @@ has_no_store_hint(Message) -> -spec is_resent(message(), binary()) -> boolean(). is_resent(Pkt, LServer) -> case xmpp:get_subtag(Pkt, #stanza_id{}) of - #stanza_id{by = #jid{luser = <<>>, lserver = LServer}} -> + #stanza_id{by = #jid{lserver = LServer}} -> true; _ -> false @@ -741,21 +725,22 @@ maybe_activate_mam(LUser, LServer) -> ok end. -select_and_send(LServer, Query, #iq{from = From, to = To} = IQ, MsgType) -> +select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) -> {Msgs, IsComplete, Count} = case MsgType of chat -> - select(LServer, From, From, Query, MsgType); + select(LServer, From, From, Query, RSM, MsgType); {groupchat, _Role, _MUCState} -> - select(LServer, From, To, Query, MsgType) + select(LServer, From, To, Query, RSM, MsgType) end, SortedMsgs = lists:keysort(2, Msgs), send(SortedMsgs, Count, IsComplete, IQ). -select(_LServer, JidRequestor, JidArchive, - #mam_query{start = Start, 'end' = End, rsm = RSM}, +select(_LServer, JidRequestor, JidArchive, Query, RSM, {groupchat, _Role, #state{config = #config{mam = false}, history = History}} = MsgType) -> + Start = proplists:get_value(start, Query), + End = proplists:get_value('end', Query), #lqueue{len = L, queue = Q} = History, Msgs = lists:flatmap( @@ -786,9 +771,9 @@ select(_LServer, JidRequestor, JidArchive, _ -> {Msgs, true, L} end; -select(LServer, JidRequestor, JidArchive, Query, MsgType) -> +select(LServer, JidRequestor, JidArchive, Query, RSM, MsgType) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:select(LServer, JidRequestor, JidArchive, Query, MsgType). + Mod:select(LServer, JidRequestor, JidArchive, Query, RSM, MsgType). msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, MsgType, JidRequestor, #jid{lserver = LServer} = JidArchive) -> diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl index e913d5a45..8b9c6676c 100644 --- a/src/mod_mam_mnesia.erl +++ b/src/mod_mam_mnesia.erl @@ -12,7 +12,7 @@ %% API -export([init/2, remove_user/2, remove_room/3, delete_old_messages/3, - extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/5]). + extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/6]). -include_lib("stdlib/include/ms_transform.hrl"). -include("xmpp.hrl"). @@ -132,8 +132,10 @@ get_prefs(LUser, LServer) -> select(_LServer, JidRequestor, #jid{luser = LUser, lserver = LServer} = JidArchive, - #mam_query{start = Start, 'end' = End, - with = With, rsm = RSM}, MsgType) -> + Query, RSM, MsgType) -> + Start = proplists:get_value(start, Query), + End = proplists:get_value('end', Query), + With = proplists:get_value(with, Query), LWith = if With /= undefined -> jid:tolower(With); true -> undefined end, diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 1491f70f2..c500745a3 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -14,7 +14,7 @@ %% API -export([init/2, remove_user/2, remove_room/3, delete_old_messages/3, - extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/5]). + extended_fields/0, store/7, write_prefs/4, get_prefs/2, select/6]). -include_lib("stdlib/include/ms_transform.hrl"). -include("xmpp.hrl"). @@ -51,7 +51,7 @@ delete_old_messages(ServerHost, TimeStamp, Type) -> ok. extended_fields() -> - [#xdata_field{type = 'text-single', var = <<"withtext">>}]. + [{withtext, <<"">>}]. store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir) -> TSinteger = p1_time_compat:system_time(micro_seconds), @@ -124,12 +124,12 @@ get_prefs(LUser, LServer) -> end. select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, - MAMQuery, MsgType) -> + MAMQuery, RSM, MsgType) -> User = case MsgType of chat -> LUser; {groupchat, _Role, _MUCState} -> jid:to_string(JidArchive) end, - {Query, CountQuery} = make_sql_query(User, LServer, MAMQuery), + {Query, CountQuery} = make_sql_query(User, LServer, MAMQuery, RSM), % TODO from XEP-0313 v0.2: "To conserve resources, a server MAY place a % reasonable limit on how many stanzas may be pushed to a client in one % request. If a query returns a number of stanzas greater than this limit @@ -139,7 +139,7 @@ select(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, case {ejabberd_sql:sql_query(LServer, Query), ejabberd_sql:sql_query(LServer, CountQuery)} of {{selected, _, Res}, {selected, _, [[Count]]}} -> - {Max, Direction, _} = get_max_direction_id(MAMQuery#mam_query.rsm), + {Max, Direction, _} = get_max_direction_id(RSM), {Res1, IsComplete} = if Max >= 0 andalso Max /= undefined andalso length(Res) > Max -> if Direction == before -> @@ -194,9 +194,11 @@ usec_to_now(Int) -> Sec = Secs rem 1000000, {MSec, Sec, USec}. -make_sql_query(User, LServer, - #mam_query{start = Start, 'end' = End, with = With, - withtext = WithText, rsm = RSM}) -> +make_sql_query(User, LServer, MAMQuery, RSM) -> + Start = proplists:get_value(start, MAMQuery), + End = proplists:get_value('end', MAMQuery), + With = proplists:get_value(with, MAMQuery), + WithText = proplists:get_value(withtext, MAMQuery), {Max, Direction, ID} = get_max_direction_id(RSM), ODBCType = ejabberd_config:get_option( {sql_type, LServer}, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 2f6d52c36..d007bf3c6 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -99,7 +99,8 @@ -callback remove_expired_messages(binary()) -> {atomic, any()}. -callback remove_old_messages(non_neg_integer(), binary()) -> {atomic, any()}. -callback remove_user(binary(), binary()) -> {atomic, any()}. --callback read_message_headers(binary(), binary()) -> any(). +-callback read_message_headers(binary(), binary()) -> + [{non_neg_integer(), jid(), jid(), undefined | erlang:timestamp(), xmlel()}]. -callback read_message(binary(), binary(), non_neg_integer()) -> {ok, #offline_msg{}} | error. -callback remove_message(binary(), binary(), non_neg_integer()) -> ok | {error, any()}. diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl index 241a8d650..24d565383 100644 --- a/src/mod_offline_riak.erl +++ b/src/mod_offline_riak.erl @@ -88,7 +88,7 @@ read_message_headers(LUser, LServer) -> fun(#offline_msg{from = From, to = To, packet = Pkt, timestamp = TS}) -> Seq = now_to_integer(TS), - {Seq, From, To, Pkt} + {Seq, From, To, TS, Pkt} end, Rs), lists:keysort(1, Hdrs); _Err -> diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 2b7a40bff..025aa56f5 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -103,8 +103,9 @@ read_message_headers(LUser, LServer) -> case xml_to_offline_msg(XML) of {ok, #offline_msg{from = From, to = To, + timestamp = TS, packet = El}} -> - [{Seq, From, To, El}]; + [{Seq, From, To, TS, El}]; _ -> [] end diff --git a/src/mod_roster.erl b/src/mod_roster.erl index c344213f3..2da09d317 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -330,7 +330,7 @@ set_roster(#roster{us = {LUser, LServer}, jid = LJID} = Item) -> transaction( LServer, fun() -> - roster_subscribe_t(LUser, LServer, LJID, Item) + update_roster_t(LUser, LServer, LJID, Item) end). del_roster(LUser, LServer, LJID) -> diff --git a/src/muc_register.erl b/src/muc_register.erl index cddce2b98..c2b951dfc 100644 --- a/src/muc_register.erl +++ b/src/muc_register.erl @@ -12,7 +12,7 @@ -include("muc_register.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_bool(<<"1">>) -> true; dec_bool(<<"0">>) -> false; diff --git a/src/muc_request.erl b/src/muc_request.erl index 4c7becd2e..2d79ba0a5 100644 --- a/src/muc_request.erl +++ b/src/muc_request.erl @@ -12,7 +12,7 @@ -include("muc_request.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_enum(Val, Enums) -> AtomVal = erlang:binary_to_existing_atom(Val, utf8), diff --git a/src/muc_roomconfig.erl b/src/muc_roomconfig.erl index 73ceb649e..7d18bab66 100644 --- a/src/muc_roomconfig.erl +++ b/src/muc_roomconfig.erl @@ -12,7 +12,7 @@ -include("muc_roomconfig.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_int(Val, Min, Max) -> case list_to_integer(binary_to_list(Val)) of diff --git a/src/muc_roominfo.erl b/src/muc_roominfo.erl index 809dcef5b..bd5cb011b 100644 --- a/src/muc_roominfo.erl +++ b/src/muc_roominfo.erl @@ -12,7 +12,7 @@ -include("muc_roominfo.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_int(Val, Min, Max) -> case list_to_integer(binary_to_list(Val)) of diff --git a/src/pubsub_get_pending.erl b/src/pubsub_get_pending.erl index 1a7de6a2d..c1f2ba3ad 100644 --- a/src/pubsub_get_pending.erl +++ b/src/pubsub_get_pending.erl @@ -12,7 +12,7 @@ -include("pubsub_get_pending.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). format_error({form_type_mismatch, Type}) -> <<"FORM_TYPE doesn't match '", Type/binary, "'">>; diff --git a/src/pubsub_node_config.erl b/src/pubsub_node_config.erl index 47ed10b49..e831d6a83 100644 --- a/src/pubsub_node_config.erl +++ b/src/pubsub_node_config.erl @@ -12,7 +12,7 @@ -include("pubsub_node_config.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_int(Val, Min, Max) -> case list_to_integer(binary_to_list(Val)) of diff --git a/src/pubsub_publish_options.erl b/src/pubsub_publish_options.erl index 8d0229071..6e96946fd 100644 --- a/src/pubsub_publish_options.erl +++ b/src/pubsub_publish_options.erl @@ -12,7 +12,7 @@ -include("pubsub_publish_options.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_enum(Val, Enums) -> AtomVal = erlang:binary_to_existing_atom(Val, utf8), diff --git a/src/pubsub_subscribe_authorization.erl b/src/pubsub_subscribe_authorization.erl index e019ed6b9..46538da8d 100644 --- a/src/pubsub_subscribe_authorization.erl +++ b/src/pubsub_subscribe_authorization.erl @@ -12,7 +12,7 @@ -include("pubsub_subscribe_authorization.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_bool(<<"1">>) -> true; dec_bool(<<"0">>) -> false; diff --git a/src/pubsub_subscribe_options.erl b/src/pubsub_subscribe_options.erl index 446a84a00..02c046995 100644 --- a/src/pubsub_subscribe_options.erl +++ b/src/pubsub_subscribe_options.erl @@ -12,7 +12,7 @@ -include("pubsub_subscribe_options.hrl"). --export_type([{property, 0}, {result, 0}, {form, 0}]). +-export_type([property/0, result/0, form/0]). dec_enum(Val, Enums) -> AtomVal = erlang:binary_to_existing_atom(Val, utf8), diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 57440b50e..22b8ea597 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -11,7 +11,8 @@ %% API -export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, is_standalone_chat_state/1, get_xdata_values/2, - has_xdata_var/2, make_adhoc_response/1, make_adhoc_response/2, + set_xdata_field/2, has_xdata_var/2, + make_adhoc_response/1, make_adhoc_response/2, decode_timestamp/1, encode_timestamp/1]). -include("xmpp.hrl"). @@ -78,6 +79,12 @@ get_xdata_values(Var, #xdata{fields = Fields}) -> false -> [] end. +-spec set_xdata_field(xdata_field(), xdata()) -> xdata(). +set_xdata_field(Field, #xdata{fields = Fields} = X) -> + NewFields = lists:keystore(Field#xdata_field.var, #xdata_field.var, + Fields, Field), + X#xdata{fields = NewFields}. + -spec has_xdata_var(binary(), xdata()) -> boolean(). has_xdata_var(Var, #xdata{fields = Fields}) -> lists:keymember(Var, #xdata_field.var, Fields). -- cgit v1.2.3 From 45e77ea4830a753b4defcc12545d60d56e849819 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Fri, 18 Nov 2016 12:25:01 +0100 Subject: Remove useless NO_EXT_LIB flag --- src/ext_mod.erl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/ext_mod.erl b/src/ext_mod.erl index a2109e569..071fb827c 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -520,11 +520,8 @@ compile(_Module, _Spec, DestDir) -> filelib:ensure_dir(filename:join(Ebin, ".")), EjabBin = filename:dirname(code:which(ejabberd)), EjabInc = filename:join(filename:dirname(EjabBin), "include"), - XmlHrl = filename:join(EjabInc, "fxml.hrl"), - ExtLib = [{d, 'NO_EXT_LIB'} || filelib:is_file(XmlHrl)], Options = [{outdir, Ebin}, {i, "include"}, {i, EjabInc}, - verbose, report_errors, report_warnings] - ++ ExtLib, + verbose, report_errors, report_warnings], [file:copy(App, Ebin) || App <- filelib:wildcard("src/*.app")], %% Compile erlang files -- cgit v1.2.3 From 9aff7e52a8ddf9ecb6637a629899ecf0b10e8825 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 19 Nov 2016 13:03:33 +0300 Subject: Switch to stand-alone XMPP library --- src/flex_offline.erl | 128 - src/jid.erl | 266 - src/mam_query.erl | 220 - src/muc_register.erl | 364 - src/muc_request.erl | 269 - src/muc_roomconfig.erl | 1675 -- src/muc_roominfo.erl | 491 - src/pubsub_get_pending.erl | 130 - src/pubsub_node_config.erl | 1666 -- src/pubsub_publish_options.erl | 157 - src/pubsub_subscribe_authorization.erl | 279 - src/pubsub_subscribe_options.erl | 508 - src/xdata_codec.erl | 648 - src/xmpp.erl | 827 - src/xmpp_codec.erl | 34647 ------------------------------- 15 files changed, 42275 deletions(-) delete mode 100644 src/flex_offline.erl delete mode 100644 src/jid.erl delete mode 100644 src/mam_query.erl delete mode 100644 src/muc_register.erl delete mode 100644 src/muc_request.erl delete mode 100644 src/muc_roomconfig.erl delete mode 100644 src/muc_roominfo.erl delete mode 100644 src/pubsub_get_pending.erl delete mode 100644 src/pubsub_node_config.erl delete mode 100644 src/pubsub_publish_options.erl delete mode 100644 src/pubsub_subscribe_authorization.erl delete mode 100644 src/pubsub_subscribe_options.erl delete mode 100644 src/xdata_codec.erl delete mode 100644 src/xmpp.erl delete mode 100644 src/xmpp_codec.erl (limited to 'src') diff --git a/src/flex_offline.erl b/src/flex_offline.erl deleted file mode 100644 index acc57342e..000000000 --- a/src/flex_offline.erl +++ /dev/null @@ -1,128 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: flex_offline.xdata -%% Form type: http://jabber.org/protocol/offline -%% Document: XEP-0013 - --module(flex_offline). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("flex_offline.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> Int; - Int when Int =< Max, Int >= Min -> Int - end. - -enc_int(Int) -> integer_to_binary(Int). - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/offline">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/offline">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {number_of_messages, Val} -> - [encode_number_of_messages(Val, Translate)]; - {number_of_messages, _, _} -> - erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/offline">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"number_of_messages">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{number_of_messages, Result} | Acc], - lists:delete(<<"number_of_messages">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"number_of_messages">>, - <<"http://jabber.org/protocol/offline">>}}) - end; -decode([#xdata_field{var = <<"number_of_messages">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"number_of_messages">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"number_of_messages">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"number_of_messages">>, - <<"http://jabber.org/protocol/offline">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/offline">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/offline">>}}); -decode([], Acc, []) -> Acc. - -encode_number_of_messages(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"number_of_messages">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Number of Offline Messages">>)}. diff --git a/src/jid.erl b/src/jid.erl deleted file mode 100644 index 287a0642b..000000000 --- a/src/jid.erl +++ /dev/null @@ -1,266 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @doc -%%% JID processing library -%%% @end -%%% Created : 24 Nov 2015 by Evgeny Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%------------------------------------------------------------------- --module(jid). - -%% API --export([start/0, - make/1, - make/2, - make/3, - split/1, - from_string/1, - to_string/1, - is_nodename/1, - nodeprep/1, - nameprep/1, - resourceprep/1, - tolower/1, - remove_resource/1, - replace_resource/2]). - --include("jid.hrl"). - --export_type([jid/0]). --export_type([ljid/0]). - -%%%=================================================================== -%%% API -%%%=================================================================== --spec start() -> ok. - -start() -> - {ok, Owner} = ets_owner(), - SplitPattern = binary:compile_pattern([<<"@">>, <<"/">>]), - %% Table is public to allow ETS insert to fix / update the table even if table already exist - %% with another owner. - catch ets:new(jlib, [named_table, public, set, {keypos, 1}, {heir, Owner, undefined}]), - ets:insert(jlib, {string_to_jid_pattern, SplitPattern}), - ok. - -ets_owner() -> - case whereis(jlib_ets) of - undefined -> - Pid = spawn(fun() -> ets_keepalive() end), - case catch register(jlib_ets, Pid) of - true -> - {ok, Pid}; - Error -> Error - end; - Pid -> - {ok,Pid} - end. - -%% Process used to keep jlib ETS table alive in case the original owner dies. -%% The table need to be public, otherwise subsequent inserts would fail. -ets_keepalive() -> - receive - _ -> - ets_keepalive() - end. - --spec make(binary(), binary(), binary()) -> jid() | error. - -make(User, Server, Resource) -> - case nodeprep(User) of - error -> error; - LUser -> - case nameprep(Server) of - error -> error; - LServer -> - case resourceprep(Resource) of - error -> error; - LResource -> - #jid{user = User, server = Server, resource = Resource, - luser = LUser, lserver = LServer, - lresource = LResource} - end - end - end. - --spec make(binary(), binary()) -> jid() | error. -make(User, Server) -> - make(User, Server, <<"">>). - --spec make({binary(), binary(), binary()} | binary()) -> jid() | error. - -make({User, Server, Resource}) -> - make(User, Server, Resource); -make(Server) -> - make(<<"">>, Server, <<"">>). - -%% This is the reverse of make_jid/1 --spec split(jid()) -> {binary(), binary(), binary()} | error. - -split(#jid{user = U, server = S, resource = R}) -> - {U, S, R}; -split(_) -> - error. - --spec from_string(binary() | string()) -> jid() | error. -from_string(S) when is_list(S) -> - %% We do not accept list because we want to enforce good practice of - %% using binaries for string. However, we do not let it crash to avoid - %% losing associated ets table. - {error, need_jid_as_binary}; -from_string(<<>>) -> - error; -from_string(S) when is_binary(S) -> - SplitPattern = ets:lookup_element(jlib, string_to_jid_pattern, 2), - Size = size(S), - End = Size-1, - case binary:match(S, SplitPattern) of - {0, _} -> - error; - {End, _} -> - error; - {Pos1, _} -> - case binary:at(S, Pos1) of - $/ -> - make(<<>>, - binary:part(S, 0, Pos1), - binary:part(S, Pos1+1, Size-Pos1-1)); - _ -> - Pos1N = Pos1+1, - case binary:match(S, SplitPattern, [{scope, {Pos1+1, Size-Pos1-1}}]) of - {End, _} -> - error; - {Pos1N, _} -> - error; - {Pos2, _} -> - case binary:at(S, Pos2) of - $/ -> - make(binary:part(S, 0, Pos1), - binary:part(S, Pos1+1, Pos2-Pos1-1), - binary:part(S, Pos2+1, Size-Pos2-1)); - _ -> error - end; - _ -> - make(binary:part(S, 0, Pos1), - binary:part(S, Pos1+1, Size-Pos1-1), - <<>>) - end - end; - _ -> - make(<<>>, S, <<>>) - end. - --spec to_string(jid() | ljid()) -> binary(). - -to_string(#jid{user = User, server = Server, - resource = Resource}) -> - to_string({User, Server, Resource}); -to_string({N, S, R}) -> - Node = iolist_to_binary(N), - Server = iolist_to_binary(S), - Resource = iolist_to_binary(R), - S1 = case Node of - <<"">> -> <<"">>; - _ -> <> - end, - S2 = <>, - S3 = case Resource of - <<"">> -> S2; - _ -> <> - end, - S3. - --spec is_nodename(binary()) -> boolean(). - -is_nodename(Node) -> - N = nodeprep(Node), - (N /= error) and (N /= <<>>). - --define(LOWER(Char), - if Char >= $A, Char =< $Z -> Char + 32; - true -> Char - end). - --spec nodeprep(binary()) -> binary() | error. - -nodeprep("") -> <<>>; -nodeprep(S) when byte_size(S) < 1024 -> - R = stringprep:nodeprep(S), - if byte_size(R) < 1024 -> R; - true -> error - end; -nodeprep(_) -> error. - --spec nameprep(binary()) -> binary() | error. - -nameprep(S) when byte_size(S) < 1024 -> - R = stringprep:nameprep(S), - if byte_size(R) < 1024 -> R; - true -> error - end; -nameprep(_) -> error. - --spec resourceprep(binary()) -> binary() | error. - -resourceprep(S) when byte_size(S) < 1024 -> - R = stringprep:resourceprep(S), - if byte_size(R) < 1024 -> R; - true -> error - end; -resourceprep(_) -> error. - --spec tolower(jid() | ljid()) -> error | ljid(). - -tolower(#jid{luser = U, lserver = S, - lresource = R}) -> - {U, S, R}; -tolower({U, S, R}) -> - case nodeprep(U) of - error -> error; - LUser -> - case nameprep(S) of - error -> error; - LServer -> - case resourceprep(R) of - error -> error; - LResource -> {LUser, LServer, LResource} - end - end - end. - --spec remove_resource(jid()) -> jid(); - (ljid()) -> ljid(). - -remove_resource(#jid{} = JID) -> - JID#jid{resource = <<"">>, lresource = <<"">>}; -remove_resource({U, S, _R}) -> {U, S, <<"">>}. - --spec replace_resource(jid(), binary()) -> error | jid(). - -replace_resource(JID, Resource) -> - case resourceprep(Resource) of - error -> error; - LResource -> - JID#jid{resource = Resource, lresource = LResource} - end. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/src/mam_query.erl b/src/mam_query.erl deleted file mode 100644 index cb5bfe13a..000000000 --- a/src/mam_query.erl +++ /dev/null @@ -1,220 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: mam_query.xdata -%% Form type: urn:xmpp:mam:1 -%% Document: XEP-0313 - --module(mam_query). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("mam_query.hrl"). - --export_type([property/0, result/0, form/0]). - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = [<<"urn:xmpp:mam:1">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, <<"urn:xmpp:mam:1">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {with, Val} -> [encode_with(Val, Translate)]; - {with, _, _} -> erlang:error({badarg, Opt}); - {start, Val} -> [encode_start(Val, Translate)]; - {start, _, _} -> erlang:error({badarg, Opt}); - {'end', Val} -> [encode_end(Val, Translate)]; - {'end', _, _} -> erlang:error({badarg, Opt}); - {withtext, Val} -> [encode_withtext(Val, Translate)]; - {withtext, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, values = [<<"urn:xmpp:mam:1">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"with">>, values = [Value]} - | Fs], - Acc, Required) -> - try dec_jid(Value) of - Result -> - decode(Fs, [{with, Result} | Acc], - lists:delete(<<"with">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"with">>, <<"urn:xmpp:mam:1">>}}) - end; -decode([#xdata_field{var = <<"with">>, values = []} = F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"with">>, values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"with">>} | _], _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"with">>, <<"urn:xmpp:mam:1">>}}); -decode([#xdata_field{var = <<"start">>, - values = [Value]} - | Fs], - Acc, Required) -> - try xmpp_util:decode_timestamp(Value) of - Result -> - decode(Fs, [{start, Result} | Acc], - lists:delete(<<"start">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"start">>, <<"urn:xmpp:mam:1">>}}) - end; -decode([#xdata_field{var = <<"start">>, values = []} = F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"start">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"start">>} | _], _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"start">>, <<"urn:xmpp:mam:1">>}}); -decode([#xdata_field{var = <<"end">>, values = [Value]} - | Fs], - Acc, Required) -> - try xmpp_util:decode_timestamp(Value) of - Result -> - decode(Fs, [{'end', Result} | Acc], - lists:delete(<<"end">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"end">>, <<"urn:xmpp:mam:1">>}}) - end; -decode([#xdata_field{var = <<"end">>, values = []} = F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"end">>, values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"end">>} | _], _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"end">>, <<"urn:xmpp:mam:1">>}}); -decode([#xdata_field{var = <<"withtext">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{withtext, Result} | Acc], - lists:delete(<<"withtext">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"withtext">>, <<"urn:xmpp:mam:1">>}}) - end; -decode([#xdata_field{var = <<"withtext">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"withtext">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"withtext">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"withtext">>, - <<"urn:xmpp:mam:1">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, <<"urn:xmpp:mam:1">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, <<"urn:xmpp:mam:1">>}}); -decode([], Acc, []) -> Acc. - -encode_with(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_jid(Value)] - end, - Opts = [], - #xdata_field{var = <<"with">>, values = Values, - required = false, type = 'jid-single', options = Opts, - desc = <<>>, label = Translate(<<"User JID">>)}. - -encode_start(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"start">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = Translate(<<"Search from the date">>)}. - -encode_end(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"end">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = Translate(<<"Search until the date">>)}. - -encode_withtext(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"withtext">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, label = Translate(<<"Search the text">>)}. diff --git a/src/muc_register.erl b/src/muc_register.erl deleted file mode 100644 index c2b951dfc..000000000 --- a/src/muc_register.erl +++ /dev/null @@ -1,364 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: muc_register.xdata -%% Form type: http://jabber.org/protocol/muc#register -%% Document: XEP-0045 - --module(muc_register). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("muc_register.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, [<<"muc#register_roomnick">>]); - #xdata_field{values = - [<<"http://jabber.org/protocol/muc#register">>]} -> - decode(Fs, Acc, [<<"muc#register_roomnick">>]); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/muc#register">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {allow, Val} -> [encode_allow(Val, Translate)]; - {allow, _, _} -> erlang:error({badarg, Opt}); - {email, Val} -> [encode_email(Val, Translate)]; - {email, _, _} -> erlang:error({badarg, Opt}); - {faqentry, Val} -> [encode_faqentry(Val, Translate)]; - {faqentry, _, _} -> erlang:error({badarg, Opt}); - {first, Val} -> [encode_first(Val, Translate)]; - {first, _, _} -> erlang:error({badarg, Opt}); - {last, Val} -> [encode_last(Val, Translate)]; - {last, _, _} -> erlang:error({badarg, Opt}); - {roomnick, Val} -> [encode_roomnick(Val, Translate)]; - {roomnick, _, _} -> erlang:error({badarg, Opt}); - {url, Val} -> [encode_url(Val, Translate)]; - {url, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/muc#register">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"muc#register_allow">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow, Result} | Acc], - lists:delete(<<"muc#register_allow">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_allow">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_allow">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_allow">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_allow">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_allow">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = <<"muc#register_email">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{email, Result} | Acc], - lists:delete(<<"muc#register_email">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_email">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_email">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_email">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_email">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_email">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = <<"muc#register_faqentry">>, - values = Values} - | Fs], - Acc, Required) -> - try [Value || Value <- Values] of - Result -> - decode(Fs, [{faqentry, Result} | Acc], - lists:delete(<<"muc#register_faqentry">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_faqentry">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_first">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{first, Result} | Acc], - lists:delete(<<"muc#register_first">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_first">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_first">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_first">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_first">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_first">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = <<"muc#register_last">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{last, Result} | Acc], - lists:delete(<<"muc#register_last">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_last">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_last">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_last">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_last">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_last">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = <<"muc#register_roomnick">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{roomnick, Result} | Acc], - lists:delete(<<"muc#register_roomnick">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_roomnick">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_roomnick">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_roomnick">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_roomnick">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_roomnick">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = <<"muc#register_url">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{url, Result} | Acc], - lists:delete(<<"muc#register_url">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#register_url">>, - <<"http://jabber.org/protocol/muc#register">>}}) - end; -decode([#xdata_field{var = <<"muc#register_url">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#register_url">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#register_url">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#register_url">>, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/muc#register">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/muc#register">>}}); -decode([], Acc, []) -> Acc. - -encode_allow(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#register_allow">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow this person to register with the " - "room?">>)}. - -encode_email(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_email">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Email Address">>)}. - -encode_faqentry(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_faqentry">>, - values = Values, required = false, type = 'text-multi', - options = Opts, desc = <<>>, - label = Translate(<<"FAQ Entry">>)}. - -encode_first(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_first">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Given Name">>)}. - -encode_last(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_last">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Family Name">>)}. - -encode_roomnick(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_roomnick">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Nickname">>)}. - -encode_url(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#register_url">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"A Web Page">>)}. diff --git a/src/muc_request.erl b/src/muc_request.erl deleted file mode 100644 index 2d79ba0a5..000000000 --- a/src/muc_request.erl +++ /dev/null @@ -1,269 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: muc_request.xdata -%% Form type: http://jabber.org/protocol/muc#request -%% Document: XEP-0045 - --module(muc_request). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("muc_request.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, [<<"muc#role">>]); - #xdata_field{values = - [<<"http://jabber.org/protocol/muc#request">>]} -> - decode(Fs, Acc, [<<"muc#role">>]); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/muc#request">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {role, Val} -> [encode_role(Val, default, Translate)]; - {role, Val, Opts} -> - [encode_role(Val, Opts, Translate)]; - {jid, Val} -> [encode_jid(Val, Translate)]; - {jid, _, _} -> erlang:error({badarg, Opt}); - {roomnick, Val} -> [encode_roomnick(Val, Translate)]; - {roomnick, _, _} -> erlang:error({badarg, Opt}); - {request_allow, Val} -> - [encode_request_allow(Val, Translate)]; - {request_allow, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/muc#request">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"muc#role">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [participant]) of - Result -> - decode(Fs, [{role, Result} | Acc], - lists:delete(<<"muc#role">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#role">>, - <<"http://jabber.org/protocol/muc#request">>}}) - end; -decode([#xdata_field{var = <<"muc#role">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#role">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#role">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#role">>, - <<"http://jabber.org/protocol/muc#request">>}}); -decode([#xdata_field{var = <<"muc#jid">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_jid(Value) of - Result -> - decode(Fs, [{jid, Result} | Acc], - lists:delete(<<"muc#jid">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#jid">>, - <<"http://jabber.org/protocol/muc#request">>}}) - end; -decode([#xdata_field{var = <<"muc#jid">>, values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#jid">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#jid">>} | _], _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#jid">>, - <<"http://jabber.org/protocol/muc#request">>}}); -decode([#xdata_field{var = <<"muc#roomnick">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{roomnick, Result} | Acc], - lists:delete(<<"muc#roomnick">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomnick">>, - <<"http://jabber.org/protocol/muc#request">>}}) - end; -decode([#xdata_field{var = <<"muc#roomnick">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roomnick">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roomnick">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomnick">>, - <<"http://jabber.org/protocol/muc#request">>}}); -decode([#xdata_field{var = <<"muc#request_allow">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{request_allow, Result} | Acc], - lists:delete(<<"muc#request_allow">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#request_allow">>, - <<"http://jabber.org/protocol/muc#request">>}}) - end; -decode([#xdata_field{var = <<"muc#request_allow">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#request_allow">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#request_allow">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#request_allow">>, - <<"http://jabber.org/protocol/muc#request">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/muc#request">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/muc#request">>}}); -decode([], Acc, []) -> Acc. - -encode_role(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"Participant">>), - value = <<"participant">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"muc#role">>, values = Values, - required = false, type = 'list-single', options = Opts, - desc = <<>>, label = Translate(<<"Requested role">>)}. - -encode_jid(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_jid(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#jid">>, values = Values, - required = false, type = 'jid-single', options = Opts, - desc = <<>>, label = Translate(<<"User JID">>)}. - -encode_roomnick(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomnick">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, label = Translate(<<"Nickname">>)}. - -encode_request_allow(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#request_allow">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Grant voice to this person?">>)}. diff --git a/src/muc_roomconfig.erl b/src/muc_roomconfig.erl deleted file mode 100644 index 7d18bab66..000000000 --- a/src/muc_roomconfig.erl +++ /dev/null @@ -1,1675 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: muc_roomconfig.xdata -%% Form type: http://jabber.org/protocol/muc#roomconfig -%% Document: XEP-0045 - --module(muc_roomconfig). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("muc_roomconfig.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> Int; - Int when Int =< Max, Int >= Min -> Int - end. - -enc_int(Int) -> integer_to_binary(Int). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -dec_enum_int(Val, Enums, Min, Max) -> - try dec_int(Val, Min, Max) catch - _:_ -> dec_enum(Val, Enums) - end. - -enc_enum_int(Int) when is_integer(Int) -> enc_int(Int); -enc_enum_int(Atom) -> enc_enum(Atom). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/muc#roomconfig">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {maxhistoryfetch, Val} -> - [encode_maxhistoryfetch(Val, Translate)]; - {maxhistoryfetch, _, _} -> erlang:error({badarg, Opt}); - {allowpm, Val} -> - [encode_allowpm(Val, default, Translate)]; - {allowpm, Val, Opts} -> - [encode_allowpm(Val, Opts, Translate)]; - {allow_private_messages, Val} -> - [encode_allow_private_messages(Val, Translate)]; - {allow_private_messages, _, _} -> - erlang:error({badarg, Opt}); - {allow_private_messages_from_visitors, Val} -> - [encode_allow_private_messages_from_visitors(Val, - default, - Translate)]; - {allow_private_messages_from_visitors, Val, Opts} -> - [encode_allow_private_messages_from_visitors(Val, Opts, - Translate)]; - {allow_visitor_status, Val} -> - [encode_allow_visitor_status(Val, Translate)]; - {allow_visitor_status, _, _} -> - erlang:error({badarg, Opt}); - {allow_visitor_nickchange, Val} -> - [encode_allow_visitor_nickchange(Val, Translate)]; - {allow_visitor_nickchange, _, _} -> - erlang:error({badarg, Opt}); - {allow_voice_requests, Val} -> - [encode_allow_voice_requests(Val, Translate)]; - {allow_voice_requests, _, _} -> - erlang:error({badarg, Opt}); - {allow_subscription, Val} -> - [encode_allow_subscription(Val, Translate)]; - {allow_subscription, _, _} -> - erlang:error({badarg, Opt}); - {voice_request_min_interval, Val} -> - [encode_voice_request_min_interval(Val, Translate)]; - {voice_request_min_interval, _, _} -> - erlang:error({badarg, Opt}); - {captcha_protected, Val} -> - [encode_captcha_protected(Val, Translate)]; - {captcha_protected, _, _} -> - erlang:error({badarg, Opt}); - {captcha_whitelist, Val} -> - [encode_captcha_whitelist(Val, Translate)]; - {captcha_whitelist, _, _} -> - erlang:error({badarg, Opt}); - {allow_query_users, Val} -> - [encode_allow_query_users(Val, Translate)]; - {allow_query_users, _, _} -> - erlang:error({badarg, Opt}); - {allowinvites, Val} -> - [encode_allowinvites(Val, Translate)]; - {allowinvites, _, _} -> erlang:error({badarg, Opt}); - {changesubject, Val} -> - [encode_changesubject(Val, Translate)]; - {changesubject, _, _} -> erlang:error({badarg, Opt}); - {enablelogging, Val} -> - [encode_enablelogging(Val, Translate)]; - {enablelogging, _, _} -> erlang:error({badarg, Opt}); - {getmemberlist, Val} -> - [encode_getmemberlist(Val, default, Translate)]; - {getmemberlist, Val, Opts} -> - [encode_getmemberlist(Val, Opts, Translate)]; - {lang, Val} -> [encode_lang(Val, Translate)]; - {lang, _, _} -> erlang:error({badarg, Opt}); - {pubsub, Val} -> [encode_pubsub(Val, Translate)]; - {pubsub, _, _} -> erlang:error({badarg, Opt}); - {maxusers, Val} -> - [encode_maxusers(Val, default, Translate)]; - {maxusers, Val, Opts} -> - [encode_maxusers(Val, Opts, Translate)]; - {membersonly, Val} -> - [encode_membersonly(Val, Translate)]; - {membersonly, _, _} -> erlang:error({badarg, Opt}); - {moderatedroom, Val} -> - [encode_moderatedroom(Val, Translate)]; - {moderatedroom, _, _} -> erlang:error({badarg, Opt}); - {members_by_default, Val} -> - [encode_members_by_default(Val, Translate)]; - {members_by_default, _, _} -> - erlang:error({badarg, Opt}); - {passwordprotectedroom, Val} -> - [encode_passwordprotectedroom(Val, Translate)]; - {passwordprotectedroom, _, _} -> - erlang:error({badarg, Opt}); - {persistentroom, Val} -> - [encode_persistentroom(Val, Translate)]; - {persistentroom, _, _} -> erlang:error({badarg, Opt}); - {presencebroadcast, Val} -> - [encode_presencebroadcast(Val, default, Translate)]; - {presencebroadcast, Val, Opts} -> - [encode_presencebroadcast(Val, Opts, Translate)]; - {publicroom, Val} -> - [encode_publicroom(Val, Translate)]; - {publicroom, _, _} -> erlang:error({badarg, Opt}); - {public_list, Val} -> - [encode_public_list(Val, Translate)]; - {public_list, _, _} -> erlang:error({badarg, Opt}); - {roomadmins, Val} -> - [encode_roomadmins(Val, Translate)]; - {roomadmins, _, _} -> erlang:error({badarg, Opt}); - {roomdesc, Val} -> [encode_roomdesc(Val, Translate)]; - {roomdesc, _, _} -> erlang:error({badarg, Opt}); - {roomname, Val} -> [encode_roomname(Val, Translate)]; - {roomname, _, _} -> erlang:error({badarg, Opt}); - {roomowners, Val} -> - [encode_roomowners(Val, Translate)]; - {roomowners, _, _} -> erlang:error({badarg, Opt}); - {roomsecret, Val} -> - [encode_roomsecret(Val, Translate)]; - {roomsecret, _, _} -> erlang:error({badarg, Opt}); - {whois, Val} -> [encode_whois(Val, default, Translate)]; - {whois, Val, Opts} -> - [encode_whois(Val, Opts, Translate)]; - {mam, Val} -> [encode_mam(Val, Translate)]; - {mam, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/muc#roomconfig">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{maxhistoryfetch, Result} | Acc], - lists:delete(<<"muc#maxhistoryfetch">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#maxhistoryfetch">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#maxhistoryfetch">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{allowpm, Result} | Acc], - lists:delete(<<"muc#roomconfig_allowpm">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_allowpm">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_allowpm">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roomconfig_allowpm">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_allowpm">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"allow_private_messages">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_private_messages, Result} | Acc], - lists:delete(<<"allow_private_messages">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_private_messages">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_private_messages">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"allow_private_messages">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"allow_private_messages">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_private_messages">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"allow_private_messages_from_visitors">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [nobody, moderators, anyone]) of - Result -> - decode(Fs, - [{allow_private_messages_from_visitors, Result} | Acc], - lists:delete(<<"allow_private_messages_from_visitors">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, - <<"allow_private_messages_from_visitors">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"allow_private_messages_from_visitors">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"allow_private_messages_from_visitors">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"allow_private_messages_from_visitors">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, - <<"allow_private_messages_from_visitors">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"allow_visitor_status">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_visitor_status, Result} | Acc], - lists:delete(<<"allow_visitor_status">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_visitor_status">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_visitor_status">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"allow_visitor_status">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"allow_visitor_status">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_visitor_status">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"allow_visitor_nickchange">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_visitor_nickchange, Result} | Acc], - lists:delete(<<"allow_visitor_nickchange">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_visitor_nickchange">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"allow_visitor_nickchange">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"allow_visitor_nickchange">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"allow_visitor_nickchange">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_visitor_nickchange">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"allow_voice_requests">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_voice_requests, Result} | Acc], - lists:delete(<<"allow_voice_requests">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_voice_requests">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_voice_requests">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"allow_voice_requests">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"allow_voice_requests">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_voice_requests">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"allow_subscription">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_subscription, Result} | Acc], - lists:delete(<<"allow_subscription">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_subscription">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_subscription">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"allow_subscription">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"allow_subscription">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_subscription">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"voice_request_min_interval">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{voice_request_min_interval, Result} | Acc], - lists:delete(<<"voice_request_min_interval">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"voice_request_min_interval">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"voice_request_min_interval">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"voice_request_min_interval">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"voice_request_min_interval">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"voice_request_min_interval">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"captcha_protected">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{captcha_protected, Result} | Acc], - lists:delete(<<"captcha_protected">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"captcha_protected">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"captcha_protected">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"captcha_protected">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"captcha_protected">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"captcha_protected">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"captcha_whitelist">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, [{captcha_whitelist, Result} | Acc], - lists:delete(<<"captcha_whitelist">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"captcha_whitelist">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_query_users">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow_query_users, Result} | Acc], - lists:delete(<<"allow_query_users">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"allow_query_users">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"allow_query_users">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"allow_query_users">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"allow_query_users">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"allow_query_users">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_allowinvites">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allowinvites, Result} | Acc], - lists:delete(<<"muc#roomconfig_allowinvites">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_allowinvites">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_allowinvites">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_allowinvites">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_allowinvites">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_allowinvites">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_changesubject">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{changesubject, Result} | Acc], - lists:delete(<<"muc#roomconfig_changesubject">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_changesubject">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_changesubject">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_changesubject">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_changesubject">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_changesubject">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_enablelogging">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{enablelogging, Result} | Acc], - lists:delete(<<"muc#roomconfig_enablelogging">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_enablelogging">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_enablelogging">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_enablelogging">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_enablelogging">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_enablelogging">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_getmemberlist">>, - values = Values} - | Fs], - Acc, Required) -> - try [Value || Value <- Values] of - Result -> - decode(Fs, [{getmemberlist, Result} | Acc], - lists:delete(<<"muc#roomconfig_getmemberlist">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_getmemberlist">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#roomconfig_lang">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{lang, Result} | Acc], - lists:delete(<<"muc#roomconfig_lang">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_lang">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#roomconfig_lang">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roomconfig_lang">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roomconfig_lang">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_lang">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{pubsub, Result} | Acc], - lists:delete(<<"muc#roomconfig_pubsub">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_pubsub">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roomconfig_pubsub">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roomconfig_pubsub">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_pubsub">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_maxusers">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum_int(Value, [none], 0, infinity) of - Result -> - decode(Fs, [{maxusers, Result} | Acc], - lists:delete(<<"muc#roomconfig_maxusers">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_maxusers">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_maxusers">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_maxusers">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_maxusers">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_maxusers">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_membersonly">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{membersonly, Result} | Acc], - lists:delete(<<"muc#roomconfig_membersonly">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_membersonly">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_membersonly">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_membersonly">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_membersonly">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_membersonly">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_moderatedroom">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{moderatedroom, Result} | Acc], - lists:delete(<<"muc#roomconfig_moderatedroom">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_moderatedroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_moderatedroom">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_moderatedroom">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_moderatedroom">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_moderatedroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"members_by_default">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{members_by_default, Result} | Acc], - lists:delete(<<"members_by_default">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"members_by_default">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"members_by_default">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"members_by_default">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"members_by_default">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"members_by_default">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_passwordprotectedroom">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{passwordprotectedroom, Result} | Acc], - lists:delete(<<"muc#roomconfig_passwordprotectedroom">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, - <<"muc#roomconfig_passwordprotectedroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_passwordprotectedroom">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_passwordprotectedroom">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_passwordprotectedroom">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, - <<"muc#roomconfig_passwordprotectedroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_persistentroom">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{persistentroom, Result} | Acc], - lists:delete(<<"muc#roomconfig_persistentroom">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_persistentroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_persistentroom">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_persistentroom">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_persistentroom">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_persistentroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_presencebroadcast">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_enum(Value, [moderator, participant, visitor]) - || Value <- Values] - of - Result -> - decode(Fs, [{presencebroadcast, Result} | Acc], - lists:delete(<<"muc#roomconfig_presencebroadcast">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_presencebroadcast">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_publicroom">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{publicroom, Result} | Acc], - lists:delete(<<"muc#roomconfig_publicroom">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_publicroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_publicroom">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_publicroom">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_publicroom">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_publicroom">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"public_list">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{public_list, Result} | Acc], - lists:delete(<<"public_list">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"public_list">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"public_list">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"public_list">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"public_list">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"public_list">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_roomadmins">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, [{roomadmins, Result} | Acc], - lists:delete(<<"muc#roomconfig_roomadmins">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_roomadmins">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_roomdesc">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{roomdesc, Result} | Acc], - lists:delete(<<"muc#roomconfig_roomdesc">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_roomdesc">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_roomdesc">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_roomdesc">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_roomdesc">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_roomdesc">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_roomname">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{roomname, Result} | Acc], - lists:delete(<<"muc#roomconfig_roomname">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_roomname">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_roomname">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_roomname">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_roomname">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_roomname">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = - <<"muc#roomconfig_roomowners">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, [{roomowners, Result} | Acc], - lists:delete(<<"muc#roomconfig_roomowners">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_roomowners">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_roomsecret">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{roomsecret, Result} | Acc], - lists:delete(<<"muc#roomconfig_roomsecret">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_roomsecret">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = - <<"muc#roomconfig_roomsecret">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roomconfig_roomsecret">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roomconfig_roomsecret">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_roomsecret">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"muc#roomconfig_whois">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [moderators, anyone]) of - Result -> - decode(Fs, [{whois, Result} | Acc], - lists:delete(<<"muc#roomconfig_whois">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roomconfig_whois">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"muc#roomconfig_whois">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roomconfig_whois">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roomconfig_whois">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roomconfig_whois">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = <<"mam">>, values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{mam, Result} | Acc], - lists:delete(<<"mam">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"mam">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}) - end; -decode([#xdata_field{var = <<"mam">>, values = []} = F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"mam">>, values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"mam">>} | _], _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"mam">>, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/muc#roomconfig">>}}); -decode([], Acc, []) -> Acc. - -encode_maxhistoryfetch(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#maxhistoryfetch">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Maximum Number of History Messages Returned " - "by Room">>)}. - -encode_allowpm(Value, Options, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = if Options == default -> []; - true -> - [#xdata_option{label = Translate(L), value = V} - || {L, V} <- Options] - end, - #xdata_field{var = <<"muc#roomconfig_allowpm">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Roles that May Send Private Messages">>)}. - -encode_allow_private_messages(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_private_messages">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow users to send private messages">>)}. - -encode_allow_private_messages_from_visitors(Value, - Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"nobody">>), - value = <<"nobody">>}, - #xdata_option{label = Translate(<<"moderators only">>), - value = <<"moderators">>}, - #xdata_option{label = Translate(<<"anyone">>), - value = <<"anyone">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = - <<"allow_private_messages_from_visitors">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Allow visitors to send private messages to">>)}. - -encode_allow_visitor_status(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_visitor_status">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow visitors to send status text in " - "presence updates">>)}. - -encode_allow_visitor_nickchange(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_visitor_nickchange">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow visitors to change nickname">>)}. - -encode_allow_voice_requests(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_voice_requests">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow visitors to send voice requests">>)}. - -encode_allow_subscription(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_subscription">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Allow subscription">>)}. - -encode_voice_request_min_interval(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"voice_request_min_interval">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Minimum interval between voice requests " - "(in seconds)">>)}. - -encode_captcha_protected(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"captcha_protected">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room CAPTCHA protected">>)}. - -encode_captcha_whitelist(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = <<"captcha_whitelist">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"Exclude Jabber IDs from CAPTCHA challenge">>)}. - -encode_allow_query_users(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"allow_query_users">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow users to query other users">>)}. - -encode_allowinvites(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_allowinvites">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Allow users to send invites">>)}. - -encode_changesubject(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_changesubject">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Allow users to change the subject">>)}. - -encode_enablelogging(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_enablelogging">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Enable logging">>)}. - -encode_getmemberlist(Value, Options, Translate) -> - Values = case Value of - [] -> []; - Value -> [Value] - end, - Opts = if Options == default -> []; - true -> - [#xdata_option{label = Translate(L), value = V} - || {L, V} <- Options] - end, - #xdata_field{var = <<"muc#roomconfig_getmemberlist">>, - values = Values, required = false, type = 'list-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"Roles and Affiliations that May Retrieve " - "Member List">>)}. - -encode_lang(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_lang">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Natural Language for Room Discussions">>)}. - -encode_pubsub(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_pubsub">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"XMPP URI of Associated Publish-Subscribe " - "Node">>)}. - -encode_maxusers(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum_int(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"No limit">>), - value = <<"none">>}, - #xdata_option{value = <<"5">>}, - #xdata_option{value = <<"10">>}, - #xdata_option{value = <<"20">>}, - #xdata_option{value = <<"30">>}, - #xdata_option{value = <<"50">>}, - #xdata_option{value = <<"100">>}, - #xdata_option{value = <<"200">>}, - #xdata_option{value = <<"500">>}, - #xdata_option{value = <<"1000">>}, - #xdata_option{value = <<"2000">>}, - #xdata_option{value = <<"5000">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum_int(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"muc#roomconfig_maxusers">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = Translate(<<"Maximum Number of Occupants">>)}. - -encode_membersonly(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_membersonly">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room members-only">>)}. - -encode_moderatedroom(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_moderatedroom">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room moderated">>)}. - -encode_members_by_default(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"members_by_default">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Default users as participants">>)}. - -encode_passwordprotectedroom(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = - <<"muc#roomconfig_passwordprotectedroom">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room password protected">>)}. - -encode_persistentroom(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_persistentroom">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room persistent">>)}. - -encode_presencebroadcast(Value, Options, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_enum(V) || V <- Value] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"Moderator">>), - value = <<"moderator">>}, - #xdata_option{label = Translate(<<"Participant">>), - value = <<"participant">>}, - #xdata_option{label = Translate(<<"Visitor">>), - value = <<"visitor">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = - <<"muc#roomconfig_presencebroadcast">>, - values = Values, required = false, type = 'list-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"Roles for which Presence is Broadcasted">>)}. - -encode_publicroom(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_publicroom">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Make room public searchable">>)}. - -encode_public_list(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"public_list">>, values = Values, - required = false, type = boolean, options = Opts, - desc = <<>>, - label = Translate(<<"Make participants list public">>)}. - -encode_roomadmins(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_roomadmins">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = Translate(<<"Full List of Room Admins">>)}. - -encode_roomdesc(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_roomdesc">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Room description">>)}. - -encode_roomname(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_roomname">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Room title">>)}. - -encode_roomowners(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_roomowners">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = Translate(<<"Full List of Room Owners">>)}. - -encode_roomsecret(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roomconfig_roomsecret">>, - values = Values, required = false, - type = 'text-private', options = Opts, desc = <<>>, - label = Translate(<<"Password">>)}. - -encode_whois(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"moderators only">>), - value = <<"moderators">>}, - #xdata_option{label = Translate(<<"anyone">>), - value = <<"anyone">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"muc#roomconfig_whois">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = Translate(<<"Present real Jabber IDs to">>)}. - -encode_mam(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"mam">>, values = Values, - required = false, type = boolean, options = Opts, - desc = <<>>, - label = Translate(<<"Enable message archiving">>)}. diff --git a/src/muc_roominfo.erl b/src/muc_roominfo.erl deleted file mode 100644 index bd5cb011b..000000000 --- a/src/muc_roominfo.erl +++ /dev/null @@ -1,491 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: muc_roominfo.xdata -%% Form type: http://jabber.org/protocol/muc#roominfo -%% Document: XEP-0045 - --module(muc_roominfo). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("muc_roominfo.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> Int; - Int when Int =< Max, Int >= Min -> Int - end. - -enc_int(Int) -> integer_to_binary(Int). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/muc#roominfo">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {maxhistoryfetch, Val} -> - [encode_maxhistoryfetch(Val, Translate)]; - {maxhistoryfetch, _, _} -> erlang:error({badarg, Opt}); - {contactjid, Val} -> - [encode_contactjid(Val, Translate)]; - {contactjid, _, _} -> erlang:error({badarg, Opt}); - {description, Val} -> - [encode_description(Val, Translate)]; - {description, _, _} -> erlang:error({badarg, Opt}); - {lang, Val} -> [encode_lang(Val, Translate)]; - {lang, _, _} -> erlang:error({badarg, Opt}); - {ldapgroup, Val} -> [encode_ldapgroup(Val, Translate)]; - {ldapgroup, _, _} -> erlang:error({badarg, Opt}); - {logs, Val} -> [encode_logs(Val, Translate)]; - {logs, _, _} -> erlang:error({badarg, Opt}); - {occupants, Val} -> [encode_occupants(Val, Translate)]; - {occupants, _, _} -> erlang:error({badarg, Opt}); - {subject, Val} -> [encode_subject(Val, Translate)]; - {subject, _, _} -> erlang:error({badarg, Opt}); - {subjectmod, Val} -> - [encode_subjectmod(Val, Translate)]; - {subjectmod, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/muc#roominfo">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{maxhistoryfetch, Result} | Acc], - lists:delete(<<"muc#maxhistoryfetch">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#maxhistoryfetch">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#maxhistoryfetch">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#maxhistoryfetch">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#maxhistoryfetch">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = - <<"muc#roominfo_contactjid">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, [{contactjid, Result} | Acc], - lists:delete(<<"muc#roominfo_contactjid">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_contactjid">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = - <<"muc#roominfo_description">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{description, Result} | Acc], - lists:delete(<<"muc#roominfo_description">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_description">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = - <<"muc#roominfo_description">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roominfo_description">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roominfo_description">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_description">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = <<"muc#roominfo_lang">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{lang, Result} | Acc], - lists:delete(<<"muc#roominfo_lang">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_lang">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#roominfo_lang">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roominfo_lang">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roominfo_lang">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_lang">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{ldapgroup, Result} | Acc], - lists:delete(<<"muc#roominfo_ldapgroup">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_ldapgroup">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roominfo_ldapgroup">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_ldapgroup">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = <<"muc#roominfo_logs">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{logs, Result} | Acc], - lists:delete(<<"muc#roominfo_logs">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_logs">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#roominfo_logs">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roominfo_logs">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roominfo_logs">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_logs">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = <<"muc#roominfo_occupants">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{occupants, Result} | Acc], - lists:delete(<<"muc#roominfo_occupants">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_occupants">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#roominfo_occupants">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roominfo_occupants">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roominfo_occupants">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_occupants">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = <<"muc#roominfo_subject">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{subject, Result} | Acc], - lists:delete(<<"muc#roominfo_subject">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_subject">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = <<"muc#roominfo_subject">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"muc#roominfo_subject">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"muc#roominfo_subject">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_subject">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = - <<"muc#roominfo_subjectmod">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{subjectmod, Result} | Acc], - lists:delete(<<"muc#roominfo_subjectmod">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"muc#roominfo_subjectmod">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}) - end; -decode([#xdata_field{var = - <<"muc#roominfo_subjectmod">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"muc#roominfo_subjectmod">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"muc#roominfo_subjectmod">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"muc#roominfo_subjectmod">>, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/muc#roominfo">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/muc#roominfo">>}}); -decode([], Acc, []) -> Acc. - -encode_maxhistoryfetch(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#maxhistoryfetch">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Maximum Number of History Messages Returned " - "by Room">>)}. - -encode_contactjid(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_contactjid">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"Contact Addresses (normally, room owner " - "or owners)">>)}. - -encode_description(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_description">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Room description">>)}. - -encode_lang(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_lang">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Natural Language for Room Discussions">>)}. - -encode_ldapgroup(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_ldapgroup">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"An associated LDAP group that defines " - "room membership; this should be an LDAP " - "Distinguished Name according to an implementa" - "tion-specific or deployment-specific " - "definition of a group.">>)}. - -encode_logs(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_logs">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"URL for Archived Discussion Logs">>)}. - -encode_occupants(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_occupants">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Number of occupants">>)}. - -encode_subject(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_subject">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Current Discussion Topic">>)}. - -encode_subjectmod(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"muc#roominfo_subjectmod">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"The room subject can be modified by " - "participants">>)}. diff --git a/src/pubsub_get_pending.erl b/src/pubsub_get_pending.erl deleted file mode 100644 index c1f2ba3ad..000000000 --- a/src/pubsub_get_pending.erl +++ /dev/null @@ -1,130 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: pubsub_get_pending.xdata -%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization -%% Document: XEP-0060 - --module(pubsub_get_pending). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("pubsub_get_pending.hrl"). - --export_type([property/0, result/0, form/0]). - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, [<<"pubsub#node">>]); - #xdata_field{values = - [<<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>]} -> - decode(Fs, Acc, [<<"pubsub#node">>]); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {node, Val} -> [encode_node(Val, default, Translate)]; - {node, Val, Opts} -> - [encode_node(Val, Opts, Translate)]; - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"pubsub#node">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{node, Result} | Acc], - lists:delete(<<"pubsub#node">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#node">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end; -decode([#xdata_field{var = <<"pubsub#node">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#node">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#node">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#node">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([], Acc, []) -> Acc. - -encode_node(Value, Options, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = if Options == default -> []; - true -> - [#xdata_option{label = Translate(L), value = V} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#node">>, values = Values, - required = false, type = 'list-single', options = Opts, - desc = <<>>, - label = - Translate(<<"The NodeID of the relevant node">>)}. diff --git a/src/pubsub_node_config.erl b/src/pubsub_node_config.erl deleted file mode 100644 index e831d6a83..000000000 --- a/src/pubsub_node_config.erl +++ /dev/null @@ -1,1666 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: pubsub_node_config.xdata -%% Form type: http://jabber.org/protocol/pubsub#node_config -%% Document: XEP-0060 - --module(pubsub_node_config). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("pubsub_node_config.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> Int; - Int when Int =< Max, Int >= Min -> Int - end. - -enc_int(Int) -> integer_to_binary(Int). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/pubsub#node_config">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {access_model, Val} -> - [encode_access_model(Val, default, Translate)]; - {access_model, Val, Opts} -> - [encode_access_model(Val, Opts, Translate)]; - {body_xslt, Val} -> [encode_body_xslt(Val, Translate)]; - {body_xslt, _, _} -> erlang:error({badarg, Opt}); - {children_association_policy, Val} -> - [encode_children_association_policy(Val, default, - Translate)]; - {children_association_policy, Val, Opts} -> - [encode_children_association_policy(Val, Opts, - Translate)]; - {children_association_whitelist, Val} -> - [encode_children_association_whitelist(Val, Translate)]; - {children_association_whitelist, _, _} -> - erlang:error({badarg, Opt}); - {children, Val} -> [encode_children(Val, Translate)]; - {children, _, _} -> erlang:error({badarg, Opt}); - {children_max, Val} -> - [encode_children_max(Val, Translate)]; - {children_max, _, _} -> erlang:error({badarg, Opt}); - {collection, Val} -> - [encode_collection(Val, Translate)]; - {collection, _, _} -> erlang:error({badarg, Opt}); - {contact, Val} -> [encode_contact(Val, Translate)]; - {contact, _, _} -> erlang:error({badarg, Opt}); - {dataform_xslt, Val} -> - [encode_dataform_xslt(Val, Translate)]; - {dataform_xslt, _, _} -> erlang:error({badarg, Opt}); - {deliver_notifications, Val} -> - [encode_deliver_notifications(Val, Translate)]; - {deliver_notifications, _, _} -> - erlang:error({badarg, Opt}); - {deliver_payloads, Val} -> - [encode_deliver_payloads(Val, Translate)]; - {deliver_payloads, _, _} -> erlang:error({badarg, Opt}); - {description, Val} -> - [encode_description(Val, Translate)]; - {description, _, _} -> erlang:error({badarg, Opt}); - {item_expire, Val} -> - [encode_item_expire(Val, Translate)]; - {item_expire, _, _} -> erlang:error({badarg, Opt}); - {itemreply, Val} -> - [encode_itemreply(Val, default, Translate)]; - {itemreply, Val, Opts} -> - [encode_itemreply(Val, Opts, Translate)]; - {language, Val} -> - [encode_language(Val, default, Translate)]; - {language, Val, Opts} -> - [encode_language(Val, Opts, Translate)]; - {max_items, Val} -> [encode_max_items(Val, Translate)]; - {max_items, _, _} -> erlang:error({badarg, Opt}); - {max_payload_size, Val} -> - [encode_max_payload_size(Val, Translate)]; - {max_payload_size, _, _} -> erlang:error({badarg, Opt}); - {node_type, Val} -> - [encode_node_type(Val, default, Translate)]; - {node_type, Val, Opts} -> - [encode_node_type(Val, Opts, Translate)]; - {notification_type, Val} -> - [encode_notification_type(Val, default, Translate)]; - {notification_type, Val, Opts} -> - [encode_notification_type(Val, Opts, Translate)]; - {notify_config, Val} -> - [encode_notify_config(Val, Translate)]; - {notify_config, _, _} -> erlang:error({badarg, Opt}); - {notify_delete, Val} -> - [encode_notify_delete(Val, Translate)]; - {notify_delete, _, _} -> erlang:error({badarg, Opt}); - {notify_retract, Val} -> - [encode_notify_retract(Val, Translate)]; - {notify_retract, _, _} -> erlang:error({badarg, Opt}); - {notify_sub, Val} -> - [encode_notify_sub(Val, Translate)]; - {notify_sub, _, _} -> erlang:error({badarg, Opt}); - {persist_items, Val} -> - [encode_persist_items(Val, Translate)]; - {persist_items, _, _} -> erlang:error({badarg, Opt}); - {presence_based_delivery, Val} -> - [encode_presence_based_delivery(Val, Translate)]; - {presence_based_delivery, _, _} -> - erlang:error({badarg, Opt}); - {publish_model, Val} -> - [encode_publish_model(Val, default, Translate)]; - {publish_model, Val, Opts} -> - [encode_publish_model(Val, Opts, Translate)]; - {purge_offline, Val} -> - [encode_purge_offline(Val, Translate)]; - {purge_offline, _, _} -> erlang:error({badarg, Opt}); - {roster_groups_allowed, Val} -> - [encode_roster_groups_allowed(Val, default, Translate)]; - {roster_groups_allowed, Val, Opts} -> - [encode_roster_groups_allowed(Val, Opts, Translate)]; - {send_last_published_item, Val} -> - [encode_send_last_published_item(Val, default, - Translate)]; - {send_last_published_item, Val, Opts} -> - [encode_send_last_published_item(Val, Opts, Translate)]; - {tempsub, Val} -> [encode_tempsub(Val, Translate)]; - {tempsub, _, _} -> erlang:error({badarg, Opt}); - {subscribe, Val} -> [encode_subscribe(Val, Translate)]; - {subscribe, _, _} -> erlang:error({badarg, Opt}); - {title, Val} -> [encode_title(Val, Translate)]; - {title, _, _} -> erlang:error({badarg, Opt}); - {type, Val} -> [encode_type(Val, Translate)]; - {type, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/pubsub#node_config">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"pubsub#access_model">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, - [authorize, open, presence, roster, whitelist]) - of - Result -> - decode(Fs, [{access_model, Result} | Acc], - lists:delete(<<"pubsub#access_model">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#access_model">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#access_model">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#access_model">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#access_model">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#access_model">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#body_xslt">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{body_xslt, Result} | Acc], - lists:delete(<<"pubsub#body_xslt">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#body_xslt">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#body_xslt">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#body_xslt">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#body_xslt">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#body_xslt">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#children_association_policy">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [all, owners, whitelist]) of - Result -> - decode(Fs, - [{children_association_policy, Result} | Acc], - lists:delete(<<"pubsub#children_association_policy">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, - <<"pubsub#children_association_policy">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#children_association_policy">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#children_association_policy">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#children_association_policy">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, - <<"pubsub#children_association_policy">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#children_association_whitelist">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, - [{children_association_whitelist, Result} | Acc], - lists:delete(<<"pubsub#children_association_whitelist">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, - <<"pubsub#children_association_whitelist">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#children">>, - values = Values} - | Fs], - Acc, Required) -> - try [Value || Value <- Values] of - Result -> - decode(Fs, [{children, Result} | Acc], - lists:delete(<<"pubsub#children">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#children">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#children_max">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{children_max, Result} | Acc], - lists:delete(<<"pubsub#children_max">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#children_max">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#children_max">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#children_max">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#children_max">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#children_max">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#collection">>, - values = Values} - | Fs], - Acc, Required) -> - try [Value || Value <- Values] of - Result -> - decode(Fs, [{collection, Result} | Acc], - lists:delete(<<"pubsub#collection">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#collection">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#contact">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_jid(Value) || Value <- Values] of - Result -> - decode(Fs, [{contact, Result} | Acc], - lists:delete(<<"pubsub#contact">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#contact">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#dataform_xslt">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{dataform_xslt, Result} | Acc], - lists:delete(<<"pubsub#dataform_xslt">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#dataform_xslt">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#dataform_xslt">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#dataform_xslt">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#dataform_xslt">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#dataform_xslt">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#deliver_notifications">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{deliver_notifications, Result} | Acc], - lists:delete(<<"pubsub#deliver_notifications">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#deliver_notifications">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#deliver_notifications">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#deliver_notifications">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#deliver_notifications">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#deliver_notifications">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#deliver_payloads">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{deliver_payloads, Result} | Acc], - lists:delete(<<"pubsub#deliver_payloads">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#deliver_payloads">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#deliver_payloads">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#deliver_payloads">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#deliver_payloads">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#deliver_payloads">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#description">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{description, Result} | Acc], - lists:delete(<<"pubsub#description">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#description">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#description">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#description">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#description">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#description">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#item_expire">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{item_expire, Result} | Acc], - lists:delete(<<"pubsub#item_expire">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#item_expire">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#item_expire">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#item_expire">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#item_expire">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#item_expire">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#itemreply">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [owner, publisher, none]) of - Result -> - decode(Fs, [{itemreply, Result} | Acc], - lists:delete(<<"pubsub#itemreply">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#itemreply">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#itemreply">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#itemreply">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#itemreply">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#itemreply">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#language">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{language, Result} | Acc], - lists:delete(<<"pubsub#language">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#language">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#language">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#language">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#language">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#language">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#max_items">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{max_items, Result} | Acc], - lists:delete(<<"pubsub#max_items">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#max_items">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#max_items">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#max_items">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#max_items">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#max_items">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#max_payload_size">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_int(Value, 0, infinity) of - Result -> - decode(Fs, [{max_payload_size, Result} | Acc], - lists:delete(<<"pubsub#max_payload_size">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#max_payload_size">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#max_payload_size">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#max_payload_size">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#max_payload_size">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#max_payload_size">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#node_type">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [leaf, collection]) of - Result -> - decode(Fs, [{node_type, Result} | Acc], - lists:delete(<<"pubsub#node_type">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#node_type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#node_type">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#node_type">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#node_type">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#node_type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#notification_type">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [normal, headline]) of - Result -> - decode(Fs, [{notification_type, Result} | Acc], - lists:delete(<<"pubsub#notification_type">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#notification_type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#notification_type">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#notification_type">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#notification_type">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#notification_type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#notify_config">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{notify_config, Result} | Acc], - lists:delete(<<"pubsub#notify_config">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#notify_config">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#notify_config">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#notify_config">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#notify_config">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#notify_config">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#notify_delete">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{notify_delete, Result} | Acc], - lists:delete(<<"pubsub#notify_delete">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#notify_delete">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#notify_delete">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#notify_delete">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#notify_delete">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#notify_delete">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#notify_retract">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{notify_retract, Result} | Acc], - lists:delete(<<"pubsub#notify_retract">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#notify_retract">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#notify_retract">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#notify_retract">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#notify_retract">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#notify_retract">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#notify_sub">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{notify_sub, Result} | Acc], - lists:delete(<<"pubsub#notify_sub">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#notify_sub">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#notify_sub">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#notify_sub">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#notify_sub">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#notify_sub">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#persist_items">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{persist_items, Result} | Acc], - lists:delete(<<"pubsub#persist_items">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#persist_items">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#persist_items">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#persist_items">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#persist_items">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#persist_items">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#presence_based_delivery">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{presence_based_delivery, Result} | Acc], - lists:delete(<<"pubsub#presence_based_delivery">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#presence_based_delivery">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#presence_based_delivery">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#presence_based_delivery">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#presence_based_delivery">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#presence_based_delivery">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#publish_model">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [publishers, subscribers, open]) of - Result -> - decode(Fs, [{publish_model, Result} | Acc], - lists:delete(<<"pubsub#publish_model">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#publish_model">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#publish_model">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#publish_model">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#publish_model">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#publish_model">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#purge_offline">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{purge_offline, Result} | Acc], - lists:delete(<<"pubsub#purge_offline">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#purge_offline">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#purge_offline">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#purge_offline">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#purge_offline">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#purge_offline">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = - <<"pubsub#roster_groups_allowed">>, - values = Values} - | Fs], - Acc, Required) -> - try [Value || Value <- Values] of - Result -> - decode(Fs, [{roster_groups_allowed, Result} | Acc], - lists:delete(<<"pubsub#roster_groups_allowed">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#roster_groups_allowed">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#send_last_published_item">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, - [never, on_sub, on_sub_and_presence]) - of - Result -> - decode(Fs, [{send_last_published_item, Result} | Acc], - lists:delete(<<"pubsub#send_last_published_item">>, - Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#send_last_published_item">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#send_last_published_item">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#send_last_published_item">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#send_last_published_item">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#send_last_published_item">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#tempsub">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{tempsub, Result} | Acc], - lists:delete(<<"pubsub#tempsub">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#tempsub">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#tempsub">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#tempsub">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#tempsub">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#tempsub">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#subscribe">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{subscribe, Result} | Acc], - lists:delete(<<"pubsub#subscribe">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#subscribe">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#subscribe">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#subscribe">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#subscribe">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#subscribe">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#title">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{title, Result} | Acc], - lists:delete(<<"pubsub#title">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#title">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#title">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#title">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#title">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#title">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = <<"pubsub#type">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{type, Result} | Acc], - lists:delete(<<"pubsub#type">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}) - end; -decode([#xdata_field{var = <<"pubsub#type">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#type">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#type">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#type">>, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/pubsub#node_config">>}}); -decode([], Acc, []) -> Acc. - -encode_access_model(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Subscription requests must be approved " - "and only subscribers may retrieve items">>), - value = <<"authorize">>}, - #xdata_option{label = - Translate(<<"Anyone may subscribe and retrieve items">>), - value = <<"open">>}, - #xdata_option{label = - Translate(<<"Anyone with a presence subscription " - "of both or from may subscribe and retrieve " - "items">>), - value = <<"presence">>}, - #xdata_option{label = - Translate(<<"Anyone in the specified roster group(s) " - "may subscribe and retrieve items">>), - value = <<"roster">>}, - #xdata_option{label = - Translate(<<"Only those on a whitelist may subscribe " - "and retrieve items">>), - value = <<"whitelist">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#access_model">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = Translate(<<"Specify the access model">>)}. - -encode_body_xslt(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#body_xslt">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"The URL of an XSL transformation which " - "can be applied to payloads in order " - "to generate an appropriate message body " - "element.">>)}. - -encode_children_association_policy(Value, Options, - Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Anyone may associate leaf nodes with " - "the collection">>), - value = <<"all">>}, - #xdata_option{label = - Translate(<<"Only collection node owners may associate " - "leaf nodes with the collection">>), - value = <<"owners">>}, - #xdata_option{label = - Translate(<<"Only those on a whitelist may associate " - "leaf nodes with the collection">>), - value = <<"whitelist">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = - <<"pubsub#children_association_policy">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Who may associate leaf nodes with a " - "collection">>)}. - -encode_children_association_whitelist(Value, - Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = - <<"pubsub#children_association_whitelist">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"The list of JIDs that may associate " - "leaf nodes with a collection">>)}. - -encode_children(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#children">>, - values = Values, required = false, type = 'text-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"The child nodes (leaf or collection) " - "associated with a collection">>)}. - -encode_children_max(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#children_max">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"The maximum number of child nodes that " - "can be associated with a collection">>)}. - -encode_collection(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#collection">>, - values = Values, required = false, type = 'text-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"The collections with which a node is " - "affiliated">>)}. - -encode_contact(Value, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_jid(V) || V <- Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#contact">>, - values = Values, required = false, type = 'jid-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"The JIDs of those to contact with questions">>)}. - -encode_dataform_xslt(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#dataform_xslt">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"The URL of an XSL transformation which " - "can be applied to the payload format " - "in order to generate a valid Data Forms " - "result that the client could display " - "using a generic Data Forms rendering " - "engine">>)}. - -encode_deliver_notifications(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#deliver_notifications">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Deliver event notifications">>)}. - -encode_deliver_payloads(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#deliver_payloads">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Deliver payloads with event notifications">>)}. - -encode_description(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#description">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"A description of the node">>)}. - -encode_item_expire(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#item_expire">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Number of seconds after which to automaticall" - "y purge items">>)}. - -encode_itemreply(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Statically specify a replyto of the " - "node owner(s)">>), - value = <<"owner">>}, - #xdata_option{label = - Translate(<<"Dynamically specify a replyto of the " - "item publisher">>), - value = <<"publisher">>}, - #xdata_option{value = <<"none">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#itemreply">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Whether owners or publisher should receive " - "replies to items">>)}. - -encode_language(Value, Options, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = if Options == default -> []; - true -> - [#xdata_option{label = Translate(L), value = V} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#language">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"The default language of the node">>)}. - -encode_max_items(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#max_items">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Max # of items to persist">>)}. - -encode_max_payload_size(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_int(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#max_payload_size">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = Translate(<<"Max payload size in bytes">>)}. - -encode_node_type(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"The node is a leaf node (default)">>), - value = <<"leaf">>}, - #xdata_option{label = - Translate(<<"The node is a collection node">>), - value = <<"collection">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#node_type">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Whether the node is a leaf (default) " - "or a collection">>)}. - -encode_notification_type(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Messages of type normal">>), - value = <<"normal">>}, - #xdata_option{label = - Translate(<<"Messages of type headline">>), - value = <<"headline">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#notification_type">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"Specify the event message type">>)}. - -encode_notify_config(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#notify_config">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Notify subscribers when the node configuratio" - "n changes">>)}. - -encode_notify_delete(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#notify_delete">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Notify subscribers when the node is " - "deleted">>)}. - -encode_notify_retract(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#notify_retract">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Notify subscribers when items are removed " - "from the node">>)}. - -encode_notify_sub(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#notify_sub">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Whether to notify owners about new subscriber" - "s and unsubscribes">>)}. - -encode_persist_items(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#persist_items">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = Translate(<<"Persist items to storage">>)}. - -encode_presence_based_delivery(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#presence_based_delivery">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Only deliver notifications to available " - "users">>)}. - -encode_publish_model(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Only publishers may publish">>), - value = <<"publishers">>}, - #xdata_option{label = - Translate(<<"Subscribers may publish">>), - value = <<"subscribers">>}, - #xdata_option{label = - Translate(<<"Anyone may publish">>), - value = <<"open">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#publish_model">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = Translate(<<"Specify the publisher model">>)}. - -encode_purge_offline(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#purge_offline">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Purge all items when the relevant publisher " - "goes offline">>)}. - -encode_roster_groups_allowed(Value, Options, - Translate) -> - Values = case Value of - [] -> []; - Value -> [Value] - end, - Opts = if Options == default -> []; - true -> - [#xdata_option{label = Translate(L), value = V} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#roster_groups_allowed">>, - values = Values, required = false, type = 'list-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"Roster groups allowed to subscribe">>)}. - -encode_send_last_published_item(Value, Options, - Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = Translate(<<"Never">>), - value = <<"never">>}, - #xdata_option{label = - Translate(<<"When a new subscription is processed">>), - value = <<"on_sub">>}, - #xdata_option{label = - Translate(<<"When a new subscription is processed " - "and whenever a subscriber comes online">>), - value = <<"on_sub_and_presence">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = - <<"pubsub#send_last_published_item">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = - Translate(<<"When to send the last published item">>)}. - -encode_tempsub(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#tempsub">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Whether to make all subscriptions temporary, " - "based on subscriber presence">>)}. - -encode_subscribe(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#subscribe">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Whether to allow subscriptions">>)}. - -encode_title(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#title">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = Translate(<<"A friendly name for the node">>)}. - -encode_type(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#type">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = - Translate(<<"The type of node data, usually specified " - "by the namespace of the payload (if " - "any)">>)}. diff --git a/src/pubsub_publish_options.erl b/src/pubsub_publish_options.erl deleted file mode 100644 index 6e96946fd..000000000 --- a/src/pubsub_publish_options.erl +++ /dev/null @@ -1,157 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: pubsub_publish_options.xdata -%% Form type: http://jabber.org/protocol/pubsub#publish-options -%% Document: XEP-0060 - --module(pubsub_publish_options). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("pubsub_publish_options.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {access_model, Val} -> - [encode_access_model(Val, default, Translate)]; - {access_model, Val, Opts} -> - [encode_access_model(Val, Opts, Translate)]; - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"pubsub#access_model">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, - [authorize, open, presence, roster, whitelist]) - of - Result -> - decode(Fs, [{access_model, Result} | Acc], - lists:delete(<<"pubsub#access_model">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#access_model">>, - <<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>}}) - end; -decode([#xdata_field{var = <<"pubsub#access_model">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#access_model">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#access_model">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#access_model">>, - <<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/pubsub#publish-opt" - "ions">>}}); -decode([], Acc, []) -> Acc. - -encode_access_model(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Access model of authorize">>), - value = <<"authorize">>}, - #xdata_option{label = - Translate(<<"Access model of open">>), - value = <<"open">>}, - #xdata_option{label = - Translate(<<"Access model of presence">>), - value = <<"presence">>}, - #xdata_option{label = - Translate(<<"Access model of roster">>), - value = <<"roster">>}, - #xdata_option{label = - Translate(<<"Access model of whitelist">>), - value = <<"whitelist">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#access_model">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, - label = Translate(<<"Specify the access model">>)}. diff --git a/src/pubsub_subscribe_authorization.erl b/src/pubsub_subscribe_authorization.erl deleted file mode 100644 index 46538da8d..000000000 --- a/src/pubsub_subscribe_authorization.erl +++ /dev/null @@ -1,279 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: pubsub_subscribe_authorization.xdata -%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization -%% Document: XEP-0060 - --module(pubsub_subscribe_authorization). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("pubsub_subscribe_authorization.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> - decode(Fs, Acc, - [<<"pubsub#allow">>, <<"pubsub#node">>, - <<"pubsub#subscriber_jid">>]); - #xdata_field{values = - [<<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>]} -> - decode(Fs, Acc, - [<<"pubsub#allow">>, <<"pubsub#node">>, - <<"pubsub#subscriber_jid">>]); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {allow, Val} -> [encode_allow(Val, Translate)]; - {allow, _, _} -> erlang:error({badarg, Opt}); - {node, Val} -> [encode_node(Val, Translate)]; - {node, _, _} -> erlang:error({badarg, Opt}); - {subscriber_jid, Val} -> - [encode_subscriber_jid(Val, Translate)]; - {subscriber_jid, _, _} -> erlang:error({badarg, Opt}); - {subid, Val} -> [encode_subid(Val, Translate)]; - {subid, _, _} -> erlang:error({badarg, Opt}); - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"pubsub#allow">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{allow, Result} | Acc], - lists:delete(<<"pubsub#allow">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#allow">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end; -decode([#xdata_field{var = <<"pubsub#allow">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#allow">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#allow">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#allow">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([#xdata_field{var = <<"pubsub#node">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{node, Result} | Acc], - lists:delete(<<"pubsub#node">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#node">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end; -decode([#xdata_field{var = <<"pubsub#node">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#node">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#node">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#node">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([#xdata_field{var = <<"pubsub#subscriber_jid">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_jid(Value) of - Result -> - decode(Fs, [{subscriber_jid, Result} | Acc], - lists:delete(<<"pubsub#subscriber_jid">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#subscriber_jid">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end; -decode([#xdata_field{var = <<"pubsub#subscriber_jid">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#subscriber_jid">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#subscriber_jid">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#subscriber_jid">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([#xdata_field{var = <<"pubsub#subid">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{subid, Result} | Acc], - lists:delete(<<"pubsub#subid">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#subid">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}) - end; -decode([#xdata_field{var = <<"pubsub#subid">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#subid">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#subid">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#subid">>, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_a" - "uthorization">>}}); -decode([], Acc, []) -> Acc. - -encode_allow(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#allow">>, values = Values, - required = false, type = boolean, options = Opts, - desc = <<>>, - label = - Translate(<<"Allow this Jabber ID to subscribe to " - "this pubsub node?">>)}. - -encode_node(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#node">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, label = Translate(<<"Node ID">>)}. - -encode_subscriber_jid(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_jid(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#subscriber_jid">>, - values = Values, required = false, type = 'jid-single', - options = Opts, desc = <<>>, - label = Translate(<<"Subscriber Address">>)}. - -encode_subid(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#subid">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = - Translate(<<"The subscription identifier associated " - "with the subscription request">>)}. diff --git a/src/pubsub_subscribe_options.erl b/src/pubsub_subscribe_options.erl deleted file mode 100644 index 02c046995..000000000 --- a/src/pubsub_subscribe_options.erl +++ /dev/null @@ -1,508 +0,0 @@ -%% Created automatically by xdata generator (xdata_codec.erl) -%% Source: pubsub_subscribe_options.xdata -%% Form type: http://jabber.org/protocol/pubsub#subscribe_options -%% Document: XEP-0060 - --module(pubsub_subscribe_options). - --export([decode/1, decode/2, encode/1, encode/2, - format_error/1]). - --include("xmpp_codec.hrl"). - --include("pubsub_subscribe_options.hrl"). - --export_type([property/0, result/0, form/0]). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, - "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", - Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", - Type/binary, "'">>. - -decode(Fs) -> decode(Fs, []). - -decode(Fs, Acc) -> - case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, - Fs) - of - false -> decode(Fs, Acc, []); - #xdata_field{values = - [<<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>]} -> - decode(Fs, Acc, []); - _ -> - erlang:error({?MODULE, - {form_type_mismatch, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end. - -encode(Cfg) -> encode(Cfg, fun (Text) -> Text end). - -encode(List, Translate) when is_list(List) -> - Fs = [case Opt of - {deliver, Val} -> [encode_deliver(Val, Translate)]; - {deliver, _, _} -> erlang:error({badarg, Opt}); - {digest, Val} -> [encode_digest(Val, Translate)]; - {digest, _, _} -> erlang:error({badarg, Opt}); - {digest_frequency, Val} -> - [encode_digest_frequency(Val, Translate)]; - {digest_frequency, _, _} -> erlang:error({badarg, Opt}); - {expire, Val} -> [encode_expire(Val, Translate)]; - {expire, _, _} -> erlang:error({badarg, Opt}); - {include_body, Val} -> - [encode_include_body(Val, Translate)]; - {include_body, _, _} -> erlang:error({badarg, Opt}); - {'show-values', Val} -> - ['encode_show-values'(Val, default, Translate)]; - {'show-values', Val, Opts} -> - ['encode_show-values'(Val, Opts, Translate)]; - {subscription_type, Val} -> - [encode_subscription_type(Val, default, Translate)]; - {subscription_type, Val, Opts} -> - [encode_subscription_type(Val, Opts, Translate)]; - {subscription_depth, Val} -> - [encode_subscription_depth(Val, default, Translate)]; - {subscription_depth, Val, Opts} -> - [encode_subscription_depth(Val, Opts, Translate)]; - #xdata_field{} -> [Opt]; - _ -> [] - end - || Opt <- List], - FormType = #xdata_field{var = <<"FORM_TYPE">>, - type = hidden, - values = - [<<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>]}, - [FormType | lists:flatten(Fs)]. - -decode([#xdata_field{var = <<"pubsub#deliver">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{deliver, Result} | Acc], - lists:delete(<<"pubsub#deliver">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#deliver">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = <<"pubsub#deliver">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#deliver">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#deliver">>} | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#deliver">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = <<"pubsub#digest">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{digest, Result} | Acc], - lists:delete(<<"pubsub#digest">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#digest">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = <<"pubsub#digest">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#digest">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#digest">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#digest">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = - <<"pubsub#digest_frequency">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{digest_frequency, Result} | Acc], - lists:delete(<<"pubsub#digest_frequency">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#digest_frequency">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#digest_frequency">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#digest_frequency">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#digest_frequency">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#digest_frequency">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = <<"pubsub#expire">>, - values = [Value]} - | Fs], - Acc, Required) -> - try Value of - Result -> - decode(Fs, [{expire, Result} | Acc], - lists:delete(<<"pubsub#expire">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#expire">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = <<"pubsub#expire">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#expire">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#expire">>} | _], _, - _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#expire">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = <<"pubsub#include_body">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_bool(Value) of - Result -> - decode(Fs, [{include_body, Result} | Acc], - lists:delete(<<"pubsub#include_body">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#include_body">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = <<"pubsub#include_body">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = <<"pubsub#include_body">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = <<"pubsub#include_body">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#include_body">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = <<"pubsub#show-values">>, - values = Values} - | Fs], - Acc, Required) -> - try [dec_enum(Value, [away, chat, dnd, online, xa]) - || Value <- Values] - of - Result -> - decode(Fs, [{'show-values', Result} | Acc], - lists:delete(<<"pubsub#show-values">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#show-values">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#subscription_type">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, [items, nodes]) of - Result -> - decode(Fs, [{subscription_type, Result} | Acc], - lists:delete(<<"pubsub#subscription_type">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#subscription_type">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#subscription_type">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#subscription_type">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#subscription_type">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#subscription_type">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = - <<"pubsub#subscription_depth">>, - values = [Value]} - | Fs], - Acc, Required) -> - try dec_enum(Value, ['1', all]) of - Result -> - decode(Fs, [{subscription_depth, Result} | Acc], - lists:delete(<<"pubsub#subscription_depth">>, Required)) - catch - _:_ -> - erlang:error({?MODULE, - {bad_var_value, <<"pubsub#subscription_depth">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}) - end; -decode([#xdata_field{var = - <<"pubsub#subscription_depth">>, - values = []} = - F - | Fs], - Acc, Required) -> - decode([F#xdata_field{var = - <<"pubsub#subscription_depth">>, - values = [<<>>]} - | Fs], - Acc, Required); -decode([#xdata_field{var = - <<"pubsub#subscription_depth">>} - | _], - _, _) -> - erlang:error({?MODULE, - {too_many_values, <<"pubsub#subscription_depth">>, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([#xdata_field{var = Var} | Fs], Acc, Required) -> - if Var /= <<"FORM_TYPE">> -> - erlang:error({?MODULE, - {unknown_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); - true -> decode(Fs, Acc, Required) - end; -decode([], _, [Var | _]) -> - erlang:error({?MODULE, - {missing_required_var, Var, - <<"http://jabber.org/protocol/pubsub#subscribe_o" - "ptions">>}}); -decode([], Acc, []) -> Acc. - -encode_deliver(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#deliver">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Whether an entity wants to receive or " - "disable notifications">>)}. - -encode_digest(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#digest">>, values = Values, - required = false, type = boolean, options = Opts, - desc = <<>>, - label = - Translate(<<"Whether an entity wants to receive digests " - "(aggregations) of notifications or all " - "notifications individually">>)}. - -encode_digest_frequency(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#digest_frequency">>, - values = Values, required = false, type = 'text-single', - options = Opts, desc = <<>>, - label = - Translate(<<"The minimum number of milliseconds between " - "sending any two notification digests">>)}. - -encode_expire(Value, Translate) -> - Values = case Value of - <<>> -> []; - Value -> [Value] - end, - Opts = [], - #xdata_field{var = <<"pubsub#expire">>, values = Values, - required = false, type = 'text-single', options = Opts, - desc = <<>>, - label = - Translate(<<"The DateTime at which a leased subscription " - "will end or has ended">>)}. - -encode_include_body(Value, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_bool(Value)] - end, - Opts = [], - #xdata_field{var = <<"pubsub#include_body">>, - values = Values, required = false, type = boolean, - options = Opts, desc = <<>>, - label = - Translate(<<"Whether an entity wants to receive an " - "XMPP message body in addition to the " - "payload format">>)}. - -'encode_show-values'(Value, Options, Translate) -> - Values = case Value of - [] -> []; - Value -> [enc_enum(V) || V <- Value] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"XMPP Show Value of Away">>), - value = <<"away">>}, - #xdata_option{label = - Translate(<<"XMPP Show Value of Chat">>), - value = <<"chat">>}, - #xdata_option{label = - Translate(<<"XMPP Show Value of DND (Do Not Disturb)">>), - value = <<"dnd">>}, - #xdata_option{label = - Translate(<<"Mere Availability in XMPP (No Show Value)">>), - value = <<"online">>}, - #xdata_option{label = - Translate(<<"XMPP Show Value of XA (Extended Away)">>), - value = <<"xa">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#show-values">>, - values = Values, required = false, type = 'list-multi', - options = Opts, desc = <<>>, - label = - Translate(<<"The presence states for which an entity " - "wants to receive notifications">>)}. - -encode_subscription_type(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Receive notification of new items only">>), - value = <<"items">>}, - #xdata_option{label = - Translate(<<"Receive notification of new nodes only">>), - value = <<"nodes">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#subscription_type">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, label = <<>>}. - -encode_subscription_depth(Value, Options, Translate) -> - Values = case Value of - undefined -> []; - Value -> [enc_enum(Value)] - end, - Opts = if Options == default -> - [#xdata_option{label = - Translate(<<"Receive notification from direct child " - "nodes only">>), - value = <<"1">>}, - #xdata_option{label = - Translate(<<"Receive notification from all descendent " - "nodes">>), - value = <<"all">>}]; - true -> - [#xdata_option{label = Translate(L), - value = enc_enum(V)} - || {L, V} <- Options] - end, - #xdata_field{var = <<"pubsub#subscription_depth">>, - values = Values, required = false, type = 'list-single', - options = Opts, desc = <<>>, label = <<>>}. diff --git a/src/xdata_codec.erl b/src/xdata_codec.erl deleted file mode 100644 index 223f24a1b..000000000 --- a/src/xdata_codec.erl +++ /dev/null @@ -1,648 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc -%%% -%%% @end -%%% Created : 27 Sep 2016 by Evgeny Khramtsov -%%%------------------------------------------------------------------- --module(xdata_codec). - -%% API --export([compile/1, compile/2]). --export([dec_int/1, dec_int/3, dec_enum/2, dec_bool/1, not_empty/1, - dec_enum_int/2, dec_enum_int/4, enc_int/1, enc_enum/1, - enc_bool/1, enc_enum_int/1, format_error/1, enc_jid/1, dec_jid/1]). --include("xmpp.hrl"). - --record(state, {mod_name :: atom(), - file_name :: string(), - erl = "" :: string(), - hrl = "" :: string(), - dir = "" :: string(), - ns = <<>> :: binary(), - doc = <<>> :: binary(), - erl_dir = "" :: string(), - hrl_dir = "" :: string(), - prefix = [] :: [binary()], - dec_mfas = [] :: [{binary(), mfa()}], - enc_mfas = [] :: [{binary(), mfa()}], - specs = [] :: [{binary(), string()}], - required = [] :: [{binary(), boolean()} | binary()], - defaults = [] :: [{binary(), any()}]}). - --define(is_multi_type(T), - ((T == 'list-multi') or (T == 'jid-multi') or (T == 'text-multi'))). - --define(is_list_type(T), - ((T == 'list-single') or (T == 'list-multi'))). - -%%%=================================================================== -%%% API -%%%=================================================================== -compile(Path) -> - compile(Path, []). - -compile(Path, Opts) -> - case filelib:is_dir(Path) of - true -> - filelib:fold_files( - Path, ".*.xdata", false, - fun(File, ok) -> - compile_file(File, Opts); - (_, Err) -> - Err - end, ok); - false -> - compile_file(Path, Opts) - end. - -compile_file(Path, Opts) -> - try - ok = application:ensure_started(fast_xml), - DirName = filename:dirname(Path), - FileName = filename:basename(Path), - RootName = filename:rootname(FileName), - ConfigPath = filename:join(DirName, RootName) ++ ".cfg", - ModName = list_to_atom(RootName), - {ok, Data} = file:read_file(Path), - Config = case file:consult(ConfigPath) of - {ok, Terms} -> lists:flatten(Terms); - {error, enoent} -> [] - end, - State = #state{mod_name = ModName, - file_name = FileName, - erl = filename:rootname(FileName) ++ ".erl", - hrl = filename:rootname(FileName) ++ ".hrl", - dir = DirName, - prefix = proplists:get_all_values(prefix, Config), - erl_dir = proplists:get_value(erl_dir, Opts, DirName), - hrl_dir = proplists:get_value(hrl_dir, Opts, DirName), - dec_mfas = proplists:get_value(decode, Config, []), - enc_mfas = proplists:get_value(encode, Config, []), - specs = proplists:get_value(specs, Config, []), - required = proplists:get_value(required, Config, []), - defaults = proplists:get_value(defaults, Config, [])}, - #xmlel{} = El = fxml_stream:parse_element(Data), - ok = compile_element(normalize(El), State), - io:format("Compiled ~s~n", [Path]) - catch _:{badmatch, Err} -> - io:format(standard_error, "Failed to compile ~s: ~p~n", - [Path, Err]), - Err - end. - -emit(Format) -> - emit(Format, []). - -emit(Format, Args) -> - put(outbuf, get(outbuf) ++ io_lib:format(Format, Args)). - -dec_int(Val) -> - dec_int(Val, infinity, infinity). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> - Int; - Int when Int =< Max, Int >= Min -> - Int - end. - -enc_int(Int) -> - integer_to_binary(Int). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> - AtomVal - end. - -enc_enum(Atom) -> - erlang:atom_to_binary(Atom, utf8). - -dec_enum_int(Val, Enums) -> - try dec_int(Val) - catch _:_ -> dec_enum(Val, Enums) - end. - -dec_enum_int(Val, Enums, Min, Max) -> - try dec_int(Val, Min, Max) - catch _:_ -> dec_enum(Val, Enums) - end. - -enc_enum_int(Int) when is_integer(Int) -> - enc_int(Int); -enc_enum_int(Atom) -> - enc_enum(Atom). - -dec_bool(<<"1">>) -> true; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"false">>) -> false. - -enc_bool(true) -> <<"1">>; -enc_bool(false) -> <<"0">>. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -not_empty(<<_, _/binary>> = Val) -> - Val. - -format_error({form_type_mismatch, Type}) -> - <<"FORM_TYPE doesn't match '", Type/binary, "'">>; -format_error({bad_var_value, Var, Type}) -> - <<"Bad value of field '", Var/binary, "' of type '", Type/binary, "'">>; -format_error({missing_value, Var, Type}) -> - <<"Missing value of field '", Var/binary, "' of type '", Type/binary, "'">>; -format_error({too_many_values, Var, Type}) -> - <<"Too many values for field '", Var/binary, "' of type '", Type/binary, "'">>; -format_error({unknown_var, Var, Type}) -> - <<"Unknown field '", Var/binary, "' of type '", Type/binary, "'">>; -format_error({missing_required_var, Var, Type}) -> - <<"Missing required field '", Var/binary, "' of type '", Type/binary, "'">>. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== -compile_element(#xmlel{name = <<"form_type">>, children = Els} = Form, - #state{erl = OutErl, erl_dir = ErlDir, - hrl = OutHrl, hrl_dir = HrlDir} = State0) -> - try - Name = fxml:get_subtag_cdata(Form, <<"name">>), - Doc = fxml:get_subtag_cdata(Form, <<"doc">>), - X = #xmlel{name = <<"x">>, - attrs = [{<<"type">>, <<"form">>}, - {<<"xmlns">>, <<"jabber:x:data">>}], - children = Els}, - State = State0#state{ns = Name, doc = Doc}, - #xdata{fields = Fs} = xmpp_codec:decode(X), - put(outbuf, []), - mk_header(State), - mk_aux_funs(), - mk_top_decoder(Fs, State), - mk_top_encoder(Fs, State), - mk_decoder(Fs, State), - mk_encoders(Fs, State), - ErlData = get(outbuf), - ok = file:write_file(filename:join(ErlDir, OutErl), ErlData), - ok = erl_tidy:file(filename:join(ErlDir, OutErl), [{backups, false}]), - put(outbuf, []), - mk_type_definitions(Fs, State), - HrlData = get(outbuf), - ok = file:write_file(filename:join(HrlDir, OutHrl), HrlData) - catch _:{badmatch, Err} -> - Err - end. - -mk_aux_funs() -> - case get_abstract_code_from_myself() of - {ok, AbsCode} -> - AST = lists:filter( - fun(T) -> - case catch erl_syntax_lib:analyze_function(T) of - {format_error, 1} -> true; - {dec_int, 3} -> true; - {dec_int, 1} -> true; - {dec_enum, 2} -> true; - {dec_enum_int, 2} -> true; - {dec_enum_int, 4} -> true; - {enc_int, 1} -> true; - {enc_enum, 1} -> true; - {enc_enum_int, 1} -> true; - {not_empty, 1} -> true; - {dec_bool, 1} -> true; - {enc_bool, 1} -> true; - {enc_jid, 1} -> true; - {dec_jid, 1} -> true; - _ -> false - end - end, AbsCode), - emit(erl_prettypr:format(erl_syntax:form_list(AST)) ++ io_lib:nl()); - error -> - erlang:error({no_abstract_code_found, ?MODULE}) - end. - -get_abstract_code_from_myself() -> - {file, File} = code:is_loaded(?MODULE), - case beam_lib:chunks(File, [abstract_code]) of - {ok, {_, List}} -> - case lists:keyfind(abstract_code, 1, List) of - {abstract_code, {raw_abstract_v1, Abstr}} -> - {ok, Abstr}; - _ -> - error - end; - _ -> - error - end. - -mk_comment_header(#state{file_name = Source, ns = NS, doc = Doc}) -> - emit("%% Created automatically by xdata generator (xdata_codec.erl)~n" - "%% Source: ~s~n" - "%% Form type: ~s~n", [Source, NS]), - if Doc /= <<>> -> emit("%% Document: ~s~n~n", [Doc]); - true -> emit("~n") - end. - -mk_header(#state{mod_name = Mod, hrl = Include} = State) -> - mk_comment_header(State), - emit("~n-module(~s).~n", [Mod]), - emit("-export([decode/1, decode/2, encode/1, encode/2, format_error/1]).~n"), - emit("-include(\"xmpp_codec.hrl\").~n"), - emit("-include(\"~s\").~n", [Include]), - emit("-export_type([property/0, result/0, form/0]).~n"). - -mk_type_definitions(Fs, State) -> - mk_comment_header(State), - lists:foreach( - fun(#xdata_field{var = Var} = F) -> - Spec = get_typespec(F, State), - case is_complex_type(Spec) of - true -> - emit("-type '~s'() :: ~s.~n", - [var_to_rec_field(Var, State), Spec]); - false -> - ok - end - end, Fs), - emit("~n-type property() :: "), - Fields = lists:map( - fun(#xdata_field{var = Var} = F) -> - RecField = var_to_rec_field(Var, State), - [io_lib:format("{'~s', ~s}", - [RecField, mk_typespec(F, State)])] - end, Fs), - emit(string:join(Fields, " |~n ") ++ ".~n"), - emit("-type result() :: [property()].~n~n"), - VarsWithSpec = lists:flatmap( - fun(#xdata_field{type = T, var = Var} = F) - when ?is_list_type(T) -> - RecName = var_to_rec_field(Var, State), - Spec0 = get_typespec(F, State), - Spec = case is_complex_type(Spec0) of - true -> - io_lib:format("'~s'()", [RecName]); - false -> - Spec0 - end, - [{RecName, mk_typespec(F, State), Spec}]; - (_) -> - [] - end, Fs), - case VarsWithSpec of - [] -> - emit("-type form() :: [property() | xdata_field()].~n"); - _ -> - emit("-type options(T) :: [{binary(), T}].~n"), - emit("-type property_with_options() ::~n "), - Options = [io_lib:format("{'~s', ~s, options(~s)}", - [Var, Spec1, Spec2]) - || {Var, Spec1, Spec2} <- VarsWithSpec], - emit(string:join(Options, " |~n ") ++ ".~n"), - emit("-type form() :: [property() | property_with_options() | xdata_field()].~n") - end. - -mk_top_decoder(Fs, State) -> - Required = [Var || #xdata_field{var = Var} <- Fs, is_required(Var, State)], - emit("decode(Fs) -> decode(Fs, []).~n"), - emit("decode(Fs, Acc) ->" - " case lists:keyfind(<<\"FORM_TYPE\">>, #xdata_field.var, Fs) of" - " false ->" - " decode(Fs, Acc, ~p);" - " #xdata_field{values = [~p]} ->" - " decode(Fs, Acc, ~p);" - " _ ->" - " erlang:error({?MODULE, {form_type_mismatch, ~p}})~n" - " end.~n", - [Required, State#state.ns, Required, State#state.ns]). - -mk_top_encoder(Fs, State) -> - Clauses = string:join( - lists:map( - fun(#xdata_field{var = Var, type = T}) when ?is_list_type(T) -> - Field = var_to_rec_field(Var, State), - io_lib:format( - "{'~s', Val} -> ['encode_~s'(Val, default, Translate)];" - "{'~s', Val, Opts} -> ['encode_~s'(Val, Opts, Translate)]", - [Field, Field, Field, Field]); - (#xdata_field{var = Var}) -> - Field = var_to_rec_field(Var, State), - io_lib:format( - "{'~s', Val} -> ['encode_~s'(Val, Translate)];" - "{'~s', _, _} -> erlang:error({badarg, Opt})", - [Field, Field, Field]) - end, Fs) ++ ["#xdata_field{} -> [Opt]; _ -> []"], - ";"), - emit("encode(Cfg) -> encode(Cfg, fun(Text) -> Text end).~n"), - emit("encode(List, Translate) when is_list(List) ->" - " Fs = [case Opt of ~s end || Opt <- List]," - " FormType = #xdata_field{var = <<\"FORM_TYPE\">>, type = hidden," - " values = [~p]}," - " [FormType|lists:flatten(Fs)].~n", - [Clauses, State#state.ns]). - -mk_decoder([#xdata_field{var = Var, type = Type} = F|Fs], State) -> - ValVar = if ?is_multi_type(Type) -> "Values"; - true -> "[Value]" - end, - DecFun = if ?is_multi_type(Type) -> - ["[", mk_decoding_fun(F, State), " || Value <- Values]"]; - true -> - mk_decoding_fun(F, State) - end, - emit("decode([#xdata_field{var = ~p, values = ~s}|Fs], Acc, Required) ->" - " try ~s of" - " Result -> decode(Fs, [{'~s', Result}|Acc]," - " lists:delete(~p, Required))" - " catch _:_ ->" - " erlang:error({?MODULE, {bad_var_value, ~p, ~p}})" - " end;", - [Var, ValVar, DecFun, var_to_rec_field(Var, State), - Var, Var, State#state.ns]), - if not ?is_multi_type(Type) -> - emit("decode([#xdata_field{var = ~p, values = []} = F|Fs]," - " Acc, Required) ->" - " decode([F#xdata_field{var = ~p, values = [<<>>]}|Fs]," - " Acc, Required);", - [Var, Var]), - emit("decode([#xdata_field{var = ~p}|_], _, _) ->" - " erlang:error({?MODULE, {too_many_values, ~p, ~p}});", - [Var, Var, State#state.ns]); - true -> - ok - end, - mk_decoder(Fs, State); -mk_decoder([], State) -> - emit("decode([#xdata_field{var = Var}|Fs], Acc, Required) ->" - " if Var /= <<\"FORM_TYPE\">> ->" - " erlang:error({?MODULE, {unknown_var, Var, ~p}});" - " true ->" - " decode(Fs, Acc, Required)" - " end;", - [State#state.ns]), - emit("decode([], _, [Var|_]) ->" - " erlang:error({?MODULE, {missing_required_var, Var, ~p}});~n", - [State#state.ns]), - emit("decode([], Acc, []) -> Acc.~n"). - -mk_encoders(Fs, State) -> - lists:foreach( - fun(#xdata_field{var = Var, required = IsRequired, desc = Desc, - label = Label, type = Type} = F) -> - EncVals = mk_encoded_values(F, State), - EncOpts = mk_encoded_options(F, State), - FieldName = var_to_rec_field(Var, State), - DescStr = if Desc == <<>> -> "<<>>"; - true -> io_lib:format("Translate(~p)", [Desc]) - end, - LabelStr = if Label == <<>> -> "<<>>"; - true -> io_lib:format("Translate(~p)", [Label]) - end, - if ?is_list_type(Type) -> - emit("'encode_~s'(Value, Options, Translate) ->", [FieldName]); - true -> - emit("'encode_~s'(Value, Translate) ->", [FieldName]) - end, - emit(" Values = ~s," - " Opts = ~s," - " #xdata_field{var = ~p," - " values = Values," - " required = ~p," - " type = ~p," - " options = Opts," - " desc = ~s," - " label = ~s}.~n", - [EncVals, EncOpts, Var, IsRequired, Type, DescStr, LabelStr]) - end, Fs). - -mk_encoded_values(#xdata_field{var = Var, type = Type, - options = Options}, State) -> - EncFun = - case get_enc_fun(Var, Type, Options, State) of - {M, Fun, Args} -> - Mod = if M == undefined -> ""; - true -> io_lib:format("~s:", [M]) - end, - FArgs = [io_lib:format(", ~p", [A]) || A <- Args], - if ?is_multi_type(Type) -> - "[" ++ io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]) ++ - " || V <- Value]"; - true -> - "[" ++ io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs]) - ++ "]" - end; - undefined -> - "[Value]" - end, - Default = case get_dec_fun(Var, Type, Options, State) of - _ when ?is_multi_type(Type) -> "[]"; - undefined -> "<<>>"; - _MFA -> "undefined" - end, - io_lib:format( - "case Value of" - " ~s -> [];~n" - " Value -> ~s~n" - "end", - [Default, EncFun]). - -mk_encoded_options(#xdata_field{var = Var, type = Type, - options = Options}, State) -> - EncFun = case get_enc_fun(Var, Type, Options, State) of - {M, Fun, Args} -> - Mod = if M == undefined -> ""; - true -> io_lib:format("~s:", [M]) - end, - FArgs = [io_lib:format(", ~p", [A]) || A <- Args], - io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]); - undefined -> - "V" - end, - EncOpts = string:join( - [case L of - <<>> -> - io_lib:format("#xdata_option{value = ~p}", [V]); - _ -> - io_lib:format( - "#xdata_option{label = Translate(~p), value = ~p}", - [L, V]) - end || #xdata_option{label = L, value = V} <- Options], - ","), - if ?is_list_type(Type) -> - io_lib:format( - "if Options == default ->" - " [~s];" - "true ->" - " [#xdata_option{label = Translate(L), value = ~s}" - " || {L, V} <- Options]" - "end", - [EncOpts, EncFun]); - true -> - "[]" - end. - -mk_decoding_fun(#xdata_field{var = Var, type = Type, - options = Options}, State) -> - case get_dec_fun(Var, Type, Options, State) of - {M, Fun, Args} -> - Mod = if M == undefined -> ""; - true -> io_lib:format("~s:", [M]) - end, - FArgs = [io_lib:format(", ~p", [A]) || A <- Args], - io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs]); - undefined -> - "Value" - end. - -var_to_rec_field(Var, #state{prefix = [Prefix|T]} = State) -> - Size = size(Prefix), - case Var of - <<(Prefix):Size/binary, Rest/binary>> -> - binary_to_atom(Rest, utf8); - _ -> - var_to_rec_field(Var, State#state{prefix = T}) - end; -var_to_rec_field(Var, #state{prefix = []}) -> - Var. - -get_dec_fun(Var, Type, Options, State) -> - case lists:keyfind(Var, 1, State#state.dec_mfas) of - false when Type == 'list-multi'; Type == 'list-single' -> - if Options /= [] -> - Variants = [binary_to_atom(V, utf8) - || #xdata_option{value = V} <- Options], - {undefined, dec_enum, [Variants]}; - true -> - undefined - end; - false when Type == 'jid-multi'; Type == 'jid-single' -> - {undefined, dec_jid, []}; - false when Type == boolean -> - {undefined, dec_bool, []}; - false -> - undefined; - {Var, {M, F, A}} -> - {M, F, A}; - {Var, {dec_bool, []}} -> - {undefined, dec_bool, []}; - {Var, {not_empty, []}} -> - {undefined, not_empty, []}; - {Var, {dec_enum, [Variants]}} -> - {undefined, dec_enum, [Variants]}; - {Var, {dec_int, Args}} -> - {undefined, dec_int, Args}; - {Var, {dec_enum_int, Args}} -> - {undefined, dec_enum_int, Args}; - {Var, {dec_jid, []}} -> - {undefined, dec_jid, []} - end. - -get_enc_fun(Var, Type, Options, State) -> - case get_dec_fun(Var, Type, Options, State) of - {undefined, dec_enum, _} -> - {undefined, enc_enum, []}; - {undefined, dec_bool, _} -> - {undefined, enc_bool, []}; - {undefined, dec_int, _} -> - {undefined, enc_int, []}; - {undefined, dec_enum_int, _} -> - {undefined, enc_enum_int, []}; - {undefined, dec_jid, _} -> - {undefined, enc_jid, []}; - _ -> - case lists:keyfind(Var, 1, State#state.enc_mfas) of - false -> - undefined; - {Var, {M, F, A}} -> - {M, F, A}; - {Var, {enc_bool, []}} -> - {undefined, enc_bool, []}; - {Var, {dec_enum, _}} -> - {undefined, enc_enum, []}; - {Var, {enc_int, _}} -> - {undefined, enc_int, []}; - {Var, {dec_enum_int, _}} -> - {undefined, enc_enum_int, []}; - {Var, {enc_jid, _}} -> - {undefined, enc_jid, []} - end - end. - -mk_typespec(#xdata_field{type = Type, var = Var} = Field, State) -> - Spec0 = get_typespec(Field, State), - Spec1 = case is_complex_type(Spec0) of - true -> - io_lib:format("'~s'()", [var_to_rec_field(Var, State)]); - false -> - Spec0 - end, - if ?is_multi_type(Type) -> "[" ++ Spec1 ++ "]"; - true -> Spec1 - end. - -get_typespec(#xdata_field{var = Var, type = Type, options = Options}, State) -> - case lists:keyfind(Var, 1, State#state.specs) of - false -> - case get_dec_fun(Var, Type, Options, State) of - {undefined, dec_enum, Args} -> - enum_spec(Args); - {undefined, dec_bool, _} -> - "boolean()"; - {undefined, dec_jid, _} -> - "jid:jid()"; - {undefined, dec_int, Args} -> - int_spec(Args); - {undefined, dec_enum_int, [Variants|T]} -> - enum_spec([Variants]) ++ " | " ++ int_spec(T); - _ -> - "binary()" - end; - {Var, Spec} -> - Spec - end. - --spec is_complex_type(string()) -> boolean(). -is_complex_type(Spec) -> - string:chr(Spec, $|) /= 0. - -int_spec([]) -> - "integer()"; -int_spec([From, To]) -> - if From /= infinity, To /= infinity -> - io_lib:format("~p..~p", [From, To]); - From > 0 -> - "pos_integer()"; - From == 0 -> - "non_neg_integer()"; - true -> - "integer()" - end. - -enum_spec([Variants]) -> - string:join([atom_to_list(V) || V <- Variants], " | "). - -is_required(Var, State) -> - lists:member(Var, State#state.required) orelse - proplists:get_bool(Var, State#state.required). - -normalize(#xmlel{name = Name, attrs = Attrs, children = Els}) -> - #xmlel{name = Name, - attrs = [normalize(Attr) || Attr <- Attrs], - children = [normalize(El) || El <- Els]}; -normalize({Key, Data}) -> - {Key, normalize(Data)}; -normalize(Txt) when is_binary(Txt) -> - case re:split(Txt, "[\\s\\r\\n\\t]+", [trim, {return, list}]) of - [""|T] -> - list_to_binary(string:join(T, " ")); - T -> - list_to_binary(string:join(T, " ")) - end. diff --git a/src/xmpp.erl b/src/xmpp.erl deleted file mode 100644 index 2c08c2bcd..000000000 --- a/src/xmpp.erl +++ /dev/null @@ -1,827 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @copyright (C) 2015, Evgeny Khramtsov -%%% @doc -%%% -%%% @end -%%% Created : 9 Dec 2015 by Evgeny Khramtsov -%%%------------------------------------------------------------------- --module(xmpp). - -%% API --export([make_iq_result/1, make_iq_result/2, make_error/2, - decode/1, decode/3, encode/1, encode/2, - get_type/1, get_to/1, get_from/1, get_id/1, - get_lang/1, get_error/1, get_els/1, get_ns/1, - set_type/2, set_to/2, set_from/2, set_id/2, - set_lang/2, set_error/2, set_els/2, set_from_to/3, - format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, - remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3, - pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2, - is_known_tag/1, is_known_tag/2, append_subtags/2]). - -%% XMPP errors --export([err_bad_request/0, err_bad_request/2, - err_conflict/0, err_conflict/2, - err_feature_not_implemented/0, err_feature_not_implemented/2, - err_forbidden/0, err_forbidden/2, - err_gone/0, err_gone/2, - err_internal_server_error/0, err_internal_server_error/2, - err_item_not_found/0, err_item_not_found/2, - err_jid_malformed/0, err_jid_malformed/2, - err_not_acceptable/0, err_not_acceptable/2, - err_not_allowed/0, err_not_allowed/2, - err_not_authorized/0, err_not_authorized/2, - err_payment_required/0, err_payment_required/2, - err_policy_violation/0, err_policy_violation/2, - err_recipient_unavailable/0, err_recipient_unavailable/2, - err_redirect/0, err_redirect/2, - err_registration_required/0, err_registration_required/2, - err_remote_server_not_found/0, err_remote_server_not_found/2, - err_remote_server_timeout/0, err_remote_server_timeout/2, - err_resource_constraint/0, err_resource_constraint/2, - err_service_unavailable/0, err_service_unavailable/2, - err_subscription_required/0, err_subscription_required/2, - err_undefined_condition/1, err_undefined_condition/3, - err_unexpected_request/0, err_unexpected_request/2]). - -%% XMPP stream errors --export([serr_bad_format/0, serr_bad_format/2, - serr_bad_namespace_prefix/0, serr_bad_namespace_prefix/2, - serr_conflict/0, serr_conflict/2, - serr_connection_timeout/0, serr_connection_timeout/2, - serr_host_gone/0, serr_host_gone/2, - serr_host_unknown/0, serr_host_unknown/2, - serr_improper_addressing/0, serr_improper_addressing/2, - serr_internal_server_error/0, serr_internal_server_error/2, - serr_invalid_from/0, serr_invalid_from/2, - serr_invalid_id/0, serr_invalid_id/2, - serr_invalid_namespace/0, serr_invalid_namespace/2, - serr_invalid_xml/0, serr_invalid_xml/2, - serr_not_authorized/0, serr_not_authorized/2, - serr_not_well_formed/0, serr_not_well_formed/2, - serr_policy_violation/0, serr_policy_violation/2, - serr_remote_connection_failed/0, serr_remote_connection_failed/2, - serr_reset/0, serr_reset/2, - serr_resource_constraint/0, serr_resource_constraint/2, - serr_restricted_xml/0, serr_restricted_xml/2, - serr_see_other_host/0, serr_see_other_host/2, - serr_system_shutdown/0, serr_system_shutdown/2, - serr_undefined_condition/0, serr_undefined_condition/2, - serr_unsupported_encoding/0, serr_unsupported_encoding/2, - serr_unsupported_stanza_type/0, serr_unsupported_stanza_type/2, - serr_unsupported_version/0, serr_unsupported_version/2]). - --include("xmpp.hrl"). - -%%%=================================================================== -%%% API -%%%=================================================================== --spec make_iq_result(iq()) -> iq(). -make_iq_result(IQ) -> - make_iq_result(IQ, undefined). - --spec make_iq_result(iq(), xmpp_element() | xmlel() | undefined) -> iq(). -make_iq_result(#iq{type = Type, from = From, to = To} = IQ, El) - when Type == get; Type == set -> - SubEls = if El == undefined -> []; - true -> [El] - end, - IQ#iq{type = result, to = From, from = To, sub_els = SubEls}. - --spec make_error(message(), stanza_error() | xmlel()) -> message(); - (presence(), stanza_error() | xmlel()) -> presence(); - (iq(), stanza_error() | xmlel()) -> iq(); - (xmlel(), stanza_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]}; -make_error(#presence{type = Type, from = From, to = To, sub_els = Els} = Pres, - Err) when Type /= error -> - Pres#presence{type = error, from = To, to = From, sub_els = Els ++ [Err]}; -make_error(#iq{type = Type, from = From, to = To, sub_els = Els} = IQ, - Err) when Type /= result, Type /= error -> - IQ#iq{type = error, from = To, to = From, sub_els = Els ++ [Err]}; -make_error(#xmlel{attrs = Attrs, children = Els} = El, Err) -> - To = fxml:get_attr(<<"to">>, Attrs), - From = fxml:get_attr(<<"from">>, Attrs), - Attrs1 = case To of - {value, T} -> - lists:keystore(<<"from">>, 1, Attrs, {<<"from">>, T}); - _ -> - Attrs - end, - Attrs2 = case From of - {value, F} -> - lists:keystore(<<"to">>, 1, Attrs1, {<<"to">>, F}); - _ -> - Attrs - end, - Attrs3 = lists:keystore(<<"type">>, 1, Attrs2, {<<"type">>, <<"error">>}), - El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err, ?NS_CLIENT)]}. - --spec get_id(iq() | message() | presence() | xmlel()) -> binary(). -get_id(#iq{id = ID}) -> ID; -get_id(#message{id = ID}) -> ID; -get_id(#presence{id = ID}) -> ID; -get_id(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"id">>, Attrs). - --spec get_type(iq()) -> iq_type(); - (message()) -> message_type(); - (presence()) -> presence_type(); - (xmlel()) -> binary(). -get_type(#iq{type = T}) -> T; -get_type(#message{type = T}) -> T; -get_type(#presence{type = T}) -> T; -get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs). - --spec get_lang(iq() | message() | presence() | xmlel()) -> binary(). -get_lang(#iq{lang = L}) -> L; -get_lang(#message{lang = L}) -> L; -get_lang(#presence{lang = L}) -> L; -get_lang(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"xml:lang">>, Attrs). - --spec get_from(iq() | message() | presence()) -> undefined | jid:jid(). -get_from(#iq{from = J}) -> J; -get_from(#message{from = J}) -> J; -get_from(#presence{from = J}) -> J. - --spec get_to(iq() | message() | presence()) -> undefined | jid:jid(). -get_to(#iq{to = J}) -> J; -get_to(#message{to = J}) -> J; -get_to(#presence{to = J}) -> J. - --spec get_error(iq() | message() | presence()) -> undefined | stanza_error(). -get_error(Stanza) -> - case get_subtag(Stanza, #stanza_error{}) of - false -> undefined; - Error -> Error - end. - --spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()]; - (xmlel()) -> [xmlel()]. -get_els(#iq{sub_els = Els}) -> Els; -get_els(#message{sub_els = Els}) -> Els; -get_els(#presence{sub_els = Els}) -> Els; -get_els(#xmlel{children = Els}) -> [El || El = #xmlel{} <- Els]. - --spec set_id(iq(), binary()) -> iq(); - (message(), binary()) -> message(); - (presence(), binary()) -> presence(). -set_id(#iq{} = IQ, I) -> IQ#iq{id = I}; -set_id(#message{} = Msg, I) -> Msg#message{id = I}; -set_id(#presence{} = Pres, I) -> Pres#presence{id = I}. - --spec set_type(iq(), iq_type()) -> iq(); - (message(), message_type()) -> message(); - (presence(), presence_type()) -> presence(). -set_type(#iq{} = IQ, T) -> IQ#iq{type = T}; -set_type(#message{} = Msg, T) -> Msg#message{type = T}; -set_type(#presence{} = Pres, T) -> Pres#presence{type = T}. - --spec set_lang(iq(), binary()) -> iq(); - (message(), binary()) -> message(); - (presence(), binary()) -> presence(). -set_lang(#iq{} = IQ, L) -> IQ#iq{lang = L}; -set_lang(#message{} = Msg, L) -> Msg#message{lang = L}; -set_lang(#presence{} = Pres, L) -> Pres#presence{lang = L}. - --spec set_from(iq(), jid:jid()) -> iq(); - (message(), jid:jid()) -> message(); - (presence(), jid:jid()) -> presence(). -set_from(#iq{} = IQ, J) -> IQ#iq{from = J}; -set_from(#message{} = Msg, J) -> Msg#message{from = J}; -set_from(#presence{} = Pres, J) -> Pres#presence{from = J}. - --spec set_to(iq(), jid:jid()) -> iq(); - (message(), jid:jid()) -> message(); - (presence(), jid:jid()) -> presence(). -set_to(#iq{} = IQ, J) -> IQ#iq{to = J}; -set_to(#message{} = Msg, J) -> Msg#message{to = J}; -set_to(#presence{} = Pres, J) -> Pres#presence{to = J}. - --spec set_from_to(iq(), undefined | jid:jid(), undefined | jid:jid()) -> iq(); - (message(), undefined | jid:jid(), undefined | jid:jid()) -> message(); - (presence(), undefined | jid:jid(), undefined | jid:jid()) -> presence(). -set_from_to(#iq{} = IQ, F, T) -> IQ#iq{from = F, to = T}; -set_from_to(#message{} = Msg, F, T) -> Msg#message{from = F, to = T}; -set_from_to(#presence{} = Pres, F, T) -> Pres#presence{from = F, to = T}. - --spec set_error(iq(), stanza_error()) -> iq(); - (message(), stanza_error()) -> message(); - (presence(), stanza_error()) -> presence(). -set_error(Stanza, E) -> set_subtag(Stanza, E). - --spec set_els(iq(), [xmpp_element() | xmlel()]) -> iq(); - (message(), [xmpp_element() | xmlel()]) -> message(); - (presence(), [xmpp_element() | xmlel()]) -> presence(). -set_els(#iq{} = IQ, Els) -> IQ#iq{sub_els = Els}; -set_els(#message{} = Msg, Els) -> Msg#message{sub_els = Els}; -set_els(#presence{} = Pres, Els) -> Pres#presence{sub_els = Els}. - --spec get_ns(xmpp_element() | xmlel()) -> binary(). -get_ns(#xmlel{attrs = Attrs}) -> - fxml:get_attr_s(<<"xmlns">>, Attrs); -get_ns(Pkt) -> - xmpp_codec:get_ns(Pkt). - --spec get_name(xmpp_element() | xmlel()) -> binary(). -get_name(#xmlel{name = Name}) -> - Name; -get_name(Pkt) -> - xmpp_codec:get_name(Pkt). - --spec decode(xmlel() | xmpp_element()) -> {ok, xmpp_element()} | {error, any()}. -decode(El) -> - decode(El, ?NS_CLIENT, []). - --spec decode(xmlel() | xmpp_element(), binary(), [proplists:property()]) -> - {ok, xmpp_element()} | {error, any()}. -decode(#xmlel{} = El, TopXMLNS, Opts) -> - xmpp_codec:decode(El, TopXMLNS, Opts); -decode(Pkt, _, _) -> - Pkt. - --spec decode_els(iq()) -> iq(); - (message()) -> message(); - (presence()) -> presence(). -decode_els(Stanza) -> - decode_els(Stanza, ?NS_CLIENT, fun is_known_tag/1). - --type match_fun() :: fun((xmlel()) -> boolean()). --spec decode_els(iq(), binary(), match_fun()) -> iq(); - (message(), binary(), match_fun()) -> message(); - (presence(), binary(), match_fun()) -> presence(). -decode_els(Stanza, TopXMLNS, MatchFun) -> - Els = lists:map( - fun(#xmlel{} = El) -> - case MatchFun(El) of - true -> decode(El, TopXMLNS, []); - false -> El - end; - (Pkt) -> - Pkt - end, get_els(Stanza)), - set_els(Stanza, Els). - --spec encode(xmpp_element() | xmlel()) -> xmlel(). -encode(Pkt) -> - encode(Pkt, <<>>). - --spec encode(xmpp_element() | xmlel(), binary()) -> xmlel(). -encode(Pkt, TopXMLNS) -> - xmpp_codec:encode(Pkt, TopXMLNS). - --spec is_known_tag(xmlel()) -> boolean(). -is_known_tag(El) -> - is_known_tag(El, ?NS_CLIENT). - --spec is_known_tag(xmlel(), binary()) -> boolean(). -is_known_tag(El, TopXMLNS) -> - xmpp_codec:is_known_tag(El, TopXMLNS). - -format_error(Reason) -> - xmpp_codec:format_error(Reason). - --spec is_stanza(any()) -> boolean(). -is_stanza(#message{}) -> true; -is_stanza(#iq{}) -> true; -is_stanza(#presence{}) -> true; -is_stanza(#xmlel{name = Name}) -> - (Name == <<"iq">>) or (Name == <<"message">>) or (Name == <<"presence">>); -is_stanza(_) -> false. - --spec set_subtag(iq(), xmpp_element()) -> iq(); - (message(), xmpp_element()) -> message(); - (presence(), xmpp_element()) -> presence(). -set_subtag(Stanza, Tag) -> - TagName = xmpp_codec:get_name(Tag), - XMLNS = xmpp_codec:get_ns(Tag), - Els = get_els(Stanza), - NewEls = set_subtag(Els, Tag, TagName, XMLNS), - set_els(Stanza, NewEls). - -set_subtag([El|Els], Tag, TagName, XMLNS) -> - case match_tag(El, TagName, XMLNS) of - true -> - [Tag|Els]; - false -> - [El|set_subtag(Els, Tag, TagName, XMLNS)] - end; -set_subtag([], Tag, _, _) -> - [Tag]. - --spec get_subtag(stanza(), xmpp_element()) -> xmpp_element() | false. -get_subtag(Stanza, Tag) -> - Els = get_els(Stanza), - TagName = xmpp_codec:get_name(Tag), - XMLNS = xmpp_codec:get_ns(Tag), - get_subtag(Els, TagName, XMLNS). - -get_subtag([El|Els], TagName, XMLNS) -> - case match_tag(El, TagName, XMLNS) of - true -> - try - decode(El) - catch _:{xmpp_codec, _Why} -> - get_subtag(Els, TagName, XMLNS) - end; - false -> - get_subtag(Els, TagName, XMLNS) - end; -get_subtag([], _, _) -> - false. - --spec remove_subtag(iq(), xmpp_element()) -> iq(); - (message(), xmpp_element()) -> message(); - (presence(), xmpp_element()) -> presence(). -remove_subtag(Stanza, Tag) -> - Els = get_els(Stanza), - TagName = xmpp_codec:get_name(Tag), - XMLNS = xmpp_codec:get_ns(Tag), - NewEls = remove_subtag(Els, TagName, XMLNS), - set_els(Stanza, NewEls). - -remove_subtag([El|Els], TagName, XMLNS) -> - case match_tag(El, TagName, XMLNS) of - true -> - remove_subtag(Els, TagName, XMLNS); - false -> - [El|remove_subtag(Els, TagName, XMLNS)] - end; -remove_subtag([], _, _) -> - []. - --spec has_subtag(stanza(), xmpp_element()) -> boolean(). -has_subtag(Stanza, Tag) -> - Els = get_els(Stanza), - TagName = xmpp_codec:get_name(Tag), - XMLNS = xmpp_codec:get_ns(Tag), - has_subtag(Els, TagName, XMLNS). - -has_subtag([El|Els], TagName, XMLNS) -> - case match_tag(El, TagName, XMLNS) of - true -> - true; - false -> - has_subtag(Els, TagName, XMLNS) - end; -has_subtag([], _, _) -> - false. - --spec append_subtags(stanza(), [xmpp_element() | xmlel()]) -> stanza(). -append_subtags(Stanza, Tags) -> - Els = get_els(Stanza), - set_els(Stanza, Els ++ Tags). - --spec get_text([text()]) -> binary(). -get_text([]) -> <<"">>; -get_text([#text{data = Data}|_]) -> Data. - --spec mk_text(binary()) -> [text()]. -mk_text(Text) -> - mk_text(Text, <<"">>). - --spec mk_text(binary(), binary()) -> [text()]. -mk_text(<<"">>, _) -> - []; -mk_text(Text, Lang) -> - [#text{lang = Lang, - data = translate:translate(Lang, Text)}]. - --spec pp(any()) -> iodata(). -pp(Term) -> - xmpp_codec:pp(Term). - -%%%=================================================================== -%%% Functions to construct general XMPP errors -%%%=================================================================== --spec err_bad_request() -> stanza_error(). -err_bad_request() -> - err(modify, 'bad-request', 400). - --spec err_bad_request(binary(), binary()) -> stanza_error(). -err_bad_request(Text, Lang) -> - err(modify, 'bad-request', 400, Text, Lang). - --spec err_conflict() -> stanza_error(). -err_conflict() -> - err(cancel, 'conflict', 409). - --spec err_conflict(binary(), binary()) -> stanza_error(). -err_conflict(Text, Lang) -> - err(cancel, 'conflict', 409, Text, Lang). - --spec err_feature_not_implemented() -> stanza_error(). -err_feature_not_implemented() -> - err(cancel, 'feature-not-implemented', 501). - --spec err_feature_not_implemented(binary(), binary()) -> stanza_error(). -err_feature_not_implemented(Text, Lang) -> - err(cancel, 'feature-not-implemented', 501, Text, Lang). - --spec err_forbidden() -> stanza_error(). -err_forbidden() -> - err(auth, 'forbidden', 403). - --spec err_forbidden(binary(), binary()) -> stanza_error(). -err_forbidden(Text, Lang) -> - err(auth, 'forbidden', 403, Text, Lang). - -%% RFC 6120 says error type SHOULD be "cancel". -%% RFC 3920 and XEP-0082 says it SHOULD be "modify". --spec err_gone() -> stanza_error(). -err_gone() -> - err(modify, 'gone', 302). - --spec err_gone(binary(), binary()) -> stanza_error(). -err_gone(Text, Lang) -> - err(modify, 'gone', 302, Text, Lang). - -%% RFC 6120 sasy error type SHOULD be "cancel". -%% RFC 3920 and XEP-0082 says it SHOULD be "wait". --spec err_internal_server_error() -> stanza_error(). -err_internal_server_error() -> - err(wait, 'internal-server-error', 500). - --spec err_internal_server_error(binary(), binary()) -> stanza_error(). -err_internal_server_error(Text, Lang) -> - err(wait, 'internal-server-error', 500, Text, Lang). - --spec err_item_not_found() -> stanza_error(). -err_item_not_found() -> - err(cancel, 'item-not-found', 404). - --spec err_item_not_found(binary(), binary()) -> stanza_error(). -err_item_not_found(Text, Lang) -> - err(cancel, 'item-not-found', 404, Text, Lang). - --spec err_jid_malformed() -> stanza_error(). -err_jid_malformed() -> - err(modify, 'jid-malformed', 400). - --spec err_jid_malformed(binary(), binary()) -> stanza_error(). -err_jid_malformed(Text, Lang) -> - err(modify, 'jid-malformed', 400, Text, Lang). - --spec err_not_acceptable() -> stanza_error(). -err_not_acceptable() -> - err(modify, 'not-acceptable', 406). - --spec err_not_acceptable(binary(), binary()) -> stanza_error(). -err_not_acceptable(Text, Lang) -> - err(modify, 'not-acceptable', 406, Text, Lang). - --spec err_not_allowed() -> stanza_error(). -err_not_allowed() -> - err(cancel, 'not-allowed', 405). - --spec err_not_allowed(binary(), binary()) -> stanza_error(). -err_not_allowed(Text, Lang) -> - err(cancel, 'not-allowed', 405, Text, Lang). - --spec err_not_authorized() -> stanza_error(). -err_not_authorized() -> - err(auth, 'not-authorized', 401). - --spec err_not_authorized(binary(), binary()) -> stanza_error(). -err_not_authorized(Text, Lang) -> - err(auth, 'not-authorized', 401, Text, Lang). - --spec err_payment_required() -> stanza_error(). -err_payment_required() -> - err(auth, 'not-authorized', 402). - --spec err_payment_required(binary(), binary()) -> stanza_error(). -err_payment_required(Text, Lang) -> - err(auth, 'not-authorized', 402, Text, Lang). - -%% is defined in neither RFC 3920 nor XEP-0086. -%% We choose '403' error code (as in ). --spec err_policy_violation() -> stanza_error(). -err_policy_violation() -> - err(modify, 'policy-violation', 403). - --spec err_policy_violation(binary(), binary()) -> stanza_error(). -err_policy_violation(Text, Lang) -> - err(modify, 'policy-violation', 403, Text, Lang). - --spec err_recipient_unavailable() -> stanza_error(). -err_recipient_unavailable() -> - err(wait, 'recipient-unavailable', 404). - --spec err_recipient_unavailable(binary(), binary()) -> stanza_error(). -err_recipient_unavailable(Text, Lang) -> - err(wait, 'recipient-unavailable', 404, Text, Lang). - --spec err_redirect() -> stanza_error(). -err_redirect() -> - err(modify, 'redirect', 302). - --spec err_redirect(binary(), binary()) -> stanza_error(). -err_redirect(Text, Lang) -> - err(modify, 'redirect', 302, Text, Lang). - --spec err_registration_required() -> stanza_error(). -err_registration_required() -> - err(auth, 'registration-required', 407). - --spec err_registration_required(binary(), binary()) -> stanza_error(). -err_registration_required(Text, Lang) -> - err(auth, 'registration-required', 407, Text, Lang). - --spec err_remote_server_not_found() -> stanza_error(). -err_remote_server_not_found() -> - err(cancel, 'remote-server-not-found', 404). - --spec err_remote_server_not_found(binary(), binary()) -> stanza_error(). -err_remote_server_not_found(Text, Lang) -> - err(cancel, 'remote-server-not-found', 404, Text, Lang). - --spec err_remote_server_timeout() -> stanza_error(). -err_remote_server_timeout() -> - err(wait, 'remote-server-timeout', 504). - --spec err_remote_server_timeout(binary(), binary()) -> stanza_error(). -err_remote_server_timeout(Text, Lang) -> - err(wait, 'remote-server-timeout', 504, Text, Lang). - --spec err_resource_constraint() -> stanza_error(). -err_resource_constraint() -> - err(wait, 'resource-constraint', 500). - --spec err_resource_constraint(binary(), binary()) -> stanza_error(). -err_resource_constraint(Text, Lang) -> - err(wait, 'resource-constraint', 500, Text, Lang). - --spec err_service_unavailable() -> stanza_error(). -err_service_unavailable() -> - err(cancel, 'service-unavailable', 503). - --spec err_service_unavailable(binary(), binary()) -> stanza_error(). -err_service_unavailable(Text, Lang) -> - err(cancel, 'service-unavailable', 503, Text, Lang). - --spec err_subscription_required() -> stanza_error(). -err_subscription_required() -> - err(auth, 'subscription-required', 407). - --spec err_subscription_required(binary(), binary()) -> stanza_error(). -err_subscription_required(Text, Lang) -> - err(auth, 'subscription-required', 407, Text, Lang). - -%% No error type is defined for . -%% Let user provide the type. --spec err_undefined_condition('auth' | 'cancel' | 'continue' | - 'modify' | 'wait') -> stanza_error(). -err_undefined_condition(Type) -> - err(Type, 'undefined-condition', 500). - --spec err_undefined_condition('auth' | 'cancel' | 'continue' | 'modify' | 'wait', - binary(), binary()) -> stanza_error(). -err_undefined_condition(Type, Text, Lang) -> - err(Type, 'undefined-condition', 500, Text, Lang). - -%% RFC 6120 says error type SHOULD be "wait" or "modify". -%% RFC 3920 and XEP-0082 says it SHOULD be "wait". --spec err_unexpected_request() -> stanza_error(). -err_unexpected_request() -> - err(wait, 'unexpected-request', 400). - --spec err_unexpected_request(binary(), binary()) -> stanza_error(). -err_unexpected_request(Text, Lang) -> - err(wait, 'unexpected-request', 400, Text, Lang). - -%%%=================================================================== -%%% Functions to construct stream errors -%%%=================================================================== --spec serr_bad_format() -> stream_error(). -serr_bad_format() -> - serr('bad-format'). - --spec serr_bad_format(binary(), binary()) -> stream_error(). -serr_bad_format(Text, Lang) -> - serr('bad-format', Text, Lang). - --spec serr_bad_namespace_prefix() -> stream_error(). -serr_bad_namespace_prefix() -> - serr('bad-namespace-prefix'). - --spec serr_bad_namespace_prefix(binary(), binary()) -> stream_error(). -serr_bad_namespace_prefix(Text, Lang) -> - serr('bad-namespace-prefix', Text, Lang). - --spec serr_conflict() -> stream_error(). -serr_conflict() -> - serr('conflict'). - --spec serr_conflict(binary(), binary()) -> stream_error(). -serr_conflict(Text, Lang) -> - serr('conflict', Text, Lang). - --spec serr_connection_timeout() -> stream_error(). -serr_connection_timeout() -> - serr('connection-timeout'). - --spec serr_connection_timeout(binary(), binary()) -> stream_error(). -serr_connection_timeout(Text, Lang) -> - serr('connection-timeout', Text, Lang). - --spec serr_host_gone() -> stream_error(). -serr_host_gone() -> - serr('host-gone'). - --spec serr_host_gone(binary(), binary()) -> stream_error(). -serr_host_gone(Text, Lang) -> - serr('host-gone', Text, Lang). - --spec serr_host_unknown() -> stream_error(). -serr_host_unknown() -> - serr('host-unknown'). - --spec serr_host_unknown(binary(), binary()) -> stream_error(). -serr_host_unknown(Text, Lang) -> - serr('host-unknown', Text, Lang). - --spec serr_improper_addressing() -> stream_error(). -serr_improper_addressing() -> - serr('improper-addressing'). - --spec serr_improper_addressing(binary(), binary()) -> stream_error(). -serr_improper_addressing(Text, Lang) -> - serr('improper-addressing', Text, Lang). - --spec serr_internal_server_error() -> stream_error(). -serr_internal_server_error() -> - serr('internal-server-error'). - --spec serr_internal_server_error(binary(), binary()) -> stream_error(). -serr_internal_server_error(Text, Lang) -> - serr('internal-server-error', Text, Lang). - --spec serr_invalid_from() -> stream_error(). -serr_invalid_from() -> - serr('invalid-from'). - --spec serr_invalid_from(binary(), binary()) -> stream_error(). -serr_invalid_from(Text, Lang) -> - serr('invalid-from', Text, Lang). - --spec serr_invalid_id() -> stream_error(). -serr_invalid_id() -> - serr('invalid-id'). - --spec serr_invalid_id(binary(), binary()) -> stream_error(). -serr_invalid_id(Text, Lang) -> - serr('invalid-id', Text, Lang). - --spec serr_invalid_namespace() -> stream_error(). -serr_invalid_namespace() -> - serr('invalid-namespace'). - --spec serr_invalid_namespace(binary(), binary()) -> stream_error(). -serr_invalid_namespace(Text, Lang) -> - serr('invalid-namespace', Text, Lang). - --spec serr_invalid_xml() -> stream_error(). -serr_invalid_xml() -> - serr('invalid-xml'). - --spec serr_invalid_xml(binary(), binary()) -> stream_error(). -serr_invalid_xml(Text, Lang) -> - serr('invalid-xml', Text, Lang). - --spec serr_not_authorized() -> stream_error(). -serr_not_authorized() -> - serr('not-authorized'). - --spec serr_not_authorized(binary(), binary()) -> stream_error(). -serr_not_authorized(Text, Lang) -> - serr('not-authorized', Text, Lang). - --spec serr_not_well_formed() -> stream_error(). -serr_not_well_formed() -> - serr('not-well-formed'). - --spec serr_not_well_formed(binary(), binary()) -> stream_error(). -serr_not_well_formed(Text, Lang) -> - serr('not-well-formed', Text, Lang). - --spec serr_policy_violation() -> stream_error(). -serr_policy_violation() -> - serr('policy-violation'). - --spec serr_policy_violation(binary(), binary()) -> stream_error(). -serr_policy_violation(Text, Lang) -> - serr('policy-violation', Text, Lang). - --spec serr_remote_connection_failed() -> stream_error(). -serr_remote_connection_failed() -> - serr('remote-connection-failed'). - --spec serr_remote_connection_failed(binary(), binary()) -> stream_error(). -serr_remote_connection_failed(Text, Lang) -> - serr('remote-connection-failed', Text, Lang). - --spec serr_reset() -> stream_error(). -serr_reset() -> - serr('reset'). - --spec serr_reset(binary(), binary()) -> stream_error(). -serr_reset(Text, Lang) -> - serr('reset', Text, Lang). - --spec serr_resource_constraint() -> stream_error(). -serr_resource_constraint() -> - serr('resource-constraint'). - --spec serr_resource_constraint(binary(), binary()) -> stream_error(). -serr_resource_constraint(Text, Lang) -> - serr('resource-constraint', Text, Lang). - --spec serr_restricted_xml() -> stream_error(). -serr_restricted_xml() -> - serr('restricted-xml'). - --spec serr_restricted_xml(binary(), binary()) -> stream_error(). -serr_restricted_xml(Text, Lang) -> - serr('restricted-xml', Text, Lang). - --spec serr_see_other_host() -> stream_error(). -serr_see_other_host() -> - serr('see-other-host'). - --spec serr_see_other_host(binary(), binary()) -> stream_error(). -serr_see_other_host(Text, Lang) -> - serr('see-other-host', Text, Lang). - --spec serr_system_shutdown() -> stream_error(). -serr_system_shutdown() -> - serr('system-shutdown'). - --spec serr_system_shutdown(binary(), binary()) -> stream_error(). -serr_system_shutdown(Text, Lang) -> - serr('system-shutdown', Text, Lang). - --spec serr_undefined_condition() -> stream_error(). -serr_undefined_condition() -> - serr('undefined-condition'). - --spec serr_undefined_condition(binary(), binary()) -> stream_error(). -serr_undefined_condition(Text, Lang) -> - serr('undefined-condition', Text, Lang). - --spec serr_unsupported_encoding() -> stream_error(). -serr_unsupported_encoding() -> - serr('unsupported-encoding'). - --spec serr_unsupported_encoding(binary(), binary()) -> stream_error(). -serr_unsupported_encoding(Text, Lang) -> - serr('unsupported-encoding', Text, Lang). - --spec serr_unsupported_stanza_type() -> stream_error(). -serr_unsupported_stanza_type() -> - serr('unsupported-stanza-type'). - --spec serr_unsupported_stanza_type(binary(), binary()) -> stream_error(). -serr_unsupported_stanza_type(Text, Lang) -> - serr('unsupported-stanza-type', Text, Lang). - --spec serr_unsupported_version() -> stream_error(). -serr_unsupported_version() -> - serr('unsupported-version'). - --spec serr_unsupported_version(binary(), binary()) -> stream_error(). -serr_unsupported_version(Text, Lang) -> - serr('unsupported-version', Text, Lang). - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== --spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', - atom() | gone() | redirect(), non_neg_integer()) -> stanza_error(). -err(Type, Reason, Code) -> - #stanza_error{type = Type, reason = Reason, code = Code}. - --spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait', - atom() | gone() | redirect(), non_neg_integer(), - binary(), binary()) -> stanza_error(). -err(Type, Reason, Code, Text, Lang) -> - #stanza_error{type = Type, reason = Reason, code = Code, - text = #text{lang = Lang, - data = translate:translate(Lang, Text)}}. - --spec serr(atom() | 'see-other-host'()) -> stream_error(). -serr(Reason) -> - #stream_error{reason = Reason}. - --spec serr(atom() | 'see-other-host'(), binary(), - binary()) -> stream_error(). -serr(Reason, Text, Lang) -> - #stream_error{reason = Reason, - text = #text{lang = Lang, - data = translate:translate(Lang, Text)}}. - --spec match_tag(xmlel() | xmpp_element(), binary(), binary()) -> boolean(). -match_tag(El, TagName, XMLNS) -> - get_name(El) == TagName andalso get_ns(El) == XMLNS. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl deleted file mode 100644 index 6089f79fc..000000000 --- a/src/xmpp_codec.erl +++ /dev/null @@ -1,34647 +0,0 @@ -%% Created automatically by XML generator (fxml_gen.erl) -%% Source: xmpp_codec.spec - --module(xmpp_codec). - --compile({nowarn_unused_function, - [{dec_int, 3}, {dec_int, 1}, {dec_enum, 2}, - {enc_int, 1}, {get_attr, 2}, {enc_enum, 1}, - {choose_top_xmlns, 3}, {enc_xmlns_attrs, 2}]}). - --export([pp/1, format_error/1, decode/1, decode/2, - decode/3, is_known_tag/2, encode/1, encode/2, - get_name/1, get_ns/1]). - -decode(_el) -> decode(_el, <<>>, []). - -decode(_el, Opts) -> decode(_el, <<>>, Opts). - -decode({xmlel, _name, _attrs, _} = _el, TopXMLNS, - Opts) -> - IgnoreEls = proplists:get_bool(ignore_els, Opts), - case {_name, get_attr(<<"xmlns">>, _attrs), TopXMLNS} of - {<<"query">>, <<"urn:xmpp:delegation:1">>, _} -> - decode_delegation_query(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"query">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - decode_delegation_query(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"delegate">>, <<"urn:xmpp:delegation:1">>, _} -> - decode_delegate(<<"urn:xmpp:delegation:1">>, IgnoreEls, - _el); - {<<"delegate">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - decode_delegate(<<"urn:xmpp:delegation:1">>, IgnoreEls, - _el); - {<<"delegation">>, <<"urn:xmpp:delegation:1">>, _} -> - decode_delegation(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"delegation">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - decode_delegation(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"delegated">>, <<"urn:xmpp:delegation:1">>, _} -> - decode_delegated(<<"urn:xmpp:delegation:1">>, IgnoreEls, - _el); - {<<"delegated">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - decode_delegated(<<"urn:xmpp:delegation:1">>, IgnoreEls, - _el); - {<<"attribute">>, <<"urn:xmpp:delegation:1">>, _} -> - decode_delegated_attribute(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"attribute">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - decode_delegated_attribute(<<"urn:xmpp:delegation:1">>, - IgnoreEls, _el); - {<<"privilege">>, <<"urn:xmpp:privilege:1">>, _} -> - decode_privilege(<<"urn:xmpp:privilege:1">>, IgnoreEls, - _el); - {<<"privilege">>, <<>>, <<"urn:xmpp:privilege:1">>} -> - decode_privilege(<<"urn:xmpp:privilege:1">>, IgnoreEls, - _el); - {<<"perm">>, <<"urn:xmpp:privilege:1">>, _} -> - decode_privilege_perm(<<"urn:xmpp:privilege:1">>, - IgnoreEls, _el); - {<<"perm">>, <<>>, <<"urn:xmpp:privilege:1">>} -> - decode_privilege_perm(<<"urn:xmpp:privilege:1">>, - IgnoreEls, _el); - {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>, _} -> - decode_thumbnail(<<"urn:xmpp:thumbs:1">>, IgnoreEls, - _el); - {<<"thumbnail">>, <<>>, <<"urn:xmpp:thumbs:1">>} -> - decode_thumbnail(<<"urn:xmpp:thumbs:1">>, IgnoreEls, - _el); - {<<"slot">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_slot(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"slot">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_slot(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"slot">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - decode_upload_slot(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"slot">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_slot(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"put">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_put(<<"urn:xmpp:http:upload">>, IgnoreEls, - _el); - {<<"put">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_put(<<"urn:xmpp:http:upload">>, IgnoreEls, - _el); - {<<"put">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - decode_upload_put(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"put">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_put(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"get">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_get(<<"urn:xmpp:http:upload">>, IgnoreEls, - _el); - {<<"get">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_get(<<"urn:xmpp:http:upload">>, IgnoreEls, - _el); - {<<"get">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - decode_upload_get(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"get">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_get(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"request">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_request(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"request">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_request(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"request">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - decode_upload_request(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"request">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_request(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"content-type">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_content_type(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"content-type">>, <<>>, - <<"urn:xmpp:http:upload">>} -> - decode_upload_content_type(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"content-type">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"content-type">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"size">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_size(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"size">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_size(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"size">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - decode_upload_size(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"size">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_size(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"filename">>, <<"urn:xmpp:http:upload">>, _} -> - decode_upload_filename(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"filename">>, <<>>, <<"urn:xmpp:http:upload">>} -> - decode_upload_filename(<<"urn:xmpp:http:upload">>, - IgnoreEls, _el); - {<<"filename">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"filename">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, - IgnoreEls, _el); - {<<"address">>, <<"urn:xmpp:sic:0">>, _} -> - decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"address">>, <<>>, <<"urn:xmpp:sic:0">>} -> - decode_sic(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"address">>, <<"urn:xmpp:sic:1">>, _} -> - decode_sic(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"address">>, <<>>, <<"urn:xmpp:sic:1">>} -> - decode_sic(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"port">>, <<"urn:xmpp:sic:1">>, _} -> - decode_sip_port(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"port">>, <<>>, <<"urn:xmpp:sic:1">>} -> - decode_sip_port(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"ip">>, <<"urn:xmpp:sic:0">>, _} -> - decode_sic_ip(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"ip">>, <<>>, <<"urn:xmpp:sic:0">>} -> - decode_sic_ip(<<"urn:xmpp:sic:0">>, IgnoreEls, _el); - {<<"ip">>, <<"urn:xmpp:sic:1">>, _} -> - decode_sic_ip(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"ip">>, <<>>, <<"urn:xmpp:sic:1">>} -> - decode_sic_ip(<<"urn:xmpp:sic:1">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:oob">>, _} -> - decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"x">>, <<>>, <<"jabber:x:oob">>} -> - decode_oob_x(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"desc">>, <<"jabber:x:oob">>, _} -> - decode_oob_desc(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"desc">>, <<>>, <<"jabber:x:oob">>} -> - decode_oob_desc(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"url">>, <<"jabber:x:oob">>, _} -> - decode_oob_url(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"url">>, <<>>, <<"jabber:x:oob">>} -> - decode_oob_url(<<"jabber:x:oob">>, IgnoreEls, _el); - {<<"media">>, <<"urn:xmpp:media-element">>, _} -> - decode_media(<<"urn:xmpp:media-element">>, IgnoreEls, - _el); - {<<"media">>, <<>>, <<"urn:xmpp:media-element">>} -> - decode_media(<<"urn:xmpp:media-element">>, IgnoreEls, - _el); - {<<"uri">>, <<"urn:xmpp:media-element">>, _} -> - decode_media_uri(<<"urn:xmpp:media-element">>, - IgnoreEls, _el); - {<<"uri">>, <<>>, <<"urn:xmpp:media-element">>} -> - decode_media_uri(<<"urn:xmpp:media-element">>, - IgnoreEls, _el); - {<<"captcha">>, <<"urn:xmpp:captcha">>, _} -> - decode_captcha(<<"urn:xmpp:captcha">>, IgnoreEls, _el); - {<<"captcha">>, <<>>, <<"urn:xmpp:captcha">>} -> - decode_captcha(<<"urn:xmpp:captcha">>, IgnoreEls, _el); - {<<"data">>, <<"urn:xmpp:bob">>, _} -> - decode_bob_data(<<"urn:xmpp:bob">>, IgnoreEls, _el); - {<<"data">>, <<>>, <<"urn:xmpp:bob">>} -> - decode_bob_data(<<"urn:xmpp:bob">>, IgnoreEls, _el); - {<<"stream:stream">>, <<"jabber:client">>, _} -> - decode_stream_start(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:stream">>, <<>>, <<"jabber:client">>} -> - decode_stream_start(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:stream">>, <<"jabber:server">>, _} -> - decode_stream_start(<<"jabber:server">>, IgnoreEls, - _el); - {<<"stream:stream">>, <<>>, <<"jabber:server">>} -> - decode_stream_start(<<"jabber:server">>, IgnoreEls, - _el); - {<<"stream:stream">>, <<"jabber:component:accept">>, - _} -> - decode_stream_start(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"stream:stream">>, <<>>, - <<"jabber:component:accept">>} -> - decode_stream_start(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"handshake">>, <<"jabber:component:accept">>, _} -> - decode_handshake(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"handshake">>, <<>>, - <<"jabber:component:accept">>} -> - decode_handshake(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"db:verify">>, <<"jabber:server">>, _} -> - decode_db_verify(<<"jabber:server">>, IgnoreEls, _el); - {<<"db:verify">>, <<>>, <<"jabber:server">>} -> - decode_db_verify(<<"jabber:server">>, IgnoreEls, _el); - {<<"db:result">>, <<"jabber:server">>, _} -> - decode_db_result(<<"jabber:server">>, IgnoreEls, _el); - {<<"db:result">>, <<>>, <<"jabber:server">>} -> - decode_db_result(<<"jabber:server">>, IgnoreEls, _el); - {<<"command">>, - <<"http://jabber.org/protocol/commands">>, _} -> - decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"command">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"note">>, <<"http://jabber.org/protocol/commands">>, - _} -> - decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"note">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"actions">>, - <<"http://jabber.org/protocol/commands">>, _} -> - decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"actions">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"complete">>, - <<"http://jabber.org/protocol/commands">>, _} -> - decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"complete">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"next">>, <<"http://jabber.org/protocol/commands">>, - _} -> - decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"next">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"prev">>, <<"http://jabber.org/protocol/commands">>, - _} -> - decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"prev">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, - IgnoreEls, _el); - {<<"client-id">>, <<"urn:xmpp:sid:0">>, _} -> - decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); - {<<"client-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> - decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); - {<<"stanza-id">>, <<"urn:xmpp:sid:0">>, _} -> - decode_stanza_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); - {<<"stanza-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> - decode_stanza_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el); - {<<"addresses">>, - <<"http://jabber.org/protocol/address">>, _} -> - decode_addresses(<<"http://jabber.org/protocol/address">>, - IgnoreEls, _el); - {<<"addresses">>, <<>>, - <<"http://jabber.org/protocol/address">>} -> - decode_addresses(<<"http://jabber.org/protocol/address">>, - IgnoreEls, _el); - {<<"address">>, - <<"http://jabber.org/protocol/address">>, _} -> - decode_address(<<"http://jabber.org/protocol/address">>, - IgnoreEls, _el); - {<<"address">>, <<>>, - <<"http://jabber.org/protocol/address">>} -> - decode_address(<<"http://jabber.org/protocol/address">>, - IgnoreEls, _el); - {<<"nick">>, <<"http://jabber.org/protocol/nick">>, - _} -> - decode_nick(<<"http://jabber.org/protocol/nick">>, - IgnoreEls, _el); - {<<"nick">>, <<>>, - <<"http://jabber.org/protocol/nick">>} -> - decode_nick(<<"http://jabber.org/protocol/nick">>, - IgnoreEls, _el); - {<<"x">>, <<"jabber:x:expire">>, _} -> - decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); - {<<"x">>, <<>>, <<"jabber:x:expire">>} -> - decode_expire(<<"jabber:x:expire">>, IgnoreEls, _el); - {<<"x">>, <<"jabber:x:event">>, _} -> - decode_xevent(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"x">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"id">>, <<"jabber:x:event">>, _} -> - decode_xevent_id(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"id">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent_id(<<"jabber:x:event">>, IgnoreEls, _el); - {<<"composing">>, <<"jabber:x:event">>, _} -> - decode_xevent_composing(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"composing">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent_composing(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"displayed">>, <<"jabber:x:event">>, _} -> - decode_xevent_displayed(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"displayed">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent_displayed(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"delivered">>, <<"jabber:x:event">>, _} -> - decode_xevent_delivered(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"delivered">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent_delivered(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"offline">>, <<"jabber:x:event">>, _} -> - decode_xevent_offline(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"offline">>, <<>>, <<"jabber:x:event">>} -> - decode_xevent_offline(<<"jabber:x:event">>, IgnoreEls, - _el); - {<<"query">>, <<"jabber:iq:search">>, _} -> - decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"jabber:iq:search">>} -> - decode_search(<<"jabber:iq:search">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:iq:search">>, _} -> - decode_search_item(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"item">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_item(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"email">>, <<"jabber:iq:search">>, _} -> - decode_search_email(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"email">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_email(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"nick">>, <<"jabber:iq:search">>, _} -> - decode_search_nick(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"nick">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_nick(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"last">>, <<"jabber:iq:search">>, _} -> - decode_search_last(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"last">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_last(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"first">>, <<"jabber:iq:search">>, _} -> - decode_search_first(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"first">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_first(<<"jabber:iq:search">>, IgnoreEls, - _el); - {<<"instructions">>, <<"jabber:iq:search">>, _} -> - decode_search_instructions(<<"jabber:iq:search">>, - IgnoreEls, _el); - {<<"instructions">>, <<>>, <<"jabber:iq:search">>} -> - decode_search_instructions(<<"jabber:iq:search">>, - IgnoreEls, _el); - {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_no_permanent_storage(<<"urn:xmpp:hints">>, - IgnoreEls, _el); - {<<"no-permanent-storage">>, <<>>, - <<"urn:xmpp:hints">>} -> - decode_hint_no_permanent_storage(<<"urn:xmpp:hints">>, - IgnoreEls, _el); - {<<"no-permanent-store">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, - IgnoreEls, _el); - {<<"no-permanent-store">>, <<>>, - <<"urn:xmpp:hints">>} -> - decode_hint_no_permanent_store(<<"urn:xmpp:hints">>, - IgnoreEls, _el); - {<<"store">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"store">>, <<>>, <<"urn:xmpp:hints">>} -> - decode_hint_store(<<"urn:xmpp:hints">>, IgnoreEls, _el); - {<<"no-storage">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_no_storage(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"no-storage">>, <<>>, <<"urn:xmpp:hints">>} -> - decode_hint_no_storage(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"no-store">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"no-store">>, <<>>, <<"urn:xmpp:hints">>} -> - decode_hint_no_store(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"no-copy">>, <<"urn:xmpp:hints">>, _} -> - decode_hint_no_copy(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"no-copy">>, <<>>, <<"urn:xmpp:hints">>} -> - decode_hint_no_copy(<<"urn:xmpp:hints">>, IgnoreEls, - _el); - {<<"participant">>, <<"urn:xmpp:mix:0">>, _} -> - decode_mix_participant(<<"urn:xmpp:mix:0">>, IgnoreEls, - _el); - {<<"participant">>, <<>>, <<"urn:xmpp:mix:0">>} -> - decode_mix_participant(<<"urn:xmpp:mix:0">>, IgnoreEls, - _el); - {<<"leave">>, <<"urn:xmpp:mix:0">>, _} -> - decode_mix_leave(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"leave">>, <<>>, <<"urn:xmpp:mix:0">>} -> - decode_mix_leave(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"join">>, <<"urn:xmpp:mix:0">>, _} -> - decode_mix_join(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"join">>, <<>>, <<"urn:xmpp:mix:0">>} -> - decode_mix_join(<<"urn:xmpp:mix:0">>, IgnoreEls, _el); - {<<"subscribe">>, <<"urn:xmpp:mix:0">>, _} -> - decode_mix_subscribe(<<"urn:xmpp:mix:0">>, IgnoreEls, - _el); - {<<"subscribe">>, <<>>, <<"urn:xmpp:mix:0">>} -> - decode_mix_subscribe(<<"urn:xmpp:mix:0">>, IgnoreEls, - _el); - {<<"offline">>, - <<"http://jabber.org/protocol/offline">>, _} -> - decode_offline(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"offline">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - decode_offline(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/offline">>, - _} -> - decode_offline_item(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - decode_offline_item(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"fetch">>, <<"http://jabber.org/protocol/offline">>, - _} -> - decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"fetch">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"purge">>, <<"http://jabber.org/protocol/offline">>, - _} -> - decode_offline_purge(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - decode_offline_purge(<<"http://jabber.org/protocol/offline">>, - IgnoreEls, _el); - {<<"failed">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"failed">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_failed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"failed">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_failed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"failed">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_failed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"a">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_a(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"a">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_a(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"a">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_a(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"a">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_a(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"r">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_r(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"r">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_r(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"r">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_r(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"r">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_r(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resumed">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_resumed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resumed">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_resumed(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resumed">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_resumed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resumed">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_resumed(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resume">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_resume(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resume">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_resume(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"resume">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_resume(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"resume">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_resume(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enabled">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_enabled(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enabled">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_enabled(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enabled">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_enabled(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enabled">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_enabled(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:sm:2">>, _} -> - decode_sm_enable(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enable">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_sm_enable(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:sm:3">>, _} -> - decode_sm_enable(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"enable">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_sm_enable(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"sm">>, <<"urn:xmpp:sm:2">>, _} -> - decode_feature_sm(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"sm">>, <<>>, <<"urn:xmpp:sm:2">>} -> - decode_feature_sm(<<"urn:xmpp:sm:2">>, IgnoreEls, _el); - {<<"sm">>, <<"urn:xmpp:sm:3">>, _} -> - decode_feature_sm(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"sm">>, <<>>, <<"urn:xmpp:sm:3">>} -> - decode_feature_sm(<<"urn:xmpp:sm:3">>, IgnoreEls, _el); - {<<"inactive">>, <<"urn:xmpp:csi:0">>, _} -> - decode_csi_inactive(<<"urn:xmpp:csi:0">>, IgnoreEls, - _el); - {<<"inactive">>, <<>>, <<"urn:xmpp:csi:0">>} -> - decode_csi_inactive(<<"urn:xmpp:csi:0">>, IgnoreEls, - _el); - {<<"active">>, <<"urn:xmpp:csi:0">>, _} -> - decode_csi_active(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); - {<<"active">>, <<>>, <<"urn:xmpp:csi:0">>} -> - decode_csi_active(<<"urn:xmpp:csi:0">>, IgnoreEls, _el); - {<<"csi">>, <<"urn:xmpp:csi:0">>, _} -> - decode_feature_csi(<<"urn:xmpp:csi:0">>, IgnoreEls, - _el); - {<<"csi">>, <<>>, <<"urn:xmpp:csi:0">>} -> - decode_feature_csi(<<"urn:xmpp:csi:0">>, IgnoreEls, - _el); - {<<"sent">>, <<"urn:xmpp:carbons:2">>, _} -> - decode_carbons_sent(<<"urn:xmpp:carbons:2">>, IgnoreEls, - _el); - {<<"sent">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - decode_carbons_sent(<<"urn:xmpp:carbons:2">>, IgnoreEls, - _el); - {<<"received">>, <<"urn:xmpp:carbons:2">>, _} -> - decode_carbons_received(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"received">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - decode_carbons_received(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"private">>, <<"urn:xmpp:carbons:2">>, _} -> - decode_carbons_private(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"private">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - decode_carbons_private(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"enable">>, <<"urn:xmpp:carbons:2">>, _} -> - decode_carbons_enable(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"enable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - decode_carbons_enable(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"disable">>, <<"urn:xmpp:carbons:2">>, _} -> - decode_carbons_disable(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"disable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - decode_carbons_disable(<<"urn:xmpp:carbons:2">>, - IgnoreEls, _el); - {<<"forwarded">>, <<"urn:xmpp:forward:0">>, _} -> - decode_forwarded(<<"urn:xmpp:forward:0">>, IgnoreEls, - _el); - {<<"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); - {<<"fin">>, <<>>, <<"urn:xmpp:mam:0">>} -> - decode_mam_fin(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"fin">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_fin(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"fin">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_fin(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:0">>, _} -> - decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:0">>} -> - decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_prefs(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_prefs(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"prefs">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> - decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"always">>, <<"urn:xmpp:mam:0">>, _} -> - decode_mam_always(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"always">>, <<>>, <<"urn:xmpp:mam:0">>} -> - decode_mam_always(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"always">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_always(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"always">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_always(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"always">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"always">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> - decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"never">>, <<"urn:xmpp:mam:0">>, _} -> - decode_mam_never(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"never">>, <<>>, <<"urn:xmpp:mam:0">>} -> - decode_mam_never(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"never">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_never(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"never">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_never(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"never">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"never">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> - decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"jid">>, <<"urn:xmpp:mam:0">>, _} -> - decode_mam_jid(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"jid">>, <<>>, <<"urn:xmpp:mam:0">>} -> - decode_mam_jid(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_jid(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"jid">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_jid(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"jid">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_jid(<<"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:0">>} -> - decode_mam_result(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"result">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_result(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"result">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_result(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"result">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_result(<<"urn:xmpp:mam:tmp">>, 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); - {<<"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:0">>} -> - decode_mam_query(<<"urn:xmpp:mam:0">>, IgnoreEls, _el); - {<<"query">>, <<"urn:xmpp:mam:1">>, _} -> - decode_mam_query(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"urn:xmpp:mam:1">>} -> - decode_mam_query(<<"urn:xmpp:mam:1">>, IgnoreEls, _el); - {<<"query">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"query">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> - decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"withtext">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"withtext">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> - decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, IgnoreEls, - _el); - {<<"with">>, <<"urn:xmpp:mam:tmp">>, _} -> - decode_mam_with(<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"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); - {<<"after">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - decode_rsm_after(<<"http://jabber.org/protocol/rsm">>, - IgnoreEls, _el); - {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> - decode_muc_unsubscribe(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"unsubscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - decode_muc_unsubscribe(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> - decode_muc_subscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, - _el); - {<<"subscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - decode_muc_subscribe(<<"urn:xmpp:mucsub:0">>, IgnoreEls, - _el); - {<<"event">>, <<"urn:xmpp:mucsub:0">>, _} -> - decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"event">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>, _} -> - decode_muc_subscriptions(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"subscriptions">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - decode_muc_subscriptions(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"subscription">>, <<"urn:xmpp:mucsub:0">>, _} -> - decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"subscription">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, - IgnoreEls, _el); - {<<"x">>, <<"jabber:x:conference">>, _} -> - decode_x_conference(<<"jabber:x:conference">>, - IgnoreEls, _el); - {<<"x">>, <<>>, <<"jabber:x:conference">>} -> - decode_x_conference(<<"jabber:x:conference">>, - IgnoreEls, _el); - {<<"unique">>, - <<"http://jabber.org/protocol/muc#unique">>, _} -> - decode_muc_unique(<<"http://jabber.org/protocol/muc#unique">>, - IgnoreEls, _el); - {<<"unique">>, <<>>, - <<"http://jabber.org/protocol/muc#unique">>} -> - decode_muc_unique(<<"http://jabber.org/protocol/muc#unique">>, - IgnoreEls, _el); - {<<"x">>, <<"http://jabber.org/protocol/muc">>, _} -> - decode_muc(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"x">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> - decode_muc(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"query">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_admin(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"continue">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"continue">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"actor">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"actor">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/muc#admin">>, - _} -> - decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/muc#owner">>, - _} -> - decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"query">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_owner(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"password">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"password">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"password">>, <<"http://jabber.org/protocol/muc">>, - _} -> - decode_muc_password(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc">>} -> - decode_muc_password(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"x">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"x">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"status">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"status">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"continue">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"continue">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"actor">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"actor">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"invite">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"invite">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"destroy">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"destroy">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"destroy">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"destroy">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"decline">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"decline">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"reason">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - IgnoreEls, _el); - {<<"reason">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - IgnoreEls, _el); - {<<"reason">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - IgnoreEls, _el); - {<<"history">>, <<"http://jabber.org/protocol/muc">>, - _} -> - decode_muc_history(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"history">>, <<>>, - <<"http://jabber.org/protocol/muc">>} -> - decode_muc_history(<<"http://jabber.org/protocol/muc">>, - IgnoreEls, _el); - {<<"query">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - decode_bytestreams(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - decode_bytestreams(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"activate">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"activate">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"streamhost-used">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"streamhost-used">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"streamhost">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"streamhost">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, - IgnoreEls, _el); - {<<"delay">>, <<"urn:xmpp:delay">>, _} -> - decode_delay(<<"urn:xmpp:delay">>, IgnoreEls, _el); - {<<"delay">>, <<>>, <<"urn:xmpp:delay">>} -> - decode_delay(<<"urn:xmpp:delay">>, IgnoreEls, _el); - {<<"paused">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - decode_chatstate_paused(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"paused">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - decode_chatstate_paused(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"inactive">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - decode_chatstate_inactive(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"inactive">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - decode_chatstate_inactive(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"gone">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - decode_chatstate_gone(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"gone">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - decode_chatstate_gone(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"composing">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - decode_chatstate_composing(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"composing">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - decode_chatstate_composing(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"active">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - decode_chatstate_active(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"active">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - decode_chatstate_active(<<"http://jabber.org/protocol/chatstates">>, - IgnoreEls, _el); - {<<"headers">>, <<"http://jabber.org/protocol/shim">>, - _} -> - decode_shim_headers(<<"http://jabber.org/protocol/shim">>, - IgnoreEls, _el); - {<<"headers">>, <<>>, - <<"http://jabber.org/protocol/shim">>} -> - decode_shim_headers(<<"http://jabber.org/protocol/shim">>, - IgnoreEls, _el); - {<<"header">>, <<"http://jabber.org/protocol/shim">>, - _} -> - decode_shim_header(<<"http://jabber.org/protocol/shim">>, - IgnoreEls, _el); - {<<"header">>, <<>>, - <<"http://jabber.org/protocol/shim">>} -> - decode_shim_header(<<"http://jabber.org/protocol/shim">>, - IgnoreEls, _el); - {<<"unsupported-access-model">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_unsupported_access_model(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"unsupported-access-model">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_unsupported_access_model(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"unsupported">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_unsupported(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"unsupported">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_unsupported(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"too-many-subscriptions">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_too_many_subscriptions(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"too-many-subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_too_many_subscriptions(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"subid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_subid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"subid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_subid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"presence-subscription-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_presence_subscription_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"presence-subscription-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_presence_subscription_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"pending-subscription">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_pending_subscription(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"pending-subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_pending_subscription(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"payload-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_payload_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"payload-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_payload_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"payload-too-big">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_payload_too_big(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"payload-too-big">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_payload_too_big(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"not-subscribed">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_not_subscribed(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"not-subscribed">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_not_subscribed(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"not-in-roster-group">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_not_in_roster_group(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"not-in-roster-group">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_not_in_roster_group(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"nodeid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_nodeid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"nodeid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_nodeid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"max-nodes-exceeded">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_max_nodes_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"max-nodes-exceeded">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_max_nodes_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"max-items-exceeded">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_max_items_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"max-items-exceeded">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_max_items_exceeded(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"jid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_jid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"jid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_jid_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"item-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_item_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"item-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_item_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"item-forbidden">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_item_forbidden(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"item-forbidden">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_item_forbidden(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-subid">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_invalid_subid(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-subid">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_invalid_subid(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-payload">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_invalid_payload(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-payload">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_invalid_payload(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-options">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_invalid_options(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-options">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_invalid_options(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-jid">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_invalid_jid(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"invalid-jid">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_invalid_jid(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"configuration-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_configuration_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"configuration-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_configuration_required(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"closed-node">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - decode_pubsub_error_closed_node(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"closed-node">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - decode_pubsub_error_closed_node(<<"http://jabber.org/protocol/pubsub#errors">>, - IgnoreEls, _el); - {<<"pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_owner(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"pubsub">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_owner(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"pubsub">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"purge">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"purge">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"purge">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"delete">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"delete">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"delete">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"default">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"default">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"default">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"default">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"publish-options">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"publish-options">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"configure">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"configure">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"configure">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"configure">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"create">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"create">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"create">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"create">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"retract">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"options">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"options">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"publish">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"publish">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"unsubscribe">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"unsubscribe">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscribe">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscribe">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"affiliations">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"affiliations">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"affiliations">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"affiliations">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscriptions">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscriptions">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"event">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"event">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_event(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"items">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"items">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"items">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"items">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"item">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"retract">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"retract">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"configuration">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"configuration">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"affiliation">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"affiliation">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"affiliation">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"affiliation">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, - IgnoreEls, _el); - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, - IgnoreEls, _el); - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, - IgnoreEls, _el); - {<<"x">>, <<"jabber:x:data">>, _} -> - decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"x">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"item">>, <<"jabber:x:data">>, _} -> - decode_xdata_item(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"item">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_item(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"reported">>, <<"jabber:x:data">>, _} -> - decode_xdata_reported(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"reported">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_reported(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"title">>, <<"jabber:x:data">>, _} -> - decode_xdata_title(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"title">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_title(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"instructions">>, <<"jabber:x:data">>, _} -> - decode_xdata_instructions(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"instructions">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_instructions(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"field">>, <<"jabber:x:data">>, _} -> - decode_xdata_field(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"field">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_field(<<"jabber:x:data">>, IgnoreEls, _el); - {<<"option">>, <<"jabber:x:data">>, _} -> - decode_xdata_field_option(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"option">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_field_option(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"value">>, <<"jabber:x:data">>, _} -> - decode_xdata_field_value(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"value">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_field_value(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"desc">>, <<"jabber:x:data">>, _} -> - decode_xdata_field_desc(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"desc">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_field_desc(<<"jabber:x:data">>, IgnoreEls, - _el); - {<<"required">>, <<"jabber:x:data">>, _} -> - decode_xdata_field_required(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"required">>, <<>>, <<"jabber:x:data">>} -> - decode_xdata_field_required(<<"jabber:x:data">>, - IgnoreEls, _el); - {<<"x">>, <<"vcard-temp:x:update">>, _} -> - decode_vcard_xupdate(<<"vcard-temp:x:update">>, - IgnoreEls, _el); - {<<"x">>, <<>>, <<"vcard-temp:x:update">>} -> - decode_vcard_xupdate(<<"vcard-temp:x:update">>, - IgnoreEls, _el); - {<<"photo">>, <<"vcard-temp:x:update">>, _} -> - decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, - IgnoreEls, _el); - {<<"photo">>, <<>>, <<"vcard-temp:x:update">>} -> - decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, - IgnoreEls, _el); - {<<"vCard">>, <<"vcard-temp">>, _} -> - decode_vcard_temp(<<"vcard-temp">>, IgnoreEls, _el); - {<<"vCard">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_temp(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CLASS">>, <<"vcard-temp">>, _} -> - decode_vcard_CLASS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CLASS">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CLASS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CATEGORIES">>, <<"vcard-temp">>, _} -> - decode_vcard_CATEGORIES(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"CATEGORIES">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CATEGORIES(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"KEY">>, <<"vcard-temp">>, _} -> - decode_vcard_KEY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"KEY">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_KEY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SOUND">>, <<"vcard-temp">>, _} -> - decode_vcard_SOUND(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SOUND">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_SOUND(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORG">>, <<"vcard-temp">>, _} -> - decode_vcard_ORG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORG">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ORG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHOTO">>, <<"vcard-temp">>, _} -> - decode_vcard_PHOTO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHOTO">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PHOTO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOGO">>, <<"vcard-temp">>, _} -> - decode_vcard_LOGO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOGO">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LOGO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BINVAL">>, <<"vcard-temp">>, _} -> - decode_vcard_BINVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BINVAL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_BINVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GEO">>, <<"vcard-temp">>, _} -> - decode_vcard_GEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GEO">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_GEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EMAIL">>, <<"vcard-temp">>, _} -> - decode_vcard_EMAIL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EMAIL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_EMAIL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TEL">>, <<"vcard-temp">>, _} -> - decode_vcard_TEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TEL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_TEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LABEL">>, <<"vcard-temp">>, _} -> - decode_vcard_LABEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LABEL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LABEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ADR">>, <<"vcard-temp">>, _} -> - decode_vcard_ADR(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ADR">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ADR(<<"vcard-temp">>, IgnoreEls, _el); - {<<"N">>, <<"vcard-temp">>, _} -> - decode_vcard_N(<<"vcard-temp">>, IgnoreEls, _el); - {<<"N">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_N(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CONFIDENTIAL">>, <<"vcard-temp">>, _} -> - decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"CONFIDENTIAL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"PRIVATE">>, <<"vcard-temp">>, _} -> - decode_vcard_PRIVATE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PRIVATE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PRIVATE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PUBLIC">>, <<"vcard-temp">>, _} -> - decode_vcard_PUBLIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PUBLIC">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PUBLIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTVAL">>, <<"vcard-temp">>, _} -> - decode_vcard_EXTVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTVAL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_EXTVAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TYPE">>, <<"vcard-temp">>, _} -> - decode_vcard_TYPE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TYPE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_TYPE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DESC">>, <<"vcard-temp">>, _} -> - decode_vcard_DESC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DESC">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_DESC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"URL">>, <<"vcard-temp">>, _} -> - decode_vcard_URL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"URL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_URL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"UID">>, <<"vcard-temp">>, _} -> - decode_vcard_UID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"UID">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_UID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SORT-STRING">>, <<"vcard-temp">>, _} -> - decode_vcard_SORT_STRING(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"SORT-STRING">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_SORT_STRING(<<"vcard-temp">>, IgnoreEls, - _el); - {<<"REV">>, <<"vcard-temp">>, _} -> - decode_vcard_REV(<<"vcard-temp">>, IgnoreEls, _el); - {<<"REV">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_REV(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PRODID">>, <<"vcard-temp">>, _} -> - decode_vcard_PRODID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PRODID">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PRODID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NOTE">>, <<"vcard-temp">>, _} -> - decode_vcard_NOTE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NOTE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_NOTE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"KEYWORD">>, <<"vcard-temp">>, _} -> - decode_vcard_KEYWORD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"KEYWORD">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_KEYWORD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ROLE">>, <<"vcard-temp">>, _} -> - decode_vcard_ROLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ROLE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ROLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TITLE">>, <<"vcard-temp">>, _} -> - decode_vcard_TITLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TITLE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_TITLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TZ">>, <<"vcard-temp">>, _} -> - decode_vcard_TZ(<<"vcard-temp">>, IgnoreEls, _el); - {<<"TZ">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_TZ(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MAILER">>, <<"vcard-temp">>, _} -> - decode_vcard_MAILER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MAILER">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_MAILER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"JABBERID">>, <<"vcard-temp">>, _} -> - decode_vcard_JABBERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"JABBERID">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_JABBERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BDAY">>, <<"vcard-temp">>, _} -> - decode_vcard_BDAY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BDAY">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_BDAY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NICKNAME">>, <<"vcard-temp">>, _} -> - decode_vcard_NICKNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NICKNAME">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_NICKNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FN">>, <<"vcard-temp">>, _} -> - decode_vcard_FN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FN">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_FN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VERSION">>, <<"vcard-temp">>, _} -> - decode_vcard_VERSION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VERSION">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_VERSION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CRED">>, <<"vcard-temp">>, _} -> - decode_vcard_CRED(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CRED">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CRED(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHONETIC">>, <<"vcard-temp">>, _} -> - decode_vcard_PHONETIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PHONETIC">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PHONETIC(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGUNIT">>, <<"vcard-temp">>, _} -> - decode_vcard_ORGUNIT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGUNIT">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ORGUNIT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGNAME">>, <<"vcard-temp">>, _} -> - decode_vcard_ORGNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ORGNAME">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ORGNAME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LON">>, <<"vcard-temp">>, _} -> - decode_vcard_LON(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LON">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LON(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LAT">>, <<"vcard-temp">>, _} -> - decode_vcard_LAT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LAT">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LAT(<<"vcard-temp">>, IgnoreEls, _el); - {<<"USERID">>, <<"vcard-temp">>, _} -> - decode_vcard_USERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"USERID">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_USERID(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NUMBER">>, <<"vcard-temp">>, _} -> - decode_vcard_NUMBER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"NUMBER">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_NUMBER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LINE">>, <<"vcard-temp">>, _} -> - decode_vcard_LINE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LINE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LINE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CTRY">>, <<"vcard-temp">>, _} -> - decode_vcard_CTRY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CTRY">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CTRY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCODE">>, <<"vcard-temp">>, _} -> - decode_vcard_PCODE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCODE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PCODE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"REGION">>, <<"vcard-temp">>, _} -> - decode_vcard_REGION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"REGION">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_REGION(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOCALITY">>, <<"vcard-temp">>, _} -> - decode_vcard_LOCALITY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"LOCALITY">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_LOCALITY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"STREET">>, <<"vcard-temp">>, _} -> - decode_vcard_STREET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"STREET">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_STREET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTADD">>, <<"vcard-temp">>, _} -> - decode_vcard_EXTADD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"EXTADD">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_EXTADD(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POBOX">>, <<"vcard-temp">>, _} -> - decode_vcard_POBOX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POBOX">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_POBOX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SUFFIX">>, <<"vcard-temp">>, _} -> - decode_vcard_SUFFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"SUFFIX">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_SUFFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREFIX">>, <<"vcard-temp">>, _} -> - decode_vcard_PREFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREFIX">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PREFIX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MIDDLE">>, <<"vcard-temp">>, _} -> - decode_vcard_MIDDLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MIDDLE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_MIDDLE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GIVEN">>, <<"vcard-temp">>, _} -> - decode_vcard_GIVEN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"GIVEN">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_GIVEN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAMILY">>, <<"vcard-temp">>, _} -> - decode_vcard_FAMILY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAMILY">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_FAMILY(<<"vcard-temp">>, IgnoreEls, _el); - {<<"X400">>, <<"vcard-temp">>, _} -> - decode_vcard_X400(<<"vcard-temp">>, IgnoreEls, _el); - {<<"X400">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_X400(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTERNET">>, <<"vcard-temp">>, _} -> - decode_vcard_INTERNET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTERNET">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_INTERNET(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREF">>, <<"vcard-temp">>, _} -> - decode_vcard_PREF(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PREF">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PREF(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTL">>, <<"vcard-temp">>, _} -> - decode_vcard_INTL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"INTL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_INTL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DOM">>, <<"vcard-temp">>, _} -> - decode_vcard_DOM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"DOM">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_DOM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PARCEL">>, <<"vcard-temp">>, _} -> - decode_vcard_PARCEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PARCEL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PARCEL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POSTAL">>, <<"vcard-temp">>, _} -> - decode_vcard_POSTAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"POSTAL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_POSTAL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCS">>, <<"vcard-temp">>, _} -> - decode_vcard_PCS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PCS">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PCS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ISDN">>, <<"vcard-temp">>, _} -> - decode_vcard_ISDN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"ISDN">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_ISDN(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MODEM">>, <<"vcard-temp">>, _} -> - decode_vcard_MODEM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MODEM">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_MODEM(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BBS">>, <<"vcard-temp">>, _} -> - decode_vcard_BBS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"BBS">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_BBS(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VIDEO">>, <<"vcard-temp">>, _} -> - decode_vcard_VIDEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VIDEO">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_VIDEO(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CELL">>, <<"vcard-temp">>, _} -> - decode_vcard_CELL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"CELL">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_CELL(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MSG">>, <<"vcard-temp">>, _} -> - decode_vcard_MSG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"MSG">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_MSG(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PAGER">>, <<"vcard-temp">>, _} -> - decode_vcard_PAGER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"PAGER">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_PAGER(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAX">>, <<"vcard-temp">>, _} -> - decode_vcard_FAX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"FAX">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_FAX(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VOICE">>, <<"vcard-temp">>, _} -> - decode_vcard_VOICE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"VOICE">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_VOICE(<<"vcard-temp">>, IgnoreEls, _el); - {<<"WORK">>, <<"vcard-temp">>, _} -> - decode_vcard_WORK(<<"vcard-temp">>, IgnoreEls, _el); - {<<"WORK">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_WORK(<<"vcard-temp">>, IgnoreEls, _el); - {<<"HOME">>, <<"vcard-temp">>, _} -> - decode_vcard_HOME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"HOME">>, <<>>, <<"vcard-temp">>} -> - decode_vcard_HOME(<<"vcard-temp">>, IgnoreEls, _el); - {<<"stream:error">>, <<"jabber:client">>, _} -> - decode_stream_error(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:error">>, <<>>, <<"jabber:client">>} -> - decode_stream_error(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:error">>, <<"jabber:server">>, _} -> - decode_stream_error(<<"jabber:server">>, IgnoreEls, - _el); - {<<"stream:error">>, <<>>, <<"jabber:server">>} -> - decode_stream_error(<<"jabber:server">>, IgnoreEls, - _el); - {<<"stream:error">>, <<"jabber:component:accept">>, - _} -> - decode_stream_error(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"stream:error">>, <<>>, - <<"jabber:component:accept">>} -> - decode_stream_error(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"unsupported-version">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"unsupported-version">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"unsupported-stanza-type">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"unsupported-stanza-type">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"unsupported-encoding">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"unsupported-encoding">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"undefined-condition">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"undefined-condition">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"system-shutdown">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"system-shutdown">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"see-other-host">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"see-other-host">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"restricted-xml">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"restricted-xml">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"resource-constraint">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"resource-constraint">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"reset">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, - _} -> - decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"reset">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"remote-connection-failed">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"remote-connection-failed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"policy-violation">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"policy-violation">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"not-well-formed">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"not-well-formed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-xml">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-xml">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-namespace">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-namespace">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-id">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-id">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-from">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"invalid-from">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"internal-server-error">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"internal-server-error">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"improper-addressing">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"improper-addressing">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"host-unknown">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"host-unknown">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"host-gone">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"host-gone">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"connection-timeout">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"connection-timeout">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"conflict">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"conflict">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"bad-namespace-prefix">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"bad-namespace-prefix">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"bad-format">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"bad-format">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, - _} -> - decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - IgnoreEls, _el); - {<<"time">>, <<"urn:xmpp:time">>, _} -> - decode_time(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"time">>, <<>>, <<"urn:xmpp:time">>} -> - decode_time(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"tzo">>, <<"urn:xmpp:time">>, _} -> - decode_time_tzo(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"tzo">>, <<>>, <<"urn:xmpp:time">>} -> - decode_time_tzo(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"utc">>, <<"urn:xmpp:time">>, _} -> - decode_time_utc(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"utc">>, <<>>, <<"urn:xmpp:time">>} -> - decode_time_utc(<<"urn:xmpp:time">>, IgnoreEls, _el); - {<<"ping">>, <<"urn:xmpp:ping">>, _} -> - decode_ping(<<"urn:xmpp:ping">>, IgnoreEls, _el); - {<<"ping">>, <<>>, <<"urn:xmpp:ping">>} -> - decode_ping(<<"urn:xmpp:ping">>, IgnoreEls, _el); - {<<"session">>, - <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> - decode_session(<<"urn:ietf:params:xml:ns:xmpp-session">>, - IgnoreEls, _el); - {<<"session">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-session">>} -> - decode_session(<<"urn:ietf:params:xml:ns:xmpp-session">>, - IgnoreEls, _el); - {<<"optional">>, - <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> - decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, - IgnoreEls, _el); - {<<"optional">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-session">>} -> - decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, - IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:register">>, _} -> - decode_register(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"query">>, <<>>, <<"jabber:iq:register">>} -> - decode_register(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"key">>, <<"jabber:iq:register">>, _} -> - decode_register_key(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"key">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_key(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"text">>, <<"jabber:iq:register">>, _} -> - decode_register_text(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"text">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_text(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"misc">>, <<"jabber:iq:register">>, _} -> - decode_register_misc(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"misc">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_misc(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"date">>, <<"jabber:iq:register">>, _} -> - decode_register_date(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"date">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_date(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"url">>, <<"jabber:iq:register">>, _} -> - decode_register_url(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"url">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_url(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"phone">>, <<"jabber:iq:register">>, _} -> - decode_register_phone(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"phone">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_phone(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"zip">>, <<"jabber:iq:register">>, _} -> - decode_register_zip(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"zip">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_zip(<<"jabber:iq:register">>, IgnoreEls, - _el); - {<<"state">>, <<"jabber:iq:register">>, _} -> - decode_register_state(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"state">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_state(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"city">>, <<"jabber:iq:register">>, _} -> - decode_register_city(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"city">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_city(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"address">>, <<"jabber:iq:register">>, _} -> - decode_register_address(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"address">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_address(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"email">>, <<"jabber:iq:register">>, _} -> - decode_register_email(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"email">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_email(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"last">>, <<"jabber:iq:register">>, _} -> - decode_register_last(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"last">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_last(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"first">>, <<"jabber:iq:register">>, _} -> - decode_register_first(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"first">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_first(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"name">>, <<"jabber:iq:register">>, _} -> - decode_register_name(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"name">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_name(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"password">>, <<"jabber:iq:register">>, _} -> - decode_register_password(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"password">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_password(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"nick">>, <<"jabber:iq:register">>, _} -> - decode_register_nick(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"nick">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_nick(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"username">>, <<"jabber:iq:register">>, _} -> - decode_register_username(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"username">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_username(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"instructions">>, <<"jabber:iq:register">>, _} -> - decode_register_instructions(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"instructions">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_instructions(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"remove">>, <<"jabber:iq:register">>, _} -> - decode_register_remove(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"remove">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_remove(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"registered">>, <<"jabber:iq:register">>, _} -> - decode_register_registered(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"registered">>, <<>>, <<"jabber:iq:register">>} -> - decode_register_registered(<<"jabber:iq:register">>, - IgnoreEls, _el); - {<<"register">>, - <<"http://jabber.org/features/iq-register">>, _} -> - decode_feature_register(<<"http://jabber.org/features/iq-register">>, - IgnoreEls, _el); - {<<"register">>, <<>>, - <<"http://jabber.org/features/iq-register">>} -> - decode_feature_register(<<"http://jabber.org/features/iq-register">>, - IgnoreEls, _el); - {<<"c">>, <<"http://jabber.org/protocol/caps">>, _} -> - decode_caps(<<"http://jabber.org/protocol/caps">>, - IgnoreEls, _el); - {<<"c">>, <<>>, - <<"http://jabber.org/protocol/caps">>} -> - decode_caps(<<"http://jabber.org/protocol/caps">>, - IgnoreEls, _el); - {<<"ack">>, <<"p1:ack">>, _} -> - decode_p1_ack(<<"p1:ack">>, IgnoreEls, _el); - {<<"ack">>, <<>>, <<"p1:ack">>} -> - decode_p1_ack(<<"p1:ack">>, IgnoreEls, _el); - {<<"rebind">>, <<"p1:rebind">>, _} -> - decode_p1_rebind(<<"p1:rebind">>, IgnoreEls, _el); - {<<"rebind">>, <<>>, <<"p1:rebind">>} -> - decode_p1_rebind(<<"p1:rebind">>, IgnoreEls, _el); - {<<"push">>, <<"p1:push">>, _} -> - decode_p1_push(<<"p1:push">>, IgnoreEls, _el); - {<<"push">>, <<>>, <<"p1:push">>} -> - decode_p1_push(<<"p1:push">>, IgnoreEls, _el); - {<<"stream:features">>, <<"jabber:client">>, _} -> - decode_stream_features(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:features">>, <<>>, <<"jabber:client">>} -> - decode_stream_features(<<"jabber:client">>, IgnoreEls, - _el); - {<<"stream:features">>, <<"jabber:server">>, _} -> - decode_stream_features(<<"jabber:server">>, IgnoreEls, - _el); - {<<"stream:features">>, <<>>, <<"jabber:server">>} -> - decode_stream_features(<<"jabber:server">>, IgnoreEls, - _el); - {<<"compression">>, - <<"http://jabber.org/features/compress">>, _} -> - decode_compression(<<"http://jabber.org/features/compress">>, - IgnoreEls, _el); - {<<"compression">>, <<>>, - <<"http://jabber.org/features/compress">>} -> - decode_compression(<<"http://jabber.org/features/compress">>, - IgnoreEls, _el); - {<<"method">>, - <<"http://jabber.org/features/compress">>, _} -> - decode_compression_method(<<"http://jabber.org/features/compress">>, - IgnoreEls, _el); - {<<"method">>, <<>>, - <<"http://jabber.org/features/compress">>} -> - decode_compression_method(<<"http://jabber.org/features/compress">>, - IgnoreEls, _el); - {<<"compressed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compressed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"compressed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compressed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"compress">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"compress">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"method">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress_method(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"method">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress_method(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"failure">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress_failure(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"failure">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress_failure(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"unsupported-method">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"unsupported-method">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"processing-failed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"processing-failed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"setup-failed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"setup-failed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, - IgnoreEls, _el); - {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - decode_starttls_failure(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - decode_starttls_failure(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"proceed">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - decode_starttls_proceed(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"proceed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - decode_starttls_proceed(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"starttls">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - decode_starttls(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"starttls">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - decode_starttls(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"required">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - IgnoreEls, _el); - {<<"mechanisms">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_mechanisms(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"mechanisms">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_mechanisms(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"mechanism">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"mechanism">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"temporary-auth-failure">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"temporary-auth-failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"bad-protocol">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"bad-protocol">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"mechanism-too-weak">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"mechanism-too-weak">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"malformed-request">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"malformed-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"invalid-mechanism">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"invalid-mechanism">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"invalid-authzid">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"invalid-authzid">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"incorrect-encoding">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"incorrect-encoding">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"encryption-required">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"encryption-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"credentials-expired">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"credentials-expired">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"account-disabled">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"account-disabled">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"aborted">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"aborted">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"success">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_success(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"success">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_success(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"response">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_response(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"response">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_response(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"challenge">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - decode_sasl_challenge(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"challenge">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_challenge(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_abort(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"abort">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_abort(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - decode_sasl_auth(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"auth">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - decode_sasl_auth(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:auth">>, _} -> - decode_legacy_auth(<<"jabber:iq:auth">>, IgnoreEls, - _el); - {<<"query">>, <<>>, <<"jabber:iq:auth">>} -> - decode_legacy_auth(<<"jabber:iq:auth">>, IgnoreEls, - _el); - {<<"resource">>, <<"jabber:iq:auth">>, _} -> - decode_legacy_auth_resource(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"resource">>, <<>>, <<"jabber:iq:auth">>} -> - decode_legacy_auth_resource(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"digest">>, <<"jabber:iq:auth">>, _} -> - decode_legacy_auth_digest(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"digest">>, <<>>, <<"jabber:iq:auth">>} -> - decode_legacy_auth_digest(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"password">>, <<"jabber:iq:auth">>, _} -> - decode_legacy_auth_password(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"password">>, <<>>, <<"jabber:iq:auth">>} -> - decode_legacy_auth_password(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"username">>, <<"jabber:iq:auth">>, _} -> - decode_legacy_auth_username(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"username">>, <<>>, <<"jabber:iq:auth">>} -> - decode_legacy_auth_username(<<"jabber:iq:auth">>, - IgnoreEls, _el); - {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - decode_bind(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"bind">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - decode_bind(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"resource">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"resource">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"jid">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - IgnoreEls, _el); - {<<"error">>, <<"jabber:client">>, _} -> - decode_error(<<"jabber:client">>, IgnoreEls, _el); - {<<"error">>, <<>>, <<"jabber:client">>} -> - decode_error(<<"jabber:client">>, IgnoreEls, _el); - {<<"error">>, <<"jabber:server">>, _} -> - decode_error(<<"jabber:server">>, IgnoreEls, _el); - {<<"error">>, <<>>, <<"jabber:server">>} -> - decode_error(<<"jabber:server">>, IgnoreEls, _el); - {<<"error">>, <<"jabber:component:accept">>, _} -> - decode_error(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"error">>, <<>>, <<"jabber:component:accept">>} -> - decode_error(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - _} -> - decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"unexpected-request">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"unexpected-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"undefined-condition">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"undefined-condition">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"subscription-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"subscription-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"service-unavailable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"service-unavailable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"resource-constraint">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"resource-constraint">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"remote-server-timeout">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"remote-server-timeout">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"remote-server-not-found">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"remote-server-not-found">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"registration-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"registration-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"redirect">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"redirect">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"recipient-unavailable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"recipient-unavailable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"policy-violation">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"policy-violation">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"payment-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"payment-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-allowed">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-allowed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-acceptable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"not-acceptable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"jid-malformed">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"jid-malformed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"item-not-found">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"item-not-found">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"internal-server-error">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"internal-server-error">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"gone">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - _} -> - decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"gone">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"forbidden">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"forbidden">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"feature-not-implemented">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"feature-not-implemented">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"conflict">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"conflict">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"bad-request">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"bad-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - IgnoreEls, _el); - {<<"presence">>, <<"jabber:client">>, _} -> - decode_presence(<<"jabber:client">>, IgnoreEls, _el); - {<<"presence">>, <<>>, <<"jabber:client">>} -> - decode_presence(<<"jabber:client">>, IgnoreEls, _el); - {<<"presence">>, <<"jabber:server">>, _} -> - decode_presence(<<"jabber:server">>, IgnoreEls, _el); - {<<"presence">>, <<>>, <<"jabber:server">>} -> - decode_presence(<<"jabber:server">>, IgnoreEls, _el); - {<<"presence">>, <<"jabber:component:accept">>, _} -> - decode_presence(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"presence">>, <<>>, <<"jabber:component:accept">>} -> - decode_presence(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"priority">>, <<"jabber:client">>, _} -> - decode_presence_priority(<<"jabber:client">>, IgnoreEls, - _el); - {<<"priority">>, <<>>, <<"jabber:client">>} -> - decode_presence_priority(<<"jabber:client">>, IgnoreEls, - _el); - {<<"priority">>, <<"jabber:server">>, _} -> - decode_presence_priority(<<"jabber:server">>, IgnoreEls, - _el); - {<<"priority">>, <<>>, <<"jabber:server">>} -> - decode_presence_priority(<<"jabber:server">>, IgnoreEls, - _el); - {<<"priority">>, <<"jabber:component:accept">>, _} -> - decode_presence_priority(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"priority">>, <<>>, <<"jabber:component:accept">>} -> - decode_presence_priority(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"status">>, <<"jabber:client">>, _} -> - decode_presence_status(<<"jabber:client">>, IgnoreEls, - _el); - {<<"status">>, <<>>, <<"jabber:client">>} -> - decode_presence_status(<<"jabber:client">>, IgnoreEls, - _el); - {<<"status">>, <<"jabber:server">>, _} -> - decode_presence_status(<<"jabber:server">>, IgnoreEls, - _el); - {<<"status">>, <<>>, <<"jabber:server">>} -> - decode_presence_status(<<"jabber:server">>, IgnoreEls, - _el); - {<<"status">>, <<"jabber:component:accept">>, _} -> - decode_presence_status(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"status">>, <<>>, <<"jabber:component:accept">>} -> - decode_presence_status(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"show">>, <<"jabber:client">>, _} -> - decode_presence_show(<<"jabber:client">>, IgnoreEls, - _el); - {<<"show">>, <<>>, <<"jabber:client">>} -> - decode_presence_show(<<"jabber:client">>, IgnoreEls, - _el); - {<<"show">>, <<"jabber:server">>, _} -> - decode_presence_show(<<"jabber:server">>, IgnoreEls, - _el); - {<<"show">>, <<>>, <<"jabber:server">>} -> - decode_presence_show(<<"jabber:server">>, IgnoreEls, - _el); - {<<"show">>, <<"jabber:component:accept">>, _} -> - decode_presence_show(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"show">>, <<>>, <<"jabber:component:accept">>} -> - decode_presence_show(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"message">>, <<"jabber:client">>, _} -> - decode_message(<<"jabber:client">>, IgnoreEls, _el); - {<<"message">>, <<>>, <<"jabber:client">>} -> - decode_message(<<"jabber:client">>, IgnoreEls, _el); - {<<"message">>, <<"jabber:server">>, _} -> - decode_message(<<"jabber:server">>, IgnoreEls, _el); - {<<"message">>, <<>>, <<"jabber:server">>} -> - decode_message(<<"jabber:server">>, IgnoreEls, _el); - {<<"message">>, <<"jabber:component:accept">>, _} -> - decode_message(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"message">>, <<>>, <<"jabber:component:accept">>} -> - decode_message(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"thread">>, <<"jabber:client">>, _} -> - decode_message_thread(<<"jabber:client">>, IgnoreEls, - _el); - {<<"thread">>, <<>>, <<"jabber:client">>} -> - decode_message_thread(<<"jabber:client">>, IgnoreEls, - _el); - {<<"thread">>, <<"jabber:server">>, _} -> - decode_message_thread(<<"jabber:server">>, IgnoreEls, - _el); - {<<"thread">>, <<>>, <<"jabber:server">>} -> - decode_message_thread(<<"jabber:server">>, IgnoreEls, - _el); - {<<"thread">>, <<"jabber:component:accept">>, _} -> - decode_message_thread(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"thread">>, <<>>, <<"jabber:component:accept">>} -> - decode_message_thread(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"body">>, <<"jabber:client">>, _} -> - decode_message_body(<<"jabber:client">>, IgnoreEls, - _el); - {<<"body">>, <<>>, <<"jabber:client">>} -> - decode_message_body(<<"jabber:client">>, IgnoreEls, - _el); - {<<"body">>, <<"jabber:server">>, _} -> - decode_message_body(<<"jabber:server">>, IgnoreEls, - _el); - {<<"body">>, <<>>, <<"jabber:server">>} -> - decode_message_body(<<"jabber:server">>, IgnoreEls, - _el); - {<<"body">>, <<"jabber:component:accept">>, _} -> - decode_message_body(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"body">>, <<>>, <<"jabber:component:accept">>} -> - decode_message_body(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"subject">>, <<"jabber:client">>, _} -> - decode_message_subject(<<"jabber:client">>, IgnoreEls, - _el); - {<<"subject">>, <<>>, <<"jabber:client">>} -> - decode_message_subject(<<"jabber:client">>, IgnoreEls, - _el); - {<<"subject">>, <<"jabber:server">>, _} -> - decode_message_subject(<<"jabber:server">>, IgnoreEls, - _el); - {<<"subject">>, <<>>, <<"jabber:server">>} -> - decode_message_subject(<<"jabber:server">>, IgnoreEls, - _el); - {<<"subject">>, <<"jabber:component:accept">>, _} -> - decode_message_subject(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"subject">>, <<>>, <<"jabber:component:accept">>} -> - decode_message_subject(<<"jabber:component:accept">>, - IgnoreEls, _el); - {<<"iq">>, <<"jabber:client">>, _} -> - decode_iq(<<"jabber:client">>, IgnoreEls, _el); - {<<"iq">>, <<>>, <<"jabber:client">>} -> - decode_iq(<<"jabber:client">>, IgnoreEls, _el); - {<<"iq">>, <<"jabber:server">>, _} -> - decode_iq(<<"jabber:server">>, IgnoreEls, _el); - {<<"iq">>, <<>>, <<"jabber:server">>} -> - decode_iq(<<"jabber:server">>, IgnoreEls, _el); - {<<"iq">>, <<"jabber:component:accept">>, _} -> - decode_iq(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"iq">>, <<>>, <<"jabber:component:accept">>} -> - decode_iq(<<"jabber:component:accept">>, IgnoreEls, - _el); - {<<"query">>, <<"http://jabber.org/protocol/stats">>, - _} -> - decode_stats(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - decode_stats(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"stat">>, <<"http://jabber.org/protocol/stats">>, - _} -> - decode_stat(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"stat">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - decode_stat(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"error">>, <<"http://jabber.org/protocol/stats">>, - _} -> - decode_stat_error(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"error">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - decode_stat_error(<<"http://jabber.org/protocol/stats">>, - IgnoreEls, _el); - {<<"storage">>, <<"storage:bookmarks">>, _} -> - decode_bookmarks_storage(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"storage">>, <<>>, <<"storage:bookmarks">>} -> - decode_bookmarks_storage(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"url">>, <<"storage:bookmarks">>, _} -> - decode_bookmark_url(<<"storage:bookmarks">>, IgnoreEls, - _el); - {<<"url">>, <<>>, <<"storage:bookmarks">>} -> - decode_bookmark_url(<<"storage:bookmarks">>, IgnoreEls, - _el); - {<<"conference">>, <<"storage:bookmarks">>, _} -> - decode_bookmark_conference(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"conference">>, <<>>, <<"storage:bookmarks">>} -> - decode_bookmark_conference(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"password">>, <<"storage:bookmarks">>, _} -> - decode_conference_password(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"password">>, <<>>, <<"storage:bookmarks">>} -> - decode_conference_password(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"nick">>, <<"storage:bookmarks">>, _} -> - decode_conference_nick(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"nick">>, <<>>, <<"storage:bookmarks">>} -> - decode_conference_nick(<<"storage:bookmarks">>, - IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:private">>, _} -> - decode_private(<<"jabber:iq:private">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"jabber:iq:private">>} -> - decode_private(<<"jabber:iq:private">>, IgnoreEls, _el); - {<<"query">>, - <<"http://jabber.org/protocol/disco#items">>, _} -> - decode_disco_items(<<"http://jabber.org/protocol/disco#items">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/disco#items">>} -> - decode_disco_items(<<"http://jabber.org/protocol/disco#items">>, - IgnoreEls, _el); - {<<"item">>, - <<"http://jabber.org/protocol/disco#items">>, _} -> - decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, - IgnoreEls, _el); - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/disco#items">>} -> - decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, - IgnoreEls, _el); - {<<"query">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - decode_disco_info(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - decode_disco_info(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"feature">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"feature">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"identity">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"identity">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, - IgnoreEls, _el); - {<<"blocklist">>, <<"urn:xmpp:blocking">>, _} -> - decode_block_list(<<"urn:xmpp:blocking">>, IgnoreEls, - _el); - {<<"blocklist">>, <<>>, <<"urn:xmpp:blocking">>} -> - decode_block_list(<<"urn:xmpp:blocking">>, IgnoreEls, - _el); - {<<"unblock">>, <<"urn:xmpp:blocking">>, _} -> - decode_unblock(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"unblock">>, <<>>, <<"urn:xmpp:blocking">>} -> - decode_unblock(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"block">>, <<"urn:xmpp:blocking">>, _} -> - decode_block(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"block">>, <<>>, <<"urn:xmpp:blocking">>} -> - decode_block(<<"urn:xmpp:blocking">>, IgnoreEls, _el); - {<<"item">>, <<"urn:xmpp:blocking">>, _} -> - decode_block_item(<<"urn:xmpp:blocking">>, IgnoreEls, - _el); - {<<"item">>, <<>>, <<"urn:xmpp:blocking">>} -> - decode_block_item(<<"urn:xmpp:blocking">>, IgnoreEls, - _el); - {<<"query">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy(<<"jabber:iq:privacy">>, IgnoreEls, _el); - {<<"active">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_active_list(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"active">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_active_list(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"default">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_default_list(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"default">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_default_list(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"list">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_list(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"list">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_list(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"item">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_item(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"item">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_item(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"presence-out">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_presence_out(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"presence-out">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_presence_out(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"presence-in">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_presence_in(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"presence-in">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_presence_in(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"iq">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_iq(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"iq">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_iq(<<"jabber:iq:privacy">>, IgnoreEls, - _el); - {<<"message">>, <<"jabber:iq:privacy">>, _} -> - decode_privacy_message(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"message">>, <<>>, <<"jabber:iq:privacy">>} -> - decode_privacy_message(<<"jabber:iq:privacy">>, - IgnoreEls, _el); - {<<"ver">>, <<"urn:xmpp:features:rosterver">>, _} -> - decode_rosterver_feature(<<"urn:xmpp:features:rosterver">>, - IgnoreEls, _el); - {<<"ver">>, <<>>, <<"urn:xmpp:features:rosterver">>} -> - decode_rosterver_feature(<<"urn:xmpp:features:rosterver">>, - IgnoreEls, _el); - {<<"query">>, <<"jabber:iq:roster">>, _} -> - decode_roster_query(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"query">>, <<>>, <<"jabber:iq:roster">>} -> - decode_roster_query(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"item">>, <<"jabber:iq:roster">>, _} -> - decode_roster_item(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"item">>, <<>>, <<"jabber:iq:roster">>} -> - decode_roster_item(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"group">>, <<"jabber:iq:roster">>, _} -> - decode_roster_group(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"group">>, <<>>, <<"jabber:iq:roster">>} -> - decode_roster_group(<<"jabber:iq:roster">>, IgnoreEls, - _el); - {<<"query">>, <<"jabber:iq:version">>, _} -> - decode_version(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"jabber:iq:version">>} -> - decode_version(<<"jabber:iq:version">>, IgnoreEls, _el); - {<<"os">>, <<"jabber:iq:version">>, _} -> - decode_version_os(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"os">>, <<>>, <<"jabber:iq:version">>} -> - decode_version_os(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"version">>, <<"jabber:iq:version">>, _} -> - decode_version_ver(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"version">>, <<>>, <<"jabber:iq:version">>} -> - decode_version_ver(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"name">>, <<"jabber:iq:version">>, _} -> - decode_version_name(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"name">>, <<>>, <<"jabber:iq:version">>} -> - decode_version_name(<<"jabber:iq:version">>, IgnoreEls, - _el); - {<<"query">>, <<"jabber:iq:last">>, _} -> - decode_last(<<"jabber:iq:last">>, IgnoreEls, _el); - {<<"query">>, <<>>, <<"jabber:iq:last">>} -> - decode_last(<<"jabber:iq:last">>, IgnoreEls, _el); - {_name, <<>>, <<>>} -> - erlang:error({xmpp_codec, {missing_tag_xmlns, _name}}); - {_name, <<>>, _} -> - erlang:error({xmpp_codec, - {unknown_tag, _name, TopXMLNS}}); - {_name, _xmlns, _} -> - erlang:error({xmpp_codec, {unknown_tag, _name, _xmlns}}) - end. - -is_known_tag({xmlel, _name, _attrs, _} = _el, - TopXMLNS) -> - case {_name, get_attr(<<"xmlns">>, _attrs), TopXMLNS} of - {<<"query">>, <<"urn:xmpp:delegation:1">>, _} -> true; - {<<"query">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - true; - {<<"delegate">>, <<"urn:xmpp:delegation:1">>, _} -> - true; - {<<"delegate">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - true; - {<<"delegation">>, <<"urn:xmpp:delegation:1">>, _} -> - true; - {<<"delegation">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - true; - {<<"delegated">>, <<"urn:xmpp:delegation:1">>, _} -> - true; - {<<"delegated">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - true; - {<<"attribute">>, <<"urn:xmpp:delegation:1">>, _} -> - true; - {<<"attribute">>, <<>>, <<"urn:xmpp:delegation:1">>} -> - true; - {<<"privilege">>, <<"urn:xmpp:privilege:1">>, _} -> - true; - {<<"privilege">>, <<>>, <<"urn:xmpp:privilege:1">>} -> - true; - {<<"perm">>, <<"urn:xmpp:privilege:1">>, _} -> true; - {<<"perm">>, <<>>, <<"urn:xmpp:privilege:1">>} -> true; - {<<"thumbnail">>, <<"urn:xmpp:thumbs:1">>, _} -> true; - {<<"thumbnail">>, <<>>, <<"urn:xmpp:thumbs:1">>} -> - true; - {<<"slot">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"slot">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; - {<<"slot">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - true; - {<<"slot">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"put">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"put">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; - {<<"put">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - true; - {<<"put">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"get">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"get">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; - {<<"get">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - true; - {<<"get">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"request">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"request">>, <<>>, <<"urn:xmpp:http:upload">>} -> - true; - {<<"request">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - true; - {<<"request">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"content-type">>, <<"urn:xmpp:http:upload">>, _} -> - true; - {<<"content-type">>, <<>>, - <<"urn:xmpp:http:upload">>} -> - true; - {<<"content-type">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - true; - {<<"content-type">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"size">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"size">>, <<>>, <<"urn:xmpp:http:upload">>} -> true; - {<<"size">>, <<"eu:siacs:conversations:http:upload">>, - _} -> - true; - {<<"size">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"filename">>, <<"urn:xmpp:http:upload">>, _} -> true; - {<<"filename">>, <<>>, <<"urn:xmpp:http:upload">>} -> - true; - {<<"filename">>, - <<"eu:siacs:conversations:http:upload">>, _} -> - true; - {<<"filename">>, <<>>, - <<"eu:siacs:conversations:http:upload">>} -> - true; - {<<"address">>, <<"urn:xmpp:sic:0">>, _} -> true; - {<<"address">>, <<>>, <<"urn:xmpp:sic:0">>} -> true; - {<<"address">>, <<"urn:xmpp:sic:1">>, _} -> true; - {<<"address">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; - {<<"port">>, <<"urn:xmpp:sic:1">>, _} -> true; - {<<"port">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; - {<<"ip">>, <<"urn:xmpp:sic:0">>, _} -> true; - {<<"ip">>, <<>>, <<"urn:xmpp:sic:0">>} -> true; - {<<"ip">>, <<"urn:xmpp:sic:1">>, _} -> true; - {<<"ip">>, <<>>, <<"urn:xmpp:sic:1">>} -> true; - {<<"x">>, <<"jabber:x:oob">>, _} -> true; - {<<"x">>, <<>>, <<"jabber:x:oob">>} -> true; - {<<"desc">>, <<"jabber:x:oob">>, _} -> true; - {<<"desc">>, <<>>, <<"jabber:x:oob">>} -> true; - {<<"url">>, <<"jabber:x:oob">>, _} -> true; - {<<"url">>, <<>>, <<"jabber:x:oob">>} -> true; - {<<"media">>, <<"urn:xmpp:media-element">>, _} -> true; - {<<"media">>, <<>>, <<"urn:xmpp:media-element">>} -> - true; - {<<"uri">>, <<"urn:xmpp:media-element">>, _} -> true; - {<<"uri">>, <<>>, <<"urn:xmpp:media-element">>} -> true; - {<<"captcha">>, <<"urn:xmpp:captcha">>, _} -> true; - {<<"captcha">>, <<>>, <<"urn:xmpp:captcha">>} -> true; - {<<"data">>, <<"urn:xmpp:bob">>, _} -> true; - {<<"data">>, <<>>, <<"urn:xmpp:bob">>} -> true; - {<<"stream:stream">>, <<"jabber:client">>, _} -> true; - {<<"stream:stream">>, <<>>, <<"jabber:client">>} -> - true; - {<<"stream:stream">>, <<"jabber:server">>, _} -> true; - {<<"stream:stream">>, <<>>, <<"jabber:server">>} -> - true; - {<<"stream:stream">>, <<"jabber:component:accept">>, - _} -> - true; - {<<"stream:stream">>, <<>>, - <<"jabber:component:accept">>} -> - true; - {<<"handshake">>, <<"jabber:component:accept">>, _} -> - true; - {<<"handshake">>, <<>>, - <<"jabber:component:accept">>} -> - true; - {<<"db:verify">>, <<"jabber:server">>, _} -> true; - {<<"db:verify">>, <<>>, <<"jabber:server">>} -> true; - {<<"db:result">>, <<"jabber:server">>, _} -> true; - {<<"db:result">>, <<>>, <<"jabber:server">>} -> true; - {<<"command">>, - <<"http://jabber.org/protocol/commands">>, _} -> - true; - {<<"command">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"note">>, <<"http://jabber.org/protocol/commands">>, - _} -> - true; - {<<"note">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"actions">>, - <<"http://jabber.org/protocol/commands">>, _} -> - true; - {<<"actions">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"complete">>, - <<"http://jabber.org/protocol/commands">>, _} -> - true; - {<<"complete">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"next">>, <<"http://jabber.org/protocol/commands">>, - _} -> - true; - {<<"next">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"prev">>, <<"http://jabber.org/protocol/commands">>, - _} -> - true; - {<<"prev">>, <<>>, - <<"http://jabber.org/protocol/commands">>} -> - true; - {<<"client-id">>, <<"urn:xmpp:sid:0">>, _} -> true; - {<<"client-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> true; - {<<"stanza-id">>, <<"urn:xmpp:sid:0">>, _} -> true; - {<<"stanza-id">>, <<>>, <<"urn:xmpp:sid:0">>} -> true; - {<<"addresses">>, - <<"http://jabber.org/protocol/address">>, _} -> - true; - {<<"addresses">>, <<>>, - <<"http://jabber.org/protocol/address">>} -> - true; - {<<"address">>, - <<"http://jabber.org/protocol/address">>, _} -> - true; - {<<"address">>, <<>>, - <<"http://jabber.org/protocol/address">>} -> - true; - {<<"nick">>, <<"http://jabber.org/protocol/nick">>, - _} -> - true; - {<<"nick">>, <<>>, - <<"http://jabber.org/protocol/nick">>} -> - true; - {<<"x">>, <<"jabber:x:expire">>, _} -> true; - {<<"x">>, <<>>, <<"jabber:x:expire">>} -> true; - {<<"x">>, <<"jabber:x:event">>, _} -> true; - {<<"x">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"id">>, <<"jabber:x:event">>, _} -> true; - {<<"id">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"composing">>, <<"jabber:x:event">>, _} -> true; - {<<"composing">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"displayed">>, <<"jabber:x:event">>, _} -> true; - {<<"displayed">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"delivered">>, <<"jabber:x:event">>, _} -> true; - {<<"delivered">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"offline">>, <<"jabber:x:event">>, _} -> true; - {<<"offline">>, <<>>, <<"jabber:x:event">>} -> true; - {<<"query">>, <<"jabber:iq:search">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"item">>, <<"jabber:iq:search">>, _} -> true; - {<<"item">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"email">>, <<"jabber:iq:search">>, _} -> true; - {<<"email">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"nick">>, <<"jabber:iq:search">>, _} -> true; - {<<"nick">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"last">>, <<"jabber:iq:search">>, _} -> true; - {<<"last">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"first">>, <<"jabber:iq:search">>, _} -> true; - {<<"first">>, <<>>, <<"jabber:iq:search">>} -> true; - {<<"instructions">>, <<"jabber:iq:search">>, _} -> true; - {<<"instructions">>, <<>>, <<"jabber:iq:search">>} -> - true; - {<<"no-permanent-storage">>, <<"urn:xmpp:hints">>, _} -> - true; - {<<"no-permanent-storage">>, <<>>, - <<"urn:xmpp:hints">>} -> - true; - {<<"no-permanent-store">>, <<"urn:xmpp:hints">>, _} -> - true; - {<<"no-permanent-store">>, <<>>, - <<"urn:xmpp:hints">>} -> - true; - {<<"store">>, <<"urn:xmpp:hints">>, _} -> true; - {<<"store">>, <<>>, <<"urn:xmpp:hints">>} -> true; - {<<"no-storage">>, <<"urn:xmpp:hints">>, _} -> true; - {<<"no-storage">>, <<>>, <<"urn:xmpp:hints">>} -> true; - {<<"no-store">>, <<"urn:xmpp:hints">>, _} -> true; - {<<"no-store">>, <<>>, <<"urn:xmpp:hints">>} -> true; - {<<"no-copy">>, <<"urn:xmpp:hints">>, _} -> true; - {<<"no-copy">>, <<>>, <<"urn:xmpp:hints">>} -> true; - {<<"participant">>, <<"urn:xmpp:mix:0">>, _} -> true; - {<<"participant">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; - {<<"leave">>, <<"urn:xmpp:mix:0">>, _} -> true; - {<<"leave">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; - {<<"join">>, <<"urn:xmpp:mix:0">>, _} -> true; - {<<"join">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; - {<<"subscribe">>, <<"urn:xmpp:mix:0">>, _} -> true; - {<<"subscribe">>, <<>>, <<"urn:xmpp:mix:0">>} -> true; - {<<"offline">>, - <<"http://jabber.org/protocol/offline">>, _} -> - true; - {<<"offline">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - true; - {<<"item">>, <<"http://jabber.org/protocol/offline">>, - _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - true; - {<<"fetch">>, <<"http://jabber.org/protocol/offline">>, - _} -> - true; - {<<"fetch">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - true; - {<<"purge">>, <<"http://jabber.org/protocol/offline">>, - _} -> - true; - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/offline">>} -> - true; - {<<"failed">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"failed">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"failed">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"failed">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"a">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"a">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"a">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"a">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"r">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"r">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"r">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"r">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"resumed">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"resumed">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"resumed">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"resumed">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"resume">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"resume">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"resume">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"resume">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"enabled">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"enabled">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"enabled">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"enabled">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"enable">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"enable">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"enable">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"enable">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"sm">>, <<"urn:xmpp:sm:2">>, _} -> true; - {<<"sm">>, <<>>, <<"urn:xmpp:sm:2">>} -> true; - {<<"sm">>, <<"urn:xmpp:sm:3">>, _} -> true; - {<<"sm">>, <<>>, <<"urn:xmpp:sm:3">>} -> true; - {<<"inactive">>, <<"urn:xmpp:csi:0">>, _} -> true; - {<<"inactive">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; - {<<"active">>, <<"urn:xmpp:csi:0">>, _} -> true; - {<<"active">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; - {<<"csi">>, <<"urn:xmpp:csi:0">>, _} -> true; - {<<"csi">>, <<>>, <<"urn:xmpp:csi:0">>} -> true; - {<<"sent">>, <<"urn:xmpp:carbons:2">>, _} -> true; - {<<"sent">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"received">>, <<"urn:xmpp:carbons:2">>, _} -> true; - {<<"received">>, <<>>, <<"urn:xmpp:carbons:2">>} -> - true; - {<<"private">>, <<"urn:xmpp:carbons:2">>, _} -> true; - {<<"private">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"enable">>, <<"urn:xmpp:carbons:2">>, _} -> true; - {<<"enable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"disable">>, <<"urn:xmpp:carbons:2">>, _} -> true; - {<<"disable">>, <<>>, <<"urn:xmpp:carbons:2">>} -> true; - {<<"forwarded">>, <<"urn:xmpp:forward:0">>, _} -> true; - {<<"forwarded">>, <<>>, <<"urn:xmpp:forward:0">>} -> - true; - {<<"fin">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"fin">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"fin">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"fin">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"prefs">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"prefs">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"always">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"always">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"always">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"always">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"never">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"never">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"never">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"never">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"jid">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"jid">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"jid">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"jid">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"result">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"result">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"result">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"result">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"archived">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"archived">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:0">>, _} -> true; - {<<"query">>, <<>>, <<"urn:xmpp:mam:0">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:1">>, _} -> true; - {<<"query">>, <<>>, <<"urn:xmpp:mam:1">>} -> true; - {<<"query">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"query">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"withtext">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"withtext">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"with">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"with">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"end">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"end">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"start">>, <<"urn:xmpp:mam:tmp">>, _} -> true; - {<<"start">>, <<>>, <<"urn:xmpp:mam:tmp">>} -> true; - {<<"set">>, <<"http://jabber.org/protocol/rsm">>, _} -> - true; - {<<"set">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"first">>, <<"http://jabber.org/protocol/rsm">>, - _} -> - true; - {<<"first">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"max">>, <<"http://jabber.org/protocol/rsm">>, _} -> - true; - {<<"max">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"index">>, <<"http://jabber.org/protocol/rsm">>, - _} -> - true; - {<<"index">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"count">>, <<"http://jabber.org/protocol/rsm">>, - _} -> - true; - {<<"count">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"last">>, <<"http://jabber.org/protocol/rsm">>, _} -> - true; - {<<"last">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"before">>, <<"http://jabber.org/protocol/rsm">>, - _} -> - true; - {<<"before">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"after">>, <<"http://jabber.org/protocol/rsm">>, - _} -> - true; - {<<"after">>, <<>>, - <<"http://jabber.org/protocol/rsm">>} -> - true; - {<<"unsubscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> true; - {<<"unsubscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - true; - {<<"subscribe">>, <<"urn:xmpp:mucsub:0">>, _} -> true; - {<<"subscribe">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - true; - {<<"event">>, <<"urn:xmpp:mucsub:0">>, _} -> true; - {<<"event">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> true; - {<<"subscriptions">>, <<"urn:xmpp:mucsub:0">>, _} -> - true; - {<<"subscriptions">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - true; - {<<"subscription">>, <<"urn:xmpp:mucsub:0">>, _} -> - true; - {<<"subscription">>, <<>>, <<"urn:xmpp:mucsub:0">>} -> - true; - {<<"x">>, <<"jabber:x:conference">>, _} -> true; - {<<"x">>, <<>>, <<"jabber:x:conference">>} -> true; - {<<"unique">>, - <<"http://jabber.org/protocol/muc#unique">>, _} -> - true; - {<<"unique">>, <<>>, - <<"http://jabber.org/protocol/muc#unique">>} -> - true; - {<<"x">>, <<"http://jabber.org/protocol/muc">>, _} -> - true; - {<<"x">>, <<>>, <<"http://jabber.org/protocol/muc">>} -> - true; - {<<"query">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; - {<<"continue">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - true; - {<<"continue">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; - {<<"actor">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - true; - {<<"actor">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; - {<<"item">>, <<"http://jabber.org/protocol/muc#admin">>, - _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; - {<<"item">>, <<"http://jabber.org/protocol/muc#owner">>, - _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - true; - {<<"query">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - true; - {<<"password">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - true; - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - true; - {<<"password">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"password">>, <<"http://jabber.org/protocol/muc">>, - _} -> - true; - {<<"password">>, <<>>, - <<"http://jabber.org/protocol/muc">>} -> - true; - {<<"x">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - true; - {<<"x">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"item">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"status">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"status">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"continue">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"continue">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"actor">>, <<"http://jabber.org/protocol/muc#user">>, - _} -> - true; - {<<"actor">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"invite">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"invite">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"destroy">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"destroy">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"destroy">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - true; - {<<"destroy">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - true; - {<<"decline">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"decline">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"reason">>, - <<"http://jabber.org/protocol/muc#user">>, _} -> - true; - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#user">>} -> - true; - {<<"reason">>, - <<"http://jabber.org/protocol/muc#admin">>, _} -> - true; - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#admin">>} -> - true; - {<<"reason">>, - <<"http://jabber.org/protocol/muc#owner">>, _} -> - true; - {<<"reason">>, <<>>, - <<"http://jabber.org/protocol/muc#owner">>} -> - true; - {<<"history">>, <<"http://jabber.org/protocol/muc">>, - _} -> - true; - {<<"history">>, <<>>, - <<"http://jabber.org/protocol/muc">>} -> - true; - {<<"query">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - true; - {<<"activate">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - true; - {<<"activate">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - true; - {<<"streamhost-used">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - true; - {<<"streamhost-used">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - true; - {<<"streamhost">>, - <<"http://jabber.org/protocol/bytestreams">>, _} -> - true; - {<<"streamhost">>, <<>>, - <<"http://jabber.org/protocol/bytestreams">>} -> - true; - {<<"delay">>, <<"urn:xmpp:delay">>, _} -> true; - {<<"delay">>, <<>>, <<"urn:xmpp:delay">>} -> true; - {<<"paused">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - true; - {<<"paused">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - true; - {<<"inactive">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - true; - {<<"inactive">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - true; - {<<"gone">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - true; - {<<"gone">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - true; - {<<"composing">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - true; - {<<"composing">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - true; - {<<"active">>, - <<"http://jabber.org/protocol/chatstates">>, _} -> - true; - {<<"active">>, <<>>, - <<"http://jabber.org/protocol/chatstates">>} -> - true; - {<<"headers">>, <<"http://jabber.org/protocol/shim">>, - _} -> - true; - {<<"headers">>, <<>>, - <<"http://jabber.org/protocol/shim">>} -> - true; - {<<"header">>, <<"http://jabber.org/protocol/shim">>, - _} -> - true; - {<<"header">>, <<>>, - <<"http://jabber.org/protocol/shim">>} -> - true; - {<<"unsupported-access-model">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"unsupported-access-model">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"unsupported">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"unsupported">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"too-many-subscriptions">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"too-many-subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"subid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"subid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"presence-subscription-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"presence-subscription-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"pending-subscription">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"pending-subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"payload-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"payload-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"payload-too-big">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"payload-too-big">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"not-subscribed">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"not-subscribed">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"not-in-roster-group">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"not-in-roster-group">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"nodeid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"nodeid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"max-nodes-exceeded">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"max-nodes-exceeded">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"max-items-exceeded">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"max-items-exceeded">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"jid-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"jid-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"item-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"item-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"item-forbidden">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"item-forbidden">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"invalid-subid">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"invalid-subid">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"invalid-payload">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"invalid-payload">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"invalid-options">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"invalid-options">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"invalid-jid">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"invalid-jid">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"configuration-required">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"configuration-required">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"closed-node">>, - <<"http://jabber.org/protocol/pubsub#errors">>, _} -> - true; - {<<"closed-node">>, <<>>, - <<"http://jabber.org/protocol/pubsub#errors">>} -> - true; - {<<"pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"pubsub">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"pubsub">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"pubsub">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"purge">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"purge">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"purge">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"purge">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"delete">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"delete">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"delete">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"delete">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"redirect">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"redirect">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"default">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"default">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"default">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"default">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"publish-options">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"publish-options">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"configure">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"configure">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"configure">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"configure">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"create">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"create">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"create">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"create">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"retract">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"retract">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"options">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"options">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"publish">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"publish">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"unsubscribe">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"unsubscribe">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"subscribe">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"subscribe">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"affiliations">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"affiliations">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"affiliations">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"affiliations">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"subscriptions">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"subscriptions">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"subscriptions">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"event">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"event">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"items">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"items">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"items">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"items">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"item">>, <<"http://jabber.org/protocol/pubsub">>, - _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"item">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"retract">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"retract">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"configuration">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"configuration">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"affiliation">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"affiliation">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"affiliation">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"affiliation">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub">>, _} -> - true; - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub">>} -> - true; - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub#owner">>, _} -> - true; - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#owner">>} -> - true; - {<<"subscription">>, - <<"http://jabber.org/protocol/pubsub#event">>, _} -> - true; - {<<"subscription">>, <<>>, - <<"http://jabber.org/protocol/pubsub#event">>} -> - true; - {<<"x">>, <<"jabber:x:data">>, _} -> true; - {<<"x">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"item">>, <<"jabber:x:data">>, _} -> true; - {<<"item">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"reported">>, <<"jabber:x:data">>, _} -> true; - {<<"reported">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"title">>, <<"jabber:x:data">>, _} -> true; - {<<"title">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"instructions">>, <<"jabber:x:data">>, _} -> true; - {<<"instructions">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"field">>, <<"jabber:x:data">>, _} -> true; - {<<"field">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"option">>, <<"jabber:x:data">>, _} -> true; - {<<"option">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"value">>, <<"jabber:x:data">>, _} -> true; - {<<"value">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"desc">>, <<"jabber:x:data">>, _} -> true; - {<<"desc">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"required">>, <<"jabber:x:data">>, _} -> true; - {<<"required">>, <<>>, <<"jabber:x:data">>} -> true; - {<<"x">>, <<"vcard-temp:x:update">>, _} -> true; - {<<"x">>, <<>>, <<"vcard-temp:x:update">>} -> true; - {<<"photo">>, <<"vcard-temp:x:update">>, _} -> true; - {<<"photo">>, <<>>, <<"vcard-temp:x:update">>} -> true; - {<<"vCard">>, <<"vcard-temp">>, _} -> true; - {<<"vCard">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CLASS">>, <<"vcard-temp">>, _} -> true; - {<<"CLASS">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CATEGORIES">>, <<"vcard-temp">>, _} -> true; - {<<"CATEGORIES">>, <<>>, <<"vcard-temp">>} -> true; - {<<"KEY">>, <<"vcard-temp">>, _} -> true; - {<<"KEY">>, <<>>, <<"vcard-temp">>} -> true; - {<<"SOUND">>, <<"vcard-temp">>, _} -> true; - {<<"SOUND">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ORG">>, <<"vcard-temp">>, _} -> true; - {<<"ORG">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PHOTO">>, <<"vcard-temp">>, _} -> true; - {<<"PHOTO">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LOGO">>, <<"vcard-temp">>, _} -> true; - {<<"LOGO">>, <<>>, <<"vcard-temp">>} -> true; - {<<"BINVAL">>, <<"vcard-temp">>, _} -> true; - {<<"BINVAL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"GEO">>, <<"vcard-temp">>, _} -> true; - {<<"GEO">>, <<>>, <<"vcard-temp">>} -> true; - {<<"EMAIL">>, <<"vcard-temp">>, _} -> true; - {<<"EMAIL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"TEL">>, <<"vcard-temp">>, _} -> true; - {<<"TEL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LABEL">>, <<"vcard-temp">>, _} -> true; - {<<"LABEL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ADR">>, <<"vcard-temp">>, _} -> true; - {<<"ADR">>, <<>>, <<"vcard-temp">>} -> true; - {<<"N">>, <<"vcard-temp">>, _} -> true; - {<<"N">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CONFIDENTIAL">>, <<"vcard-temp">>, _} -> true; - {<<"CONFIDENTIAL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PRIVATE">>, <<"vcard-temp">>, _} -> true; - {<<"PRIVATE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PUBLIC">>, <<"vcard-temp">>, _} -> true; - {<<"PUBLIC">>, <<>>, <<"vcard-temp">>} -> true; - {<<"EXTVAL">>, <<"vcard-temp">>, _} -> true; - {<<"EXTVAL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"TYPE">>, <<"vcard-temp">>, _} -> true; - {<<"TYPE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"DESC">>, <<"vcard-temp">>, _} -> true; - {<<"DESC">>, <<>>, <<"vcard-temp">>} -> true; - {<<"URL">>, <<"vcard-temp">>, _} -> true; - {<<"URL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"UID">>, <<"vcard-temp">>, _} -> true; - {<<"UID">>, <<>>, <<"vcard-temp">>} -> true; - {<<"SORT-STRING">>, <<"vcard-temp">>, _} -> true; - {<<"SORT-STRING">>, <<>>, <<"vcard-temp">>} -> true; - {<<"REV">>, <<"vcard-temp">>, _} -> true; - {<<"REV">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PRODID">>, <<"vcard-temp">>, _} -> true; - {<<"PRODID">>, <<>>, <<"vcard-temp">>} -> true; - {<<"NOTE">>, <<"vcard-temp">>, _} -> true; - {<<"NOTE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"KEYWORD">>, <<"vcard-temp">>, _} -> true; - {<<"KEYWORD">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ROLE">>, <<"vcard-temp">>, _} -> true; - {<<"ROLE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"TITLE">>, <<"vcard-temp">>, _} -> true; - {<<"TITLE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"TZ">>, <<"vcard-temp">>, _} -> true; - {<<"TZ">>, <<>>, <<"vcard-temp">>} -> true; - {<<"MAILER">>, <<"vcard-temp">>, _} -> true; - {<<"MAILER">>, <<>>, <<"vcard-temp">>} -> true; - {<<"JABBERID">>, <<"vcard-temp">>, _} -> true; - {<<"JABBERID">>, <<>>, <<"vcard-temp">>} -> true; - {<<"BDAY">>, <<"vcard-temp">>, _} -> true; - {<<"BDAY">>, <<>>, <<"vcard-temp">>} -> true; - {<<"NICKNAME">>, <<"vcard-temp">>, _} -> true; - {<<"NICKNAME">>, <<>>, <<"vcard-temp">>} -> true; - {<<"FN">>, <<"vcard-temp">>, _} -> true; - {<<"FN">>, <<>>, <<"vcard-temp">>} -> true; - {<<"VERSION">>, <<"vcard-temp">>, _} -> true; - {<<"VERSION">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CRED">>, <<"vcard-temp">>, _} -> true; - {<<"CRED">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PHONETIC">>, <<"vcard-temp">>, _} -> true; - {<<"PHONETIC">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ORGUNIT">>, <<"vcard-temp">>, _} -> true; - {<<"ORGUNIT">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ORGNAME">>, <<"vcard-temp">>, _} -> true; - {<<"ORGNAME">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LON">>, <<"vcard-temp">>, _} -> true; - {<<"LON">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LAT">>, <<"vcard-temp">>, _} -> true; - {<<"LAT">>, <<>>, <<"vcard-temp">>} -> true; - {<<"USERID">>, <<"vcard-temp">>, _} -> true; - {<<"USERID">>, <<>>, <<"vcard-temp">>} -> true; - {<<"NUMBER">>, <<"vcard-temp">>, _} -> true; - {<<"NUMBER">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LINE">>, <<"vcard-temp">>, _} -> true; - {<<"LINE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CTRY">>, <<"vcard-temp">>, _} -> true; - {<<"CTRY">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PCODE">>, <<"vcard-temp">>, _} -> true; - {<<"PCODE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"REGION">>, <<"vcard-temp">>, _} -> true; - {<<"REGION">>, <<>>, <<"vcard-temp">>} -> true; - {<<"LOCALITY">>, <<"vcard-temp">>, _} -> true; - {<<"LOCALITY">>, <<>>, <<"vcard-temp">>} -> true; - {<<"STREET">>, <<"vcard-temp">>, _} -> true; - {<<"STREET">>, <<>>, <<"vcard-temp">>} -> true; - {<<"EXTADD">>, <<"vcard-temp">>, _} -> true; - {<<"EXTADD">>, <<>>, <<"vcard-temp">>} -> true; - {<<"POBOX">>, <<"vcard-temp">>, _} -> true; - {<<"POBOX">>, <<>>, <<"vcard-temp">>} -> true; - {<<"SUFFIX">>, <<"vcard-temp">>, _} -> true; - {<<"SUFFIX">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PREFIX">>, <<"vcard-temp">>, _} -> true; - {<<"PREFIX">>, <<>>, <<"vcard-temp">>} -> true; - {<<"MIDDLE">>, <<"vcard-temp">>, _} -> true; - {<<"MIDDLE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"GIVEN">>, <<"vcard-temp">>, _} -> true; - {<<"GIVEN">>, <<>>, <<"vcard-temp">>} -> true; - {<<"FAMILY">>, <<"vcard-temp">>, _} -> true; - {<<"FAMILY">>, <<>>, <<"vcard-temp">>} -> true; - {<<"X400">>, <<"vcard-temp">>, _} -> true; - {<<"X400">>, <<>>, <<"vcard-temp">>} -> true; - {<<"INTERNET">>, <<"vcard-temp">>, _} -> true; - {<<"INTERNET">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PREF">>, <<"vcard-temp">>, _} -> true; - {<<"PREF">>, <<>>, <<"vcard-temp">>} -> true; - {<<"INTL">>, <<"vcard-temp">>, _} -> true; - {<<"INTL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"DOM">>, <<"vcard-temp">>, _} -> true; - {<<"DOM">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PARCEL">>, <<"vcard-temp">>, _} -> true; - {<<"PARCEL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"POSTAL">>, <<"vcard-temp">>, _} -> true; - {<<"POSTAL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PCS">>, <<"vcard-temp">>, _} -> true; - {<<"PCS">>, <<>>, <<"vcard-temp">>} -> true; - {<<"ISDN">>, <<"vcard-temp">>, _} -> true; - {<<"ISDN">>, <<>>, <<"vcard-temp">>} -> true; - {<<"MODEM">>, <<"vcard-temp">>, _} -> true; - {<<"MODEM">>, <<>>, <<"vcard-temp">>} -> true; - {<<"BBS">>, <<"vcard-temp">>, _} -> true; - {<<"BBS">>, <<>>, <<"vcard-temp">>} -> true; - {<<"VIDEO">>, <<"vcard-temp">>, _} -> true; - {<<"VIDEO">>, <<>>, <<"vcard-temp">>} -> true; - {<<"CELL">>, <<"vcard-temp">>, _} -> true; - {<<"CELL">>, <<>>, <<"vcard-temp">>} -> true; - {<<"MSG">>, <<"vcard-temp">>, _} -> true; - {<<"MSG">>, <<>>, <<"vcard-temp">>} -> true; - {<<"PAGER">>, <<"vcard-temp">>, _} -> true; - {<<"PAGER">>, <<>>, <<"vcard-temp">>} -> true; - {<<"FAX">>, <<"vcard-temp">>, _} -> true; - {<<"FAX">>, <<>>, <<"vcard-temp">>} -> true; - {<<"VOICE">>, <<"vcard-temp">>, _} -> true; - {<<"VOICE">>, <<>>, <<"vcard-temp">>} -> true; - {<<"WORK">>, <<"vcard-temp">>, _} -> true; - {<<"WORK">>, <<>>, <<"vcard-temp">>} -> true; - {<<"HOME">>, <<"vcard-temp">>, _} -> true; - {<<"HOME">>, <<>>, <<"vcard-temp">>} -> true; - {<<"stream:error">>, <<"jabber:client">>, _} -> true; - {<<"stream:error">>, <<>>, <<"jabber:client">>} -> true; - {<<"stream:error">>, <<"jabber:server">>, _} -> true; - {<<"stream:error">>, <<>>, <<"jabber:server">>} -> true; - {<<"stream:error">>, <<"jabber:component:accept">>, - _} -> - true; - {<<"stream:error">>, <<>>, - <<"jabber:component:accept">>} -> - true; - {<<"unsupported-version">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"unsupported-version">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"unsupported-stanza-type">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"unsupported-stanza-type">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"unsupported-encoding">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"unsupported-encoding">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"undefined-condition">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"undefined-condition">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"system-shutdown">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"system-shutdown">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"see-other-host">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"see-other-host">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"restricted-xml">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"restricted-xml">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"resource-constraint">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"resource-constraint">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"reset">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, - _} -> - true; - {<<"reset">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"remote-connection-failed">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"remote-connection-failed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"policy-violation">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"policy-violation">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"not-well-formed">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"not-well-formed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"invalid-xml">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"invalid-xml">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"invalid-namespace">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"invalid-namespace">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"invalid-id">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"invalid-id">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"invalid-from">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"invalid-from">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"internal-server-error">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"internal-server-error">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"improper-addressing">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"improper-addressing">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"host-unknown">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"host-unknown">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"host-gone">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"host-gone">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"connection-timeout">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"connection-timeout">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"conflict">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"conflict">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"bad-namespace-prefix">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"bad-namespace-prefix">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"bad-format">>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>, _} -> - true; - {<<"bad-format">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-streams">>, - _} -> - true; - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-streams">>} -> - true; - {<<"time">>, <<"urn:xmpp:time">>, _} -> true; - {<<"time">>, <<>>, <<"urn:xmpp:time">>} -> true; - {<<"tzo">>, <<"urn:xmpp:time">>, _} -> true; - {<<"tzo">>, <<>>, <<"urn:xmpp:time">>} -> true; - {<<"utc">>, <<"urn:xmpp:time">>, _} -> true; - {<<"utc">>, <<>>, <<"urn:xmpp:time">>} -> true; - {<<"ping">>, <<"urn:xmpp:ping">>, _} -> true; - {<<"ping">>, <<>>, <<"urn:xmpp:ping">>} -> true; - {<<"session">>, - <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> - true; - {<<"session">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-session">>} -> - true; - {<<"optional">>, - <<"urn:ietf:params:xml:ns:xmpp-session">>, _} -> - true; - {<<"optional">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-session">>} -> - true; - {<<"query">>, <<"jabber:iq:register">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"key">>, <<"jabber:iq:register">>, _} -> true; - {<<"key">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"text">>, <<"jabber:iq:register">>, _} -> true; - {<<"text">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"misc">>, <<"jabber:iq:register">>, _} -> true; - {<<"misc">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"date">>, <<"jabber:iq:register">>, _} -> true; - {<<"date">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"url">>, <<"jabber:iq:register">>, _} -> true; - {<<"url">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"phone">>, <<"jabber:iq:register">>, _} -> true; - {<<"phone">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"zip">>, <<"jabber:iq:register">>, _} -> true; - {<<"zip">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"state">>, <<"jabber:iq:register">>, _} -> true; - {<<"state">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"city">>, <<"jabber:iq:register">>, _} -> true; - {<<"city">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"address">>, <<"jabber:iq:register">>, _} -> true; - {<<"address">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"email">>, <<"jabber:iq:register">>, _} -> true; - {<<"email">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"last">>, <<"jabber:iq:register">>, _} -> true; - {<<"last">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"first">>, <<"jabber:iq:register">>, _} -> true; - {<<"first">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"name">>, <<"jabber:iq:register">>, _} -> true; - {<<"name">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"password">>, <<"jabber:iq:register">>, _} -> true; - {<<"password">>, <<>>, <<"jabber:iq:register">>} -> - true; - {<<"nick">>, <<"jabber:iq:register">>, _} -> true; - {<<"nick">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"username">>, <<"jabber:iq:register">>, _} -> true; - {<<"username">>, <<>>, <<"jabber:iq:register">>} -> - true; - {<<"instructions">>, <<"jabber:iq:register">>, _} -> - true; - {<<"instructions">>, <<>>, <<"jabber:iq:register">>} -> - true; - {<<"remove">>, <<"jabber:iq:register">>, _} -> true; - {<<"remove">>, <<>>, <<"jabber:iq:register">>} -> true; - {<<"registered">>, <<"jabber:iq:register">>, _} -> true; - {<<"registered">>, <<>>, <<"jabber:iq:register">>} -> - true; - {<<"register">>, - <<"http://jabber.org/features/iq-register">>, _} -> - true; - {<<"register">>, <<>>, - <<"http://jabber.org/features/iq-register">>} -> - true; - {<<"c">>, <<"http://jabber.org/protocol/caps">>, _} -> - true; - {<<"c">>, <<>>, - <<"http://jabber.org/protocol/caps">>} -> - true; - {<<"ack">>, <<"p1:ack">>, _} -> true; - {<<"ack">>, <<>>, <<"p1:ack">>} -> true; - {<<"rebind">>, <<"p1:rebind">>, _} -> true; - {<<"rebind">>, <<>>, <<"p1:rebind">>} -> true; - {<<"push">>, <<"p1:push">>, _} -> true; - {<<"push">>, <<>>, <<"p1:push">>} -> true; - {<<"stream:features">>, <<"jabber:client">>, _} -> true; - {<<"stream:features">>, <<>>, <<"jabber:client">>} -> - true; - {<<"stream:features">>, <<"jabber:server">>, _} -> true; - {<<"stream:features">>, <<>>, <<"jabber:server">>} -> - true; - {<<"compression">>, - <<"http://jabber.org/features/compress">>, _} -> - true; - {<<"compression">>, <<>>, - <<"http://jabber.org/features/compress">>} -> - true; - {<<"method">>, - <<"http://jabber.org/features/compress">>, _} -> - true; - {<<"method">>, <<>>, - <<"http://jabber.org/features/compress">>} -> - true; - {<<"compressed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"compressed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"compress">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"compress">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"method">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"method">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"failure">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"failure">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"unsupported-method">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"unsupported-method">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"processing-failed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"processing-failed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"setup-failed">>, - <<"http://jabber.org/protocol/compress">>, _} -> - true; - {<<"setup-failed">>, <<>>, - <<"http://jabber.org/protocol/compress">>} -> - true; - {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - true; - {<<"failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - true; - {<<"proceed">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - true; - {<<"proceed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - true; - {<<"starttls">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - true; - {<<"starttls">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - true; - {<<"required">>, <<"urn:ietf:params:xml:ns:xmpp-tls">>, - _} -> - true; - {<<"required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-tls">>} -> - true; - {<<"mechanisms">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"mechanisms">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"mechanism">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"mechanism">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"failure">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"temporary-auth-failure">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"temporary-auth-failure">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"bad-protocol">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"bad-protocol">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"mechanism-too-weak">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"mechanism-too-weak">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"malformed-request">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"malformed-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"invalid-mechanism">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"invalid-mechanism">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"invalid-authzid">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"invalid-authzid">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"incorrect-encoding">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"incorrect-encoding">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"encryption-required">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"encryption-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"credentials-expired">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"credentials-expired">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"account-disabled">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"account-disabled">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"aborted">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"aborted">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"success">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"success">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"response">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"response">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"challenge">>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>, _} -> - true; - {<<"challenge">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"abort">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>, - _} -> - true; - {<<"auth">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-sasl">>} -> - true; - {<<"query">>, <<"jabber:iq:auth">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:auth">>} -> true; - {<<"resource">>, <<"jabber:iq:auth">>, _} -> true; - {<<"resource">>, <<>>, <<"jabber:iq:auth">>} -> true; - {<<"digest">>, <<"jabber:iq:auth">>, _} -> true; - {<<"digest">>, <<>>, <<"jabber:iq:auth">>} -> true; - {<<"password">>, <<"jabber:iq:auth">>, _} -> true; - {<<"password">>, <<>>, <<"jabber:iq:auth">>} -> true; - {<<"username">>, <<"jabber:iq:auth">>, _} -> true; - {<<"username">>, <<>>, <<"jabber:iq:auth">>} -> true; - {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - true; - {<<"bind">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - true; - {<<"resource">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - true; - {<<"resource">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - true; - {<<"jid">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>, - _} -> - true; - {<<"jid">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-bind">>} -> - true; - {<<"error">>, <<"jabber:client">>, _} -> true; - {<<"error">>, <<>>, <<"jabber:client">>} -> true; - {<<"error">>, <<"jabber:server">>, _} -> true; - {<<"error">>, <<>>, <<"jabber:server">>} -> true; - {<<"error">>, <<"jabber:component:accept">>, _} -> true; - {<<"error">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"text">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - _} -> - true; - {<<"text">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"unexpected-request">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"unexpected-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"undefined-condition">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"undefined-condition">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"subscription-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"subscription-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"service-unavailable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"service-unavailable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"resource-constraint">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"resource-constraint">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"remote-server-timeout">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"remote-server-timeout">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"remote-server-not-found">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"remote-server-not-found">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"registration-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"registration-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"redirect">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"redirect">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"recipient-unavailable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"recipient-unavailable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"policy-violation">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"policy-violation">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"payment-required">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"payment-required">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"not-authorized">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"not-authorized">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"not-allowed">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"not-allowed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"not-acceptable">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"not-acceptable">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"jid-malformed">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"jid-malformed">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"item-not-found">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"item-not-found">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"internal-server-error">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"internal-server-error">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"gone">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - _} -> - true; - {<<"gone">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"forbidden">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"forbidden">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"feature-not-implemented">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"feature-not-implemented">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"conflict">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"conflict">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"bad-request">>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>, _} -> - true; - {<<"bad-request">>, <<>>, - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>} -> - true; - {<<"presence">>, <<"jabber:client">>, _} -> true; - {<<"presence">>, <<>>, <<"jabber:client">>} -> true; - {<<"presence">>, <<"jabber:server">>, _} -> true; - {<<"presence">>, <<>>, <<"jabber:server">>} -> true; - {<<"presence">>, <<"jabber:component:accept">>, _} -> - true; - {<<"presence">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"priority">>, <<"jabber:client">>, _} -> true; - {<<"priority">>, <<>>, <<"jabber:client">>} -> true; - {<<"priority">>, <<"jabber:server">>, _} -> true; - {<<"priority">>, <<>>, <<"jabber:server">>} -> true; - {<<"priority">>, <<"jabber:component:accept">>, _} -> - true; - {<<"priority">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"status">>, <<"jabber:client">>, _} -> true; - {<<"status">>, <<>>, <<"jabber:client">>} -> true; - {<<"status">>, <<"jabber:server">>, _} -> true; - {<<"status">>, <<>>, <<"jabber:server">>} -> true; - {<<"status">>, <<"jabber:component:accept">>, _} -> - true; - {<<"status">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"show">>, <<"jabber:client">>, _} -> true; - {<<"show">>, <<>>, <<"jabber:client">>} -> true; - {<<"show">>, <<"jabber:server">>, _} -> true; - {<<"show">>, <<>>, <<"jabber:server">>} -> true; - {<<"show">>, <<"jabber:component:accept">>, _} -> true; - {<<"show">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"message">>, <<"jabber:client">>, _} -> true; - {<<"message">>, <<>>, <<"jabber:client">>} -> true; - {<<"message">>, <<"jabber:server">>, _} -> true; - {<<"message">>, <<>>, <<"jabber:server">>} -> true; - {<<"message">>, <<"jabber:component:accept">>, _} -> - true; - {<<"message">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"thread">>, <<"jabber:client">>, _} -> true; - {<<"thread">>, <<>>, <<"jabber:client">>} -> true; - {<<"thread">>, <<"jabber:server">>, _} -> true; - {<<"thread">>, <<>>, <<"jabber:server">>} -> true; - {<<"thread">>, <<"jabber:component:accept">>, _} -> - true; - {<<"thread">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"body">>, <<"jabber:client">>, _} -> true; - {<<"body">>, <<>>, <<"jabber:client">>} -> true; - {<<"body">>, <<"jabber:server">>, _} -> true; - {<<"body">>, <<>>, <<"jabber:server">>} -> true; - {<<"body">>, <<"jabber:component:accept">>, _} -> true; - {<<"body">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"subject">>, <<"jabber:client">>, _} -> true; - {<<"subject">>, <<>>, <<"jabber:client">>} -> true; - {<<"subject">>, <<"jabber:server">>, _} -> true; - {<<"subject">>, <<>>, <<"jabber:server">>} -> true; - {<<"subject">>, <<"jabber:component:accept">>, _} -> - true; - {<<"subject">>, <<>>, <<"jabber:component:accept">>} -> - true; - {<<"iq">>, <<"jabber:client">>, _} -> true; - {<<"iq">>, <<>>, <<"jabber:client">>} -> true; - {<<"iq">>, <<"jabber:server">>, _} -> true; - {<<"iq">>, <<>>, <<"jabber:server">>} -> true; - {<<"iq">>, <<"jabber:component:accept">>, _} -> true; - {<<"iq">>, <<>>, <<"jabber:component:accept">>} -> true; - {<<"query">>, <<"http://jabber.org/protocol/stats">>, - _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"stat">>, <<"http://jabber.org/protocol/stats">>, - _} -> - true; - {<<"stat">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"error">>, <<"http://jabber.org/protocol/stats">>, - _} -> - true; - {<<"error">>, <<>>, - <<"http://jabber.org/protocol/stats">>} -> - true; - {<<"storage">>, <<"storage:bookmarks">>, _} -> true; - {<<"storage">>, <<>>, <<"storage:bookmarks">>} -> true; - {<<"url">>, <<"storage:bookmarks">>, _} -> true; - {<<"url">>, <<>>, <<"storage:bookmarks">>} -> true; - {<<"conference">>, <<"storage:bookmarks">>, _} -> true; - {<<"conference">>, <<>>, <<"storage:bookmarks">>} -> - true; - {<<"password">>, <<"storage:bookmarks">>, _} -> true; - {<<"password">>, <<>>, <<"storage:bookmarks">>} -> true; - {<<"nick">>, <<"storage:bookmarks">>, _} -> true; - {<<"nick">>, <<>>, <<"storage:bookmarks">>} -> true; - {<<"query">>, <<"jabber:iq:private">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:private">>} -> true; - {<<"query">>, - <<"http://jabber.org/protocol/disco#items">>, _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/disco#items">>} -> - true; - {<<"item">>, - <<"http://jabber.org/protocol/disco#items">>, _} -> - true; - {<<"item">>, <<>>, - <<"http://jabber.org/protocol/disco#items">>} -> - true; - {<<"query">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - true; - {<<"query">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - true; - {<<"feature">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - true; - {<<"feature">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - true; - {<<"identity">>, - <<"http://jabber.org/protocol/disco#info">>, _} -> - true; - {<<"identity">>, <<>>, - <<"http://jabber.org/protocol/disco#info">>} -> - true; - {<<"blocklist">>, <<"urn:xmpp:blocking">>, _} -> true; - {<<"blocklist">>, <<>>, <<"urn:xmpp:blocking">>} -> - true; - {<<"unblock">>, <<"urn:xmpp:blocking">>, _} -> true; - {<<"unblock">>, <<>>, <<"urn:xmpp:blocking">>} -> true; - {<<"block">>, <<"urn:xmpp:blocking">>, _} -> true; - {<<"block">>, <<>>, <<"urn:xmpp:blocking">>} -> true; - {<<"item">>, <<"urn:xmpp:blocking">>, _} -> true; - {<<"item">>, <<>>, <<"urn:xmpp:blocking">>} -> true; - {<<"query">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"active">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"active">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"default">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"default">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"list">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"list">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"item">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"item">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"presence-out">>, <<"jabber:iq:privacy">>, _} -> - true; - {<<"presence-out">>, <<>>, <<"jabber:iq:privacy">>} -> - true; - {<<"presence-in">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"presence-in">>, <<>>, <<"jabber:iq:privacy">>} -> - true; - {<<"iq">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"iq">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"message">>, <<"jabber:iq:privacy">>, _} -> true; - {<<"message">>, <<>>, <<"jabber:iq:privacy">>} -> true; - {<<"ver">>, <<"urn:xmpp:features:rosterver">>, _} -> - true; - {<<"ver">>, <<>>, <<"urn:xmpp:features:rosterver">>} -> - true; - {<<"query">>, <<"jabber:iq:roster">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:roster">>} -> true; - {<<"item">>, <<"jabber:iq:roster">>, _} -> true; - {<<"item">>, <<>>, <<"jabber:iq:roster">>} -> true; - {<<"group">>, <<"jabber:iq:roster">>, _} -> true; - {<<"group">>, <<>>, <<"jabber:iq:roster">>} -> true; - {<<"query">>, <<"jabber:iq:version">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:version">>} -> true; - {<<"os">>, <<"jabber:iq:version">>, _} -> true; - {<<"os">>, <<>>, <<"jabber:iq:version">>} -> true; - {<<"version">>, <<"jabber:iq:version">>, _} -> true; - {<<"version">>, <<>>, <<"jabber:iq:version">>} -> true; - {<<"name">>, <<"jabber:iq:version">>, _} -> true; - {<<"name">>, <<>>, <<"jabber:iq:version">>} -> true; - {<<"query">>, <<"jabber:iq:last">>, _} -> true; - {<<"query">>, <<>>, <<"jabber:iq:last">>} -> true; - _ -> false - end. - -encode(_el) -> encode(_el, <<>>). - -encode({xmlel, _, _, _} = El, _) -> El; -encode({last, _, _} = Query, TopXMLNS) -> - encode_last(Query, TopXMLNS); -encode({version, _, _, _} = Query, TopXMLNS) -> - encode_version(Query, TopXMLNS); -encode({roster_item, _, _, _, _, _} = Item, TopXMLNS) -> - encode_roster_item(Item, TopXMLNS); -encode({roster_query, _, _} = Query, TopXMLNS) -> - encode_roster_query(Query, TopXMLNS); -encode({rosterver_feature} = Ver, TopXMLNS) -> - encode_rosterver_feature(Ver, TopXMLNS); -encode({privacy_item, _, _, _, _, _, _, _, _} = Item, - TopXMLNS) -> - encode_privacy_item(Item, TopXMLNS); -encode({privacy_list, _, _} = List, TopXMLNS) -> - encode_privacy_list(List, TopXMLNS); -encode({privacy_query, _, _, _} = Query, TopXMLNS) -> - encode_privacy(Query, TopXMLNS); -encode({block, _} = Block, TopXMLNS) -> - encode_block(Block, TopXMLNS); -encode({unblock, _} = Unblock, TopXMLNS) -> - encode_unblock(Unblock, TopXMLNS); -encode({block_list, _} = Blocklist, TopXMLNS) -> - encode_block_list(Blocklist, TopXMLNS); -encode({identity, _, _, _, _} = Identity, TopXMLNS) -> - encode_disco_identity(Identity, TopXMLNS); -encode({disco_info, _, _, _, _} = Query, TopXMLNS) -> - encode_disco_info(Query, TopXMLNS); -encode({disco_item, _, _, _} = Item, TopXMLNS) -> - encode_disco_item(Item, TopXMLNS); -encode({disco_items, _, _, _} = Query, TopXMLNS) -> - encode_disco_items(Query, TopXMLNS); -encode({private, _} = Query, TopXMLNS) -> - encode_private(Query, TopXMLNS); -encode({bookmark_conference, _, _, _, _, _} = - Conference, - TopXMLNS) -> - encode_bookmark_conference(Conference, TopXMLNS); -encode({bookmark_url, _, _} = Url, TopXMLNS) -> - encode_bookmark_url(Url, TopXMLNS); -encode({bookmark_storage, _, _} = Storage, TopXMLNS) -> - encode_bookmarks_storage(Storage, TopXMLNS); -encode({stat_error, _, _} = Error, TopXMLNS) -> - encode_stat_error(Error, TopXMLNS); -encode({stat, _, _, _, _} = Stat, TopXMLNS) -> - encode_stat(Stat, TopXMLNS); -encode({stats, _, _} = Query, TopXMLNS) -> - encode_stats(Query, TopXMLNS); -encode({iq, _, _, _, _, _, _} = Iq, TopXMLNS) -> - encode_iq(Iq, TopXMLNS); -encode({message, _, _, _, _, _, _, _, _, _} = Message, - TopXMLNS) -> - encode_message(Message, TopXMLNS); -encode({presence, _, _, _, _, _, _, _, _, _} = Presence, - TopXMLNS) -> - encode_presence(Presence, TopXMLNS); -encode({gone, _} = Gone, TopXMLNS) -> - encode_error_gone(Gone, TopXMLNS); -encode({redirect, _} = Redirect, TopXMLNS) -> - encode_error_redirect(Redirect, TopXMLNS); -encode({stanza_error, _, _, _, _, _, _} = Error, - TopXMLNS) -> - encode_error(Error, TopXMLNS); -encode({bind, _, _} = Bind, TopXMLNS) -> - encode_bind(Bind, TopXMLNS); -encode({legacy_auth, _, _, _, _} = Query, TopXMLNS) -> - encode_legacy_auth(Query, TopXMLNS); -encode({sasl_auth, _, _} = Auth, TopXMLNS) -> - encode_sasl_auth(Auth, TopXMLNS); -encode({sasl_abort} = Abort, TopXMLNS) -> - encode_sasl_abort(Abort, TopXMLNS); -encode({sasl_challenge, _} = Challenge, TopXMLNS) -> - encode_sasl_challenge(Challenge, TopXMLNS); -encode({sasl_response, _} = Response, TopXMLNS) -> - encode_sasl_response(Response, TopXMLNS); -encode({sasl_success, _} = Success, TopXMLNS) -> - encode_sasl_success(Success, TopXMLNS); -encode({sasl_failure, _, _} = Failure, TopXMLNS) -> - encode_sasl_failure(Failure, TopXMLNS); -encode({sasl_mechanisms, _} = Mechanisms, TopXMLNS) -> - encode_sasl_mechanisms(Mechanisms, TopXMLNS); -encode({starttls, _} = Starttls, TopXMLNS) -> - encode_starttls(Starttls, TopXMLNS); -encode({starttls_proceed} = Proceed, TopXMLNS) -> - encode_starttls_proceed(Proceed, TopXMLNS); -encode({starttls_failure} = Failure, TopXMLNS) -> - encode_starttls_failure(Failure, TopXMLNS); -encode({compress_failure, _} = Failure, TopXMLNS) -> - encode_compress_failure(Failure, TopXMLNS); -encode({compress, _} = Compress, TopXMLNS) -> - encode_compress(Compress, TopXMLNS); -encode({compressed} = Compressed, TopXMLNS) -> - encode_compressed(Compressed, TopXMLNS); -encode({compression, _} = Compression, TopXMLNS) -> - encode_compression(Compression, TopXMLNS); -encode({stream_features, _} = Stream_features, - TopXMLNS) -> - encode_stream_features(Stream_features, TopXMLNS); -encode({p1_push} = Push, TopXMLNS) -> - encode_p1_push(Push, TopXMLNS); -encode({p1_rebind} = Rebind, TopXMLNS) -> - encode_p1_rebind(Rebind, TopXMLNS); -encode({p1_ack} = Ack, TopXMLNS) -> - encode_p1_ack(Ack, TopXMLNS); -encode({caps, _, _, _, _} = C, TopXMLNS) -> - encode_caps(C, TopXMLNS); -encode({feature_register} = Register, TopXMLNS) -> - encode_feature_register(Register, TopXMLNS); -encode({register, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _} = - Query, - TopXMLNS) -> - encode_register(Query, TopXMLNS); -encode({xmpp_session, _} = Session, TopXMLNS) -> - encode_session(Session, TopXMLNS); -encode({ping} = Ping, TopXMLNS) -> - encode_ping(Ping, TopXMLNS); -encode({time, _, _} = Time, TopXMLNS) -> - encode_time(Time, TopXMLNS); -encode({text, _, _} = Text, TopXMLNS) -> - encode_stream_error_text(Text, TopXMLNS); -encode({'see-other-host', _} = See_other_host, - TopXMLNS) -> - encode_stream_error_see_other_host(See_other_host, - TopXMLNS); -encode({stream_error, _, _} = Stream_error, TopXMLNS) -> - encode_stream_error(Stream_error, TopXMLNS); -encode({vcard_name, _, _, _, _, _} = N, TopXMLNS) -> - encode_vcard_N(N, TopXMLNS); -encode({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, - _, _} = - Adr, - TopXMLNS) -> - encode_vcard_ADR(Adr, TopXMLNS); -encode({vcard_label, _, _, _, _, _, _, _, _} = Label, - TopXMLNS) -> - encode_vcard_LABEL(Label, TopXMLNS); -encode({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, - _, _} = - Tel, - TopXMLNS) -> - encode_vcard_TEL(Tel, TopXMLNS); -encode({vcard_email, _, _, _, _, _, _} = Email, - TopXMLNS) -> - encode_vcard_EMAIL(Email, TopXMLNS); -encode({vcard_geo, _, _} = Geo, TopXMLNS) -> - encode_vcard_GEO(Geo, TopXMLNS); -encode({vcard_logo, _, _, _} = Logo, TopXMLNS) -> - encode_vcard_LOGO(Logo, TopXMLNS); -encode({vcard_photo, _, _, _} = Photo, TopXMLNS) -> - encode_vcard_PHOTO(Photo, TopXMLNS); -encode({vcard_org, _, _} = Org, TopXMLNS) -> - encode_vcard_ORG(Org, TopXMLNS); -encode({vcard_sound, _, _, _} = Sound, TopXMLNS) -> - encode_vcard_SOUND(Sound, TopXMLNS); -encode({vcard_key, _, _} = Key, TopXMLNS) -> - encode_vcard_KEY(Key, TopXMLNS); -encode({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = - Vcard, - TopXMLNS) -> - encode_vcard_temp(Vcard, TopXMLNS); -encode({vcard_xupdate, _, _} = X, TopXMLNS) -> - encode_vcard_xupdate(X, TopXMLNS); -encode({xdata_option, _, _} = Option, TopXMLNS) -> - encode_xdata_field_option(Option, TopXMLNS); -encode({xdata_field, _, _, _, _, _, _, _, _} = Field, - TopXMLNS) -> - encode_xdata_field(Field, TopXMLNS); -encode({xdata, _, _, _, _, _, _} = X, TopXMLNS) -> - encode_xdata(X, TopXMLNS); -encode({ps_subscription, _, _, _, _, _, _} = - Subscription, - TopXMLNS) -> - encode_pubsub_subscription(Subscription, TopXMLNS); -encode({ps_affiliation, - <<"http://jabber.org/protocol/pubsub">>, _, _, _} = - Affiliation, - TopXMLNS) -> - encode_pubsub_affiliation(Affiliation, TopXMLNS); -encode({ps_affiliation, <<>>, _, _, _} = Affiliation, - TopXMLNS = <<"http://jabber.org/protocol/pubsub">>) -> - encode_pubsub_affiliation(Affiliation, TopXMLNS); -encode({ps_affiliation, - <<"http://jabber.org/protocol/pubsub#owner">>, _, _, - _} = - Affiliation, - TopXMLNS) -> - encode_pubsub_owner_affiliation(Affiliation, TopXMLNS); -encode({ps_affiliation, <<>>, _, _, _} = Affiliation, - TopXMLNS = - <<"http://jabber.org/protocol/pubsub#owner">>) -> - encode_pubsub_owner_affiliation(Affiliation, TopXMLNS); -encode({ps_item, _, _, _, _, _} = Item, TopXMLNS) -> - encode_pubsub_item(Item, TopXMLNS); -encode({ps_items, _, _, _, _, _, _} = Items, - TopXMLNS) -> - encode_pubsub_items(Items, TopXMLNS); -encode({ps_event, _, _, _, _, _, _} = Event, - TopXMLNS) -> - encode_pubsub_event(Event, TopXMLNS); -encode({ps_subscribe, _, _} = Subscribe, TopXMLNS) -> - encode_pubsub_subscribe(Subscribe, TopXMLNS); -encode({ps_unsubscribe, _, _, _} = Unsubscribe, - TopXMLNS) -> - encode_pubsub_unsubscribe(Unsubscribe, TopXMLNS); -encode({ps_publish, _, _} = Publish, TopXMLNS) -> - encode_pubsub_publish(Publish, TopXMLNS); -encode({ps_options, _, _, _, _} = Options, TopXMLNS) -> - encode_pubsub_options(Options, TopXMLNS); -encode({ps_retract, _, _, _} = Retract, TopXMLNS) -> - encode_pubsub_retract(Retract, TopXMLNS); -encode({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _} = - Pubsub, - TopXMLNS) -> - encode_pubsub(Pubsub, TopXMLNS); -encode({pubsub_owner, _, _, _, _, _, _} = Pubsub, - TopXMLNS) -> - encode_pubsub_owner(Pubsub, TopXMLNS); -encode({ps_error, 'closed-node', _} = Closed_node, - TopXMLNS) -> - encode_pubsub_error_closed_node(Closed_node, TopXMLNS); -encode({ps_error, 'configuration-required', _} = - Configuration_required, - TopXMLNS) -> - encode_pubsub_error_configuration_required(Configuration_required, - TopXMLNS); -encode({ps_error, 'invalid-jid', _} = Invalid_jid, - TopXMLNS) -> - encode_pubsub_error_invalid_jid(Invalid_jid, TopXMLNS); -encode({ps_error, 'invalid-options', _} = - Invalid_options, - TopXMLNS) -> - encode_pubsub_error_invalid_options(Invalid_options, - TopXMLNS); -encode({ps_error, 'invalid-payload', _} = - Invalid_payload, - TopXMLNS) -> - encode_pubsub_error_invalid_payload(Invalid_payload, - TopXMLNS); -encode({ps_error, 'invalid-subid', _} = Invalid_subid, - TopXMLNS) -> - encode_pubsub_error_invalid_subid(Invalid_subid, - TopXMLNS); -encode({ps_error, 'item-forbidden', _} = Item_forbidden, - TopXMLNS) -> - encode_pubsub_error_item_forbidden(Item_forbidden, - TopXMLNS); -encode({ps_error, 'item-required', _} = Item_required, - TopXMLNS) -> - encode_pubsub_error_item_required(Item_required, - TopXMLNS); -encode({ps_error, 'jid-required', _} = Jid_required, - TopXMLNS) -> - encode_pubsub_error_jid_required(Jid_required, - TopXMLNS); -encode({ps_error, 'max-items-exceeded', _} = - Max_items_exceeded, - TopXMLNS) -> - encode_pubsub_error_max_items_exceeded(Max_items_exceeded, - TopXMLNS); -encode({ps_error, 'max-nodes-exceeded', _} = - Max_nodes_exceeded, - TopXMLNS) -> - encode_pubsub_error_max_nodes_exceeded(Max_nodes_exceeded, - TopXMLNS); -encode({ps_error, 'nodeid-required', _} = - Nodeid_required, - TopXMLNS) -> - encode_pubsub_error_nodeid_required(Nodeid_required, - TopXMLNS); -encode({ps_error, 'not-in-roster-group', _} = - Not_in_roster_group, - TopXMLNS) -> - encode_pubsub_error_not_in_roster_group(Not_in_roster_group, - TopXMLNS); -encode({ps_error, 'not-subscribed', _} = Not_subscribed, - TopXMLNS) -> - encode_pubsub_error_not_subscribed(Not_subscribed, - TopXMLNS); -encode({ps_error, 'payload-too-big', _} = - Payload_too_big, - TopXMLNS) -> - encode_pubsub_error_payload_too_big(Payload_too_big, - TopXMLNS); -encode({ps_error, 'payload-required', _} = - Payload_required, - TopXMLNS) -> - encode_pubsub_error_payload_required(Payload_required, - TopXMLNS); -encode({ps_error, 'pending-subscription', _} = - Pending_subscription, - TopXMLNS) -> - encode_pubsub_error_pending_subscription(Pending_subscription, - TopXMLNS); -encode({ps_error, 'presence-subscription-required', _} = - Presence_subscription_required, - TopXMLNS) -> - encode_pubsub_error_presence_subscription_required(Presence_subscription_required, - TopXMLNS); -encode({ps_error, 'subid-required', _} = Subid_required, - TopXMLNS) -> - encode_pubsub_error_subid_required(Subid_required, - TopXMLNS); -encode({ps_error, 'too-many-subscriptions', _} = - Too_many_subscriptions, - TopXMLNS) -> - encode_pubsub_error_too_many_subscriptions(Too_many_subscriptions, - TopXMLNS); -encode({ps_error, unsupported, _} = Unsupported, - TopXMLNS) -> - encode_pubsub_error_unsupported(Unsupported, TopXMLNS); -encode({ps_error, 'unsupported-access-model', _} = - Unsupported_access_model, - TopXMLNS) -> - encode_pubsub_error_unsupported_access_model(Unsupported_access_model, - TopXMLNS); -encode({shim, _} = Headers, TopXMLNS) -> - encode_shim_headers(Headers, TopXMLNS); -encode({chatstate, active} = Active, TopXMLNS) -> - encode_chatstate_active(Active, TopXMLNS); -encode({chatstate, composing} = Composing, TopXMLNS) -> - encode_chatstate_composing(Composing, TopXMLNS); -encode({chatstate, gone} = Gone, TopXMLNS) -> - encode_chatstate_gone(Gone, TopXMLNS); -encode({chatstate, inactive} = Inactive, TopXMLNS) -> - encode_chatstate_inactive(Inactive, TopXMLNS); -encode({chatstate, paused} = Paused, TopXMLNS) -> - encode_chatstate_paused(Paused, TopXMLNS); -encode({delay, _, _, _} = Delay, TopXMLNS) -> - encode_delay(Delay, TopXMLNS); -encode({streamhost, _, _, _} = Streamhost, TopXMLNS) -> - encode_bytestreams_streamhost(Streamhost, TopXMLNS); -encode({bytestreams, _, _, _, _, _, _} = Query, - TopXMLNS) -> - encode_bytestreams(Query, TopXMLNS); -encode({muc_history, _, _, _, _} = History, TopXMLNS) -> - encode_muc_history(History, TopXMLNS); -encode({muc_decline, _, _, _} = Decline, TopXMLNS) -> - encode_muc_user_decline(Decline, TopXMLNS); -encode({muc_destroy, _, _, _, _} = Destroy, TopXMLNS) -> - encode_muc_destroy(Destroy, TopXMLNS); -encode({muc_invite, _, _, _, _} = Invite, TopXMLNS) -> - encode_muc_user_invite(Invite, TopXMLNS); -encode({muc_user, _, _, _, _, _, _} = X, TopXMLNS) -> - encode_muc_user(X, TopXMLNS); -encode({muc_owner, _, _, _} = Query, TopXMLNS) -> - encode_muc_owner(Query, TopXMLNS); -encode({muc_item, _, _, _, _, _, _, _} = Item, - TopXMLNS) -> - encode_muc_admin_item(Item, TopXMLNS); -encode({muc_actor, _, _} = Actor, TopXMLNS) -> - encode_muc_admin_actor(Actor, TopXMLNS); -encode({muc_admin, _} = Query, TopXMLNS) -> - encode_muc_admin(Query, TopXMLNS); -encode({muc, _, _} = X, TopXMLNS) -> - encode_muc(X, TopXMLNS); -encode({muc_unique, _} = Unique, TopXMLNS) -> - encode_muc_unique(Unique, TopXMLNS); -encode({x_conference, _, _, _, _, _} = X, TopXMLNS) -> - encode_x_conference(X, TopXMLNS); -encode({muc_subscriptions, _} = Subscriptions, - TopXMLNS) -> - encode_muc_subscriptions(Subscriptions, TopXMLNS); -encode({muc_subscribe, _, _} = Subscribe, TopXMLNS) -> - encode_muc_subscribe(Subscribe, TopXMLNS); -encode({muc_unsubscribe} = Unsubscribe, TopXMLNS) -> - encode_muc_unsubscribe(Unsubscribe, TopXMLNS); -encode({rsm_first, _, _} = First, TopXMLNS) -> - encode_rsm_first(First, TopXMLNS); -encode({rsm_set, _, _, _, _, _, _, _} = Set, - TopXMLNS) -> - encode_rsm_set(Set, TopXMLNS); -encode({mam_query, _, _, _, _, _, _, _, _} = Query, - TopXMLNS) -> - encode_mam_query(Query, TopXMLNS); -encode({mam_archived, _, _} = Archived, TopXMLNS) -> - encode_mam_archived(Archived, TopXMLNS); -encode({mam_result, _, _, _, _} = Result, TopXMLNS) -> - encode_mam_result(Result, TopXMLNS); -encode({mam_prefs, _, _, _, _} = Prefs, TopXMLNS) -> - encode_mam_prefs(Prefs, TopXMLNS); -encode({mam_fin, _, _, _, _, _} = Fin, TopXMLNS) -> - encode_mam_fin(Fin, TopXMLNS); -encode({forwarded, _, _} = Forwarded, TopXMLNS) -> - encode_forwarded(Forwarded, TopXMLNS); -encode({carbons_disable} = Disable, TopXMLNS) -> - encode_carbons_disable(Disable, TopXMLNS); -encode({carbons_enable} = Enable, TopXMLNS) -> - encode_carbons_enable(Enable, TopXMLNS); -encode({carbons_private} = Private, TopXMLNS) -> - encode_carbons_private(Private, TopXMLNS); -encode({carbons_received, _} = Received, TopXMLNS) -> - encode_carbons_received(Received, TopXMLNS); -encode({carbons_sent, _} = Sent, TopXMLNS) -> - encode_carbons_sent(Sent, TopXMLNS); -encode({feature_csi, <<"urn:xmpp:csi:0">>} = Csi, - TopXMLNS) -> - encode_feature_csi(Csi, TopXMLNS); -encode({feature_csi, <<>>} = Csi, - TopXMLNS = <<"urn:xmpp:csi:0">>) -> - encode_feature_csi(Csi, TopXMLNS); -encode({csi, active} = Active, TopXMLNS) -> - encode_csi_active(Active, TopXMLNS); -encode({csi, inactive} = Inactive, TopXMLNS) -> - encode_csi_inactive(Inactive, TopXMLNS); -encode({feature_sm, _} = Sm, TopXMLNS) -> - encode_feature_sm(Sm, TopXMLNS); -encode({sm_enable, _, _, _} = Enable, TopXMLNS) -> - encode_sm_enable(Enable, TopXMLNS); -encode({sm_enabled, _, _, _, _, _} = Enabled, - TopXMLNS) -> - encode_sm_enabled(Enabled, TopXMLNS); -encode({sm_resume, _, _, _} = Resume, TopXMLNS) -> - encode_sm_resume(Resume, TopXMLNS); -encode({sm_resumed, _, _, _} = Resumed, TopXMLNS) -> - encode_sm_resumed(Resumed, TopXMLNS); -encode({sm_r, _} = R, TopXMLNS) -> - encode_sm_r(R, TopXMLNS); -encode({sm_a, _, _} = A, TopXMLNS) -> - encode_sm_a(A, TopXMLNS); -encode({sm_failed, _, _, _} = Failed, TopXMLNS) -> - encode_sm_failed(Failed, TopXMLNS); -encode({offline_item, _, _} = Item, TopXMLNS) -> - encode_offline_item(Item, TopXMLNS); -encode({offline, _, _, _} = Offline, TopXMLNS) -> - encode_offline(Offline, TopXMLNS); -encode({mix_join, _, _} = Join, TopXMLNS) -> - encode_mix_join(Join, TopXMLNS); -encode({mix_leave} = Leave, TopXMLNS) -> - encode_mix_leave(Leave, TopXMLNS); -encode({mix_participant, _, _} = Participant, - TopXMLNS) -> - encode_mix_participant(Participant, TopXMLNS); -encode({hint, 'no-copy'} = No_copy, TopXMLNS) -> - encode_hint_no_copy(No_copy, TopXMLNS); -encode({hint, 'no-store'} = No_store, TopXMLNS) -> - encode_hint_no_store(No_store, TopXMLNS); -encode({hint, 'no-storage'} = No_storage, TopXMLNS) -> - encode_hint_no_storage(No_storage, TopXMLNS); -encode({hint, store} = Store, TopXMLNS) -> - encode_hint_store(Store, TopXMLNS); -encode({hint, 'no-permanent-store'} = - No_permanent_store, - TopXMLNS) -> - encode_hint_no_permanent_store(No_permanent_store, - TopXMLNS); -encode({hint, 'no-permanent-storage'} = - No_permanent_storage, - TopXMLNS) -> - encode_hint_no_permanent_storage(No_permanent_storage, - TopXMLNS); -encode({search_item, _, _, _, _, _} = Item, TopXMLNS) -> - encode_search_item(Item, TopXMLNS); -encode({search, _, _, _, _, _, _, _} = Query, - TopXMLNS) -> - encode_search(Query, TopXMLNS); -encode({xevent, _, _, _, _, _} = X, TopXMLNS) -> - encode_xevent(X, TopXMLNS); -encode({expire, _, _} = X, TopXMLNS) -> - encode_expire(X, TopXMLNS); -encode({nick, _} = Nick, TopXMLNS) -> - encode_nick(Nick, TopXMLNS); -encode({address, _, _, _, _, _} = Address, TopXMLNS) -> - encode_address(Address, TopXMLNS); -encode({addresses, _} = Addresses, TopXMLNS) -> - encode_addresses(Addresses, TopXMLNS); -encode({stanza_id, _, _} = Stanza_id, TopXMLNS) -> - encode_stanza_id(Stanza_id, TopXMLNS); -encode({client_id, _} = Client_id, TopXMLNS) -> - encode_client_id(Client_id, TopXMLNS); -encode({adhoc_actions, _, _, _, _} = Actions, - TopXMLNS) -> - encode_adhoc_command_actions(Actions, TopXMLNS); -encode({adhoc_note, _, _} = Note, TopXMLNS) -> - encode_adhoc_command_notes(Note, TopXMLNS); -encode({adhoc_command, _, _, _, _, _, _, _, _} = - Command, - TopXMLNS) -> - encode_adhoc_command(Command, TopXMLNS); -encode({db_result, _, _, _, _, _} = Db_result, - TopXMLNS) -> - encode_db_result(Db_result, TopXMLNS); -encode({db_verify, _, _, _, _, _, _} = Db_verify, - TopXMLNS) -> - encode_db_verify(Db_verify, TopXMLNS); -encode({handshake, _} = Handshake, TopXMLNS) -> - encode_handshake(Handshake, TopXMLNS); -encode({stream_start, _, _, _, _, _, _, _, _} = - Stream_stream, - TopXMLNS) -> - encode_stream_start(Stream_stream, TopXMLNS); -encode({bob_data, _, _, _, _} = Data, TopXMLNS) -> - encode_bob_data(Data, TopXMLNS); -encode({xcaptcha, _} = Captcha, TopXMLNS) -> - encode_captcha(Captcha, TopXMLNS); -encode({media_uri, _, _} = Uri, TopXMLNS) -> - encode_media_uri(Uri, TopXMLNS); -encode({media, _, _, _} = Media, TopXMLNS) -> - encode_media(Media, TopXMLNS); -encode({oob_x, _, _, _} = X, TopXMLNS) -> - encode_oob_x(X, TopXMLNS); -encode({sic, _, _, _} = Address, TopXMLNS) -> - encode_sic(Address, TopXMLNS); -encode({upload_request, _, _, _, _} = Request, - TopXMLNS) -> - encode_upload_request(Request, TopXMLNS); -encode({upload_slot, _, _, _} = Slot, TopXMLNS) -> - encode_upload_slot(Slot, TopXMLNS); -encode({thumbnail, _, _, _, _} = Thumbnail, TopXMLNS) -> - encode_thumbnail(Thumbnail, TopXMLNS); -encode({privilege_perm, _, _} = Perm, TopXMLNS) -> - encode_privilege_perm(Perm, TopXMLNS); -encode({privilege, _, _} = Privilege, TopXMLNS) -> - encode_privilege(Privilege, TopXMLNS); -encode({delegated, _, _} = Delegated, TopXMLNS) -> - encode_delegated(Delegated, TopXMLNS); -encode({delegation, _, _} = Delegation, TopXMLNS) -> - encode_delegation(Delegation, TopXMLNS); -encode({delegation_query, _, _} = Query, TopXMLNS) -> - encode_delegation_query(Query, TopXMLNS). - -get_name({address, _, _, _, _, _}) -> <<"address">>; -get_name({addresses, _}) -> <<"addresses">>; -get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>; -get_name({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"command">>; -get_name({adhoc_note, _, _}) -> <<"note">>; -get_name({bind, _, _}) -> <<"bind">>; -get_name({block, _}) -> <<"block">>; -get_name({block_list, _}) -> <<"blocklist">>; -get_name({bob_data, _, _, _, _}) -> <<"data">>; -get_name({bookmark_conference, _, _, _, _, _}) -> - <<"conference">>; -get_name({bookmark_storage, _, _}) -> <<"storage">>; -get_name({bookmark_url, _, _}) -> <<"url">>; -get_name({bytestreams, _, _, _, _, _, _}) -> - <<"query">>; -get_name({caps, _, _, _, _}) -> <<"c">>; -get_name({carbons_disable}) -> <<"disable">>; -get_name({carbons_enable}) -> <<"enable">>; -get_name({carbons_private}) -> <<"private">>; -get_name({carbons_received, _}) -> <<"received">>; -get_name({carbons_sent, _}) -> <<"sent">>; -get_name({chatstate, active}) -> <<"active">>; -get_name({chatstate, composing}) -> <<"composing">>; -get_name({chatstate, gone}) -> <<"gone">>; -get_name({chatstate, inactive}) -> <<"inactive">>; -get_name({chatstate, paused}) -> <<"paused">>; -get_name({client_id, _}) -> <<"client-id">>; -get_name({compress, _}) -> <<"compress">>; -get_name({compress_failure, _}) -> <<"failure">>; -get_name({compressed}) -> <<"compressed">>; -get_name({compression, _}) -> <<"compression">>; -get_name({csi, active}) -> <<"active">>; -get_name({csi, inactive}) -> <<"inactive">>; -get_name({db_result, _, _, _, _, _}) -> <<"db:result">>; -get_name({db_verify, _, _, _, _, _, _}) -> - <<"db:verify">>; -get_name({delay, _, _, _}) -> <<"delay">>; -get_name({delegated, _, _}) -> <<"delegated">>; -get_name({delegation, _, _}) -> <<"delegation">>; -get_name({delegation_query, _, _}) -> <<"query">>; -get_name({disco_info, _, _, _, _}) -> <<"query">>; -get_name({disco_item, _, _, _}) -> <<"item">>; -get_name({disco_items, _, _, _}) -> <<"query">>; -get_name({expire, _, _}) -> <<"x">>; -get_name({feature_csi, _}) -> <<"csi">>; -get_name({feature_register}) -> <<"register">>; -get_name({feature_sm, _}) -> <<"sm">>; -get_name({forwarded, _, _}) -> <<"forwarded">>; -get_name({gone, _}) -> <<"gone">>; -get_name({handshake, _}) -> <<"handshake">>; -get_name({hint, 'no-copy'}) -> <<"no-copy">>; -get_name({hint, 'no-permanent-storage'}) -> - <<"no-permanent-storage">>; -get_name({hint, 'no-permanent-store'}) -> - <<"no-permanent-store">>; -get_name({hint, 'no-storage'}) -> <<"no-storage">>; -get_name({hint, 'no-store'}) -> <<"no-store">>; -get_name({hint, store}) -> <<"store">>; -get_name({identity, _, _, _, _}) -> <<"identity">>; -get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; -get_name({last, _, _}) -> <<"query">>; -get_name({legacy_auth, _, _, _, _}) -> <<"query">>; -get_name({mam_archived, _, _}) -> <<"archived">>; -get_name({mam_fin, _, _, _, _, _}) -> <<"fin">>; -get_name({mam_prefs, _, _, _, _}) -> <<"prefs">>; -get_name({mam_query, _, _, _, _, _, _, _, _}) -> - <<"query">>; -get_name({mam_result, _, _, _, _}) -> <<"result">>; -get_name({media, _, _, _}) -> <<"media">>; -get_name({media_uri, _, _}) -> <<"uri">>; -get_name({message, _, _, _, _, _, _, _, _, _}) -> - <<"message">>; -get_name({mix_join, _, _}) -> <<"join">>; -get_name({mix_leave}) -> <<"leave">>; -get_name({mix_participant, _, _}) -> <<"participant">>; -get_name({muc, _, _}) -> <<"x">>; -get_name({muc_actor, _, _}) -> <<"actor">>; -get_name({muc_admin, _}) -> <<"query">>; -get_name({muc_decline, _, _, _}) -> <<"decline">>; -get_name({muc_destroy, _, _, _, _}) -> <<"destroy">>; -get_name({muc_history, _, _, _, _}) -> <<"history">>; -get_name({muc_invite, _, _, _, _}) -> <<"invite">>; -get_name({muc_item, _, _, _, _, _, _, _}) -> <<"item">>; -get_name({muc_owner, _, _, _}) -> <<"query">>; -get_name({muc_subscribe, _, _}) -> <<"subscribe">>; -get_name({muc_subscriptions, _}) -> <<"subscriptions">>; -get_name({muc_unique, _}) -> <<"unique">>; -get_name({muc_unsubscribe}) -> <<"unsubscribe">>; -get_name({muc_user, _, _, _, _, _, _}) -> <<"x">>; -get_name({nick, _}) -> <<"nick">>; -get_name({offline, _, _, _}) -> <<"offline">>; -get_name({offline_item, _, _}) -> <<"item">>; -get_name({oob_x, _, _, _}) -> <<"x">>; -get_name({p1_ack}) -> <<"ack">>; -get_name({p1_push}) -> <<"push">>; -get_name({p1_rebind}) -> <<"rebind">>; -get_name({ping}) -> <<"ping">>; -get_name({presence, _, _, _, _, _, _, _, _, _}) -> - <<"presence">>; -get_name({privacy_item, _, _, _, _, _, _, _, _}) -> - <<"item">>; -get_name({privacy_list, _, _}) -> <<"list">>; -get_name({privacy_query, _, _, _}) -> <<"query">>; -get_name({private, _}) -> <<"query">>; -get_name({privilege, _, _}) -> <<"privilege">>; -get_name({privilege_perm, _, _}) -> <<"perm">>; -get_name({ps_affiliation, _, _, _, _}) -> - <<"affiliation">>; -get_name({ps_error, 'closed-node', _}) -> - <<"closed-node">>; -get_name({ps_error, 'configuration-required', _}) -> - <<"configuration-required">>; -get_name({ps_error, 'invalid-jid', _}) -> - <<"invalid-jid">>; -get_name({ps_error, 'invalid-options', _}) -> - <<"invalid-options">>; -get_name({ps_error, 'invalid-payload', _}) -> - <<"invalid-payload">>; -get_name({ps_error, 'invalid-subid', _}) -> - <<"invalid-subid">>; -get_name({ps_error, 'item-forbidden', _}) -> - <<"item-forbidden">>; -get_name({ps_error, 'item-required', _}) -> - <<"item-required">>; -get_name({ps_error, 'jid-required', _}) -> - <<"jid-required">>; -get_name({ps_error, 'max-items-exceeded', _}) -> - <<"max-items-exceeded">>; -get_name({ps_error, 'max-nodes-exceeded', _}) -> - <<"max-nodes-exceeded">>; -get_name({ps_error, 'nodeid-required', _}) -> - <<"nodeid-required">>; -get_name({ps_error, 'not-in-roster-group', _}) -> - <<"not-in-roster-group">>; -get_name({ps_error, 'not-subscribed', _}) -> - <<"not-subscribed">>; -get_name({ps_error, 'payload-required', _}) -> - <<"payload-required">>; -get_name({ps_error, 'payload-too-big', _}) -> - <<"payload-too-big">>; -get_name({ps_error, 'pending-subscription', _}) -> - <<"pending-subscription">>; -get_name({ps_error, 'presence-subscription-required', - _}) -> - <<"presence-subscription-required">>; -get_name({ps_error, 'subid-required', _}) -> - <<"subid-required">>; -get_name({ps_error, 'too-many-subscriptions', _}) -> - <<"too-many-subscriptions">>; -get_name({ps_error, unsupported, _}) -> - <<"unsupported">>; -get_name({ps_error, 'unsupported-access-model', _}) -> - <<"unsupported-access-model">>; -get_name({ps_event, _, _, _, _, _, _}) -> <<"event">>; -get_name({ps_item, _, _, _, _, _}) -> <<"item">>; -get_name({ps_items, _, _, _, _, _, _}) -> <<"items">>; -get_name({ps_options, _, _, _, _}) -> <<"options">>; -get_name({ps_publish, _, _}) -> <<"publish">>; -get_name({ps_retract, _, _, _}) -> <<"retract">>; -get_name({ps_subscribe, _, _}) -> <<"subscribe">>; -get_name({ps_subscription, _, _, _, _, _, _}) -> - <<"subscription">>; -get_name({ps_unsubscribe, _, _, _}) -> - <<"unsubscribe">>; -get_name({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _}) -> - <<"pubsub">>; -get_name({pubsub_owner, _, _, _, _, _, _}) -> - <<"pubsub">>; -get_name({redirect, _}) -> <<"redirect">>; -get_name({register, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _}) -> - <<"query">>; -get_name({roster_item, _, _, _, _, _}) -> <<"item">>; -get_name({roster_query, _, _}) -> <<"query">>; -get_name({rosterver_feature}) -> <<"ver">>; -get_name({rsm_first, _, _}) -> <<"first">>; -get_name({rsm_set, _, _, _, _, _, _, _}) -> <<"set">>; -get_name({sasl_abort}) -> <<"abort">>; -get_name({sasl_auth, _, _}) -> <<"auth">>; -get_name({sasl_challenge, _}) -> <<"challenge">>; -get_name({sasl_failure, _, _}) -> <<"failure">>; -get_name({sasl_mechanisms, _}) -> <<"mechanisms">>; -get_name({sasl_response, _}) -> <<"response">>; -get_name({sasl_success, _}) -> <<"success">>; -get_name({search, _, _, _, _, _, _, _}) -> <<"query">>; -get_name({search_item, _, _, _, _, _}) -> <<"item">>; -get_name({'see-other-host', _}) -> <<"see-other-host">>; -get_name({shim, _}) -> <<"headers">>; -get_name({sic, _, _, _}) -> <<"address">>; -get_name({sm_a, _, _}) -> <<"a">>; -get_name({sm_enable, _, _, _}) -> <<"enable">>; -get_name({sm_enabled, _, _, _, _, _}) -> <<"enabled">>; -get_name({sm_failed, _, _, _}) -> <<"failed">>; -get_name({sm_r, _}) -> <<"r">>; -get_name({sm_resume, _, _, _}) -> <<"resume">>; -get_name({sm_resumed, _, _, _}) -> <<"resumed">>; -get_name({stanza_error, _, _, _, _, _, _}) -> - <<"error">>; -get_name({stanza_id, _, _}) -> <<"stanza-id">>; -get_name({starttls, _}) -> <<"starttls">>; -get_name({starttls_failure}) -> <<"failure">>; -get_name({starttls_proceed}) -> <<"proceed">>; -get_name({stat, _, _, _, _}) -> <<"stat">>; -get_name({stat_error, _, _}) -> <<"error">>; -get_name({stats, _, _}) -> <<"query">>; -get_name({stream_error, _, _}) -> <<"stream:error">>; -get_name({stream_features, _}) -> <<"stream:features">>; -get_name({stream_start, _, _, _, _, _, _, _, _}) -> - <<"stream:stream">>; -get_name({streamhost, _, _, _}) -> <<"streamhost">>; -get_name({text, _, _}) -> <<"text">>; -get_name({thumbnail, _, _, _, _}) -> <<"thumbnail">>; -get_name({time, _, _}) -> <<"time">>; -get_name({unblock, _}) -> <<"unblock">>; -get_name({upload_request, _, _, _, _}) -> <<"request">>; -get_name({upload_slot, _, _, _}) -> <<"slot">>; -get_name({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"ADR">>; -get_name({vcard_email, _, _, _, _, _, _}) -> - <<"EMAIL">>; -get_name({vcard_geo, _, _}) -> <<"GEO">>; -get_name({vcard_key, _, _}) -> <<"KEY">>; -get_name({vcard_label, _, _, _, _, _, _, _, _}) -> - <<"LABEL">>; -get_name({vcard_logo, _, _, _}) -> <<"LOGO">>; -get_name({vcard_name, _, _, _, _, _}) -> <<"N">>; -get_name({vcard_org, _, _}) -> <<"ORG">>; -get_name({vcard_photo, _, _, _}) -> <<"PHOTO">>; -get_name({vcard_sound, _, _, _}) -> <<"SOUND">>; -get_name({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"TEL">>; -get_name({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _}) -> - <<"vCard">>; -get_name({vcard_xupdate, _, _}) -> <<"x">>; -get_name({version, _, _, _}) -> <<"query">>; -get_name({x_conference, _, _, _, _, _}) -> <<"x">>; -get_name({xcaptcha, _}) -> <<"captcha">>; -get_name({xdata, _, _, _, _, _, _}) -> <<"x">>; -get_name({xdata_field, _, _, _, _, _, _, _, _}) -> - <<"field">>; -get_name({xdata_option, _, _}) -> <<"option">>; -get_name({xevent, _, _, _, _, _}) -> <<"x">>; -get_name({xmpp_session, _}) -> <<"session">>. - -get_ns({address, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/address">>; -get_ns({addresses, _}) -> - <<"http://jabber.org/protocol/address">>; -get_ns({adhoc_actions, _, _, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({adhoc_command, _, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({adhoc_note, _, _}) -> - <<"http://jabber.org/protocol/commands">>; -get_ns({bind, _, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-bind">>; -get_ns({block, _}) -> <<"urn:xmpp:blocking">>; -get_ns({block_list, _}) -> <<"urn:xmpp:blocking">>; -get_ns({bob_data, _, _, _, _}) -> <<"urn:xmpp:bob">>; -get_ns({bookmark_conference, _, _, _, _, _}) -> - <<"storage:bookmarks">>; -get_ns({bookmark_storage, _, _}) -> - <<"storage:bookmarks">>; -get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>; -get_ns({bytestreams, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/bytestreams">>; -get_ns({caps, _, _, _, _}) -> - <<"http://jabber.org/protocol/caps">>; -get_ns({carbons_disable}) -> <<"urn:xmpp:carbons:2">>; -get_ns({carbons_enable}) -> <<"urn:xmpp:carbons:2">>; -get_ns({carbons_private}) -> <<"urn:xmpp:carbons:2">>; -get_ns({carbons_received, _}) -> - <<"urn:xmpp:carbons:2">>; -get_ns({carbons_sent, _}) -> <<"urn:xmpp:carbons:2">>; -get_ns({chatstate, active}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, composing}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, gone}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, inactive}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({chatstate, paused}) -> - <<"http://jabber.org/protocol/chatstates">>; -get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>; -get_ns({compress, _}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compress_failure, _}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compressed}) -> - <<"http://jabber.org/protocol/compress">>; -get_ns({compression, _}) -> - <<"http://jabber.org/features/compress">>; -get_ns({csi, active}) -> <<"urn:xmpp:csi:0">>; -get_ns({csi, inactive}) -> <<"urn:xmpp:csi:0">>; -get_ns({db_result, _, _, _, _, _}) -> - <<"jabber:server">>; -get_ns({db_verify, _, _, _, _, _, _}) -> - <<"jabber:server">>; -get_ns({delay, _, _, _}) -> <<"urn:xmpp:delay">>; -get_ns({delegated, _, _}) -> - <<"urn:xmpp:delegation:1">>; -get_ns({delegation, _, _}) -> - <<"urn:xmpp:delegation:1">>; -get_ns({delegation_query, _, _}) -> - <<"urn:xmpp:delegation:1">>; -get_ns({disco_info, _, _, _, _}) -> - <<"http://jabber.org/protocol/disco#info">>; -get_ns({disco_item, _, _, _}) -> - <<"http://jabber.org/protocol/disco#items">>; -get_ns({disco_items, _, _, _}) -> - <<"http://jabber.org/protocol/disco#items">>; -get_ns({expire, _, _}) -> <<"jabber:x:expire">>; -get_ns({feature_csi, Xmlns}) -> Xmlns; -get_ns({feature_register}) -> - <<"http://jabber.org/features/iq-register">>; -get_ns({feature_sm, Xmlns}) -> Xmlns; -get_ns({forwarded, _, _}) -> <<"urn:xmpp:forward:0">>; -get_ns({gone, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; -get_ns({handshake, _}) -> <<"jabber:component:accept">>; -get_ns({hint, 'no-copy'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, 'no-permanent-storage'}) -> - <<"urn:xmpp:hints">>; -get_ns({hint, 'no-permanent-store'}) -> - <<"urn:xmpp:hints">>; -get_ns({hint, 'no-storage'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, 'no-store'}) -> <<"urn:xmpp:hints">>; -get_ns({hint, store}) -> <<"urn:xmpp:hints">>; -get_ns({identity, _, _, _, _}) -> - <<"http://jabber.org/protocol/disco#info">>; -get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>; -get_ns({last, _, _}) -> <<"jabber:iq:last">>; -get_ns({legacy_auth, _, _, _, _}) -> - <<"jabber:iq:auth">>; -get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>; -get_ns({mam_fin, Xmlns, _, _, _, _}) -> Xmlns; -get_ns({mam_prefs, Xmlns, _, _, _}) -> Xmlns; -get_ns({mam_query, Xmlns, _, _, _, _, _, _, _}) -> - Xmlns; -get_ns({mam_result, Xmlns, _, _, _}) -> Xmlns; -get_ns({media, _, _, _}) -> - <<"urn:xmpp:media-element">>; -get_ns({media_uri, _, _}) -> - <<"urn:xmpp:media-element">>; -get_ns({message, _, _, _, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({mix_join, _, _}) -> <<"urn:xmpp:mix:0">>; -get_ns({mix_leave}) -> <<"urn:xmpp:mix:0">>; -get_ns({mix_participant, _, _}) -> <<"urn:xmpp:mix:0">>; -get_ns({muc, _, _}) -> - <<"http://jabber.org/protocol/muc">>; -get_ns({muc_admin, _}) -> - <<"http://jabber.org/protocol/muc#admin">>; -get_ns({muc_decline, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_destroy, Xmlns, _, _, _}) -> Xmlns; -get_ns({muc_history, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc">>; -get_ns({muc_invite, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({muc_owner, _, _, _}) -> - <<"http://jabber.org/protocol/muc#owner">>; -get_ns({muc_subscribe, _, _}) -> - <<"urn:xmpp:mucsub:0">>; -get_ns({muc_subscriptions, _}) -> - <<"urn:xmpp:mucsub:0">>; -get_ns({muc_unique, _}) -> - <<"http://jabber.org/protocol/muc#unique">>; -get_ns({muc_unsubscribe}) -> <<"urn:xmpp:mucsub:0">>; -get_ns({muc_user, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/muc#user">>; -get_ns({nick, _}) -> - <<"http://jabber.org/protocol/nick">>; -get_ns({offline, _, _, _}) -> - <<"http://jabber.org/protocol/offline">>; -get_ns({offline_item, _, _}) -> - <<"http://jabber.org/protocol/offline">>; -get_ns({oob_x, _, _, _}) -> <<"jabber:x:oob">>; -get_ns({p1_ack}) -> <<"p1:ack">>; -get_ns({p1_push}) -> <<"p1:push">>; -get_ns({p1_rebind}) -> <<"p1:rebind">>; -get_ns({ping}) -> <<"urn:xmpp:ping">>; -get_ns({presence, _, _, _, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({privacy_item, _, _, _, _, _, _, _, _}) -> - <<"jabber:iq:privacy">>; -get_ns({privacy_list, _, _}) -> <<"jabber:iq:privacy">>; -get_ns({privacy_query, _, _, _}) -> - <<"jabber:iq:privacy">>; -get_ns({private, _}) -> <<"jabber:iq:private">>; -get_ns({privilege, _, _}) -> <<"urn:xmpp:privilege:1">>; -get_ns({privilege_perm, _, _}) -> - <<"urn:xmpp:privilege:1">>; -get_ns({ps_affiliation, Xmlns, _, _, _}) -> Xmlns; -get_ns({ps_error, 'closed-node', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'configuration-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'invalid-jid', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'invalid-options', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'invalid-payload', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'invalid-subid', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'item-forbidden', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'item-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'jid-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'max-items-exceeded', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'max-nodes-exceeded', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'nodeid-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'not-in-roster-group', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'not-subscribed', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'payload-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'payload-too-big', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'pending-subscription', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'presence-subscription-required', - _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'subid-required', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'too-many-subscriptions', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, unsupported, _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_error, 'unsupported-access-model', _}) -> - <<"http://jabber.org/protocol/pubsub#errors">>; -get_ns({ps_event, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub#event">>; -get_ns({ps_item, Xmlns, _, _, _, _}) -> Xmlns; -get_ns({ps_items, Xmlns, _, _, _, _, _}) -> Xmlns; -get_ns({ps_options, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({ps_publish, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({ps_retract, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({ps_subscribe, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({ps_subscription, Xmlns, _, _, _, _, _}) -> - Xmlns; -get_ns({ps_unsubscribe, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _}) -> - <<"http://jabber.org/protocol/pubsub">>; -get_ns({pubsub_owner, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/pubsub#owner">>; -get_ns({redirect, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; -get_ns({register, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _}) -> - <<"jabber:iq:register">>; -get_ns({roster_item, _, _, _, _, _}) -> - <<"jabber:iq:roster">>; -get_ns({roster_query, _, _}) -> <<"jabber:iq:roster">>; -get_ns({rosterver_feature}) -> - <<"urn:xmpp:features:rosterver">>; -get_ns({rsm_first, _, _}) -> - <<"http://jabber.org/protocol/rsm">>; -get_ns({rsm_set, _, _, _, _, _, _, _}) -> - <<"http://jabber.org/protocol/rsm">>; -get_ns({sasl_abort}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_auth, _, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_challenge, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_failure, _, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_mechanisms, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_response, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({sasl_success, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-sasl">>; -get_ns({search, _, _, _, _, _, _, _}) -> - <<"jabber:iq:search">>; -get_ns({search_item, _, _, _, _, _}) -> - <<"jabber:iq:search">>; -get_ns({'see-other-host', _}) -> - <<"urn:ietf:params:xml:ns:xmpp-streams">>; -get_ns({shim, _}) -> - <<"http://jabber.org/protocol/shim">>; -get_ns({sic, _, _, Xmlns}) -> Xmlns; -get_ns({sm_a, _, Xmlns}) -> Xmlns; -get_ns({sm_enable, _, _, Xmlns}) -> Xmlns; -get_ns({sm_enabled, _, _, _, _, Xmlns}) -> Xmlns; -get_ns({sm_failed, _, _, Xmlns}) -> Xmlns; -get_ns({sm_r, Xmlns}) -> Xmlns; -get_ns({sm_resume, _, _, Xmlns}) -> Xmlns; -get_ns({sm_resumed, _, _, Xmlns}) -> Xmlns; -get_ns({stanza_error, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>; -get_ns({starttls, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-tls">>; -get_ns({starttls_failure}) -> - <<"urn:ietf:params:xml:ns:xmpp-tls">>; -get_ns({starttls_proceed}) -> - <<"urn:ietf:params:xml:ns:xmpp-tls">>; -get_ns({stat, _, _, _, _}) -> - <<"http://jabber.org/protocol/stats">>; -get_ns({stat_error, _, _}) -> - <<"http://jabber.org/protocol/stats">>; -get_ns({stats, _, _}) -> - <<"http://jabber.org/protocol/stats">>; -get_ns({stream_error, _, _}) -> <<"jabber:client">>; -get_ns({stream_features, _}) -> <<"jabber:client">>; -get_ns({stream_start, _, _, _, _, Xmlns, _, _, _}) -> - Xmlns; -get_ns({streamhost, _, _, _}) -> - <<"http://jabber.org/protocol/bytestreams">>; -get_ns({thumbnail, _, _, _, _}) -> - <<"urn:xmpp:thumbs:1">>; -get_ns({time, _, _}) -> <<"urn:xmpp:time">>; -get_ns({unblock, _}) -> <<"urn:xmpp:blocking">>; -get_ns({upload_request, _, _, _, Xmlns}) -> Xmlns; -get_ns({upload_slot, _, _, Xmlns}) -> Xmlns; -get_ns({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_email, _, _, _, _, _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_geo, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_key, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_label, _, _, _, _, _, _, _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_logo, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_name, _, _, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_org, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_photo, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_sound, _, _, _}) -> <<"vcard-temp">>; -get_ns({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _, - _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_temp, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> - <<"vcard-temp">>; -get_ns({vcard_xupdate, _, _}) -> - <<"vcard-temp:x:update">>; -get_ns({version, _, _, _}) -> <<"jabber:iq:version">>; -get_ns({x_conference, _, _, _, _, _}) -> - <<"jabber:x:conference">>; -get_ns({xcaptcha, _}) -> <<"urn:xmpp:captcha">>; -get_ns({xdata, _, _, _, _, _, _}) -> - <<"jabber:x:data">>; -get_ns({xdata_field, _, _, _, _, _, _, _, _}) -> - <<"jabber:x:data">>; -get_ns({xdata_option, _, _}) -> <<"jabber:x:data">>; -get_ns({xevent, _, _, _, _, _}) -> <<"jabber:x:event">>; -get_ns({xmpp_session, _}) -> - <<"urn:ietf:params:xml:ns:xmpp-session">>. - -dec_int(Val) -> dec_int(Val, infinity, infinity). - -dec_int(Val, Min, Max) -> - case list_to_integer(binary_to_list(Val)) of - Int when Int =< Max, Min == infinity -> Int; - Int when Int =< Max, Int >= Min -> Int - end. - -enc_int(Int) -> list_to_binary(integer_to_list(Int)). - -dec_enum(Val, Enums) -> - AtomVal = erlang:binary_to_existing_atom(Val, utf8), - case lists:member(AtomVal, Enums) of - true -> AtomVal - end. - -enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8). - -format_error({bad_attr_value, Attr, Tag, XMLNS}) -> - <<"Bad value of attribute '", Attr/binary, "' in tag <", - Tag/binary, "/> qualified by namespace '", XMLNS/binary, - "'">>; -format_error({bad_cdata_value, <<>>, Tag, XMLNS}) -> - <<"Bad value of cdata in tag <", Tag/binary, - "/> qualified by namespace '", XMLNS/binary, "'">>; -format_error({missing_tag, Tag, XMLNS}) -> - <<"Missing tag <", Tag/binary, - "/> qualified by namespace '", XMLNS/binary, "'">>; -format_error({missing_attr, Attr, Tag, XMLNS}) -> - <<"Missing attribute '", Attr/binary, "' in tag <", - Tag/binary, "/> qualified by namespace '", XMLNS/binary, - "'">>; -format_error({missing_cdata, <<>>, Tag, XMLNS}) -> - <<"Missing cdata in tag <", Tag/binary, - "/> qualified by namespace '", XMLNS/binary, "'">>; -format_error({unknown_tag, Tag, XMLNS}) -> - <<"Unknown tag <", Tag/binary, - "/> qualified by namespace '", XMLNS/binary, "'">>; -format_error({missing_tag_xmlns, Tag}) -> - <<"Missing namespace for tag <", Tag/binary, "/>">>. - -get_attr(Attr, Attrs) -> - case lists:keyfind(Attr, 1, Attrs) of - {_, Val} -> Val; - false -> <<>> - end. - -enc_xmlns_attrs(XMLNS, XMLNS) -> []; -enc_xmlns_attrs(XMLNS, _) -> [{<<"xmlns">>, XMLNS}]. - -choose_top_xmlns(<<>>, NSList, TopXMLNS) -> - case lists:member(TopXMLNS, NSList) of - true -> TopXMLNS; - false -> hd(NSList) - end; -choose_top_xmlns(XMLNS, _, _) -> XMLNS. - -pp(Term) -> io_lib_pretty:print(Term, fun pp/2). - -pp(last, 2) -> [seconds, status]; -pp(version, 3) -> [name, ver, os]; -pp(roster_item, 5) -> - [jid, name, groups, subscription, ask]; -pp(roster_query, 2) -> [items, ver]; -pp(rosterver_feature, 0) -> []; -pp(privacy_item, 8) -> - [order, action, type, value, message, iq, presence_in, - presence_out]; -pp(privacy_list, 2) -> [name, items]; -pp(privacy_query, 3) -> [lists, default, active]; -pp(block, 1) -> [items]; -pp(unblock, 1) -> [items]; -pp(block_list, 1) -> [items]; -pp(identity, 4) -> [category, type, lang, name]; -pp(disco_info, 4) -> - [node, identities, features, xdata]; -pp(disco_item, 3) -> [jid, name, node]; -pp(disco_items, 3) -> [node, items, rsm]; -pp(private, 1) -> [xml_els]; -pp(bookmark_conference, 5) -> - [name, jid, autojoin, nick, password]; -pp(bookmark_url, 2) -> [name, url]; -pp(bookmark_storage, 2) -> [conference, url]; -pp(stat_error, 2) -> [code, reason]; -pp(stat, 4) -> [name, units, value, error]; -pp(stats, 2) -> [list, node]; -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, 9) -> - [id, type, lang, from, to, show, status, priority, - sub_els]; -pp(gone, 1) -> [uri]; -pp(redirect, 1) -> [uri]; -pp(stanza_error, 6) -> - [type, code, by, reason, text, sub_els]; -pp(bind, 2) -> [jid, resource]; -pp(legacy_auth, 4) -> - [username, password, digest, resource]; -pp(sasl_auth, 2) -> [mechanism, text]; -pp(sasl_abort, 0) -> []; -pp(sasl_challenge, 1) -> [text]; -pp(sasl_response, 1) -> [text]; -pp(sasl_success, 1) -> [text]; -pp(sasl_failure, 2) -> [reason, text]; -pp(sasl_mechanisms, 1) -> [list]; -pp(starttls, 1) -> [required]; -pp(starttls_proceed, 0) -> []; -pp(starttls_failure, 0) -> []; -pp(compress_failure, 1) -> [reason]; -pp(compress, 1) -> [methods]; -pp(compressed, 0) -> []; -pp(compression, 1) -> [methods]; -pp(stream_features, 1) -> [sub_els]; -pp(p1_push, 0) -> []; -pp(p1_rebind, 0) -> []; -pp(p1_ack, 0) -> []; -pp(caps, 4) -> [node, version, hash, exts]; -pp(feature_register, 0) -> []; -pp(register, 22) -> - [registered, remove, instructions, username, nick, - password, name, first, last, email, address, city, - state, zip, phone, url, date, misc, text, key, xdata, - sub_els]; -pp(xmpp_session, 1) -> [optional]; -pp(ping, 0) -> []; -pp(time, 2) -> [tzo, utc]; -pp(text, 2) -> [lang, data]; -pp('see-other-host', 1) -> [host]; -pp(stream_error, 2) -> [reason, text]; -pp(vcard_name, 5) -> - [family, given, middle, prefix, suffix]; -pp(vcard_adr, 14) -> - [home, work, postal, parcel, dom, intl, pref, pobox, - extadd, street, locality, region, pcode, ctry]; -pp(vcard_label, 8) -> - [home, work, postal, parcel, dom, intl, pref, line]; -pp(vcard_tel, 14) -> - [home, work, voice, fax, pager, msg, cell, video, bbs, - modem, isdn, pcs, pref, number]; -pp(vcard_email, 6) -> - [home, work, internet, pref, x400, userid]; -pp(vcard_geo, 2) -> [lat, lon]; -pp(vcard_logo, 3) -> [type, binval, extval]; -pp(vcard_photo, 3) -> [type, binval, extval]; -pp(vcard_org, 2) -> [name, units]; -pp(vcard_sound, 3) -> [phonetic, binval, extval]; -pp(vcard_key, 2) -> [type, cred]; -pp(vcard_temp, 29) -> - [version, fn, n, nickname, photo, bday, adr, label, tel, - email, jabberid, mailer, tz, geo, title, role, logo, - org, categories, note, prodid, rev, sort_string, sound, - uid, url, class, key, desc]; -pp(xdata_option, 2) -> [label, value]; -pp(xdata_field, 8) -> - [label, type, var, required, desc, values, options, - sub_els]; -pp(xdata, 6) -> - [type, instructions, title, reported, items, fields]; -pp(ps_subscription, 6) -> - [xmlns, jid, type, node, subid, expiry]; -pp(ps_item, 5) -> [xmlns, id, xml_els, node, publisher]; -pp(ps_items, 6) -> - [xmlns, node, items, max_items, subid, retract]; -pp(ps_event, 6) -> - [items, purge, subscription, delete, create, - configuration]; -pp(ps_subscribe, 2) -> [node, jid]; -pp(ps_unsubscribe, 3) -> [node, jid, subid]; -pp(ps_publish, 2) -> [node, items]; -pp(ps_options, 4) -> [node, jid, subid, xdata]; -pp(ps_retract, 3) -> [node, notify, items]; -pp(pubsub, 16) -> - [subscriptions, subscription, affiliations, publish, - publish_options, subscribe, unsubscribe, options, items, - retract, create, configure, default, delete, purge, - rsm]; -pp(pubsub_owner, 6) -> - [affiliations, configure, default, delete, purge, - subscriptions]; -pp(shim, 1) -> [headers]; -pp(delay, 3) -> [stamp, from, desc]; -pp(streamhost, 3) -> [jid, host, port]; -pp(bytestreams, 6) -> - [hosts, used, activate, dstaddr, mode, sid]; -pp(muc_history, 4) -> - [maxchars, maxstanzas, seconds, since]; -pp(muc_decline, 3) -> [reason, from, to]; -pp(muc_destroy, 4) -> [xmlns, jid, reason, password]; -pp(muc_invite, 4) -> [reason, from, to, continue]; -pp(muc_user, 6) -> - [decline, destroy, invites, items, status_codes, - password]; -pp(muc_owner, 3) -> [destroy, config, items]; -pp(muc_item, 7) -> - [actor, continue, reason, affiliation, role, jid, nick]; -pp(muc_actor, 2) -> [jid, nick]; -pp(muc_admin, 1) -> [items]; -pp(muc, 2) -> [history, password]; -pp(muc_unique, 1) -> [name]; -pp(x_conference, 5) -> - [jid, password, reason, continue, thread]; -pp(muc_subscriptions, 1) -> [list]; -pp(muc_subscribe, 2) -> [nick, events]; -pp(muc_unsubscribe, 0) -> []; -pp(rsm_first, 2) -> [index, data]; -pp(rsm_set, 7) -> - ['after', before, count, first, index, last, max]; -pp(mam_query, 8) -> - [xmlns, id, start, 'end', with, withtext, 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, 5) -> [xmlns, id, rsm, stable, complete]; -pp(forwarded, 2) -> [delay, xml_els]; -pp(carbons_disable, 0) -> []; -pp(carbons_enable, 0) -> []; -pp(carbons_private, 0) -> []; -pp(carbons_received, 1) -> [forwarded]; -pp(carbons_sent, 1) -> [forwarded]; -pp(feature_csi, 1) -> [xmlns]; -pp(feature_sm, 1) -> [xmlns]; -pp(sm_enable, 3) -> [max, resume, xmlns]; -pp(sm_enabled, 5) -> [id, location, max, resume, xmlns]; -pp(sm_resume, 3) -> [h, previd, xmlns]; -pp(sm_resumed, 3) -> [h, previd, xmlns]; -pp(sm_r, 1) -> [xmlns]; -pp(sm_a, 2) -> [h, xmlns]; -pp(sm_failed, 3) -> [reason, h, xmlns]; -pp(offline_item, 2) -> [node, action]; -pp(offline, 3) -> [items, purge, fetch]; -pp(mix_join, 2) -> [jid, subscribe]; -pp(mix_leave, 0) -> []; -pp(mix_participant, 2) -> [jid, nick]; -pp(search_item, 5) -> [jid, first, last, nick, email]; -pp(search, 7) -> - [instructions, first, last, nick, email, items, xdata]; -pp(xevent, 5) -> - [offline, delivered, displayed, composing, id]; -pp(expire, 2) -> [seconds, stored]; -pp(nick, 1) -> [name]; -pp(address, 5) -> [type, jid, desc, node, delivered]; -pp(addresses, 1) -> [list]; -pp(stanza_id, 2) -> [by, id]; -pp(client_id, 1) -> [id]; -pp(adhoc_actions, 4) -> [execute, prev, next, complete]; -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, 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, - lang]; -pp(bob_data, 4) -> [cid, 'max-age', type, data]; -pp(xcaptcha, 1) -> [xdata]; -pp(media_uri, 2) -> [type, uri]; -pp(media, 3) -> [height, width, uri]; -pp(oob_x, 3) -> [url, desc, sid]; -pp(sic, 3) -> [ip, port, xmlns]; -pp(upload_request, 4) -> - [filename, size, 'content-type', xmlns]; -pp(upload_slot, 3) -> [get, put, xmlns]; -pp(thumbnail, 4) -> [uri, 'media-type', width, height]; -pp(privilege_perm, 2) -> [access, type]; -pp(privilege, 2) -> [perms, forwarded]; -pp(delegated, 2) -> [ns, attrs]; -pp(delegation, 2) -> [delegated, forwarded]; -pp(delegation_query, 2) -> [to, delegate]; -pp(_, _) -> no. - -enc_ps_aff(member) -> <<"member">>; -enc_ps_aff(none) -> <<"none">>; -enc_ps_aff(outcast) -> <<"outcast">>; -enc_ps_aff(owner) -> <<"owner">>; -enc_ps_aff(publisher) -> <<"publisher">>; -enc_ps_aff(publish_only) -> <<"publish-only">>. - -dec_ps_aff(<<"member">>) -> member; -dec_ps_aff(<<"none">>) -> none; -dec_ps_aff(<<"outcast">>) -> outcast; -dec_ps_aff(<<"owner">>) -> owner; -dec_ps_aff(<<"publisher">>) -> publisher; -dec_ps_aff(<<"publish-only">>) -> publish_only. - -enc_version({Maj, Min}) -> - <<(integer_to_binary(Maj))/binary, $., - (integer_to_binary(Min))/binary>>. - -dec_version(S) -> - [Major, Minor] = binary:split(S, <<$.>>), - {binary_to_integer(Major), binary_to_integer(Minor)}. - -enc_host_port(Host) when is_binary(Host) -> Host; -enc_host_port({{_, _, _, _, _, _, _, _} = IPv6, - Port}) -> - enc_host_port({<<$[, (enc_ip(IPv6))/binary, $]>>, - Port}); -enc_host_port({{_, _, _, _} = IPv4, Port}) -> - enc_host_port({enc_ip(IPv4), Port}); -enc_host_port({Host, Port}) -> - <>; -enc_host_port(Addr) -> enc_ip(Addr). - -dec_host_port(<<$[, T/binary>>) -> - [IP, <<$:, Port/binary>>] = binary:split(T, <<$]>>), - {dec_ip(IP), dec_int(Port, 0, 65535)}; -dec_host_port(S) -> - case binary:split(S, <<$:>>) of - [S] -> try dec_ip(S) catch _:_ -> S end; - [S, P] -> - {try dec_ip(S) catch _:_ -> S end, dec_int(P, 0, 65535)} - end. - -enc_ip({0, 0, 0, 0, 0, 65535, A, B}) -> - enc_ip({(A bsr 8) band 255, A band 255, - (B bsr 8) band 255, B band 255}); -enc_ip(Addr) -> list_to_binary(inet_parse:ntoa(Addr)). - -dec_ip(S) -> - {ok, Addr} = inet_parse:address(binary_to_list(S)), - Addr. - -join([], _Sep) -> <<>>; -join([H | T], Sep) -> - <> || X <- T >>/binary>>. - -enc_bool(false) -> <<"false">>; -enc_bool(true) -> <<"true">>. - -dec_bool(<<"false">>) -> false; -dec_bool(<<"0">>) -> false; -dec_bool(<<"true">>) -> true; -dec_bool(<<"1">>) -> true. - -nameprep(S) -> - case jid:nameprep(S) of - error -> erlang:error(badarg); - S1 -> S1 - end. - -resourceprep(R) -> - case jid:resourceprep(R) of - error -> erlang:error(badarg); - R1 -> R1 - end. - -enc_jid(J) -> jid:to_string(J). - -dec_jid(Val) -> - case jid:from_string(Val) of - error -> erlang:error(badarg); - J -> J - end. - -enc_utc(Val) -> xmpp_util:encode_timestamp(Val). - -dec_utc(Val) -> xmpp_util:decode_timestamp(Val). - -enc_tzo({H, M}) -> - Sign = if H >= 0 -> <<>>; - true -> <<"-">> - end, - list_to_binary([Sign, - io_lib:format("~2..0w:~2..0w", [H, M])]). - -dec_tzo(Val) -> - [H1, M1] = str:tokens(Val, <<":">>), - H = binary_to_integer(H1), - M = binary_to_integer(M1), - if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end. - -decode_delegation_query(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - Delegate = decode_delegation_query_els(__TopXMLNS, - __IgnoreEls, _els, []), - To = decode_delegation_query_attrs(__TopXMLNS, _attrs, - undefined), - {delegation_query, To, Delegate}. - -decode_delegation_query_els(__TopXMLNS, __IgnoreEls, [], - Delegate) -> - lists:reverse(Delegate); -decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delegate">>, _attrs, _} = _el | _els], - Delegate) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:delegation:1">> -> - decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_delegate(__TopXMLNS, __IgnoreEls, - _el) - | Delegate]); - <<"urn:xmpp:delegation:1">> -> - decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_delegate(<<"urn:xmpp:delegation:1">>, - __IgnoreEls, _el) - | Delegate]); - _ -> - decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - _els, Delegate) - end; -decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Delegate) -> - decode_delegation_query_els(__TopXMLNS, __IgnoreEls, - _els, Delegate). - -decode_delegation_query_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], _To) -> - decode_delegation_query_attrs(__TopXMLNS, _attrs, _val); -decode_delegation_query_attrs(__TopXMLNS, [_ | _attrs], - To) -> - decode_delegation_query_attrs(__TopXMLNS, _attrs, To); -decode_delegation_query_attrs(__TopXMLNS, [], To) -> - decode_delegation_query_attr_to(__TopXMLNS, To). - -encode_delegation_query({delegation_query, To, - Delegate}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:delegation:1">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_delegation_query_$delegate'(Delegate, - __NewTopXMLNS, [])), - _attrs = encode_delegation_query_attr_to(To, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_delegation_query_$delegate'([], __TopXMLNS, - _acc) -> - _acc; -'encode_delegation_query_$delegate'([Delegate | _els], - __TopXMLNS, _acc) -> - 'encode_delegation_query_$delegate'(_els, __TopXMLNS, - [encode_delegate(Delegate, __TopXMLNS) - | _acc]). - -decode_delegation_query_attr_to(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"to">>, <<"query">>, __TopXMLNS}}); -decode_delegation_query_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"query">>, __TopXMLNS}}); - _res -> _res - end. - -encode_delegation_query_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -decode_delegate(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delegate">>, _attrs, _els}) -> - Namespace = decode_delegate_attrs(__TopXMLNS, _attrs, - undefined), - Namespace. - -decode_delegate_attrs(__TopXMLNS, - [{<<"namespace">>, _val} | _attrs], _Namespace) -> - decode_delegate_attrs(__TopXMLNS, _attrs, _val); -decode_delegate_attrs(__TopXMLNS, [_ | _attrs], - Namespace) -> - decode_delegate_attrs(__TopXMLNS, _attrs, Namespace); -decode_delegate_attrs(__TopXMLNS, [], Namespace) -> - decode_delegate_attr_namespace(__TopXMLNS, Namespace). - -encode_delegate(Namespace, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:delegation:1">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_delegate_attr_namespace(Namespace, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"delegate">>, _attrs, _els}. - -decode_delegate_attr_namespace(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"namespace">>, <<"delegate">>, - __TopXMLNS}}); -decode_delegate_attr_namespace(__TopXMLNS, _val) -> - _val. - -encode_delegate_attr_namespace(_val, _acc) -> - [{<<"namespace">>, _val} | _acc]. - -decode_delegation(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delegation">>, _attrs, _els}) -> - {Forwarded, Delegated} = - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - undefined, []), - {delegation, Delegated, Forwarded}. - -decode_delegation_els(__TopXMLNS, __IgnoreEls, [], - Forwarded, Delegated) -> - {Forwarded, lists:reverse(Delegated)}; -decode_delegation_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delegated">>, _attrs, _} = _el | _els], - Forwarded, Delegated) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:delegation:1">> -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded, - [decode_delegated(__TopXMLNS, __IgnoreEls, _el) - | Delegated]); - <<"urn:xmpp:delegation:1">> -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded, - [decode_delegated(<<"urn:xmpp:delegation:1">>, - __IgnoreEls, _el) - | Delegated]); - _ -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded, Delegated) - end; -decode_delegation_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], - Forwarded, Delegated) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:xmpp:forward:0">> -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - decode_forwarded(<<"urn:xmpp:forward:0">>, - __IgnoreEls, _el), - Delegated); - _ -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded, Delegated) - end; -decode_delegation_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Forwarded, Delegated) -> - decode_delegation_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded, Delegated). - -encode_delegation({delegation, Delegated, Forwarded}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:delegation:1">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_delegation_$forwarded'(Forwarded, - __NewTopXMLNS, - 'encode_delegation_$delegated'(Delegated, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"delegation">>, _attrs, _els}. - -'encode_delegation_$forwarded'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_delegation_$forwarded'(Forwarded, __TopXMLNS, - _acc) -> - [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. - -'encode_delegation_$delegated'([], __TopXMLNS, _acc) -> - _acc; -'encode_delegation_$delegated'([Delegated | _els], - __TopXMLNS, _acc) -> - 'encode_delegation_$delegated'(_els, __TopXMLNS, - [encode_delegated(Delegated, __TopXMLNS) - | _acc]). - -decode_delegated(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delegated">>, _attrs, _els}) -> - Attrs = decode_delegated_els(__TopXMLNS, __IgnoreEls, - _els, []), - Ns = decode_delegated_attrs(__TopXMLNS, _attrs, - undefined), - {delegated, Ns, Attrs}. - -decode_delegated_els(__TopXMLNS, __IgnoreEls, [], - Attrs) -> - lists:reverse(Attrs); -decode_delegated_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"attribute">>, _attrs, _} = _el | _els], - Attrs) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:delegation:1">> -> - decode_delegated_els(__TopXMLNS, __IgnoreEls, _els, - [decode_delegated_attribute(__TopXMLNS, - __IgnoreEls, _el) - | Attrs]); - <<"urn:xmpp:delegation:1">> -> - decode_delegated_els(__TopXMLNS, __IgnoreEls, _els, - [decode_delegated_attribute(<<"urn:xmpp:delegation:1">>, - __IgnoreEls, _el) - | Attrs]); - _ -> - decode_delegated_els(__TopXMLNS, __IgnoreEls, _els, - Attrs) - end; -decode_delegated_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Attrs) -> - decode_delegated_els(__TopXMLNS, __IgnoreEls, _els, - Attrs). - -decode_delegated_attrs(__TopXMLNS, - [{<<"namespace">>, _val} | _attrs], _Ns) -> - decode_delegated_attrs(__TopXMLNS, _attrs, _val); -decode_delegated_attrs(__TopXMLNS, [_ | _attrs], Ns) -> - decode_delegated_attrs(__TopXMLNS, _attrs, Ns); -decode_delegated_attrs(__TopXMLNS, [], Ns) -> - decode_delegated_attr_namespace(__TopXMLNS, Ns). - -encode_delegated({delegated, Ns, Attrs}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:delegation:1">>, [], - __TopXMLNS), - _els = lists:reverse('encode_delegated_$attrs'(Attrs, - __NewTopXMLNS, [])), - _attrs = encode_delegated_attr_namespace(Ns, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"delegated">>, _attrs, _els}. - -'encode_delegated_$attrs'([], __TopXMLNS, _acc) -> _acc; -'encode_delegated_$attrs'([Attrs | _els], __TopXMLNS, - _acc) -> - 'encode_delegated_$attrs'(_els, __TopXMLNS, - [encode_delegated_attribute(Attrs, __TopXMLNS) - | _acc]). - -decode_delegated_attr_namespace(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"namespace">>, <<"delegated">>, - __TopXMLNS}}); -decode_delegated_attr_namespace(__TopXMLNS, _val) -> - _val. - -encode_delegated_attr_namespace(_val, _acc) -> - [{<<"namespace">>, _val} | _acc]. - -decode_delegated_attribute(__TopXMLNS, __IgnoreEls, - {xmlel, <<"attribute">>, _attrs, _els}) -> - Name = decode_delegated_attribute_attrs(__TopXMLNS, - _attrs, undefined), - Name. - -decode_delegated_attribute_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_delegated_attribute_attrs(__TopXMLNS, _attrs, - _val); -decode_delegated_attribute_attrs(__TopXMLNS, - [_ | _attrs], Name) -> - decode_delegated_attribute_attrs(__TopXMLNS, _attrs, - Name); -decode_delegated_attribute_attrs(__TopXMLNS, [], - Name) -> - decode_delegated_attribute_attr_name(__TopXMLNS, Name). - -encode_delegated_attribute(Name, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:delegation:1">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_delegated_attribute_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"attribute">>, _attrs, _els}. - -decode_delegated_attribute_attr_name(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"attribute">>, - __TopXMLNS}}); -decode_delegated_attribute_attr_name(__TopXMLNS, - _val) -> - _val. - -encode_delegated_attribute_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_privilege(__TopXMLNS, __IgnoreEls, - {xmlel, <<"privilege">>, _attrs, _els}) -> - {Perms, Forwarded} = decode_privilege_els(__TopXMLNS, - __IgnoreEls, _els, [], undefined), - {privilege, Perms, Forwarded}. - -decode_privilege_els(__TopXMLNS, __IgnoreEls, [], Perms, - Forwarded) -> - {lists:reverse(Perms), Forwarded}; -decode_privilege_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"perm">>, _attrs, _} = _el | _els], Perms, - Forwarded) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:privilege:1">> -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privilege_perm(__TopXMLNS, __IgnoreEls, - _el) - | Perms], - Forwarded); - <<"urn:xmpp:privilege:1">> -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privilege_perm(<<"urn:xmpp:privilege:1">>, - __IgnoreEls, _el) - | Perms], - Forwarded); - _ -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - Perms, Forwarded) - end; -decode_privilege_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], - Perms, Forwarded) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:xmpp:forward:0">> -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - Perms, - decode_forwarded(<<"urn:xmpp:forward:0">>, - __IgnoreEls, _el)); - _ -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - Perms, Forwarded) - end; -decode_privilege_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Perms, Forwarded) -> - decode_privilege_els(__TopXMLNS, __IgnoreEls, _els, - Perms, Forwarded). - -encode_privilege({privilege, Perms, Forwarded}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:privilege:1">>, [], - __TopXMLNS), - _els = lists:reverse('encode_privilege_$perms'(Perms, - __NewTopXMLNS, - 'encode_privilege_$forwarded'(Forwarded, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"privilege">>, _attrs, _els}. - -'encode_privilege_$perms'([], __TopXMLNS, _acc) -> _acc; -'encode_privilege_$perms'([Perms | _els], __TopXMLNS, - _acc) -> - 'encode_privilege_$perms'(_els, __TopXMLNS, - [encode_privilege_perm(Perms, __TopXMLNS) - | _acc]). - -'encode_privilege_$forwarded'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_privilege_$forwarded'(Forwarded, __TopXMLNS, - _acc) -> - [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. - -decode_privilege_perm(__TopXMLNS, __IgnoreEls, - {xmlel, <<"perm">>, _attrs, _els}) -> - {Access, Type} = decode_privilege_perm_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {privilege_perm, Access, Type}. - -decode_privilege_perm_attrs(__TopXMLNS, - [{<<"access">>, _val} | _attrs], _Access, Type) -> - decode_privilege_perm_attrs(__TopXMLNS, _attrs, _val, - Type); -decode_privilege_perm_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Access, _Type) -> - decode_privilege_perm_attrs(__TopXMLNS, _attrs, Access, - _val); -decode_privilege_perm_attrs(__TopXMLNS, [_ | _attrs], - Access, Type) -> - decode_privilege_perm_attrs(__TopXMLNS, _attrs, Access, - Type); -decode_privilege_perm_attrs(__TopXMLNS, [], Access, - Type) -> - {decode_privilege_perm_attr_access(__TopXMLNS, Access), - decode_privilege_perm_attr_type(__TopXMLNS, Type)}. - -encode_privilege_perm({privilege_perm, Access, Type}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:privilege:1">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_privilege_perm_attr_type(Type, - encode_privilege_perm_attr_access(Access, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"perm">>, _attrs, _els}. - -decode_privilege_perm_attr_access(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"access">>, <<"perm">>, __TopXMLNS}}); -decode_privilege_perm_attr_access(__TopXMLNS, _val) -> - case catch dec_enum(_val, [roster, message, presence]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"access">>, <<"perm">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_privilege_perm_attr_access(_val, _acc) -> - [{<<"access">>, enc_enum(_val)} | _acc]. - -decode_privilege_perm_attr_type(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"perm">>, __TopXMLNS}}); -decode_privilege_perm_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [none, get, set, both, outgoing, roster, - managed_entity]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"perm">>, __TopXMLNS}}); - _res -> _res - end. - -encode_privilege_perm_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_thumbnail(__TopXMLNS, __IgnoreEls, - {xmlel, <<"thumbnail">>, _attrs, _els}) -> - {Uri, Media_type, Width, Height} = - decode_thumbnail_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {thumbnail, Uri, Media_type, Width, Height}. - -decode_thumbnail_attrs(__TopXMLNS, - [{<<"uri">>, _val} | _attrs], _Uri, Media_type, Width, - Height) -> - decode_thumbnail_attrs(__TopXMLNS, _attrs, _val, - Media_type, Width, Height); -decode_thumbnail_attrs(__TopXMLNS, - [{<<"media-type">>, _val} | _attrs], Uri, _Media_type, - Width, Height) -> - decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, _val, - Width, Height); -decode_thumbnail_attrs(__TopXMLNS, - [{<<"width">>, _val} | _attrs], Uri, Media_type, _Width, - Height) -> - decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, - Media_type, _val, Height); -decode_thumbnail_attrs(__TopXMLNS, - [{<<"height">>, _val} | _attrs], Uri, Media_type, Width, - _Height) -> - decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, - Media_type, Width, _val); -decode_thumbnail_attrs(__TopXMLNS, [_ | _attrs], Uri, - Media_type, Width, Height) -> - decode_thumbnail_attrs(__TopXMLNS, _attrs, Uri, - Media_type, Width, Height); -decode_thumbnail_attrs(__TopXMLNS, [], Uri, Media_type, - Width, Height) -> - {decode_thumbnail_attr_uri(__TopXMLNS, Uri), - 'decode_thumbnail_attr_media-type'(__TopXMLNS, - Media_type), - decode_thumbnail_attr_width(__TopXMLNS, Width), - decode_thumbnail_attr_height(__TopXMLNS, Height)}. - -encode_thumbnail({thumbnail, Uri, Media_type, Width, - Height}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:thumbs:1">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_thumbnail_attr_height(Height, - encode_thumbnail_attr_width(Width, - 'encode_thumbnail_attr_media-type'(Media_type, - encode_thumbnail_attr_uri(Uri, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"thumbnail">>, _attrs, _els}. - -decode_thumbnail_attr_uri(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"uri">>, <<"thumbnail">>, - __TopXMLNS}}); -decode_thumbnail_attr_uri(__TopXMLNS, _val) -> _val. - -encode_thumbnail_attr_uri(_val, _acc) -> - [{<<"uri">>, _val} | _acc]. - -'decode_thumbnail_attr_media-type'(__TopXMLNS, - undefined) -> - <<>>; -'decode_thumbnail_attr_media-type'(__TopXMLNS, _val) -> - _val. - -'encode_thumbnail_attr_media-type'(<<>>, _acc) -> _acc; -'encode_thumbnail_attr_media-type'(_val, _acc) -> - [{<<"media-type">>, _val} | _acc]. - -decode_thumbnail_attr_width(__TopXMLNS, undefined) -> - undefined; -decode_thumbnail_attr_width(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"width">>, <<"thumbnail">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_thumbnail_attr_width(undefined, _acc) -> _acc; -encode_thumbnail_attr_width(_val, _acc) -> - [{<<"width">>, enc_int(_val)} | _acc]. - -decode_thumbnail_attr_height(__TopXMLNS, undefined) -> - undefined; -decode_thumbnail_attr_height(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"height">>, <<"thumbnail">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_thumbnail_attr_height(undefined, _acc) -> _acc; -encode_thumbnail_attr_height(_val, _acc) -> - [{<<"height">>, enc_int(_val)} | _acc]. - -decode_upload_slot(__TopXMLNS, __IgnoreEls, - {xmlel, <<"slot">>, _attrs, _els}) -> - {Put, Get} = decode_upload_slot_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - Xmlns = decode_upload_slot_attrs(__TopXMLNS, _attrs, - undefined), - {upload_slot, Get, Put, Xmlns}. - -decode_upload_slot_els(__TopXMLNS, __IgnoreEls, [], Put, - Get) -> - {Put, Get}; -decode_upload_slot_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"get">>, _attrs, _} = _el | _els], Put, - Get) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"eu:siacs:conversations:http:upload">>; - __TopXMLNS == <<"urn:xmpp:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, - decode_upload_get(__TopXMLNS, __IgnoreEls, - _el)); - <<"urn:xmpp:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, - decode_upload_get(<<"urn:xmpp:http:upload">>, - __IgnoreEls, _el)); - <<"eu:siacs:conversations:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, - decode_upload_get(<<"eu:siacs:conversations:http:upload">>, - __IgnoreEls, _el)); - _ -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, Get) - end; -decode_upload_slot_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"put">>, _attrs, _} = _el | _els], Put, - Get) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"eu:siacs:conversations:http:upload">>; - __TopXMLNS == <<"urn:xmpp:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_put(__TopXMLNS, __IgnoreEls, - _el), - Get); - <<"urn:xmpp:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_put(<<"urn:xmpp:http:upload">>, - __IgnoreEls, _el), - Get); - <<"eu:siacs:conversations:http:upload">> -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_put(<<"eu:siacs:conversations:http:upload">>, - __IgnoreEls, _el), - Get); - _ -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, Get) - end; -decode_upload_slot_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Put, Get) -> - decode_upload_slot_els(__TopXMLNS, __IgnoreEls, _els, - Put, Get). - -decode_upload_slot_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_upload_slot_attrs(__TopXMLNS, _attrs, _val); -decode_upload_slot_attrs(__TopXMLNS, [_ | _attrs], - Xmlns) -> - decode_upload_slot_attrs(__TopXMLNS, _attrs, Xmlns); -decode_upload_slot_attrs(__TopXMLNS, [], Xmlns) -> - decode_upload_slot_attr_xmlns(__TopXMLNS, Xmlns). - -encode_upload_slot({upload_slot, Get, Put, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = lists:reverse('encode_upload_slot_$put'(Put, - __NewTopXMLNS, - 'encode_upload_slot_$get'(Get, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"slot">>, _attrs, _els}. - -'encode_upload_slot_$put'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_upload_slot_$put'(Put, __TopXMLNS, _acc) -> - [encode_upload_put(Put, __TopXMLNS) | _acc]. - -'encode_upload_slot_$get'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_upload_slot_$get'(Get, __TopXMLNS, _acc) -> - [encode_upload_get(Get, __TopXMLNS) | _acc]. - -decode_upload_slot_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_upload_slot_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_upload_put(__TopXMLNS, __IgnoreEls, - {xmlel, <<"put">>, _attrs, _els}) -> - Cdata = decode_upload_put_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_upload_put_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_upload_put_cdata(__TopXMLNS, Cdata); -decode_upload_put_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_upload_put_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_upload_put_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_upload_put_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_upload_put(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = encode_upload_put_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"put">>, _attrs, _els}. - -decode_upload_put_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"put">>, __TopXMLNS}}); -decode_upload_put_cdata(__TopXMLNS, _val) -> _val. - -encode_upload_put_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_upload_get(__TopXMLNS, __IgnoreEls, - {xmlel, <<"get">>, _attrs, _els}) -> - Cdata = decode_upload_get_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_upload_get_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_upload_get_cdata(__TopXMLNS, Cdata); -decode_upload_get_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_upload_get_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_upload_get_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_upload_get_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_upload_get(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = encode_upload_get_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"get">>, _attrs, _els}. - -decode_upload_get_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"get">>, __TopXMLNS}}); -decode_upload_get_cdata(__TopXMLNS, _val) -> _val. - -encode_upload_get_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_upload_request(__TopXMLNS, __IgnoreEls, - {xmlel, <<"request">>, _attrs, _els}) -> - {Content_type, Size, Filename} = - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - <<>>, error, error), - Xmlns = decode_upload_request_attrs(__TopXMLNS, _attrs, - undefined), - {upload_request, Filename, Size, Content_type, Xmlns}. - -decode_upload_request_els(__TopXMLNS, __IgnoreEls, [], - Content_type, Size, Filename) -> - {Content_type, - case Size of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"size">>, __TopXMLNS}}); - {value, Size1} -> Size1 - end, - case Filename of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"filename">>, __TopXMLNS}}); - {value, Filename1} -> Filename1 - end}; -decode_upload_request_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"filename">>, _attrs, _} = _el | _els], - Content_type, Size, Filename) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"eu:siacs:conversations:http:upload">>; - __TopXMLNS == <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, - {value, - decode_upload_filename(__TopXMLNS, - __IgnoreEls, _el)}); - <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, - {value, - decode_upload_filename(<<"urn:xmpp:http:upload">>, - __IgnoreEls, _el)}); - <<"eu:siacs:conversations:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, - {value, - decode_upload_filename(<<"eu:siacs:conversations:http:upload">>, - __IgnoreEls, _el)}); - _ -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, Filename) - end; -decode_upload_request_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"size">>, _attrs, _} = _el | _els], - Content_type, Size, Filename) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"eu:siacs:conversations:http:upload">>; - __TopXMLNS == <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, - {value, - decode_upload_size(__TopXMLNS, __IgnoreEls, - _el)}, - Filename); - <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, - {value, - decode_upload_size(<<"urn:xmpp:http:upload">>, - __IgnoreEls, _el)}, - Filename); - <<"eu:siacs:conversations:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, - {value, - decode_upload_size(<<"eu:siacs:conversations:http:upload">>, - __IgnoreEls, _el)}, - Filename); - _ -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, Filename) - end; -decode_upload_request_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"content-type">>, _attrs, _} = _el | _els], - Content_type, Size, Filename) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"eu:siacs:conversations:http:upload">>; - __TopXMLNS == <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_content_type(__TopXMLNS, - __IgnoreEls, - _el), - Size, Filename); - <<"urn:xmpp:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_content_type(<<"urn:xmpp:http:upload">>, - __IgnoreEls, - _el), - Size, Filename); - <<"eu:siacs:conversations:http:upload">> -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - decode_upload_content_type(<<"eu:siacs:conversations:http:upload">>, - __IgnoreEls, - _el), - Size, Filename); - _ -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, Filename) - end; -decode_upload_request_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Content_type, Size, Filename) -> - decode_upload_request_els(__TopXMLNS, __IgnoreEls, _els, - Content_type, Size, Filename). - -decode_upload_request_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_upload_request_attrs(__TopXMLNS, _attrs, _val); -decode_upload_request_attrs(__TopXMLNS, [_ | _attrs], - Xmlns) -> - decode_upload_request_attrs(__TopXMLNS, _attrs, Xmlns); -decode_upload_request_attrs(__TopXMLNS, [], Xmlns) -> - decode_upload_request_attr_xmlns(__TopXMLNS, Xmlns). - -encode_upload_request({upload_request, Filename, Size, - Content_type, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = - lists:reverse('encode_upload_request_$content-type'(Content_type, - __NewTopXMLNS, - 'encode_upload_request_$size'(Size, - __NewTopXMLNS, - 'encode_upload_request_$filename'(Filename, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"request">>, _attrs, _els}. - -'encode_upload_request_$content-type'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_upload_request_$content-type'(Content_type, - __TopXMLNS, _acc) -> - [encode_upload_content_type(Content_type, __TopXMLNS) - | _acc]. - -'encode_upload_request_$size'(Size, __TopXMLNS, _acc) -> - [encode_upload_size(Size, __TopXMLNS) | _acc]. - -'encode_upload_request_$filename'(Filename, __TopXMLNS, - _acc) -> - [encode_upload_filename(Filename, __TopXMLNS) | _acc]. - -decode_upload_request_attr_xmlns(__TopXMLNS, - undefined) -> - <<>>; -decode_upload_request_attr_xmlns(__TopXMLNS, _val) -> - _val. - -decode_upload_content_type(__TopXMLNS, __IgnoreEls, - {xmlel, <<"content-type">>, _attrs, _els}) -> - Cdata = decode_upload_content_type_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_upload_content_type_cdata(__TopXMLNS, Cdata); -decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_upload_content_type_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_upload_content_type(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = encode_upload_content_type_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"content-type">>, _attrs, _els}. - -decode_upload_content_type_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_upload_content_type_cdata(__TopXMLNS, _val) -> - _val. - -encode_upload_content_type_cdata(<<>>, _acc) -> _acc; -encode_upload_content_type_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_upload_size(__TopXMLNS, __IgnoreEls, - {xmlel, <<"size">>, _attrs, _els}) -> - Cdata = decode_upload_size_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_upload_size_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_upload_size_cdata(__TopXMLNS, Cdata); -decode_upload_size_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_upload_size_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_upload_size_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_upload_size_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_upload_size(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = encode_upload_size_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"size">>, _attrs, _els}. - -decode_upload_size_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"size">>, __TopXMLNS}}); -decode_upload_size_cdata(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"size">>, __TopXMLNS}}); - _res -> _res - end. - -encode_upload_size_cdata(_val, _acc) -> - [{xmlcdata, enc_int(_val)} | _acc]. - -decode_upload_filename(__TopXMLNS, __IgnoreEls, - {xmlel, <<"filename">>, _attrs, _els}) -> - Cdata = decode_upload_filename_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_upload_filename_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_upload_filename_cdata(__TopXMLNS, Cdata); -decode_upload_filename_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_upload_filename_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_upload_filename_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_upload_filename_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_upload_filename(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:http:upload">>, - <<"eu:siacs:conversations:http:upload">>], - __TopXMLNS), - _els = encode_upload_filename_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"filename">>, _attrs, _els}. - -decode_upload_filename_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"filename">>, __TopXMLNS}}); -decode_upload_filename_cdata(__TopXMLNS, _val) -> _val. - -encode_upload_filename_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_sic(__TopXMLNS, __IgnoreEls, - {xmlel, <<"address">>, _attrs, _els}) -> - {Ip, Port} = decode_sic_els(__TopXMLNS, __IgnoreEls, - _els, undefined, undefined), - Xmlns = decode_sic_attrs(__TopXMLNS, _attrs, undefined), - {sic, Ip, Port, Xmlns}. - -decode_sic_els(__TopXMLNS, __IgnoreEls, [], Ip, Port) -> - {Ip, Port}; -decode_sic_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ip">>, _attrs, _} = _el | _els], Ip, - Port) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:sic:1">>; - __TopXMLNS == <<"urn:xmpp:sic:0">> -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, - decode_sic_ip(__TopXMLNS, __IgnoreEls, _el), Port); - <<"urn:xmpp:sic:0">> -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, - decode_sic_ip(<<"urn:xmpp:sic:0">>, __IgnoreEls, _el), - Port); - <<"urn:xmpp:sic:1">> -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, - decode_sic_ip(<<"urn:xmpp:sic:1">>, __IgnoreEls, _el), - Port); - _ -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port) - end; -decode_sic_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"port">>, _attrs, _} = _el | _els], Ip, - Port) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:sic:1">> -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, - decode_sip_port(__TopXMLNS, __IgnoreEls, _el)); - <<"urn:xmpp:sic:1">> -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, - decode_sip_port(<<"urn:xmpp:sic:1">>, __IgnoreEls, - _el)); - _ -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port) - end; -decode_sic_els(__TopXMLNS, __IgnoreEls, [_ | _els], Ip, - Port) -> - decode_sic_els(__TopXMLNS, __IgnoreEls, _els, Ip, Port). - -decode_sic_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_sic_attrs(__TopXMLNS, _attrs, _val); -decode_sic_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> - decode_sic_attrs(__TopXMLNS, _attrs, Xmlns); -decode_sic_attrs(__TopXMLNS, [], Xmlns) -> - decode_sic_attr_xmlns(__TopXMLNS, Xmlns). - -encode_sic({sic, Ip, Port, Xmlns}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sic:0">>, - <<"urn:xmpp:sic:1">>], - __TopXMLNS), - _els = lists:reverse('encode_sic_$ip'(Ip, __NewTopXMLNS, - 'encode_sic_$port'(Port, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"address">>, _attrs, _els}. - -'encode_sic_$ip'(undefined, __TopXMLNS, _acc) -> _acc; -'encode_sic_$ip'(Ip, __TopXMLNS, _acc) -> - [encode_sic_ip(Ip, __TopXMLNS) | _acc]. - -'encode_sic_$port'(undefined, __TopXMLNS, _acc) -> _acc; -'encode_sic_$port'(Port, __TopXMLNS, _acc) -> - [encode_sip_port(Port, __TopXMLNS) | _acc]. - -decode_sic_attr_xmlns(__TopXMLNS, undefined) -> <<>>; -decode_sic_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sip_port(__TopXMLNS, __IgnoreEls, - {xmlel, <<"port">>, _attrs, _els}) -> - Cdata = decode_sip_port_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_sip_port_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_sip_port_cdata(__TopXMLNS, Cdata); -decode_sip_port_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_sip_port_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sip_port_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_sip_port_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_sip_port(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sic:1">>, - [], __TopXMLNS), - _els = encode_sip_port_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"port">>, _attrs, _els}. - -decode_sip_port_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"port">>, __TopXMLNS}}); -decode_sip_port_cdata(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, 65535) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"port">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sip_port_cdata(_val, _acc) -> - [{xmlcdata, enc_int(_val)} | _acc]. - -decode_sic_ip(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ip">>, _attrs, _els}) -> - Cdata = decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, - <<>>), - Cdata. - -decode_sic_ip_els(__TopXMLNS, __IgnoreEls, [], Cdata) -> - decode_sic_ip_cdata(__TopXMLNS, Cdata); -decode_sic_ip_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sic_ip_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_sic_ip_els(__TopXMLNS, __IgnoreEls, _els, Cdata). - -encode_sic_ip(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:sic:0">>, - <<"urn:xmpp:sic:1">>], - __TopXMLNS), - _els = encode_sic_ip_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ip">>, _attrs, _els}. - -decode_sic_ip_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"ip">>, __TopXMLNS}}); -decode_sic_ip_cdata(__TopXMLNS, _val) -> - case catch dec_ip(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"ip">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sic_ip_cdata(_val, _acc) -> - [{xmlcdata, enc_ip(_val)} | _acc]. - -decode_oob_x(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Desc, Url} = decode_oob_x_els(__TopXMLNS, __IgnoreEls, - _els, <<>>, error), - Sid = decode_oob_x_attrs(__TopXMLNS, _attrs, undefined), - {oob_x, Url, Desc, Sid}. - -decode_oob_x_els(__TopXMLNS, __IgnoreEls, [], Desc, - Url) -> - {Desc, - case Url of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"url">>, __TopXMLNS}}); - {value, Url1} -> Url1 - end}; -decode_oob_x_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"url">>, _attrs, _} = _el | _els], Desc, - Url) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:oob">> -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, - {value, - decode_oob_url(__TopXMLNS, __IgnoreEls, _el)}); - <<"jabber:x:oob">> -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, - {value, - decode_oob_url(<<"jabber:x:oob">>, __IgnoreEls, - _el)}); - _ -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, - Url) - end; -decode_oob_x_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"desc">>, _attrs, _} = _el | _els], Desc, - Url) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:oob">> -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, - decode_oob_desc(__TopXMLNS, __IgnoreEls, _el), Url); - <<"jabber:x:oob">> -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, - decode_oob_desc(<<"jabber:x:oob">>, __IgnoreEls, - _el), - Url); - _ -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, - Url) - end; -decode_oob_x_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Desc, Url) -> - decode_oob_x_els(__TopXMLNS, __IgnoreEls, _els, Desc, - Url). - -decode_oob_x_attrs(__TopXMLNS, - [{<<"sid">>, _val} | _attrs], _Sid) -> - decode_oob_x_attrs(__TopXMLNS, _attrs, _val); -decode_oob_x_attrs(__TopXMLNS, [_ | _attrs], Sid) -> - decode_oob_x_attrs(__TopXMLNS, _attrs, Sid); -decode_oob_x_attrs(__TopXMLNS, [], Sid) -> - decode_oob_x_attr_sid(__TopXMLNS, Sid). - -encode_oob_x({oob_x, Url, Desc, Sid}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], - __TopXMLNS), - _els = lists:reverse('encode_oob_x_$desc'(Desc, - __NewTopXMLNS, - 'encode_oob_x_$url'(Url, - __NewTopXMLNS, - []))), - _attrs = encode_oob_x_attr_sid(Sid, - enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_oob_x_$desc'(<<>>, __TopXMLNS, _acc) -> _acc; -'encode_oob_x_$desc'(Desc, __TopXMLNS, _acc) -> - [encode_oob_desc(Desc, __TopXMLNS) | _acc]. - -'encode_oob_x_$url'(Url, __TopXMLNS, _acc) -> - [encode_oob_url(Url, __TopXMLNS) | _acc]. - -decode_oob_x_attr_sid(__TopXMLNS, undefined) -> <<>>; -decode_oob_x_attr_sid(__TopXMLNS, _val) -> _val. - -encode_oob_x_attr_sid(<<>>, _acc) -> _acc; -encode_oob_x_attr_sid(_val, _acc) -> - [{<<"sid">>, _val} | _acc]. - -decode_oob_desc(__TopXMLNS, __IgnoreEls, - {xmlel, <<"desc">>, _attrs, _els}) -> - Cdata = decode_oob_desc_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_oob_desc_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_oob_desc_cdata(__TopXMLNS, Cdata); -decode_oob_desc_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_oob_desc_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_oob_desc_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_oob_desc_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_oob_desc(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], - __TopXMLNS), - _els = encode_oob_desc_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"desc">>, _attrs, _els}. - -decode_oob_desc_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_oob_desc_cdata(__TopXMLNS, _val) -> _val. - -encode_oob_desc_cdata(<<>>, _acc) -> _acc; -encode_oob_desc_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_oob_url(__TopXMLNS, __IgnoreEls, - {xmlel, <<"url">>, _attrs, _els}) -> - Cdata = decode_oob_url_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_oob_url_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_oob_url_cdata(__TopXMLNS, Cdata); -decode_oob_url_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_oob_url_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_oob_url_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_oob_url_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_oob_url(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:oob">>, [], - __TopXMLNS), - _els = encode_oob_url_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"url">>, _attrs, _els}. - -decode_oob_url_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"url">>, __TopXMLNS}}); -decode_oob_url_cdata(__TopXMLNS, _val) -> _val. - -encode_oob_url_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_media(__TopXMLNS, __IgnoreEls, - {xmlel, <<"media">>, _attrs, _els}) -> - Uri = decode_media_els(__TopXMLNS, __IgnoreEls, _els, - []), - {Height, Width} = decode_media_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {media, Height, Width, Uri}. - -decode_media_els(__TopXMLNS, __IgnoreEls, [], Uri) -> - lists:reverse(Uri); -decode_media_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"uri">>, _attrs, _} = _el | _els], Uri) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:media-element">> -> - decode_media_els(__TopXMLNS, __IgnoreEls, _els, - [decode_media_uri(__TopXMLNS, __IgnoreEls, _el) - | Uri]); - <<"urn:xmpp:media-element">> -> - decode_media_els(__TopXMLNS, __IgnoreEls, _els, - [decode_media_uri(<<"urn:xmpp:media-element">>, - __IgnoreEls, _el) - | Uri]); - _ -> - decode_media_els(__TopXMLNS, __IgnoreEls, _els, Uri) - end; -decode_media_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Uri) -> - decode_media_els(__TopXMLNS, __IgnoreEls, _els, Uri). - -decode_media_attrs(__TopXMLNS, - [{<<"height">>, _val} | _attrs], _Height, Width) -> - decode_media_attrs(__TopXMLNS, _attrs, _val, Width); -decode_media_attrs(__TopXMLNS, - [{<<"width">>, _val} | _attrs], Height, _Width) -> - decode_media_attrs(__TopXMLNS, _attrs, Height, _val); -decode_media_attrs(__TopXMLNS, [_ | _attrs], Height, - Width) -> - decode_media_attrs(__TopXMLNS, _attrs, Height, Width); -decode_media_attrs(__TopXMLNS, [], Height, Width) -> - {decode_media_attr_height(__TopXMLNS, Height), - decode_media_attr_width(__TopXMLNS, Width)}. - -encode_media({media, Height, Width, Uri}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:media-element">>, [], - __TopXMLNS), - _els = lists:reverse('encode_media_$uri'(Uri, - __NewTopXMLNS, [])), - _attrs = encode_media_attr_width(Width, - encode_media_attr_height(Height, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"media">>, _attrs, _els}. - -'encode_media_$uri'([], __TopXMLNS, _acc) -> _acc; -'encode_media_$uri'([Uri | _els], __TopXMLNS, _acc) -> - 'encode_media_$uri'(_els, __TopXMLNS, - [encode_media_uri(Uri, __TopXMLNS) | _acc]). - -decode_media_attr_height(__TopXMLNS, undefined) -> - undefined; -decode_media_attr_height(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"height">>, <<"media">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_media_attr_height(undefined, _acc) -> _acc; -encode_media_attr_height(_val, _acc) -> - [{<<"height">>, enc_int(_val)} | _acc]. - -decode_media_attr_width(__TopXMLNS, undefined) -> - undefined; -decode_media_attr_width(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, inifinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"width">>, <<"media">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_media_attr_width(undefined, _acc) -> _acc; -encode_media_attr_width(_val, _acc) -> - [{<<"width">>, enc_int(_val)} | _acc]. - -decode_media_uri(__TopXMLNS, __IgnoreEls, - {xmlel, <<"uri">>, _attrs, _els}) -> - Uri = decode_media_uri_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Type = decode_media_uri_attrs(__TopXMLNS, _attrs, - undefined), - {media_uri, Type, Uri}. - -decode_media_uri_els(__TopXMLNS, __IgnoreEls, [], - Uri) -> - decode_media_uri_cdata(__TopXMLNS, Uri); -decode_media_uri_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Uri) -> - decode_media_uri_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_media_uri_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Uri) -> - decode_media_uri_els(__TopXMLNS, __IgnoreEls, _els, - Uri). - -decode_media_uri_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], _Type) -> - decode_media_uri_attrs(__TopXMLNS, _attrs, _val); -decode_media_uri_attrs(__TopXMLNS, [_ | _attrs], - Type) -> - decode_media_uri_attrs(__TopXMLNS, _attrs, Type); -decode_media_uri_attrs(__TopXMLNS, [], Type) -> - decode_media_uri_attr_type(__TopXMLNS, Type). - -encode_media_uri({media_uri, Type, Uri}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:media-element">>, [], - __TopXMLNS), - _els = encode_media_uri_cdata(Uri, []), - _attrs = encode_media_uri_attr_type(Type, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"uri">>, _attrs, _els}. - -decode_media_uri_attr_type(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"uri">>, __TopXMLNS}}); -decode_media_uri_attr_type(__TopXMLNS, _val) -> _val. - -encode_media_uri_attr_type(_val, _acc) -> - [{<<"type">>, _val} | _acc]. - -decode_media_uri_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_media_uri_cdata(__TopXMLNS, _val) -> _val. - -encode_media_uri_cdata(<<>>, _acc) -> _acc; -encode_media_uri_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_captcha(__TopXMLNS, __IgnoreEls, - {xmlel, <<"captcha">>, _attrs, _els}) -> - Xdata = decode_captcha_els(__TopXMLNS, __IgnoreEls, - _els, error), - {xcaptcha, Xdata}. - -decode_captcha_els(__TopXMLNS, __IgnoreEls, [], - Xdata) -> - case Xdata of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"x">>, __TopXMLNS}}); - {value, Xdata1} -> Xdata1 - end; -decode_captcha_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, - {value, - decode_xdata(<<"jabber:x:data">>, __IgnoreEls, - _el)}); - _ -> - decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, Xdata) - end; -decode_captcha_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Xdata) -> - decode_captcha_els(__TopXMLNS, __IgnoreEls, _els, - Xdata). - -encode_captcha({xcaptcha, Xdata}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:captcha">>, - [], __TopXMLNS), - _els = lists:reverse('encode_captcha_$xdata'(Xdata, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"captcha">>, _attrs, _els}. - -'encode_captcha_$xdata'(Xdata, __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_bob_data(__TopXMLNS, __IgnoreEls, - {xmlel, <<"data">>, _attrs, _els}) -> - Data = decode_bob_data_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {Cid, Max_age, Type} = decode_bob_data_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {bob_data, Cid, Max_age, Type, Data}. - -decode_bob_data_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_bob_data_cdata(__TopXMLNS, Data); -decode_bob_data_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_bob_data_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_bob_data_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Data) -> - decode_bob_data_els(__TopXMLNS, __IgnoreEls, _els, - Data). - -decode_bob_data_attrs(__TopXMLNS, - [{<<"cid">>, _val} | _attrs], _Cid, Max_age, Type) -> - decode_bob_data_attrs(__TopXMLNS, _attrs, _val, Max_age, - Type); -decode_bob_data_attrs(__TopXMLNS, - [{<<"max-age">>, _val} | _attrs], Cid, _Max_age, - Type) -> - decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, _val, - Type); -decode_bob_data_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Cid, Max_age, _Type) -> - decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, Max_age, - _val); -decode_bob_data_attrs(__TopXMLNS, [_ | _attrs], Cid, - Max_age, Type) -> - decode_bob_data_attrs(__TopXMLNS, _attrs, Cid, Max_age, - Type); -decode_bob_data_attrs(__TopXMLNS, [], Cid, Max_age, - Type) -> - {decode_bob_data_attr_cid(__TopXMLNS, Cid), - 'decode_bob_data_attr_max-age'(__TopXMLNS, Max_age), - decode_bob_data_attr_type(__TopXMLNS, Type)}. - -encode_bob_data({bob_data, Cid, Max_age, Type, Data}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:bob">>, [], - __TopXMLNS), - _els = encode_bob_data_cdata(Data, []), - _attrs = encode_bob_data_attr_type(Type, - 'encode_bob_data_attr_max-age'(Max_age, - encode_bob_data_attr_cid(Cid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"data">>, _attrs, _els}. - -decode_bob_data_attr_cid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"cid">>, <<"data">>, __TopXMLNS}}); -decode_bob_data_attr_cid(__TopXMLNS, _val) -> _val. - -encode_bob_data_attr_cid(_val, _acc) -> - [{<<"cid">>, _val} | _acc]. - -'decode_bob_data_attr_max-age'(__TopXMLNS, undefined) -> - undefined; -'decode_bob_data_attr_max-age'(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"max-age">>, <<"data">>, - __TopXMLNS}}); - _res -> _res - end. - -'encode_bob_data_attr_max-age'(undefined, _acc) -> _acc; -'encode_bob_data_attr_max-age'(_val, _acc) -> - [{<<"max-age">>, enc_int(_val)} | _acc]. - -decode_bob_data_attr_type(__TopXMLNS, undefined) -> - <<>>; -decode_bob_data_attr_type(__TopXMLNS, _val) -> _val. - -encode_bob_data_attr_type(<<>>, _acc) -> _acc; -encode_bob_data_attr_type(_val, _acc) -> - [{<<"type">>, _val} | _acc]. - -decode_bob_data_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_bob_data_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"data">>, __TopXMLNS}}); - _res -> _res - end. - -encode_bob_data_cdata(<<>>, _acc) -> _acc; -encode_bob_data_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_stream_start(__TopXMLNS, __IgnoreEls, - {xmlel, <<"stream:stream">>, _attrs, _els}) -> - {From, To, Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, - Id} = - decode_stream_start_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined, undefined, - undefined, undefined, undefined), - {stream_start, From, To, Id, Version, Xmlns, - Stream_xmlns, Db_xmlns, Lang}. - -decode_stream_start_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], _From, To, Xmlns, - Stream_xmlns, Db_xmlns, Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, _val, To, - Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], From, _To, Xmlns, - Stream_xmlns, Db_xmlns, Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, - _val, Xmlns, Stream_xmlns, Db_xmlns, Lang, - Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], From, To, _Xmlns, - Stream_xmlns, Db_xmlns, Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - _val, Stream_xmlns, Db_xmlns, Lang, Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"xmlns:stream">>, _val} | _attrs], From, To, - Xmlns, _Stream_xmlns, Db_xmlns, Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, _val, Db_xmlns, Lang, Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"xmlns:db">>, _val} | _attrs], From, To, Xmlns, - Stream_xmlns, _Db_xmlns, Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, Stream_xmlns, _val, Lang, Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], From, To, Xmlns, - Stream_xmlns, Db_xmlns, _Lang, Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, Stream_xmlns, Db_xmlns, _val, Version, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"version">>, _val} | _attrs], From, To, Xmlns, - Stream_xmlns, Db_xmlns, Lang, _Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, Stream_xmlns, Db_xmlns, Lang, _val, Id); -decode_stream_start_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], From, To, Xmlns, - Stream_xmlns, Db_xmlns, Lang, Version, _Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, - _val); -decode_stream_start_attrs(__TopXMLNS, [_ | _attrs], - From, To, Xmlns, Stream_xmlns, Db_xmlns, Lang, - Version, Id) -> - decode_stream_start_attrs(__TopXMLNS, _attrs, From, To, - Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id); -decode_stream_start_attrs(__TopXMLNS, [], From, To, - Xmlns, Stream_xmlns, Db_xmlns, Lang, Version, Id) -> - {decode_stream_start_attr_from(__TopXMLNS, From), - decode_stream_start_attr_to(__TopXMLNS, To), - decode_stream_start_attr_xmlns(__TopXMLNS, Xmlns), - 'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, - Stream_xmlns), - 'decode_stream_start_attr_xmlns:db'(__TopXMLNS, - Db_xmlns), - 'decode_stream_start_attr_xml:lang'(__TopXMLNS, Lang), - decode_stream_start_attr_version(__TopXMLNS, Version), - decode_stream_start_attr_id(__TopXMLNS, Id)}. - -encode_stream_start({stream_start, From, To, Id, - Version, Xmlns, Stream_xmlns, Db_xmlns, Lang}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = [], - _attrs = encode_stream_start_attr_id(Id, - encode_stream_start_attr_version(Version, - 'encode_stream_start_attr_xml:lang'(Lang, - 'encode_stream_start_attr_xmlns:db'(Db_xmlns, - 'encode_stream_start_attr_xmlns:stream'(Stream_xmlns, - encode_stream_start_attr_to(To, - encode_stream_start_attr_from(From, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))))), - {xmlel, <<"stream:stream">>, _attrs, _els}. - -decode_stream_start_attr_from(__TopXMLNS, undefined) -> - undefined; -decode_stream_start_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"stream:stream">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_stream_start_attr_from(undefined, _acc) -> _acc; -encode_stream_start_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_stream_start_attr_to(__TopXMLNS, undefined) -> - undefined; -decode_stream_start_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"stream:stream">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_stream_start_attr_to(undefined, _acc) -> _acc; -encode_stream_start_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -decode_stream_start_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_stream_start_attr_xmlns(__TopXMLNS, _val) -> - _val. - -'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, - undefined) -> - <<>>; -'decode_stream_start_attr_xmlns:stream'(__TopXMLNS, - _val) -> - _val. - -'encode_stream_start_attr_xmlns:stream'(<<>>, _acc) -> - _acc; -'encode_stream_start_attr_xmlns:stream'(_val, _acc) -> - [{<<"xmlns:stream">>, _val} | _acc]. - -'decode_stream_start_attr_xmlns:db'(__TopXMLNS, - undefined) -> - <<>>; -'decode_stream_start_attr_xmlns:db'(__TopXMLNS, _val) -> - _val. - -'encode_stream_start_attr_xmlns:db'(<<>>, _acc) -> _acc; -'encode_stream_start_attr_xmlns:db'(_val, _acc) -> - [{<<"xmlns:db">>, _val} | _acc]. - -'decode_stream_start_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_stream_start_attr_xml:lang'(__TopXMLNS, _val) -> - _val. - -'encode_stream_start_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_stream_start_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_stream_start_attr_version(__TopXMLNS, - undefined) -> - undefined; -decode_stream_start_attr_version(__TopXMLNS, _val) -> - case catch dec_version(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"version">>, <<"stream:stream">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_stream_start_attr_version(undefined, _acc) -> - _acc; -encode_stream_start_attr_version(_val, _acc) -> - [{<<"version">>, enc_version(_val)} | _acc]. - -decode_stream_start_attr_id(__TopXMLNS, undefined) -> - <<>>; -decode_stream_start_attr_id(__TopXMLNS, _val) -> _val. - -encode_stream_start_attr_id(<<>>, _acc) -> _acc; -encode_stream_start_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_handshake(__TopXMLNS, __IgnoreEls, - {xmlel, <<"handshake">>, _attrs, _els}) -> - Data = decode_handshake_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {handshake, Data}. - -decode_handshake_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_handshake_cdata(__TopXMLNS, Data); -decode_handshake_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_handshake_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_handshake_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_handshake_els(__TopXMLNS, __IgnoreEls, _els, - Data). - -encode_handshake({handshake, Data}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:component:accept">>, [], - __TopXMLNS), - _els = encode_handshake_cdata(Data, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"handshake">>, _attrs, _els}. - -decode_handshake_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_handshake_cdata(__TopXMLNS, _val) -> _val. - -encode_handshake_cdata(<<>>, _acc) -> _acc; -encode_handshake_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_db_verify(__TopXMLNS, __IgnoreEls, - {xmlel, <<"db:verify">>, _attrs, _els}) -> - {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, __Els}. - -decode_db_verify_els(__TopXMLNS, __IgnoreEls, [], Key, - __Els) -> - {decode_db_verify_cdata(__TopXMLNS, Key), - lists:reverse(__Els)}; -decode_db_verify_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Key, __Els) -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, - <>, __Els); -decode_db_verify_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Key, __Els) -> - if __IgnoreEls -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - [decode(_el, __TopXMLNS, []) | __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) -> - decode_db_verify_attrs(__TopXMLNS, _attrs, _val, To, Id, - Type); -decode_db_verify_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], From, _To, Id, Type) -> - decode_db_verify_attrs(__TopXMLNS, _attrs, From, _val, - Id, Type); -decode_db_verify_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], From, To, _Id, Type) -> - decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, - _val, Type); -decode_db_verify_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], From, To, Id, _Type) -> - decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, Id, - _val); -decode_db_verify_attrs(__TopXMLNS, [_ | _attrs], From, - To, Id, Type) -> - decode_db_verify_attrs(__TopXMLNS, _attrs, From, To, Id, - Type); -decode_db_verify_attrs(__TopXMLNS, [], From, To, Id, - Type) -> - {decode_db_verify_attr_from(__TopXMLNS, From), - decode_db_verify_attr_to(__TopXMLNS, To), - decode_db_verify_attr_id(__TopXMLNS, Id), - decode_db_verify_attr_type(__TopXMLNS, Type)}. - -encode_db_verify({db_verify, From, To, Id, Type, Key, - __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:server">>, - [], __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _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, - encode_db_verify_attr_from(From, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"db:verify">>, _attrs, _els}. - -decode_db_verify_attr_from(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"from">>, <<"db:verify">>, - __TopXMLNS}}); -decode_db_verify_attr_from(__TopXMLNS, _val) -> - case catch nameprep(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"db:verify">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_verify_attr_from(_val, _acc) -> - [{<<"from">>, nameprep(_val)} | _acc]. - -decode_db_verify_attr_to(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"to">>, <<"db:verify">>, __TopXMLNS}}); -decode_db_verify_attr_to(__TopXMLNS, _val) -> - case catch nameprep(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"db:verify">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_verify_attr_to(_val, _acc) -> - [{<<"to">>, nameprep(_val)} | _acc]. - -decode_db_verify_attr_id(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"db:verify">>, __TopXMLNS}}); -decode_db_verify_attr_id(__TopXMLNS, _val) -> _val. - -encode_db_verify_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_db_verify_attr_type(__TopXMLNS, undefined) -> - undefined; -decode_db_verify_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, [valid, invalid, error]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"db:verify">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_verify_attr_type(undefined, _acc) -> _acc; -encode_db_verify_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_db_verify_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_db_verify_cdata(__TopXMLNS, _val) -> _val. - -encode_db_verify_cdata(<<>>, _acc) -> _acc; -encode_db_verify_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_db_result(__TopXMLNS, __IgnoreEls, - {xmlel, <<"db:result">>, _attrs, _els}) -> - {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, __Els}. - -decode_db_result_els(__TopXMLNS, __IgnoreEls, [], Key, - __Els) -> - {decode_db_result_cdata(__TopXMLNS, Key), - lists:reverse(__Els)}; -decode_db_result_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Key, __Els) -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, - <>, __Els); -decode_db_result_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Key, __Els) -> - if __IgnoreEls -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - __Els) - end - end. - -decode_db_result_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], _From, To, Type) -> - decode_db_result_attrs(__TopXMLNS, _attrs, _val, To, - Type); -decode_db_result_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], From, _To, Type) -> - decode_db_result_attrs(__TopXMLNS, _attrs, From, _val, - Type); -decode_db_result_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], From, To, _Type) -> - decode_db_result_attrs(__TopXMLNS, _attrs, From, To, - _val); -decode_db_result_attrs(__TopXMLNS, [_ | _attrs], From, - To, Type) -> - decode_db_result_attrs(__TopXMLNS, _attrs, From, To, - Type); -decode_db_result_attrs(__TopXMLNS, [], From, To, - Type) -> - {decode_db_result_attr_from(__TopXMLNS, From), - decode_db_result_attr_to(__TopXMLNS, To), - decode_db_result_attr_type(__TopXMLNS, Type)}. - -encode_db_result({db_result, From, To, Type, Key, - __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:server">>, - [], __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _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, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"db:result">>, _attrs, _els}. - -decode_db_result_attr_from(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"from">>, <<"db:result">>, - __TopXMLNS}}); -decode_db_result_attr_from(__TopXMLNS, _val) -> - case catch nameprep(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"db:result">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_result_attr_from(_val, _acc) -> - [{<<"from">>, nameprep(_val)} | _acc]. - -decode_db_result_attr_to(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"to">>, <<"db:result">>, __TopXMLNS}}); -decode_db_result_attr_to(__TopXMLNS, _val) -> - case catch nameprep(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"db:result">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_result_attr_to(_val, _acc) -> - [{<<"to">>, nameprep(_val)} | _acc]. - -decode_db_result_attr_type(__TopXMLNS, undefined) -> - undefined; -decode_db_result_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, [valid, invalid, error]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"db:result">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_db_result_attr_type(undefined, _acc) -> _acc; -encode_db_result_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_db_result_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_db_result_cdata(__TopXMLNS, _val) -> _val. - -encode_db_result_cdata(<<>>, _acc) -> _acc; -encode_db_result_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_adhoc_command(__TopXMLNS, __IgnoreEls, - {xmlel, <<"command">>, _attrs, _els}) -> - {Xdata, Notes, Actions} = - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - undefined, [], undefined), - {Node, Lang, Sid, Status, Action} = - decode_adhoc_command_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, undefined, - undefined), - {adhoc_command, Node, Action, Sid, Status, Lang, - Actions, Notes, Xdata}. - -decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, [], - Xdata, Notes, Actions) -> - {Xdata, lists:reverse(Notes), Actions}; -decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"actions">>, _attrs, _} = _el | _els], - Xdata, Notes, Actions) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, - decode_adhoc_command_actions(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, - decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>, - __IgnoreEls, - _el)); - _ -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, Actions) - end; -decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, - Notes, Actions) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el), - Notes, Actions); - _ -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, Actions) - end; -decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"note">>, _attrs, _} = _el | _els], Xdata, - Notes, Actions) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - [decode_adhoc_command_notes(__TopXMLNS, - __IgnoreEls, _el) - | Notes], - Actions); - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - [decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>, - __IgnoreEls, _el) - | Notes], - Actions); - _ -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, Actions) - end; -decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata, Notes, Actions) -> - decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Notes, Actions). - -decode_adhoc_command_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Lang, Sid, - Status, Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, _val, - Lang, Sid, Status, Action); -decode_adhoc_command_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], Node, _Lang, Sid, - Status, Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, - _val, Sid, Status, Action); -decode_adhoc_command_attrs(__TopXMLNS, - [{<<"sessionid">>, _val} | _attrs], Node, Lang, _Sid, - Status, Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, - Lang, _val, Status, Action); -decode_adhoc_command_attrs(__TopXMLNS, - [{<<"status">>, _val} | _attrs], Node, Lang, Sid, - _Status, Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, - Lang, Sid, _val, Action); -decode_adhoc_command_attrs(__TopXMLNS, - [{<<"action">>, _val} | _attrs], Node, Lang, Sid, - Status, _Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, - Lang, Sid, Status, _val); -decode_adhoc_command_attrs(__TopXMLNS, [_ | _attrs], - Node, Lang, Sid, Status, Action) -> - decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node, - Lang, Sid, Status, Action); -decode_adhoc_command_attrs(__TopXMLNS, [], Node, Lang, - Sid, Status, Action) -> - {decode_adhoc_command_attr_node(__TopXMLNS, Node), - 'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, Lang), - decode_adhoc_command_attr_sessionid(__TopXMLNS, Sid), - decode_adhoc_command_attr_status(__TopXMLNS, Status), - decode_adhoc_command_attr_action(__TopXMLNS, Action)}. - -encode_adhoc_command({adhoc_command, Node, Action, Sid, - Status, Lang, Actions, Notes, Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_adhoc_command_$xdata'(Xdata, - __NewTopXMLNS, - 'encode_adhoc_command_$notes'(Notes, - __NewTopXMLNS, - 'encode_adhoc_command_$actions'(Actions, - __NewTopXMLNS, - [])))), - _attrs = encode_adhoc_command_attr_action(Action, - encode_adhoc_command_attr_status(Status, - encode_adhoc_command_attr_sessionid(Sid, - 'encode_adhoc_command_attr_xml:lang'(Lang, - encode_adhoc_command_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"command">>, _attrs, _els}. - -'encode_adhoc_command_$xdata'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_adhoc_command_$xdata'(Xdata, __TopXMLNS, - _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -'encode_adhoc_command_$notes'([], __TopXMLNS, _acc) -> - _acc; -'encode_adhoc_command_$notes'([Notes | _els], - __TopXMLNS, _acc) -> - 'encode_adhoc_command_$notes'(_els, __TopXMLNS, - [encode_adhoc_command_notes(Notes, __TopXMLNS) - | _acc]). - -'encode_adhoc_command_$actions'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_adhoc_command_$actions'(Actions, __TopXMLNS, - _acc) -> - [encode_adhoc_command_actions(Actions, __TopXMLNS) - | _acc]. - -decode_adhoc_command_attr_node(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"command">>, __TopXMLNS}}); -decode_adhoc_command_attr_node(__TopXMLNS, _val) -> - _val. - -encode_adhoc_command_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_adhoc_command_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_adhoc_command_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_adhoc_command_attr_sessionid(__TopXMLNS, - undefined) -> - <<>>; -decode_adhoc_command_attr_sessionid(__TopXMLNS, _val) -> - _val. - -encode_adhoc_command_attr_sessionid(<<>>, _acc) -> _acc; -encode_adhoc_command_attr_sessionid(_val, _acc) -> - [{<<"sessionid">>, _val} | _acc]. - -decode_adhoc_command_attr_status(__TopXMLNS, - undefined) -> - undefined; -decode_adhoc_command_attr_status(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [canceled, completed, executing]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"status">>, <<"command">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_adhoc_command_attr_status(undefined, _acc) -> - _acc; -encode_adhoc_command_attr_status(_val, _acc) -> - [{<<"status">>, enc_enum(_val)} | _acc]. - -decode_adhoc_command_attr_action(__TopXMLNS, - undefined) -> - execute; -decode_adhoc_command_attr_action(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [cancel, complete, execute, next, prev]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"action">>, <<"command">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_adhoc_command_attr_action(execute, _acc) -> _acc; -encode_adhoc_command_attr_action(_val, _acc) -> - [{<<"action">>, enc_enum(_val)} | _acc]. - -decode_adhoc_command_notes(__TopXMLNS, __IgnoreEls, - {xmlel, <<"note">>, _attrs, _els}) -> - Data = decode_adhoc_command_notes_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Type = decode_adhoc_command_notes_attrs(__TopXMLNS, - _attrs, undefined), - {adhoc_note, Type, Data}. - -decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, - [], Data) -> - decode_adhoc_command_notes_cdata(__TopXMLNS, Data); -decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls, - _els, Data). - -decode_adhoc_command_notes_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], _Type) -> - decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs, - _val); -decode_adhoc_command_notes_attrs(__TopXMLNS, - [_ | _attrs], Type) -> - decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs, - Type); -decode_adhoc_command_notes_attrs(__TopXMLNS, [], - Type) -> - decode_adhoc_command_notes_attr_type(__TopXMLNS, Type). - -encode_adhoc_command_notes({adhoc_note, Type, Data}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = encode_adhoc_command_notes_cdata(Data, []), - _attrs = encode_adhoc_command_notes_attr_type(Type, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"note">>, _attrs, _els}. - -decode_adhoc_command_notes_attr_type(__TopXMLNS, - undefined) -> - info; -decode_adhoc_command_notes_attr_type(__TopXMLNS, - _val) -> - case catch dec_enum(_val, [info, warn, error]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"note">>, __TopXMLNS}}); - _res -> _res - end. - -encode_adhoc_command_notes_attr_type(info, _acc) -> - _acc; -encode_adhoc_command_notes_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_adhoc_command_notes_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_adhoc_command_notes_cdata(__TopXMLNS, _val) -> - _val. - -encode_adhoc_command_notes_cdata(<<>>, _acc) -> _acc; -encode_adhoc_command_notes_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_adhoc_command_actions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"actions">>, _attrs, _els}) -> - {Next, Complete, Prev} = - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, false, false, - false), - Execute = decode_adhoc_command_actions_attrs(__TopXMLNS, - _attrs, undefined), - {adhoc_actions, Execute, Prev, Next, Complete}. - -decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, [], Next, Complete, Prev) -> - {Next, Complete, Prev}; -decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"prev">>, _attrs, _} = _el | _els], - Next, Complete, Prev) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, - decode_adhoc_command_prev(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, - decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>, - __IgnoreEls, - _el)); - _ -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, - Prev) - end; -decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"next">>, _attrs, _} = _el | _els], - Next, Complete, Prev) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, - decode_adhoc_command_next(__TopXMLNS, - __IgnoreEls, - _el), - Complete, Prev); - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, - decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>, - __IgnoreEls, - _el), - Complete, Prev); - _ -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, - Prev) - end; -decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"complete">>, _attrs, _} = _el - | _els], - Next, Complete, Prev) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, - decode_adhoc_command_complete(__TopXMLNS, - __IgnoreEls, - _el), - Prev); - <<"http://jabber.org/protocol/commands">> -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, - decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>, - __IgnoreEls, - _el), - Prev); - _ -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, - Prev) - end; -decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Next, Complete, - Prev) -> - decode_adhoc_command_actions_els(__TopXMLNS, - __IgnoreEls, _els, Next, Complete, Prev). - -decode_adhoc_command_actions_attrs(__TopXMLNS, - [{<<"execute">>, _val} | _attrs], - _Execute) -> - decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs, - _val); -decode_adhoc_command_actions_attrs(__TopXMLNS, - [_ | _attrs], Execute) -> - decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs, - Execute); -decode_adhoc_command_actions_attrs(__TopXMLNS, [], - Execute) -> - decode_adhoc_command_actions_attr_execute(__TopXMLNS, - Execute). - -encode_adhoc_command_actions({adhoc_actions, Execute, - Prev, Next, Complete}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_adhoc_command_actions_$next'(Next, - __NewTopXMLNS, - 'encode_adhoc_command_actions_$complete'(Complete, - __NewTopXMLNS, - 'encode_adhoc_command_actions_$prev'(Prev, - __NewTopXMLNS, - [])))), - _attrs = - encode_adhoc_command_actions_attr_execute(Execute, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"actions">>, _attrs, _els}. - -'encode_adhoc_command_actions_$next'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_adhoc_command_actions_$next'(Next, __TopXMLNS, - _acc) -> - [encode_adhoc_command_next(Next, __TopXMLNS) | _acc]. - -'encode_adhoc_command_actions_$complete'(false, - __TopXMLNS, _acc) -> - _acc; -'encode_adhoc_command_actions_$complete'(Complete, - __TopXMLNS, _acc) -> - [encode_adhoc_command_complete(Complete, __TopXMLNS) - | _acc]. - -'encode_adhoc_command_actions_$prev'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_adhoc_command_actions_$prev'(Prev, __TopXMLNS, - _acc) -> - [encode_adhoc_command_prev(Prev, __TopXMLNS) | _acc]. - -decode_adhoc_command_actions_attr_execute(__TopXMLNS, - undefined) -> - undefined; -decode_adhoc_command_actions_attr_execute(__TopXMLNS, - _val) -> - case catch dec_enum(_val, [complete, next, prev]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"execute">>, <<"actions">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_adhoc_command_actions_attr_execute(undefined, - _acc) -> - _acc; -encode_adhoc_command_actions_attr_execute(_val, _acc) -> - [{<<"execute">>, enc_enum(_val)} | _acc]. - -decode_adhoc_command_complete(__TopXMLNS, __IgnoreEls, - {xmlel, <<"complete">>, _attrs, _els}) -> - true. - -encode_adhoc_command_complete(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"complete">>, _attrs, _els}. - -decode_adhoc_command_next(__TopXMLNS, __IgnoreEls, - {xmlel, <<"next">>, _attrs, _els}) -> - true. - -encode_adhoc_command_next(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"next">>, _attrs, _els}. - -decode_adhoc_command_prev(__TopXMLNS, __IgnoreEls, - {xmlel, <<"prev">>, _attrs, _els}) -> - true. - -encode_adhoc_command_prev(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/commands">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"prev">>, _attrs, _els}. - -decode_client_id(__TopXMLNS, __IgnoreEls, - {xmlel, <<"client-id">>, _attrs, _els}) -> - Id = decode_client_id_attrs(__TopXMLNS, _attrs, - undefined), - {client_id, Id}. - -decode_client_id_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id) -> - decode_client_id_attrs(__TopXMLNS, _attrs, _val); -decode_client_id_attrs(__TopXMLNS, [_ | _attrs], Id) -> - decode_client_id_attrs(__TopXMLNS, _attrs, Id); -decode_client_id_attrs(__TopXMLNS, [], Id) -> - decode_client_id_attr_id(__TopXMLNS, Id). - -encode_client_id({client_id, Id}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sid:0">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_client_id_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"client-id">>, _attrs, _els}. - -decode_client_id_attr_id(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"client-id">>, __TopXMLNS}}); -decode_client_id_attr_id(__TopXMLNS, _val) -> _val. - -encode_client_id_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_stanza_id(__TopXMLNS, __IgnoreEls, - {xmlel, <<"stanza-id">>, _attrs, _els}) -> - {Id, By} = decode_stanza_id_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {stanza_id, By, Id}. - -decode_stanza_id_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, By) -> - decode_stanza_id_attrs(__TopXMLNS, _attrs, _val, By); -decode_stanza_id_attrs(__TopXMLNS, - [{<<"by">>, _val} | _attrs], Id, _By) -> - decode_stanza_id_attrs(__TopXMLNS, _attrs, Id, _val); -decode_stanza_id_attrs(__TopXMLNS, [_ | _attrs], Id, - By) -> - decode_stanza_id_attrs(__TopXMLNS, _attrs, Id, By); -decode_stanza_id_attrs(__TopXMLNS, [], Id, By) -> - {decode_stanza_id_attr_id(__TopXMLNS, Id), - decode_stanza_id_attr_by(__TopXMLNS, By)}. - -encode_stanza_id({stanza_id, By, Id}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:sid:0">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_stanza_id_attr_by(By, - encode_stanza_id_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"stanza-id">>, _attrs, _els}. - -decode_stanza_id_attr_id(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"stanza-id">>, __TopXMLNS}}); -decode_stanza_id_attr_id(__TopXMLNS, _val) -> _val. - -encode_stanza_id_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_stanza_id_attr_by(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"by">>, <<"stanza-id">>, __TopXMLNS}}); -decode_stanza_id_attr_by(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"by">>, <<"stanza-id">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_stanza_id_attr_by(_val, _acc) -> - [{<<"by">>, enc_jid(_val)} | _acc]. - -decode_addresses(__TopXMLNS, __IgnoreEls, - {xmlel, <<"addresses">>, _attrs, _els}) -> - List = decode_addresses_els(__TopXMLNS, __IgnoreEls, - _els, []), - {addresses, List}. - -decode_addresses_els(__TopXMLNS, __IgnoreEls, [], - List) -> - lists:reverse(List); -decode_addresses_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"address">>, _attrs, _} = _el | _els], - List) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/address">> -> - decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, - [decode_address(__TopXMLNS, __IgnoreEls, _el) - | List]); - <<"http://jabber.org/protocol/address">> -> - decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, - [decode_address(<<"http://jabber.org/protocol/address">>, - __IgnoreEls, _el) - | List]); - _ -> - decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, - List) - end; -decode_addresses_els(__TopXMLNS, __IgnoreEls, - [_ | _els], List) -> - decode_addresses_els(__TopXMLNS, __IgnoreEls, _els, - List). - -encode_addresses({addresses, List}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/address">>, - [], __TopXMLNS), - _els = lists:reverse('encode_addresses_$list'(List, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"addresses">>, _attrs, _els}. - -'encode_addresses_$list'([], __TopXMLNS, _acc) -> _acc; -'encode_addresses_$list'([List | _els], __TopXMLNS, - _acc) -> - 'encode_addresses_$list'(_els, __TopXMLNS, - [encode_address(List, __TopXMLNS) | _acc]). - -decode_address(__TopXMLNS, __IgnoreEls, - {xmlel, <<"address">>, _attrs, _els}) -> - {Type, Jid, Desc, Node, Delivered} = - decode_address_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined, undefined), - {address, Type, Jid, Desc, Node, Delivered}. - -decode_address_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], _Type, Jid, Desc, Node, - Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, _val, Jid, - Desc, Node, Delivered); -decode_address_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Type, _Jid, Desc, Node, - Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, Type, _val, - Desc, Node, Delivered); -decode_address_attrs(__TopXMLNS, - [{<<"desc">>, _val} | _attrs], Type, Jid, _Desc, Node, - Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, - _val, Node, Delivered); -decode_address_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Type, Jid, Desc, _Node, - Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, - Desc, _val, Delivered); -decode_address_attrs(__TopXMLNS, - [{<<"delivered">>, _val} | _attrs], Type, Jid, Desc, - Node, _Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, - Desc, Node, _val); -decode_address_attrs(__TopXMLNS, [_ | _attrs], Type, - Jid, Desc, Node, Delivered) -> - decode_address_attrs(__TopXMLNS, _attrs, Type, Jid, - Desc, Node, Delivered); -decode_address_attrs(__TopXMLNS, [], Type, Jid, Desc, - Node, Delivered) -> - {decode_address_attr_type(__TopXMLNS, Type), - decode_address_attr_jid(__TopXMLNS, Jid), - decode_address_attr_desc(__TopXMLNS, Desc), - decode_address_attr_node(__TopXMLNS, Node), - decode_address_attr_delivered(__TopXMLNS, Delivered)}. - -encode_address({address, Type, Jid, Desc, Node, - Delivered}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/address">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_address_attr_delivered(Delivered, - encode_address_attr_node(Node, - encode_address_attr_desc(Desc, - encode_address_attr_jid(Jid, - encode_address_attr_type(Type, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"address">>, _attrs, _els}. - -decode_address_attr_type(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"address">>, __TopXMLNS}}); -decode_address_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [bcc, cc, noreply, ofrom, replyroom, replyto, to]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"address">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_address_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_address_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_address_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"address">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_address_attr_jid(undefined, _acc) -> _acc; -encode_address_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_address_attr_desc(__TopXMLNS, undefined) -> <<>>; -decode_address_attr_desc(__TopXMLNS, _val) -> _val. - -encode_address_attr_desc(<<>>, _acc) -> _acc; -encode_address_attr_desc(_val, _acc) -> - [{<<"desc">>, _val} | _acc]. - -decode_address_attr_node(__TopXMLNS, undefined) -> <<>>; -decode_address_attr_node(__TopXMLNS, _val) -> _val. - -encode_address_attr_node(<<>>, _acc) -> _acc; -encode_address_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_address_attr_delivered(__TopXMLNS, undefined) -> - undefined; -decode_address_attr_delivered(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"delivered">>, <<"address">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_address_attr_delivered(undefined, _acc) -> _acc; -encode_address_attr_delivered(_val, _acc) -> - [{<<"delivered">>, enc_bool(_val)} | _acc]. - -decode_nick(__TopXMLNS, __IgnoreEls, - {xmlel, <<"nick">>, _attrs, _els}) -> - Name = decode_nick_els(__TopXMLNS, __IgnoreEls, _els, - <<>>), - {nick, Name}. - -decode_nick_els(__TopXMLNS, __IgnoreEls, [], Name) -> - decode_nick_cdata(__TopXMLNS, Name); -decode_nick_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Name) -> - decode_nick_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_nick_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Name) -> - decode_nick_els(__TopXMLNS, __IgnoreEls, _els, Name). - -encode_nick({nick, Name}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/nick">>, - [], __TopXMLNS), - _els = encode_nick_cdata(Name, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"nick">>, _attrs, _els}. - -decode_nick_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"nick">>, __TopXMLNS}}); -decode_nick_cdata(__TopXMLNS, _val) -> _val. - -encode_nick_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_expire(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Seconds, Stored} = decode_expire_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {expire, Seconds, Stored}. - -decode_expire_attrs(__TopXMLNS, - [{<<"seconds">>, _val} | _attrs], _Seconds, Stored) -> - decode_expire_attrs(__TopXMLNS, _attrs, _val, Stored); -decode_expire_attrs(__TopXMLNS, - [{<<"stored">>, _val} | _attrs], Seconds, _Stored) -> - decode_expire_attrs(__TopXMLNS, _attrs, Seconds, _val); -decode_expire_attrs(__TopXMLNS, [_ | _attrs], Seconds, - Stored) -> - decode_expire_attrs(__TopXMLNS, _attrs, Seconds, - Stored); -decode_expire_attrs(__TopXMLNS, [], Seconds, Stored) -> - {decode_expire_attr_seconds(__TopXMLNS, Seconds), - decode_expire_attr_stored(__TopXMLNS, Stored)}. - -encode_expire({expire, Seconds, Stored}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:expire">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_expire_attr_stored(Stored, - encode_expire_attr_seconds(Seconds, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"x">>, _attrs, _els}. - -decode_expire_attr_seconds(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"seconds">>, <<"x">>, __TopXMLNS}}); -decode_expire_attr_seconds(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"seconds">>, <<"x">>, __TopXMLNS}}); - _res -> _res - end. - -encode_expire_attr_seconds(_val, _acc) -> - [{<<"seconds">>, enc_int(_val)} | _acc]. - -decode_expire_attr_stored(__TopXMLNS, undefined) -> - undefined; -decode_expire_attr_stored(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"stored">>, <<"x">>, __TopXMLNS}}); - _res -> _res - end. - -encode_expire_attr_stored(undefined, _acc) -> _acc; -encode_expire_attr_stored(_val, _acc) -> - [{<<"stored">>, enc_int(_val)} | _acc]. - -decode_xevent(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Id, Displayed, Delivered, Offline, Composing} = - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, - undefined, false, false, false, false), - {xevent, Offline, Delivered, Displayed, Composing, Id}. - -decode_xevent_els(__TopXMLNS, __IgnoreEls, [], Id, - Displayed, Delivered, Offline, Composing) -> - {Id, Displayed, Delivered, Offline, Composing}; -decode_xevent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"offline">>, _attrs, _} = _el | _els], Id, - Displayed, Delivered, Offline, Composing) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, - decode_xevent_offline(__TopXMLNS, __IgnoreEls, _el), - Composing); - <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, - decode_xevent_offline(<<"jabber:x:event">>, - __IgnoreEls, _el), - Composing); - _ -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing) - end; -decode_xevent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delivered">>, _attrs, _} = _el | _els], Id, - Displayed, Delivered, Offline, Composing) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, - decode_xevent_delivered(__TopXMLNS, __IgnoreEls, - _el), - Offline, Composing); - <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, - decode_xevent_delivered(<<"jabber:x:event">>, - __IgnoreEls, _el), - Offline, Composing); - _ -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing) - end; -decode_xevent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"displayed">>, _attrs, _} = _el | _els], Id, - Displayed, Delivered, Offline, Composing) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - decode_xevent_displayed(__TopXMLNS, __IgnoreEls, - _el), - Delivered, Offline, Composing); - <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - decode_xevent_displayed(<<"jabber:x:event">>, - __IgnoreEls, _el), - Delivered, Offline, Composing); - _ -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing) - end; -decode_xevent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"composing">>, _attrs, _} = _el | _els], Id, - Displayed, Delivered, Offline, Composing) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, - decode_xevent_composing(__TopXMLNS, __IgnoreEls, - _el)); - <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, - decode_xevent_composing(<<"jabber:x:event">>, - __IgnoreEls, _el)); - _ -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing) - end; -decode_xevent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"id">>, _attrs, _} = _el | _els], Id, - Displayed, Delivered, Offline, Composing) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, - decode_xevent_id(__TopXMLNS, __IgnoreEls, _el), - Displayed, Delivered, Offline, Composing); - <<"jabber:x:event">> -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, - decode_xevent_id(<<"jabber:x:event">>, __IgnoreEls, - _el), - Displayed, Delivered, Offline, Composing); - _ -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing) - end; -decode_xevent_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Id, Displayed, Delivered, Offline, Composing) -> - decode_xevent_els(__TopXMLNS, __IgnoreEls, _els, Id, - Displayed, Delivered, Offline, Composing). - -encode_xevent({xevent, Offline, Delivered, Displayed, - Composing, Id}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = lists:reverse('encode_xevent_$id'(Id, - __NewTopXMLNS, - 'encode_xevent_$displayed'(Displayed, - __NewTopXMLNS, - 'encode_xevent_$delivered'(Delivered, - __NewTopXMLNS, - 'encode_xevent_$offline'(Offline, - __NewTopXMLNS, - 'encode_xevent_$composing'(Composing, - __NewTopXMLNS, - [])))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_xevent_$id'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_xevent_$id'(Id, __TopXMLNS, _acc) -> - [encode_xevent_id(Id, __TopXMLNS) | _acc]. - -'encode_xevent_$displayed'(false, __TopXMLNS, _acc) -> - _acc; -'encode_xevent_$displayed'(Displayed, __TopXMLNS, - _acc) -> - [encode_xevent_displayed(Displayed, __TopXMLNS) | _acc]. - -'encode_xevent_$delivered'(false, __TopXMLNS, _acc) -> - _acc; -'encode_xevent_$delivered'(Delivered, __TopXMLNS, - _acc) -> - [encode_xevent_delivered(Delivered, __TopXMLNS) | _acc]. - -'encode_xevent_$offline'(false, __TopXMLNS, _acc) -> - _acc; -'encode_xevent_$offline'(Offline, __TopXMLNS, _acc) -> - [encode_xevent_offline(Offline, __TopXMLNS) | _acc]. - -'encode_xevent_$composing'(false, __TopXMLNS, _acc) -> - _acc; -'encode_xevent_$composing'(Composing, __TopXMLNS, - _acc) -> - [encode_xevent_composing(Composing, __TopXMLNS) | _acc]. - -decode_xevent_id(__TopXMLNS, __IgnoreEls, - {xmlel, <<"id">>, _attrs, _els}) -> - Cdata = decode_xevent_id_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_xevent_id_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_xevent_id_cdata(__TopXMLNS, Cdata); -decode_xevent_id_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_xevent_id_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_xevent_id_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_xevent_id_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_xevent_id(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = encode_xevent_id_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"id">>, _attrs, _els}. - -decode_xevent_id_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_xevent_id_cdata(__TopXMLNS, _val) -> _val. - -encode_xevent_id_cdata(<<>>, _acc) -> _acc; -encode_xevent_id_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_xevent_composing(__TopXMLNS, __IgnoreEls, - {xmlel, <<"composing">>, _attrs, _els}) -> - true. - -encode_xevent_composing(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"composing">>, _attrs, _els}. - -decode_xevent_displayed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"displayed">>, _attrs, _els}) -> - true. - -encode_xevent_displayed(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"displayed">>, _attrs, _els}. - -decode_xevent_delivered(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delivered">>, _attrs, _els}) -> - true. - -encode_xevent_delivered(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"delivered">>, _attrs, _els}. - -decode_xevent_offline(__TopXMLNS, __IgnoreEls, - {xmlel, <<"offline">>, _attrs, _els}) -> - true. - -encode_xevent_offline(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:event">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"offline">>, _attrs, _els}. - -decode_search(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Xdata, Items, Instructions, Last, First, Nick, Email} = - decode_search_els(__TopXMLNS, __IgnoreEls, _els, - undefined, [], undefined, undefined, undefined, - undefined, undefined), - {search, Instructions, First, Last, Nick, Email, Items, - Xdata}. - -decode_search_els(__TopXMLNS, __IgnoreEls, [], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - {Xdata, lists:reverse(Items), Instructions, Last, First, - Nick, Email}; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], - Xdata, Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, - decode_search_instructions(__TopXMLNS, __IgnoreEls, - _el), - Last, First, Nick, Email); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, - decode_search_instructions(<<"jabber:iq:search">>, - __IgnoreEls, _el), - Last, First, Nick, Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"first">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, - decode_search_first(__TopXMLNS, __IgnoreEls, _el), - Nick, Email); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, - decode_search_first(<<"jabber:iq:search">>, - __IgnoreEls, _el), - Nick, Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"last">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, - decode_search_last(__TopXMLNS, __IgnoreEls, _el), - First, Nick, Email); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, - decode_search_last(<<"jabber:iq:search">>, - __IgnoreEls, _el), - First, Nick, Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, - decode_search_nick(__TopXMLNS, __IgnoreEls, _el), - Email); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, - decode_search_nick(<<"jabber:iq:search">>, - __IgnoreEls, _el), - Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"email">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, - decode_search_email(__TopXMLNS, __IgnoreEls, _el)); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, - decode_search_email(<<"jabber:iq:search">>, - __IgnoreEls, _el)); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - [decode_search_item(__TopXMLNS, __IgnoreEls, _el) - | Items], - Instructions, Last, First, Nick, Email); - <<"jabber:iq:search">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - [decode_search_item(<<"jabber:iq:search">>, - __IgnoreEls, _el) - | Items], - Instructions, Last, First, Nick, Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, - Items, Instructions, Last, First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, __IgnoreEls, _el), - Items, Instructions, Last, First, Nick, Email); - _ -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email) - end; -decode_search_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Xdata, Items, Instructions, Last, First, Nick, Email) -> - decode_search_els(__TopXMLNS, __IgnoreEls, _els, Xdata, - Items, Instructions, Last, First, Nick, Email). - -encode_search({search, Instructions, First, Last, Nick, - Email, Items, Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = lists:reverse('encode_search_$xdata'(Xdata, - __NewTopXMLNS, - 'encode_search_$items'(Items, - __NewTopXMLNS, - 'encode_search_$instructions'(Instructions, - __NewTopXMLNS, - 'encode_search_$last'(Last, - __NewTopXMLNS, - 'encode_search_$first'(First, - __NewTopXMLNS, - 'encode_search_$nick'(Nick, - __NewTopXMLNS, - 'encode_search_$email'(Email, - __NewTopXMLNS, - [])))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_search_$xdata'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_search_$xdata'(Xdata, __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -'encode_search_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_search_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_search_$items'(_els, __TopXMLNS, - [encode_search_item(Items, __TopXMLNS) | _acc]). - -'encode_search_$instructions'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_search_$instructions'(Instructions, __TopXMLNS, - _acc) -> - [encode_search_instructions(Instructions, __TopXMLNS) - | _acc]. - -'encode_search_$last'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_search_$last'(Last, __TopXMLNS, _acc) -> - [encode_search_last(Last, __TopXMLNS) | _acc]. - -'encode_search_$first'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_search_$first'(First, __TopXMLNS, _acc) -> - [encode_search_first(First, __TopXMLNS) | _acc]. - -'encode_search_$nick'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_search_$nick'(Nick, __TopXMLNS, _acc) -> - [encode_search_nick(Nick, __TopXMLNS) | _acc]. - -'encode_search_$email'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_search_$email'(Email, __TopXMLNS, _acc) -> - [encode_search_email(Email, __TopXMLNS) | _acc]. - -decode_search_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Last, First, Nick, Email} = - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined), - Jid = decode_search_item_attrs(__TopXMLNS, _attrs, - undefined), - {search_item, Jid, First, Last, Nick, Email}. - -decode_search_item_els(__TopXMLNS, __IgnoreEls, [], - Last, First, Nick, Email) -> - {Last, First, Nick, Email}; -decode_search_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"first">>, _attrs, _} = _el | _els], Last, - First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, - decode_search_first(__TopXMLNS, __IgnoreEls, - _el), - Nick, Email); - <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, - decode_search_first(<<"jabber:iq:search">>, - __IgnoreEls, _el), - Nick, Email); - _ -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, Email) - end; -decode_search_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"last">>, _attrs, _} = _el | _els], Last, - First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_search_last(__TopXMLNS, __IgnoreEls, - _el), - First, Nick, Email); - <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_search_last(<<"jabber:iq:search">>, - __IgnoreEls, _el), - First, Nick, Email); - _ -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, Email) - end; -decode_search_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Last, - First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, - decode_search_nick(__TopXMLNS, __IgnoreEls, - _el), - Email); - <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, - decode_search_nick(<<"jabber:iq:search">>, - __IgnoreEls, _el), - Email); - _ -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, Email) - end; -decode_search_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"email">>, _attrs, _} = _el | _els], Last, - First, Nick, Email) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, - decode_search_email(__TopXMLNS, __IgnoreEls, - _el)); - <<"jabber:iq:search">> -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, - decode_search_email(<<"jabber:iq:search">>, - __IgnoreEls, _el)); - _ -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, Email) - end; -decode_search_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Last, First, Nick, Email) -> - decode_search_item_els(__TopXMLNS, __IgnoreEls, _els, - Last, First, Nick, Email). - -decode_search_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_search_item_attrs(__TopXMLNS, _attrs, _val); -decode_search_item_attrs(__TopXMLNS, [_ | _attrs], - Jid) -> - decode_search_item_attrs(__TopXMLNS, _attrs, Jid); -decode_search_item_attrs(__TopXMLNS, [], Jid) -> - decode_search_item_attr_jid(__TopXMLNS, Jid). - -encode_search_item({search_item, Jid, First, Last, Nick, - Email}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = lists:reverse('encode_search_item_$last'(Last, - __NewTopXMLNS, - 'encode_search_item_$first'(First, - __NewTopXMLNS, - 'encode_search_item_$nick'(Nick, - __NewTopXMLNS, - 'encode_search_item_$email'(Email, - __NewTopXMLNS, - []))))), - _attrs = encode_search_item_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_search_item_$last'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_search_item_$last'(Last, __TopXMLNS, _acc) -> - [encode_search_last(Last, __TopXMLNS) | _acc]. - -'encode_search_item_$first'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_search_item_$first'(First, __TopXMLNS, _acc) -> - [encode_search_first(First, __TopXMLNS) | _acc]. - -'encode_search_item_$nick'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_search_item_$nick'(Nick, __TopXMLNS, _acc) -> - [encode_search_nick(Nick, __TopXMLNS) | _acc]. - -'encode_search_item_$email'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_search_item_$email'(Email, __TopXMLNS, _acc) -> - [encode_search_email(Email, __TopXMLNS) | _acc]. - -decode_search_item_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); -decode_search_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_search_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_search_email(__TopXMLNS, __IgnoreEls, - {xmlel, <<"email">>, _attrs, _els}) -> - Cdata = decode_search_email_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_search_email_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_search_email_cdata(__TopXMLNS, Cdata); -decode_search_email_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_search_email_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_search_email_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_search_email_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_search_email(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = encode_search_email_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"email">>, _attrs, _els}. - -decode_search_email_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_search_email_cdata(__TopXMLNS, _val) -> _val. - -encode_search_email_cdata(<<>>, _acc) -> _acc; -encode_search_email_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_search_nick(__TopXMLNS, __IgnoreEls, - {xmlel, <<"nick">>, _attrs, _els}) -> - Cdata = decode_search_nick_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_search_nick_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_search_nick_cdata(__TopXMLNS, Cdata); -decode_search_nick_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_search_nick_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_search_nick_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_search_nick_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_search_nick(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = encode_search_nick_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"nick">>, _attrs, _els}. - -decode_search_nick_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_search_nick_cdata(__TopXMLNS, _val) -> _val. - -encode_search_nick_cdata(<<>>, _acc) -> _acc; -encode_search_nick_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_search_last(__TopXMLNS, __IgnoreEls, - {xmlel, <<"last">>, _attrs, _els}) -> - Cdata = decode_search_last_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_search_last_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_search_last_cdata(__TopXMLNS, Cdata); -decode_search_last_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_search_last_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_search_last_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_search_last_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_search_last(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = encode_search_last_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"last">>, _attrs, _els}. - -decode_search_last_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_search_last_cdata(__TopXMLNS, _val) -> _val. - -encode_search_last_cdata(<<>>, _acc) -> _acc; -encode_search_last_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_search_first(__TopXMLNS, __IgnoreEls, - {xmlel, <<"first">>, _attrs, _els}) -> - Cdata = decode_search_first_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_search_first_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_search_first_cdata(__TopXMLNS, Cdata); -decode_search_first_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_search_first_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_search_first_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_search_first_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_search_first(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = encode_search_first_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"first">>, _attrs, _els}. - -decode_search_first_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_search_first_cdata(__TopXMLNS, _val) -> _val. - -encode_search_first_cdata(<<>>, _acc) -> _acc; -encode_search_first_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_search_instructions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"instructions">>, _attrs, _els}) -> - Cdata = decode_search_instructions_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_search_instructions_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_search_instructions_cdata(__TopXMLNS, Cdata); -decode_search_instructions_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_search_instructions_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_search_instructions_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_search_instructions_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_search_instructions(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:search">>, - [], __TopXMLNS), - _els = encode_search_instructions_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"instructions">>, _attrs, _els}. - -decode_search_instructions_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_search_instructions_cdata(__TopXMLNS, _val) -> - _val. - -encode_search_instructions_cdata(<<>>, _acc) -> _acc; -encode_search_instructions_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_hint_no_permanent_storage(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"no-permanent-storage">>, _attrs, - _els}) -> - {hint, 'no-permanent-storage'}. - -encode_hint_no_permanent_storage({hint, - 'no-permanent-storage'}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"no-permanent-storage">>, _attrs, _els}. - -decode_hint_no_permanent_store(__TopXMLNS, __IgnoreEls, - {xmlel, <<"no-permanent-store">>, _attrs, - _els}) -> - {hint, 'no-permanent-store'}. - -encode_hint_no_permanent_store({hint, - 'no-permanent-store'}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"no-permanent-store">>, _attrs, _els}. - -decode_hint_store(__TopXMLNS, __IgnoreEls, - {xmlel, <<"store">>, _attrs, _els}) -> - {hint, store}. - -encode_hint_store({hint, store}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"store">>, _attrs, _els}. - -decode_hint_no_storage(__TopXMLNS, __IgnoreEls, - {xmlel, <<"no-storage">>, _attrs, _els}) -> - {hint, 'no-storage'}. - -encode_hint_no_storage({hint, 'no-storage'}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"no-storage">>, _attrs, _els}. - -decode_hint_no_store(__TopXMLNS, __IgnoreEls, - {xmlel, <<"no-store">>, _attrs, _els}) -> - {hint, 'no-store'}. - -encode_hint_no_store({hint, 'no-store'}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"no-store">>, _attrs, _els}. - -decode_hint_no_copy(__TopXMLNS, __IgnoreEls, - {xmlel, <<"no-copy">>, _attrs, _els}) -> - {hint, 'no-copy'}. - -encode_hint_no_copy({hint, 'no-copy'}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:hints">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"no-copy">>, _attrs, _els}. - -decode_mix_participant(__TopXMLNS, __IgnoreEls, - {xmlel, <<"participant">>, _attrs, _els}) -> - {Jid, Nick} = decode_mix_participant_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {mix_participant, Jid, Nick}. - -decode_mix_participant_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> - decode_mix_participant_attrs(__TopXMLNS, _attrs, _val, - Nick); -decode_mix_participant_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> - decode_mix_participant_attrs(__TopXMLNS, _attrs, Jid, - _val); -decode_mix_participant_attrs(__TopXMLNS, [_ | _attrs], - Jid, Nick) -> - decode_mix_participant_attrs(__TopXMLNS, _attrs, Jid, - Nick); -decode_mix_participant_attrs(__TopXMLNS, [], Jid, - Nick) -> - {decode_mix_participant_attr_jid(__TopXMLNS, Jid), - decode_mix_participant_attr_nick(__TopXMLNS, Nick)}. - -encode_mix_participant({mix_participant, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_mix_participant_attr_nick(Nick, - encode_mix_participant_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"participant">>, _attrs, _els}. - -decode_mix_participant_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"participant">>, - __TopXMLNS}}); -decode_mix_participant_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"participant">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_mix_participant_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_mix_participant_attr_nick(__TopXMLNS, - undefined) -> - <<>>; -decode_mix_participant_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_mix_participant_attr_nick(<<>>, _acc) -> _acc; -encode_mix_participant_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_mix_leave(__TopXMLNS, __IgnoreEls, - {xmlel, <<"leave">>, _attrs, _els}) -> - {mix_leave}. - -encode_mix_leave({mix_leave}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"leave">>, _attrs, _els}. - -decode_mix_join(__TopXMLNS, __IgnoreEls, - {xmlel, <<"join">>, _attrs, _els}) -> - Subscribe = decode_mix_join_els(__TopXMLNS, __IgnoreEls, - _els, []), - Jid = decode_mix_join_attrs(__TopXMLNS, _attrs, - undefined), - {mix_join, Jid, Subscribe}. - -decode_mix_join_els(__TopXMLNS, __IgnoreEls, [], - Subscribe) -> - lists:reverse(Subscribe); -decode_mix_join_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], - Subscribe) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mix:0">> -> - decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mix_subscribe(__TopXMLNS, __IgnoreEls, - _el) - | Subscribe]); - <<"urn:xmpp:mix:0">> -> - decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mix_subscribe(<<"urn:xmpp:mix:0">>, - __IgnoreEls, _el) - | Subscribe]); - _ -> - decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, - Subscribe) - end; -decode_mix_join_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Subscribe) -> - decode_mix_join_els(__TopXMLNS, __IgnoreEls, _els, - Subscribe). - -decode_mix_join_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_mix_join_attrs(__TopXMLNS, _attrs, _val); -decode_mix_join_attrs(__TopXMLNS, [_ | _attrs], Jid) -> - decode_mix_join_attrs(__TopXMLNS, _attrs, Jid); -decode_mix_join_attrs(__TopXMLNS, [], Jid) -> - decode_mix_join_attr_jid(__TopXMLNS, Jid). - -encode_mix_join({mix_join, Jid, Subscribe}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_mix_join_$subscribe'(Subscribe, - __NewTopXMLNS, [])), - _attrs = encode_mix_join_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"join">>, _attrs, _els}. - -'encode_mix_join_$subscribe'([], __TopXMLNS, _acc) -> - _acc; -'encode_mix_join_$subscribe'([Subscribe | _els], - __TopXMLNS, _acc) -> - 'encode_mix_join_$subscribe'(_els, __TopXMLNS, - [encode_mix_subscribe(Subscribe, __TopXMLNS) - | _acc]). - -decode_mix_join_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_mix_join_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"join">>, __TopXMLNS}}); - _res -> _res - end. - -encode_mix_join_attr_jid(undefined, _acc) -> _acc; -encode_mix_join_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_mix_subscribe(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscribe">>, _attrs, _els}) -> - Node = decode_mix_subscribe_attrs(__TopXMLNS, _attrs, - undefined), - Node. - -decode_mix_subscribe_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_mix_subscribe_attrs(__TopXMLNS, _attrs, _val); -decode_mix_subscribe_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_mix_subscribe_attrs(__TopXMLNS, _attrs, Node); -decode_mix_subscribe_attrs(__TopXMLNS, [], Node) -> - decode_mix_subscribe_attr_node(__TopXMLNS, Node). - -encode_mix_subscribe(Node, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mix:0">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_mix_subscribe_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"subscribe">>, _attrs, _els}. - -decode_mix_subscribe_attr_node(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"subscribe">>, - __TopXMLNS}}); -decode_mix_subscribe_attr_node(__TopXMLNS, _val) -> - _val. - -encode_mix_subscribe_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_offline(__TopXMLNS, __IgnoreEls, - {xmlel, <<"offline">>, _attrs, _els}) -> - {Items, Purge, Fetch} = decode_offline_els(__TopXMLNS, - __IgnoreEls, _els, [], false, - false), - {offline, Items, Purge, Fetch}. - -decode_offline_els(__TopXMLNS, __IgnoreEls, [], Items, - Purge, Fetch) -> - {lists:reverse(Items), Purge, Fetch}; -decode_offline_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"purge">>, _attrs, _} = _el | _els], Items, - Purge, Fetch) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - decode_offline_purge(__TopXMLNS, __IgnoreEls, _el), - Fetch); - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - decode_offline_purge(<<"http://jabber.org/protocol/offline">>, - __IgnoreEls, _el), - Fetch); - _ -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, Fetch) - end; -decode_offline_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"fetch">>, _attrs, _} = _el | _els], Items, - Purge, Fetch) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, - decode_offline_fetch(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, - decode_offline_fetch(<<"http://jabber.org/protocol/offline">>, - __IgnoreEls, _el)); - _ -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, Fetch) - end; -decode_offline_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, - Purge, Fetch) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, - [decode_offline_item(__TopXMLNS, __IgnoreEls, _el) - | Items], - Purge, Fetch); - <<"http://jabber.org/protocol/offline">> -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, - [decode_offline_item(<<"http://jabber.org/protocol/offline">>, - __IgnoreEls, _el) - | Items], - Purge, Fetch); - _ -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, Fetch) - end; -decode_offline_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Items, Purge, Fetch) -> - decode_offline_els(__TopXMLNS, __IgnoreEls, _els, Items, - Purge, Fetch). - -encode_offline({offline, Items, Purge, Fetch}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, - [], __TopXMLNS), - _els = lists:reverse('encode_offline_$items'(Items, - __NewTopXMLNS, - 'encode_offline_$purge'(Purge, - __NewTopXMLNS, - 'encode_offline_$fetch'(Fetch, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"offline">>, _attrs, _els}. - -'encode_offline_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_offline_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_offline_$items'(_els, __TopXMLNS, - [encode_offline_item(Items, __TopXMLNS) | _acc]). - -'encode_offline_$purge'(false, __TopXMLNS, _acc) -> - _acc; -'encode_offline_$purge'(Purge, __TopXMLNS, _acc) -> - [encode_offline_purge(Purge, __TopXMLNS) | _acc]. - -'encode_offline_$fetch'(false, __TopXMLNS, _acc) -> - _acc; -'encode_offline_$fetch'(Fetch, __TopXMLNS, _acc) -> - [encode_offline_fetch(Fetch, __TopXMLNS) | _acc]. - -decode_offline_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Node, Action} = decode_offline_item_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {offline_item, Node, Action}. - -decode_offline_item_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Action) -> - decode_offline_item_attrs(__TopXMLNS, _attrs, _val, - Action); -decode_offline_item_attrs(__TopXMLNS, - [{<<"action">>, _val} | _attrs], Node, _Action) -> - decode_offline_item_attrs(__TopXMLNS, _attrs, Node, - _val); -decode_offline_item_attrs(__TopXMLNS, [_ | _attrs], - Node, Action) -> - decode_offline_item_attrs(__TopXMLNS, _attrs, Node, - Action); -decode_offline_item_attrs(__TopXMLNS, [], Node, - Action) -> - {decode_offline_item_attr_node(__TopXMLNS, Node), - decode_offline_item_attr_action(__TopXMLNS, Action)}. - -encode_offline_item({offline_item, Node, Action}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_offline_item_attr_action(Action, - encode_offline_item_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"item">>, _attrs, _els}. - -decode_offline_item_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_offline_item_attr_node(__TopXMLNS, _val) -> _val. - -encode_offline_item_attr_node(<<>>, _acc) -> _acc; -encode_offline_item_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_offline_item_attr_action(__TopXMLNS, - undefined) -> - undefined; -decode_offline_item_attr_action(__TopXMLNS, _val) -> - case catch dec_enum(_val, [view, remove]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"action">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_offline_item_attr_action(undefined, _acc) -> - _acc; -encode_offline_item_attr_action(_val, _acc) -> - [{<<"action">>, enc_enum(_val)} | _acc]. - -decode_offline_fetch(__TopXMLNS, __IgnoreEls, - {xmlel, <<"fetch">>, _attrs, _els}) -> - true. - -encode_offline_fetch(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"fetch">>, _attrs, _els}. - -decode_offline_purge(__TopXMLNS, __IgnoreEls, - {xmlel, <<"purge">>, _attrs, _els}) -> - true. - -encode_offline_purge(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/offline">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"purge">>, _attrs, _els}. - -decode_sm_failed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"failed">>, _attrs, _els}) -> - Reason = decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - _els, undefined), - {H, Xmlns} = decode_sm_failed_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {sm_failed, Reason, H, Xmlns}. - -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - Reason; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"bad-request">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"feature-not-implemented">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forbidden">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"gone">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"internal-server-error">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item-not-found">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"jid-malformed">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-acceptable">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-allowed">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"policy-violation">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"recipient-unavailable">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"registration-required">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remote-server-not-found">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remote-server-timeout">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"resource-constraint">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"service-unavailable">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription-required">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"undefined-condition">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unexpected-request">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); - _ -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason) - end; -decode_sm_failed_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> - decode_sm_failed_els(__TopXMLNS, __IgnoreEls, _els, - Reason). - -decode_sm_failed_attrs(__TopXMLNS, - [{<<"h">>, _val} | _attrs], _H, Xmlns) -> - decode_sm_failed_attrs(__TopXMLNS, _attrs, _val, Xmlns); -decode_sm_failed_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], H, _Xmlns) -> - decode_sm_failed_attrs(__TopXMLNS, _attrs, H, _val); -decode_sm_failed_attrs(__TopXMLNS, [_ | _attrs], H, - Xmlns) -> - decode_sm_failed_attrs(__TopXMLNS, _attrs, H, Xmlns); -decode_sm_failed_attrs(__TopXMLNS, [], H, Xmlns) -> - {decode_sm_failed_attr_h(__TopXMLNS, H), - decode_sm_failed_attr_xmlns(__TopXMLNS, Xmlns)}. - -encode_sm_failed({sm_failed, Reason, H, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = lists:reverse('encode_sm_failed_$reason'(Reason, - __NewTopXMLNS, [])), - _attrs = encode_sm_failed_attr_h(H, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"failed">>, _attrs, _els}. - -'encode_sm_failed_$reason'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_sm_failed_$reason'('bad-request' = Reason, - __TopXMLNS, _acc) -> - [encode_error_bad_request(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'(conflict = Reason, - __TopXMLNS, _acc) -> - [encode_error_conflict(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'('feature-not-implemented' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_feature_not_implemented(Reason, - __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'(forbidden = Reason, - __TopXMLNS, _acc) -> - [encode_error_forbidden(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'({gone, _} = Reason, - __TopXMLNS, _acc) -> - [encode_error_gone(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'('internal-server-error' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_internal_server_error(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('item-not-found' = Reason, - __TopXMLNS, _acc) -> - [encode_error_item_not_found(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('jid-malformed' = Reason, - __TopXMLNS, _acc) -> - [encode_error_jid_malformed(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'('not-acceptable' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_acceptable(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('not-allowed' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_allowed(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'('not-authorized' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_authorized(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('policy-violation' = Reason, - __TopXMLNS, _acc) -> - [encode_error_policy_violation(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('recipient-unavailable' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_recipient_unavailable(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'({redirect, _} = Reason, - __TopXMLNS, _acc) -> - [encode_error_redirect(Reason, __TopXMLNS) | _acc]; -'encode_sm_failed_$reason'('registration-required' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_registration_required(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('remote-server-not-found' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_remote_server_not_found(Reason, - __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('remote-server-timeout' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_remote_server_timeout(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('resource-constraint' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_resource_constraint(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('service-unavailable' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_service_unavailable(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('subscription-required' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_subscription_required(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('undefined-condition' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_undefined_condition(Reason, __TopXMLNS) - | _acc]; -'encode_sm_failed_$reason'('unexpected-request' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_unexpected_request(Reason, __TopXMLNS) - | _acc]. - -decode_sm_failed_attr_h(__TopXMLNS, undefined) -> - undefined; -decode_sm_failed_attr_h(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"h">>, <<"failed">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sm_failed_attr_h(undefined, _acc) -> _acc; -encode_sm_failed_attr_h(_val, _acc) -> - [{<<"h">>, enc_int(_val)} | _acc]. - -decode_sm_failed_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_sm_failed_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_a(__TopXMLNS, __IgnoreEls, - {xmlel, <<"a">>, _attrs, _els}) -> - {H, Xmlns} = decode_sm_a_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {sm_a, H, Xmlns}. - -decode_sm_a_attrs(__TopXMLNS, - [{<<"h">>, _val} | _attrs], _H, Xmlns) -> - decode_sm_a_attrs(__TopXMLNS, _attrs, _val, Xmlns); -decode_sm_a_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], H, _Xmlns) -> - decode_sm_a_attrs(__TopXMLNS, _attrs, H, _val); -decode_sm_a_attrs(__TopXMLNS, [_ | _attrs], H, Xmlns) -> - decode_sm_a_attrs(__TopXMLNS, _attrs, H, Xmlns); -decode_sm_a_attrs(__TopXMLNS, [], H, Xmlns) -> - {decode_sm_a_attr_h(__TopXMLNS, H), - decode_sm_a_attr_xmlns(__TopXMLNS, Xmlns)}. - -encode_sm_a({sm_a, H, Xmlns}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = encode_sm_a_attr_h(H, - enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), - {xmlel, <<"a">>, _attrs, _els}. - -decode_sm_a_attr_h(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"h">>, <<"a">>, __TopXMLNS}}); -decode_sm_a_attr_h(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"h">>, <<"a">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sm_a_attr_h(_val, _acc) -> - [{<<"h">>, enc_int(_val)} | _acc]. - -decode_sm_a_attr_xmlns(__TopXMLNS, undefined) -> <<>>; -decode_sm_a_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_r(__TopXMLNS, __IgnoreEls, - {xmlel, <<"r">>, _attrs, _els}) -> - Xmlns = decode_sm_r_attrs(__TopXMLNS, _attrs, - undefined), - {sm_r, Xmlns}. - -decode_sm_r_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_sm_r_attrs(__TopXMLNS, _attrs, _val); -decode_sm_r_attrs(__TopXMLNS, [_ | _attrs], Xmlns) -> - decode_sm_r_attrs(__TopXMLNS, _attrs, Xmlns); -decode_sm_r_attrs(__TopXMLNS, [], Xmlns) -> - decode_sm_r_attr_xmlns(__TopXMLNS, Xmlns). - -encode_sm_r({sm_r, Xmlns}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"r">>, _attrs, _els}. - -decode_sm_r_attr_xmlns(__TopXMLNS, undefined) -> <<>>; -decode_sm_r_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_resumed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"resumed">>, _attrs, _els}) -> - {H, Xmlns, Previd} = decode_sm_resumed_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {sm_resumed, H, Previd, Xmlns}. - -decode_sm_resumed_attrs(__TopXMLNS, - [{<<"h">>, _val} | _attrs], _H, Xmlns, Previd) -> - decode_sm_resumed_attrs(__TopXMLNS, _attrs, _val, Xmlns, - Previd); -decode_sm_resumed_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], H, _Xmlns, Previd) -> - decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, _val, - Previd); -decode_sm_resumed_attrs(__TopXMLNS, - [{<<"previd">>, _val} | _attrs], H, Xmlns, _Previd) -> - decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, Xmlns, - _val); -decode_sm_resumed_attrs(__TopXMLNS, [_ | _attrs], H, - Xmlns, Previd) -> - decode_sm_resumed_attrs(__TopXMLNS, _attrs, H, Xmlns, - Previd); -decode_sm_resumed_attrs(__TopXMLNS, [], H, Xmlns, - Previd) -> - {decode_sm_resumed_attr_h(__TopXMLNS, H), - decode_sm_resumed_attr_xmlns(__TopXMLNS, Xmlns), - decode_sm_resumed_attr_previd(__TopXMLNS, Previd)}. - -encode_sm_resumed({sm_resumed, H, Previd, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = encode_sm_resumed_attr_previd(Previd, - encode_sm_resumed_attr_h(H, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"resumed">>, _attrs, _els}. - -decode_sm_resumed_attr_h(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"h">>, <<"resumed">>, __TopXMLNS}}); -decode_sm_resumed_attr_h(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"h">>, <<"resumed">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sm_resumed_attr_h(_val, _acc) -> - [{<<"h">>, enc_int(_val)} | _acc]. - -decode_sm_resumed_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_sm_resumed_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_resumed_attr_previd(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"previd">>, <<"resumed">>, - __TopXMLNS}}); -decode_sm_resumed_attr_previd(__TopXMLNS, _val) -> _val. - -encode_sm_resumed_attr_previd(_val, _acc) -> - [{<<"previd">>, _val} | _acc]. - -decode_sm_resume(__TopXMLNS, __IgnoreEls, - {xmlel, <<"resume">>, _attrs, _els}) -> - {H, Xmlns, Previd} = decode_sm_resume_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {sm_resume, H, Previd, Xmlns}. - -decode_sm_resume_attrs(__TopXMLNS, - [{<<"h">>, _val} | _attrs], _H, Xmlns, Previd) -> - decode_sm_resume_attrs(__TopXMLNS, _attrs, _val, Xmlns, - Previd); -decode_sm_resume_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], H, _Xmlns, Previd) -> - decode_sm_resume_attrs(__TopXMLNS, _attrs, H, _val, - Previd); -decode_sm_resume_attrs(__TopXMLNS, - [{<<"previd">>, _val} | _attrs], H, Xmlns, _Previd) -> - decode_sm_resume_attrs(__TopXMLNS, _attrs, H, Xmlns, - _val); -decode_sm_resume_attrs(__TopXMLNS, [_ | _attrs], H, - Xmlns, Previd) -> - decode_sm_resume_attrs(__TopXMLNS, _attrs, H, Xmlns, - Previd); -decode_sm_resume_attrs(__TopXMLNS, [], H, Xmlns, - Previd) -> - {decode_sm_resume_attr_h(__TopXMLNS, H), - decode_sm_resume_attr_xmlns(__TopXMLNS, Xmlns), - decode_sm_resume_attr_previd(__TopXMLNS, Previd)}. - -encode_sm_resume({sm_resume, H, Previd, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = encode_sm_resume_attr_previd(Previd, - encode_sm_resume_attr_h(H, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"resume">>, _attrs, _els}. - -decode_sm_resume_attr_h(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"h">>, <<"resume">>, __TopXMLNS}}); -decode_sm_resume_attr_h(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"h">>, <<"resume">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sm_resume_attr_h(_val, _acc) -> - [{<<"h">>, enc_int(_val)} | _acc]. - -decode_sm_resume_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_sm_resume_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_resume_attr_previd(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"previd">>, <<"resume">>, - __TopXMLNS}}); -decode_sm_resume_attr_previd(__TopXMLNS, _val) -> _val. - -encode_sm_resume_attr_previd(_val, _acc) -> - [{<<"previd">>, _val} | _acc]. - -decode_sm_enabled(__TopXMLNS, __IgnoreEls, - {xmlel, <<"enabled">>, _attrs, _els}) -> - {Id, Location, Xmlns, Max, Resume} = - decode_sm_enabled_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined, undefined), - {sm_enabled, Id, Location, Max, Resume, Xmlns}. - -decode_sm_enabled_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, Location, Xmlns, Max, - Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, _val, - Location, Xmlns, Max, Resume); -decode_sm_enabled_attrs(__TopXMLNS, - [{<<"location">>, _val} | _attrs], Id, _Location, Xmlns, - Max, Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, _val, - Xmlns, Max, Resume); -decode_sm_enabled_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Id, Location, _Xmlns, - Max, Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, - Location, _val, Max, Resume); -decode_sm_enabled_attrs(__TopXMLNS, - [{<<"max">>, _val} | _attrs], Id, Location, Xmlns, _Max, - Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, - Location, Xmlns, _val, Resume); -decode_sm_enabled_attrs(__TopXMLNS, - [{<<"resume">>, _val} | _attrs], Id, Location, Xmlns, - Max, _Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, - Location, Xmlns, Max, _val); -decode_sm_enabled_attrs(__TopXMLNS, [_ | _attrs], Id, - Location, Xmlns, Max, Resume) -> - decode_sm_enabled_attrs(__TopXMLNS, _attrs, Id, - Location, Xmlns, Max, Resume); -decode_sm_enabled_attrs(__TopXMLNS, [], Id, Location, - Xmlns, Max, Resume) -> - {decode_sm_enabled_attr_id(__TopXMLNS, Id), - decode_sm_enabled_attr_location(__TopXMLNS, Location), - decode_sm_enabled_attr_xmlns(__TopXMLNS, Xmlns), - decode_sm_enabled_attr_max(__TopXMLNS, Max), - decode_sm_enabled_attr_resume(__TopXMLNS, Resume)}. - -encode_sm_enabled({sm_enabled, Id, Location, Max, - Resume, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = encode_sm_enabled_attr_resume(Resume, - encode_sm_enabled_attr_max(Max, - encode_sm_enabled_attr_location(Location, - encode_sm_enabled_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"enabled">>, _attrs, _els}. - -decode_sm_enabled_attr_id(__TopXMLNS, undefined) -> - <<>>; -decode_sm_enabled_attr_id(__TopXMLNS, _val) -> _val. - -encode_sm_enabled_attr_id(<<>>, _acc) -> _acc; -encode_sm_enabled_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_sm_enabled_attr_location(__TopXMLNS, - undefined) -> - <<>>; -decode_sm_enabled_attr_location(__TopXMLNS, _val) -> - _val. - -encode_sm_enabled_attr_location(<<>>, _acc) -> _acc; -encode_sm_enabled_attr_location(_val, _acc) -> - [{<<"location">>, _val} | _acc]. - -decode_sm_enabled_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_sm_enabled_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_enabled_attr_max(__TopXMLNS, undefined) -> - undefined; -decode_sm_enabled_attr_max(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"max">>, <<"enabled">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_sm_enabled_attr_max(undefined, _acc) -> _acc; -encode_sm_enabled_attr_max(_val, _acc) -> - [{<<"max">>, enc_int(_val)} | _acc]. - -decode_sm_enabled_attr_resume(__TopXMLNS, undefined) -> - false; -decode_sm_enabled_attr_resume(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"resume">>, <<"enabled">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_sm_enabled_attr_resume(false, _acc) -> _acc; -encode_sm_enabled_attr_resume(_val, _acc) -> - [{<<"resume">>, enc_bool(_val)} | _acc]. - -decode_sm_enable(__TopXMLNS, __IgnoreEls, - {xmlel, <<"enable">>, _attrs, _els}) -> - {Max, Xmlns, Resume} = - decode_sm_enable_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined), - {sm_enable, Max, Resume, Xmlns}. - -decode_sm_enable_attrs(__TopXMLNS, - [{<<"max">>, _val} | _attrs], _Max, Xmlns, Resume) -> - decode_sm_enable_attrs(__TopXMLNS, _attrs, _val, Xmlns, - Resume); -decode_sm_enable_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Max, _Xmlns, Resume) -> - decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, _val, - Resume); -decode_sm_enable_attrs(__TopXMLNS, - [{<<"resume">>, _val} | _attrs], Max, Xmlns, _Resume) -> - decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, Xmlns, - _val); -decode_sm_enable_attrs(__TopXMLNS, [_ | _attrs], Max, - Xmlns, Resume) -> - decode_sm_enable_attrs(__TopXMLNS, _attrs, Max, Xmlns, - Resume); -decode_sm_enable_attrs(__TopXMLNS, [], Max, Xmlns, - Resume) -> - {decode_sm_enable_attr_max(__TopXMLNS, Max), - decode_sm_enable_attr_xmlns(__TopXMLNS, Xmlns), - decode_sm_enable_attr_resume(__TopXMLNS, Resume)}. - -encode_sm_enable({sm_enable, Max, Resume, Xmlns}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = encode_sm_enable_attr_resume(Resume, - encode_sm_enable_attr_max(Max, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"enable">>, _attrs, _els}. - -decode_sm_enable_attr_max(__TopXMLNS, undefined) -> - undefined; -decode_sm_enable_attr_max(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"max">>, <<"enable">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sm_enable_attr_max(undefined, _acc) -> _acc; -encode_sm_enable_attr_max(_val, _acc) -> - [{<<"max">>, enc_int(_val)} | _acc]. - -decode_sm_enable_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_sm_enable_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_sm_enable_attr_resume(__TopXMLNS, undefined) -> - false; -decode_sm_enable_attr_resume(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"resume">>, <<"enable">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_sm_enable_attr_resume(false, _acc) -> _acc; -encode_sm_enable_attr_resume(_val, _acc) -> - [{<<"resume">>, enc_bool(_val)} | _acc]. - -decode_feature_sm(__TopXMLNS, __IgnoreEls, - {xmlel, <<"sm">>, _attrs, _els}) -> - Xmlns = decode_feature_sm_attrs(__TopXMLNS, _attrs, - undefined), - {feature_sm, Xmlns}. - -decode_feature_sm_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_feature_sm_attrs(__TopXMLNS, _attrs, _val); -decode_feature_sm_attrs(__TopXMLNS, [_ | _attrs], - Xmlns) -> - decode_feature_sm_attrs(__TopXMLNS, _attrs, Xmlns); -decode_feature_sm_attrs(__TopXMLNS, [], Xmlns) -> - decode_feature_sm_attr_xmlns(__TopXMLNS, Xmlns). - -encode_feature_sm({feature_sm, Xmlns}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:sm:2">>, <<"urn:xmpp:sm:3">>], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"sm">>, _attrs, _els}. - -decode_feature_sm_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_feature_sm_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_csi_inactive(__TopXMLNS, __IgnoreEls, - {xmlel, <<"inactive">>, _attrs, _els}) -> - {csi, inactive}. - -encode_csi_inactive({csi, inactive}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:csi:0">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"inactive">>, _attrs, _els}. - -decode_csi_active(__TopXMLNS, __IgnoreEls, - {xmlel, <<"active">>, _attrs, _els}) -> - {csi, active}. - -encode_csi_active({csi, active}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:csi:0">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"active">>, _attrs, _els}. - -decode_feature_csi(__TopXMLNS, __IgnoreEls, - {xmlel, <<"csi">>, _attrs, _els}) -> - Xmlns = decode_feature_csi_attrs(__TopXMLNS, _attrs, - undefined), - {feature_csi, Xmlns}. - -decode_feature_csi_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns) -> - decode_feature_csi_attrs(__TopXMLNS, _attrs, _val); -decode_feature_csi_attrs(__TopXMLNS, [_ | _attrs], - Xmlns) -> - decode_feature_csi_attrs(__TopXMLNS, _attrs, Xmlns); -decode_feature_csi_attrs(__TopXMLNS, [], Xmlns) -> - decode_feature_csi_attr_xmlns(__TopXMLNS, Xmlns). - -encode_feature_csi({feature_csi, Xmlns}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:csi:0">>], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"csi">>, _attrs, _els}. - -decode_feature_csi_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_feature_csi_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_carbons_sent(__TopXMLNS, __IgnoreEls, - {xmlel, <<"sent">>, _attrs, _els}) -> - Forwarded = decode_carbons_sent_els(__TopXMLNS, - __IgnoreEls, _els, error), - {carbons_sent, Forwarded}. - -decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, [], - Forwarded) -> - case Forwarded of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"forwarded">>, __TopXMLNS}}); - {value, Forwarded1} -> Forwarded1 - end; -decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], - Forwarded) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:xmpp:forward:0">> -> - decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, - {value, - decode_forwarded(<<"urn:xmpp:forward:0">>, - __IgnoreEls, _el)}); - _ -> - decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded) - end; -decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Forwarded) -> - decode_carbons_sent_els(__TopXMLNS, __IgnoreEls, _els, - Forwarded). - -encode_carbons_sent({carbons_sent, Forwarded}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_carbons_sent_$forwarded'(Forwarded, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"sent">>, _attrs, _els}. - -'encode_carbons_sent_$forwarded'(Forwarded, __TopXMLNS, - _acc) -> - [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. - -decode_carbons_received(__TopXMLNS, __IgnoreEls, - {xmlel, <<"received">>, _attrs, _els}) -> - Forwarded = decode_carbons_received_els(__TopXMLNS, - __IgnoreEls, _els, error), - {carbons_received, Forwarded}. - -decode_carbons_received_els(__TopXMLNS, __IgnoreEls, [], - Forwarded) -> - case Forwarded of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"forwarded">>, __TopXMLNS}}); - {value, Forwarded1} -> Forwarded1 - end; -decode_carbons_received_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forwarded">>, _attrs, _} = _el | _els], - Forwarded) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:xmpp:forward:0">> -> - decode_carbons_received_els(__TopXMLNS, __IgnoreEls, - _els, - {value, - decode_forwarded(<<"urn:xmpp:forward:0">>, - __IgnoreEls, _el)}); - _ -> - decode_carbons_received_els(__TopXMLNS, __IgnoreEls, - _els, Forwarded) - end; -decode_carbons_received_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Forwarded) -> - decode_carbons_received_els(__TopXMLNS, __IgnoreEls, - _els, Forwarded). - -encode_carbons_received({carbons_received, Forwarded}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_carbons_received_$forwarded'(Forwarded, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"received">>, _attrs, _els}. - -'encode_carbons_received_$forwarded'(Forwarded, - __TopXMLNS, _acc) -> - [encode_forwarded(Forwarded, __TopXMLNS) | _acc]. - -decode_carbons_private(__TopXMLNS, __IgnoreEls, - {xmlel, <<"private">>, _attrs, _els}) -> - {carbons_private}. - -encode_carbons_private({carbons_private}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"private">>, _attrs, _els}. - -decode_carbons_enable(__TopXMLNS, __IgnoreEls, - {xmlel, <<"enable">>, _attrs, _els}) -> - {carbons_enable}. - -encode_carbons_enable({carbons_enable}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"enable">>, _attrs, _els}. - -decode_carbons_disable(__TopXMLNS, __IgnoreEls, - {xmlel, <<"disable">>, _attrs, _els}) -> - {carbons_disable}. - -encode_carbons_disable({carbons_disable}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:carbons:2">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"disable">>, _attrs, _els}. - -decode_forwarded(__TopXMLNS, __IgnoreEls, - {xmlel, <<"forwarded">>, _attrs, _els}) -> - {Delay, __Xmls} = decode_forwarded_els(__TopXMLNS, - __IgnoreEls, _els, undefined, []), - {forwarded, Delay, __Xmls}. - -decode_forwarded_els(__TopXMLNS, __IgnoreEls, [], Delay, - __Xmls) -> - {Delay, lists:reverse(__Xmls)}; -decode_forwarded_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delay">>, _attrs, _} = _el | _els], Delay, - __Xmls) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:xmpp:delay">> -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - decode_delay(<<"urn:xmpp:delay">>, __IgnoreEls, - _el), - __Xmls); - _ -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, __Xmls) - end; -decode_forwarded_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Delay, __Xmls) -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, [_el | __Xmls]); -decode_forwarded_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Delay, __Xmls) -> - decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els, - Delay, __Xmls). - -encode_forwarded({forwarded, Delay, __Xmls}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:forward:0">>, [], - __TopXMLNS), - _els = __Xmls ++ - lists:reverse('encode_forwarded_$delay'(Delay, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"forwarded">>, _attrs, _els}. - -'encode_forwarded_$delay'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_forwarded_$delay'(Delay, __TopXMLNS, _acc) -> - [encode_delay(Delay, __TopXMLNS) | _acc]. - -decode_mam_fin(__TopXMLNS, __IgnoreEls, - {xmlel, <<"fin">>, _attrs, _els}) -> - Rsm = decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, - undefined), - {Id, Xmlns, Stable, Complete} = - decode_mam_fin_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {mam_fin, Xmlns, Id, Rsm, Stable, Complete}. - -decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [], Rsm) -> - Rsm; -decode_mam_fin_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"set">>, _attrs, _} = _el | _els], Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/rsm">> -> - decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, - decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el)); - _ -> - 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, Xmlns, Stable, - Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, _val, Xmlns, - Stable, Complete); -decode_mam_fin_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Id, _Xmlns, Stable, - Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, _val, - Stable, Complete); -decode_mam_fin_attrs(__TopXMLNS, - [{<<"stable">>, _val} | _attrs], Id, Xmlns, _Stable, - Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, - _val, Complete); -decode_mam_fin_attrs(__TopXMLNS, - [{<<"complete">>, _val} | _attrs], Id, Xmlns, Stable, - _Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, - Stable, _val); -decode_mam_fin_attrs(__TopXMLNS, [_ | _attrs], Id, - Xmlns, Stable, Complete) -> - decode_mam_fin_attrs(__TopXMLNS, _attrs, Id, Xmlns, - Stable, Complete); -decode_mam_fin_attrs(__TopXMLNS, [], Id, Xmlns, Stable, - Complete) -> - {decode_mam_fin_attr_queryid(__TopXMLNS, Id), - decode_mam_fin_attr_xmlns(__TopXMLNS, Xmlns), - decode_mam_fin_attr_stable(__TopXMLNS, Stable), - decode_mam_fin_attr_complete(__TopXMLNS, Complete)}. - -encode_mam_fin({mam_fin, Xmlns, Id, Rsm, Stable, - Complete}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>], - __TopXMLNS), - _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, - __NewTopXMLNS, [])), - _attrs = encode_mam_fin_attr_complete(Complete, - encode_mam_fin_attr_stable(Stable, - encode_mam_fin_attr_queryid(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"fin">>, _attrs, _els}. - -'encode_mam_fin_$rsm'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_mam_fin_$rsm'(Rsm, __TopXMLNS, _acc) -> - [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. - -decode_mam_fin_attr_queryid(__TopXMLNS, undefined) -> - <<>>; -decode_mam_fin_attr_queryid(__TopXMLNS, _val) -> _val. - -encode_mam_fin_attr_queryid(<<>>, _acc) -> _acc; -encode_mam_fin_attr_queryid(_val, _acc) -> - [{<<"queryid">>, _val} | _acc]. - -decode_mam_fin_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_mam_fin_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_mam_fin_attr_stable(__TopXMLNS, undefined) -> - undefined; -decode_mam_fin_attr_stable(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"stable">>, <<"fin">>, __TopXMLNS}}); - _res -> _res - end. - -encode_mam_fin_attr_stable(undefined, _acc) -> _acc; -encode_mam_fin_attr_stable(_val, _acc) -> - [{<<"stable">>, enc_bool(_val)} | _acc]. - -decode_mam_fin_attr_complete(__TopXMLNS, undefined) -> - undefined; -decode_mam_fin_attr_complete(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"complete">>, <<"fin">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_mam_fin_attr_complete(undefined, _acc) -> _acc; -encode_mam_fin_attr_complete(_val, _acc) -> - [{<<"complete">>, enc_bool(_val)} | _acc]. - -decode_mam_prefs(__TopXMLNS, __IgnoreEls, - {xmlel, <<"prefs">>, _attrs, _els}) -> - {Never, Always} = decode_mam_prefs_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - {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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:mam:1">>; - __TopXMLNS == <<"urn:xmpp:mam:0">>; - __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - Never, - decode_mam_always(__TopXMLNS, __IgnoreEls, _el)); - <<"urn:xmpp:mam:0">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - Never, - decode_mam_always(<<"urn:xmpp:mam:0">>, - __IgnoreEls, _el)); - <<"urn:xmpp:mam:1">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - Never, - decode_mam_always(<<"urn:xmpp:mam:1">>, - __IgnoreEls, _el)); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - Never, - decode_mam_always(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el)); - _ -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - Never, Always) - end; -decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"never">>, _attrs, _} = _el | _els], Never, - Always) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:mam:1">>; - __TopXMLNS == <<"urn:xmpp:mam:0">>; - __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - decode_mam_never(__TopXMLNS, __IgnoreEls, _el), - Always); - <<"urn:xmpp:mam:0">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - decode_mam_never(<<"urn:xmpp:mam:0">>, - __IgnoreEls, _el), - Always); - <<"urn:xmpp:mam:1">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - decode_mam_never(<<"urn:xmpp:mam:1">>, - __IgnoreEls, _el), - Always); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els, - decode_mam_never(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el), - Always); - _ -> - 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}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = lists:reverse('encode_mam_prefs_$never'(Never, - __NewTopXMLNS, - 'encode_mam_prefs_$always'(Always, - __NewTopXMLNS, - []))), - _attrs = encode_mam_prefs_attr_default(Default, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"prefs">>, _attrs, _els}. - -'encode_mam_prefs_$never'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_mam_prefs_$never'(Never, __TopXMLNS, _acc) -> - [encode_mam_never(Never, __TopXMLNS) | _acc]. - -'encode_mam_prefs_$always'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_mam_prefs_$always'(Always, __TopXMLNS, _acc) -> - [encode_mam_always(Always, __TopXMLNS) | _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) -> - <<>>; -decode_mam_prefs_attr_xmlns(__TopXMLNS, _val) -> _val. - -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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:mam:1">>; - __TopXMLNS == <<"urn:xmpp:mam:0">>; - __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(__TopXMLNS, __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:0">> -> - decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:0">>, - __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:1">> -> - decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:1">>, - __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el) - | Jids]); - _ -> - 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, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = lists:reverse('encode_mam_always_$jids'(Jids, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"always">>, _attrs, _els}. - -'encode_mam_always_$jids'([], __TopXMLNS, _acc) -> _acc; -'encode_mam_always_$jids'([Jids | _els], __TopXMLNS, - _acc) -> - 'encode_mam_always_$jids'(_els, __TopXMLNS, - [encode_mam_jid(Jids, __TopXMLNS) | _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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"urn:xmpp:mam:1">>; - __TopXMLNS == <<"urn:xmpp:mam:0">>; - __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(__TopXMLNS, __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:0">> -> - decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:0">>, - __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:1">> -> - decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:1">>, - __IgnoreEls, _el) - | Jids]); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els, - [decode_mam_jid(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el) - | Jids]); - _ -> - 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, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = lists:reverse('encode_mam_never_$jids'(Jids, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"never">>, _attrs, _els}. - -'encode_mam_never_$jids'([], __TopXMLNS, _acc) -> _acc; -'encode_mam_never_$jids'([Jids | _els], __TopXMLNS, - _acc) -> - 'encode_mam_never_$jids'(_els, __TopXMLNS, - [encode_mam_jid(Jids, __TopXMLNS) | _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, - <>); -decode_mam_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_mam_jid_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_mam_jid(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = encode_mam_jid_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, __TopXMLNS) of - true -> - decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, - [decode(_el, __TopXMLNS, []) | __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}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], - _attrs = encode_mam_result_attr_id(Id, - encode_mam_result_attr_queryid(Queryid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"result">>, _attrs, _els}. - -decode_mam_result_attr_queryid(__TopXMLNS, undefined) -> - <<>>; -decode_mam_result_attr_queryid(__TopXMLNS, _val) -> - _val. - -encode_mam_result_attr_queryid(<<>>, _acc) -> _acc; -encode_mam_result_attr_queryid(_val, _acc) -> - [{<<"queryid">>, _val} | _acc]. - -decode_mam_result_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_mam_result_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_mam_result_attr_id(__TopXMLNS, undefined) -> - <<>>; -decode_mam_result_attr_id(__TopXMLNS, _val) -> _val. - -encode_mam_result_attr_id(<<>>, _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}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_mam_archived_attr_by(By, - encode_mam_archived_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"archived">>, _attrs, _els}. - -decode_mam_archived_attr_id(__TopXMLNS, undefined) -> - <<>>; -decode_mam_archived_attr_id(__TopXMLNS, _val) -> _val. - -encode_mam_archived_attr_id(<<>>, _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, Withtext, End, Start, With, Rsm} = - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, - undefined, undefined), - {Id, Xmlns} = decode_mam_query_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {mam_query, Xmlns, Id, Start, End, With, Withtext, Rsm, - Xdata}. - -decode_mam_query_els(__TopXMLNS, __IgnoreEls, [], Xdata, - Withtext, End, Start, With, Rsm) -> - {Xdata, Withtext, End, Start, With, Rsm}; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"start">>, _attrs, _} = _el | _els], Xdata, - Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, - decode_mam_start(__TopXMLNS, __IgnoreEls, _el), - With, Rsm); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, - decode_mam_start(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el), - With, Rsm); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"end">>, _attrs, _} = _el | _els], Xdata, - Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, - decode_mam_end(__TopXMLNS, __IgnoreEls, _el), - Start, With, Rsm); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, - decode_mam_end(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el), - Start, With, Rsm); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"with">>, _attrs, _} = _el | _els], Xdata, - Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, - decode_mam_with(__TopXMLNS, __IgnoreEls, _el), - Rsm); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, - decode_mam_with(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el), - Rsm); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"withtext">>, _attrs, _} = _el | _els], - Xdata, Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - decode_mam_withtext(__TopXMLNS, __IgnoreEls, - _el), - End, Start, With, Rsm); - <<"urn:xmpp:mam:tmp">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - decode_mam_withtext(<<"urn:xmpp:mam:tmp">>, - __IgnoreEls, _el), - End, Start, With, Rsm); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"set">>, _attrs, _} = _el | _els], Xdata, - Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/rsm">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, - decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el)); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, - Withtext, End, Start, With, Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, __IgnoreEls, - _el), - Withtext, End, Start, With, Rsm); - _ -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, End, Start, With, Rsm) - end; -decode_mam_query_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata, Withtext, End, Start, With, Rsm) -> - decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Withtext, 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, Withtext, Rsm, Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"urn:xmpp:mam:0">>, - <<"urn:xmpp:mam:1">>, - <<"urn:xmpp:mam:tmp">>], - __TopXMLNS), - _els = lists:reverse('encode_mam_query_$xdata'(Xdata, - __NewTopXMLNS, - 'encode_mam_query_$withtext'(Withtext, - __NewTopXMLNS, - 'encode_mam_query_$end'(End, - __NewTopXMLNS, - 'encode_mam_query_$start'(Start, - __NewTopXMLNS, - 'encode_mam_query_$with'(With, - __NewTopXMLNS, - 'encode_mam_query_$rsm'(Rsm, - __NewTopXMLNS, - []))))))), - _attrs = encode_mam_query_attr_queryid(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_mam_query_$xdata'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_mam_query_$xdata'(Xdata, __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -'encode_mam_query_$withtext'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_mam_query_$withtext'(Withtext, __TopXMLNS, - _acc) -> - [encode_mam_withtext(Withtext, __TopXMLNS) | _acc]. - -'encode_mam_query_$end'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_mam_query_$end'(End, __TopXMLNS, _acc) -> - [encode_mam_end(End, __TopXMLNS) | _acc]. - -'encode_mam_query_$start'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_mam_query_$start'(Start, __TopXMLNS, _acc) -> - [encode_mam_start(Start, __TopXMLNS) | _acc]. - -'encode_mam_query_$with'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_mam_query_$with'(With, __TopXMLNS, _acc) -> - [encode_mam_with(With, __TopXMLNS) | _acc]. - -'encode_mam_query_$rsm'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_mam_query_$rsm'(Rsm, __TopXMLNS, _acc) -> - [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. - -decode_mam_query_attr_queryid(__TopXMLNS, undefined) -> - <<>>; -decode_mam_query_attr_queryid(__TopXMLNS, _val) -> _val. - -encode_mam_query_attr_queryid(<<>>, _acc) -> _acc; -encode_mam_query_attr_queryid(_val, _acc) -> - [{<<"queryid">>, _val} | _acc]. - -decode_mam_query_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_mam_query_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_mam_withtext(__TopXMLNS, __IgnoreEls, - {xmlel, <<"withtext">>, _attrs, _els}) -> - Cdata = decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_mam_withtext_cdata(__TopXMLNS, Cdata); -decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_mam_withtext_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_mam_withtext(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, - [], __TopXMLNS), - _els = encode_mam_withtext_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"withtext">>, _attrs, _els}. - -decode_mam_withtext_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"withtext">>, __TopXMLNS}}); -decode_mam_withtext_cdata(__TopXMLNS, _val) -> _val. - -encode_mam_withtext_cdata(_val, _acc) -> - [{xmlcdata, _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, - <>); -decode_mam_with_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_mam_with_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_mam_with(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, - [], __TopXMLNS), - _els = encode_mam_with_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, - <>); -decode_mam_end_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_mam_end(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, - [], __TopXMLNS), - _els = encode_mam_end_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, - <>); -decode_mam_start_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_mam_start(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:mam:tmp">>, - [], __TopXMLNS), - _els = encode_mam_start_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, - decode_rsm_after(__TopXMLNS, __IgnoreEls, _el), - Last, First, Count, Before, Max, Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, - decode_rsm_after(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Last, First, Count, Before, Max, Index); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, - decode_rsm_before(__TopXMLNS, __IgnoreEls, _el), - Max, Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, - decode_rsm_before(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Max, Index); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, - decode_rsm_count(__TopXMLNS, __IgnoreEls, _el), - Before, Max, Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, - decode_rsm_count(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Before, Max, Index); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, - decode_rsm_first(__TopXMLNS, __IgnoreEls, _el), - Count, Before, Max, Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, - decode_rsm_first(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Count, Before, Max, Index); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, Before, Max, - decode_rsm_index(__TopXMLNS, __IgnoreEls, _el)); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, Before, Max, - decode_rsm_index(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el)); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - decode_rsm_last(__TopXMLNS, __IgnoreEls, _el), - First, Count, Before, Max, Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - decode_rsm_last(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - First, Count, Before, Max, Index); - _ -> - 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) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, Before, - decode_rsm_max(__TopXMLNS, __IgnoreEls, _el), - Index); - <<"http://jabber.org/protocol/rsm">> -> - decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After, - Last, First, Count, Before, - decode_rsm_max(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Index); - _ -> - 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}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = lists:reverse('encode_rsm_set_$after'(After, - __NewTopXMLNS, - 'encode_rsm_set_$last'(Last, - __NewTopXMLNS, - 'encode_rsm_set_$first'(First, - __NewTopXMLNS, - 'encode_rsm_set_$count'(Count, - __NewTopXMLNS, - 'encode_rsm_set_$before'(Before, - __NewTopXMLNS, - 'encode_rsm_set_$max'(Max, - __NewTopXMLNS, - 'encode_rsm_set_$index'(Index, - __NewTopXMLNS, - [])))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"set">>, _attrs, _els}. - -'encode_rsm_set_$after'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$after'(After, __TopXMLNS, _acc) -> - [encode_rsm_after(After, __TopXMLNS) | _acc]. - -'encode_rsm_set_$last'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$last'(Last, __TopXMLNS, _acc) -> - [encode_rsm_last(Last, __TopXMLNS) | _acc]. - -'encode_rsm_set_$first'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$first'(First, __TopXMLNS, _acc) -> - [encode_rsm_first(First, __TopXMLNS) | _acc]. - -'encode_rsm_set_$count'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$count'(Count, __TopXMLNS, _acc) -> - [encode_rsm_count(Count, __TopXMLNS) | _acc]. - -'encode_rsm_set_$before'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$before'(Before, __TopXMLNS, _acc) -> - [encode_rsm_before(Before, __TopXMLNS) | _acc]. - -'encode_rsm_set_$max'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$max'(Max, __TopXMLNS, _acc) -> - [encode_rsm_max(Max, __TopXMLNS) | _acc]. - -'encode_rsm_set_$index'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_rsm_set_$index'(Index, __TopXMLNS, _acc) -> - [encode_rsm_index(Index, __TopXMLNS) | _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, - <>); -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}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_first_cdata(Data, []), - _attrs = encode_rsm_first_attr_index(Index, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {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, <<>>) -> <<>>; -decode_rsm_first_cdata(__TopXMLNS, _val) -> _val. - -encode_rsm_first_cdata(<<>>, _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, - <>); -decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_max(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_max_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, - <>); -decode_rsm_index_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_index(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_index_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, - <>); -decode_rsm_count_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_count(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_count_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {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, - <>); -decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_last(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_last_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"last">>, _attrs, _els}. - -decode_rsm_last_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_rsm_last_cdata(__TopXMLNS, _val) -> _val. - -encode_rsm_last_cdata(<<>>, _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, - <>); -decode_rsm_before_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_before(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_before_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"before">>, _attrs, _els}. - -decode_rsm_before_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_rsm_before_cdata(__TopXMLNS, _val) -> _val. - -encode_rsm_before_cdata(<<>>, _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, - <>); -decode_rsm_after_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_rsm_after_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_rsm_after(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/rsm">>, - [], __TopXMLNS), - _els = encode_rsm_after_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"after">>, _attrs, _els}. - -decode_rsm_after_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_rsm_after_cdata(__TopXMLNS, _val) -> _val. - -encode_rsm_after_cdata(<<>>, _acc) -> _acc; -encode_rsm_after_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_muc_unsubscribe(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unsubscribe">>, _attrs, _els}) -> - {muc_unsubscribe}. - -encode_muc_unsubscribe({muc_unsubscribe}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsubscribe">>, _attrs, _els}. - -decode_muc_subscribe(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscribe">>, _attrs, _els}) -> - Events = decode_muc_subscribe_els(__TopXMLNS, - __IgnoreEls, _els, []), - Nick = decode_muc_subscribe_attrs(__TopXMLNS, _attrs, - undefined), - {muc_subscribe, Nick, Events}. - -decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, [], - Events) -> - lists:reverse(Events); -decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"event">>, _attrs, _} = _el | _els], - Events) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mucsub:0">> -> - decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_subscribe_event(__TopXMLNS, - __IgnoreEls, _el) - | Events]); - <<"urn:xmpp:mucsub:0">> -> - decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_subscribe_event(<<"urn:xmpp:mucsub:0">>, - __IgnoreEls, _el) - | Events]); - _ -> - decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, - Events) - end; -decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Events) -> - decode_muc_subscribe_els(__TopXMLNS, __IgnoreEls, _els, - Events). - -decode_muc_subscribe_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], _Nick) -> - decode_muc_subscribe_attrs(__TopXMLNS, _attrs, _val); -decode_muc_subscribe_attrs(__TopXMLNS, [_ | _attrs], - Nick) -> - decode_muc_subscribe_attrs(__TopXMLNS, _attrs, Nick); -decode_muc_subscribe_attrs(__TopXMLNS, [], Nick) -> - decode_muc_subscribe_attr_nick(__TopXMLNS, Nick). - -encode_muc_subscribe({muc_subscribe, Nick, Events}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_muc_subscribe_$events'(Events, - __NewTopXMLNS, [])), - _attrs = encode_muc_subscribe_attr_nick(Nick, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"subscribe">>, _attrs, _els}. - -'encode_muc_subscribe_$events'([], __TopXMLNS, _acc) -> - _acc; -'encode_muc_subscribe_$events'([Events | _els], - __TopXMLNS, _acc) -> - 'encode_muc_subscribe_$events'(_els, __TopXMLNS, - [encode_muc_subscribe_event(Events, - __TopXMLNS) - | _acc]). - -decode_muc_subscribe_attr_nick(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"nick">>, <<"subscribe">>, - __TopXMLNS}}); -decode_muc_subscribe_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_subscribe_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_subscribe_event(__TopXMLNS, __IgnoreEls, - {xmlel, <<"event">>, _attrs, _els}) -> - Node = decode_muc_subscribe_event_attrs(__TopXMLNS, - _attrs, undefined), - Node. - -decode_muc_subscribe_event_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_muc_subscribe_event_attrs(__TopXMLNS, _attrs, - _val); -decode_muc_subscribe_event_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_muc_subscribe_event_attrs(__TopXMLNS, _attrs, - Node); -decode_muc_subscribe_event_attrs(__TopXMLNS, [], - Node) -> - decode_muc_subscribe_event_attr_node(__TopXMLNS, Node). - -encode_muc_subscribe_event(Node, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_muc_subscribe_event_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"event">>, _attrs, _els}. - -decode_muc_subscribe_event_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"event">>, __TopXMLNS}}); -decode_muc_subscribe_event_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_muc_subscribe_event_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_muc_subscriptions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscriptions">>, _attrs, _els}) -> - List = decode_muc_subscriptions_els(__TopXMLNS, - __IgnoreEls, _els, []), - {muc_subscriptions, List}. - -decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - [], List) -> - lists:reverse(List); -decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription">>, _attrs, _} = _el - | _els], - List) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:mucsub:0">> -> - decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_muc_subscription(__TopXMLNS, - __IgnoreEls, - _el) - | List]); - <<"urn:xmpp:mucsub:0">> -> - decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_muc_subscription(<<"urn:xmpp:mucsub:0">>, - __IgnoreEls, - _el) - | List]); - _ -> - decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, List) - end; -decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - [_ | _els], List) -> - decode_muc_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, List). - -encode_muc_subscriptions({muc_subscriptions, List}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_muc_subscriptions_$list'(List, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"subscriptions">>, _attrs, _els}. - -'encode_muc_subscriptions_$list'([], __TopXMLNS, - _acc) -> - _acc; -'encode_muc_subscriptions_$list'([List | _els], - __TopXMLNS, _acc) -> - 'encode_muc_subscriptions_$list'(_els, __TopXMLNS, - [encode_muc_subscription(List, __TopXMLNS) - | _acc]). - -decode_muc_subscription(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscription">>, _attrs, _els}) -> - Jid = decode_muc_subscription_attrs(__TopXMLNS, _attrs, - undefined), - Jid. - -decode_muc_subscription_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_muc_subscription_attrs(__TopXMLNS, _attrs, _val); -decode_muc_subscription_attrs(__TopXMLNS, [_ | _attrs], - Jid) -> - decode_muc_subscription_attrs(__TopXMLNS, _attrs, Jid); -decode_muc_subscription_attrs(__TopXMLNS, [], Jid) -> - decode_muc_subscription_attr_jid(__TopXMLNS, Jid). - -encode_muc_subscription(Jid, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:mucsub:0">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_muc_subscription_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"subscription">>, _attrs, _els}. - -decode_muc_subscription_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"subscription">>, - __TopXMLNS}}); -decode_muc_subscription_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"subscription">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_subscription_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_x_conference(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Jid, Password, Reason, Thread, Continue} = - decode_x_conference_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined, undefined), - {x_conference, Jid, Password, Reason, Continue, Thread}. - -decode_x_conference_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Password, Reason, - Thread, Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, _val, - Password, Reason, Thread, Continue); -decode_x_conference_attrs(__TopXMLNS, - [{<<"password">>, _val} | _attrs], Jid, _Password, - Reason, Thread, Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, _val, - Reason, Thread, Continue); -decode_x_conference_attrs(__TopXMLNS, - [{<<"reason">>, _val} | _attrs], Jid, Password, - _Reason, Thread, Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, - Password, _val, Thread, Continue); -decode_x_conference_attrs(__TopXMLNS, - [{<<"thread">>, _val} | _attrs], Jid, Password, - Reason, _Thread, Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, - Password, Reason, _val, Continue); -decode_x_conference_attrs(__TopXMLNS, - [{<<"continue">>, _val} | _attrs], Jid, Password, - Reason, Thread, _Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, - Password, Reason, Thread, _val); -decode_x_conference_attrs(__TopXMLNS, [_ | _attrs], Jid, - Password, Reason, Thread, Continue) -> - decode_x_conference_attrs(__TopXMLNS, _attrs, Jid, - Password, Reason, Thread, Continue); -decode_x_conference_attrs(__TopXMLNS, [], Jid, Password, - Reason, Thread, Continue) -> - {decode_x_conference_attr_jid(__TopXMLNS, Jid), - decode_x_conference_attr_password(__TopXMLNS, Password), - decode_x_conference_attr_reason(__TopXMLNS, Reason), - decode_x_conference_attr_thread(__TopXMLNS, Thread), - decode_x_conference_attr_continue(__TopXMLNS, - Continue)}. - -encode_x_conference({x_conference, Jid, Password, - Reason, Continue, Thread}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:x:conference">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_x_conference_attr_continue(Continue, - encode_x_conference_attr_thread(Thread, - encode_x_conference_attr_reason(Reason, - encode_x_conference_attr_password(Password, - encode_x_conference_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"x">>, _attrs, _els}. - -decode_x_conference_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"x">>, __TopXMLNS}}); -decode_x_conference_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"x">>, __TopXMLNS}}); - _res -> _res - end. - -encode_x_conference_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_x_conference_attr_password(__TopXMLNS, - undefined) -> - <<>>; -decode_x_conference_attr_password(__TopXMLNS, _val) -> - _val. - -encode_x_conference_attr_password(<<>>, _acc) -> _acc; -encode_x_conference_attr_password(_val, _acc) -> - [{<<"password">>, _val} | _acc]. - -decode_x_conference_attr_reason(__TopXMLNS, - undefined) -> - <<>>; -decode_x_conference_attr_reason(__TopXMLNS, _val) -> - _val. - -encode_x_conference_attr_reason(<<>>, _acc) -> _acc; -encode_x_conference_attr_reason(_val, _acc) -> - [{<<"reason">>, _val} | _acc]. - -decode_x_conference_attr_thread(__TopXMLNS, - undefined) -> - <<>>; -decode_x_conference_attr_thread(__TopXMLNS, _val) -> - _val. - -encode_x_conference_attr_thread(<<>>, _acc) -> _acc; -encode_x_conference_attr_thread(_val, _acc) -> - [{<<"thread">>, _val} | _acc]. - -decode_x_conference_attr_continue(__TopXMLNS, - undefined) -> - undefined; -decode_x_conference_attr_continue(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"continue">>, <<"x">>, __TopXMLNS}}); - _res -> _res - end. - -encode_x_conference_attr_continue(undefined, _acc) -> - _acc; -encode_x_conference_attr_continue(_val, _acc) -> - [{<<"continue">>, enc_bool(_val)} | _acc]. - -decode_muc_unique(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unique">>, _attrs, _els}) -> - Name = decode_muc_unique_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {muc_unique, Name}. - -decode_muc_unique_els(__TopXMLNS, __IgnoreEls, [], - Name) -> - decode_muc_unique_cdata(__TopXMLNS, Name); -decode_muc_unique_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Name) -> - decode_muc_unique_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_muc_unique_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Name) -> - decode_muc_unique_els(__TopXMLNS, __IgnoreEls, _els, - Name). - -encode_muc_unique({muc_unique, Name}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#unique">>, - [], __TopXMLNS), - _els = encode_muc_unique_cdata(Name, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unique">>, _attrs, _els}. - -decode_muc_unique_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_muc_unique_cdata(__TopXMLNS, _val) -> _val. - -encode_muc_unique_cdata(<<>>, _acc) -> _acc; -encode_muc_unique_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_muc(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Password, History} = decode_muc_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - {muc, History, Password}. - -decode_muc_els(__TopXMLNS, __IgnoreEls, [], Password, - History) -> - {Password, History}; -decode_muc_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"history">>, _attrs, _} = _el | _els], - Password, History) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, - decode_muc_history(__TopXMLNS, __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, - decode_muc_history(<<"http://jabber.org/protocol/muc">>, - __IgnoreEls, _el)); - _ -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, - History) - end; -decode_muc_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], - Password, History) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(__TopXMLNS, __IgnoreEls, _el), - History); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el), - History); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - History); - <<"http://jabber.org/protocol/muc">> -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc">>, - __IgnoreEls, _el), - History); - _ -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, - History) - end; -decode_muc_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Password, History) -> - decode_muc_els(__TopXMLNS, __IgnoreEls, _els, Password, - History). - -encode_muc({muc, History, Password}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc">>, - [], __TopXMLNS), - _els = lists:reverse('encode_muc_$password'(Password, - __NewTopXMLNS, - 'encode_muc_$history'(History, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_muc_$password'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_muc_$password'(Password, __TopXMLNS, _acc) -> - [encode_muc_password(Password, __TopXMLNS) | _acc]. - -'encode_muc_$history'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_muc_$history'(History, __TopXMLNS, _acc) -> - [encode_muc_history(History, __TopXMLNS) | _acc]. - -decode_muc_admin(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - Items = decode_muc_admin_els(__TopXMLNS, __IgnoreEls, - _els, []), - {muc_admin, Items}. - -decode_muc_admin_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_muc_admin_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_admin_item(__TopXMLNS, __IgnoreEls, - _el) - | Items]); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_admin_item(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_muc_admin_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_muc_admin_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -encode_muc_admin({muc_admin, Items}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, - [], __TopXMLNS), - _els = lists:reverse('encode_muc_admin_$items'(Items, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_muc_admin_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_muc_admin_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_muc_admin_$items'(_els, __TopXMLNS, - [encode_muc_admin_item(Items, __TopXMLNS) - | _acc]). - -decode_muc_admin_continue(__TopXMLNS, __IgnoreEls, - {xmlel, <<"continue">>, _attrs, _els}) -> - Thread = decode_muc_admin_continue_attrs(__TopXMLNS, - _attrs, undefined), - Thread. - -decode_muc_admin_continue_attrs(__TopXMLNS, - [{<<"thread">>, _val} | _attrs], _Thread) -> - decode_muc_admin_continue_attrs(__TopXMLNS, _attrs, - _val); -decode_muc_admin_continue_attrs(__TopXMLNS, - [_ | _attrs], Thread) -> - decode_muc_admin_continue_attrs(__TopXMLNS, _attrs, - Thread); -decode_muc_admin_continue_attrs(__TopXMLNS, [], - Thread) -> - decode_muc_admin_continue_attr_thread(__TopXMLNS, - Thread). - -encode_muc_admin_continue(Thread, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_admin_continue_attr_thread(Thread, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"continue">>, _attrs, _els}. - -decode_muc_admin_continue_attr_thread(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_admin_continue_attr_thread(__TopXMLNS, - _val) -> - _val. - -encode_muc_admin_continue_attr_thread(<<>>, _acc) -> - _acc; -encode_muc_admin_continue_attr_thread(_val, _acc) -> - [{<<"thread">>, _val} | _acc]. - -decode_muc_admin_actor(__TopXMLNS, __IgnoreEls, - {xmlel, <<"actor">>, _attrs, _els}) -> - {Jid, Nick} = decode_muc_admin_actor_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {muc_actor, Jid, Nick}. - -decode_muc_admin_actor_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> - decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, _val, - Nick); -decode_muc_admin_actor_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> - decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, Jid, - _val); -decode_muc_admin_actor_attrs(__TopXMLNS, [_ | _attrs], - Jid, Nick) -> - decode_muc_admin_actor_attrs(__TopXMLNS, _attrs, Jid, - Nick); -decode_muc_admin_actor_attrs(__TopXMLNS, [], Jid, - Nick) -> - {decode_muc_admin_actor_attr_jid(__TopXMLNS, Jid), - decode_muc_admin_actor_attr_nick(__TopXMLNS, Nick)}. - -encode_muc_admin_actor({muc_actor, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_admin_actor_attr_nick(Nick, - encode_muc_admin_actor_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"actor">>, _attrs, _els}. - -decode_muc_admin_actor_attr_jid(__TopXMLNS, - undefined) -> - undefined; -decode_muc_admin_actor_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"actor">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_admin_actor_attr_jid(undefined, _acc) -> - _acc; -encode_muc_admin_actor_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_admin_actor_attr_nick(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_admin_actor_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_admin_actor_attr_nick(<<>>, _acc) -> _acc; -encode_muc_admin_actor_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_admin_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Actor, Continue, Reason} = - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, <<>>), - {Affiliation, Role, Jid, Nick} = - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, undefined), - {muc_item, Actor, Continue, Reason, Affiliation, Role, - Jid, Nick}. - -decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, [], - Actor, Continue, Reason) -> - {Actor, Continue, Reason}; -decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_admin_actor(__TopXMLNS, - __IgnoreEls, _el), - Continue, Reason); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el), - Continue, Reason); - _ -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"continue">>, _attrs, _} = _el | _els], - Actor, Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, - decode_muc_admin_continue(__TopXMLNS, - __IgnoreEls, _el), - Reason); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, - decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Actor, Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Actor, Continue, Reason) -> - decode_muc_admin_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason). - -decode_muc_admin_item_attrs(__TopXMLNS, - [{<<"affiliation">>, _val} | _attrs], _Affiliation, - Role, Jid, Nick) -> - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, _val, - Role, Jid, Nick); -decode_muc_admin_item_attrs(__TopXMLNS, - [{<<"role">>, _val} | _attrs], Affiliation, _Role, - Jid, Nick) -> - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, - Affiliation, _val, Jid, Nick); -decode_muc_admin_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Affiliation, Role, - _Jid, Nick) -> - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, _val, Nick); -decode_muc_admin_item_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Affiliation, Role, - Jid, _Nick) -> - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, _val); -decode_muc_admin_item_attrs(__TopXMLNS, [_ | _attrs], - Affiliation, Role, Jid, Nick) -> - decode_muc_admin_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, Nick); -decode_muc_admin_item_attrs(__TopXMLNS, [], Affiliation, - Role, Jid, Nick) -> - {decode_muc_admin_item_attr_affiliation(__TopXMLNS, - Affiliation), - decode_muc_admin_item_attr_role(__TopXMLNS, Role), - decode_muc_admin_item_attr_jid(__TopXMLNS, Jid), - decode_muc_admin_item_attr_nick(__TopXMLNS, Nick)}. - -encode_muc_admin_item({muc_item, Actor, Continue, - Reason, Affiliation, Role, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#admin">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_admin_item_$actor'(Actor, - __NewTopXMLNS, - 'encode_muc_admin_item_$continue'(Continue, - __NewTopXMLNS, - 'encode_muc_admin_item_$reason'(Reason, - __NewTopXMLNS, - [])))), - _attrs = encode_muc_admin_item_attr_nick(Nick, - encode_muc_admin_item_attr_jid(Jid, - encode_muc_admin_item_attr_role(Role, - encode_muc_admin_item_attr_affiliation(Affiliation, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_muc_admin_item_$actor'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_admin_item_$actor'(Actor, __TopXMLNS, - _acc) -> - [encode_muc_admin_actor(Actor, __TopXMLNS) | _acc]. - -'encode_muc_admin_item_$continue'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_admin_item_$continue'(Continue, __TopXMLNS, - _acc) -> - [encode_muc_admin_continue(Continue, __TopXMLNS) - | _acc]. - -'encode_muc_admin_item_$reason'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_admin_item_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_admin_item_attr_affiliation(__TopXMLNS, - undefined) -> - undefined; -decode_muc_admin_item_attr_affiliation(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - [admin, member, none, outcast, owner]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"affiliation">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_admin_item_attr_affiliation(undefined, - _acc) -> - _acc; -encode_muc_admin_item_attr_affiliation(_val, _acc) -> - [{<<"affiliation">>, enc_enum(_val)} | _acc]. - -decode_muc_admin_item_attr_role(__TopXMLNS, - undefined) -> - undefined; -decode_muc_admin_item_attr_role(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [moderator, none, participant, visitor]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_admin_item_attr_role(undefined, _acc) -> - _acc; -encode_muc_admin_item_attr_role(_val, _acc) -> - [{<<"role">>, enc_enum(_val)} | _acc]. - -decode_muc_admin_item_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_muc_admin_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_admin_item_attr_jid(undefined, _acc) -> _acc; -encode_muc_admin_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_admin_item_attr_nick(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_admin_item_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_admin_item_attr_nick(<<>>, _acc) -> _acc; -encode_muc_admin_item_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_owner_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Actor, Continue, Reason} = - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, <<>>), - {Affiliation, Role, Jid, Nick} = - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, undefined), - {muc_item, Actor, Continue, Reason, Affiliation, Role, - Jid, Nick}. - -decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, [], - Actor, Continue, Reason) -> - {Actor, Continue, Reason}; -decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_admin_actor(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el), - Continue, Reason); - _ -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"continue">>, _attrs, _} = _el | _els], - Actor, Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, - decode_muc_admin_continue(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Actor, Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Actor, Continue, Reason) -> - decode_muc_owner_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason). - -decode_muc_owner_item_attrs(__TopXMLNS, - [{<<"affiliation">>, _val} | _attrs], _Affiliation, - Role, Jid, Nick) -> - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, _val, - Role, Jid, Nick); -decode_muc_owner_item_attrs(__TopXMLNS, - [{<<"role">>, _val} | _attrs], Affiliation, _Role, - Jid, Nick) -> - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, - Affiliation, _val, Jid, Nick); -decode_muc_owner_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Affiliation, Role, - _Jid, Nick) -> - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, _val, Nick); -decode_muc_owner_item_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Affiliation, Role, - Jid, _Nick) -> - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, _val); -decode_muc_owner_item_attrs(__TopXMLNS, [_ | _attrs], - Affiliation, Role, Jid, Nick) -> - decode_muc_owner_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, Nick); -decode_muc_owner_item_attrs(__TopXMLNS, [], Affiliation, - Role, Jid, Nick) -> - {decode_muc_owner_item_attr_affiliation(__TopXMLNS, - Affiliation), - decode_muc_owner_item_attr_role(__TopXMLNS, Role), - decode_muc_owner_item_attr_jid(__TopXMLNS, Jid), - decode_muc_owner_item_attr_nick(__TopXMLNS, Nick)}. - -encode_muc_owner_item({muc_item, Actor, Continue, - Reason, Affiliation, Role, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#owner">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_owner_item_$actor'(Actor, - __NewTopXMLNS, - 'encode_muc_owner_item_$continue'(Continue, - __NewTopXMLNS, - 'encode_muc_owner_item_$reason'(Reason, - __NewTopXMLNS, - [])))), - _attrs = encode_muc_owner_item_attr_nick(Nick, - encode_muc_owner_item_attr_jid(Jid, - encode_muc_owner_item_attr_role(Role, - encode_muc_owner_item_attr_affiliation(Affiliation, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_muc_owner_item_$actor'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_owner_item_$actor'(Actor, __TopXMLNS, - _acc) -> - [encode_muc_admin_actor(Actor, __TopXMLNS) | _acc]. - -'encode_muc_owner_item_$continue'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_owner_item_$continue'(Continue, __TopXMLNS, - _acc) -> - [encode_muc_admin_continue(Continue, __TopXMLNS) - | _acc]. - -'encode_muc_owner_item_$reason'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_owner_item_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_owner_item_attr_affiliation(__TopXMLNS, - undefined) -> - undefined; -decode_muc_owner_item_attr_affiliation(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - [admin, member, none, outcast, owner]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"affiliation">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_owner_item_attr_affiliation(undefined, - _acc) -> - _acc; -encode_muc_owner_item_attr_affiliation(_val, _acc) -> - [{<<"affiliation">>, enc_enum(_val)} | _acc]. - -decode_muc_owner_item_attr_role(__TopXMLNS, - undefined) -> - undefined; -decode_muc_owner_item_attr_role(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [moderator, none, participant, visitor]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_owner_item_attr_role(undefined, _acc) -> - _acc; -encode_muc_owner_item_attr_role(_val, _acc) -> - [{<<"role">>, enc_enum(_val)} | _acc]. - -decode_muc_owner_item_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_muc_owner_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_owner_item_attr_jid(undefined, _acc) -> _acc; -encode_muc_owner_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_owner_item_attr_nick(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_owner_item_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_owner_item_attr_nick(<<>>, _acc) -> _acc; -encode_muc_owner_item_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_owner(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Items, Config, Destroy} = - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, [], - undefined, undefined), - {muc_owner, Destroy, Config, Items}. - -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, [], Items, - Config, Destroy) -> - {lists:reverse(Items), Config, Destroy}; -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], Items, - Config, Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, - decode_muc_destroy(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, - decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, - decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, Destroy) - end; -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Items, - Config, Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_xdata(<<"jabber:x:data">>, __IgnoreEls, - _el), - Destroy); - _ -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, Destroy) - end; -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, - Config, Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_owner_item(__TopXMLNS, __IgnoreEls, - _el) - | Items], - Config, Destroy); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - [decode_muc_owner_item(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el) - | Items], - Config, Destroy); - _ -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, Destroy) - end; -decode_muc_owner_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items, Config, Destroy) -> - decode_muc_owner_els(__TopXMLNS, __IgnoreEls, _els, - Items, Config, Destroy). - -encode_muc_owner({muc_owner, Destroy, Config, Items}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#owner">>, - [], __TopXMLNS), - _els = lists:reverse('encode_muc_owner_$items'(Items, - __NewTopXMLNS, - 'encode_muc_owner_$config'(Config, - __NewTopXMLNS, - 'encode_muc_owner_$destroy'(Destroy, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_muc_owner_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_muc_owner_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_muc_owner_$items'(_els, __TopXMLNS, - [encode_muc_owner_item(Items, __TopXMLNS) - | _acc]). - -'encode_muc_owner_$config'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_owner_$config'(Config, __TopXMLNS, _acc) -> - [encode_xdata(Config, __TopXMLNS) | _acc]. - -'encode_muc_owner_$destroy'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_owner_$destroy'(Destroy, __TopXMLNS, - _acc) -> - [encode_muc_destroy(Destroy, __TopXMLNS) | _acc]. - -decode_muc_password(__TopXMLNS, __IgnoreEls, - {xmlel, <<"password">>, _attrs, _els}) -> - Cdata = decode_muc_password_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_muc_password_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_muc_password_cdata(__TopXMLNS, Cdata); -decode_muc_password_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_password_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_muc_password_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_password_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_muc_password(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/muc#owner">>, - <<"http://jabber.org/protocol/muc#user">>, - <<"http://jabber.org/protocol/muc">>], - __TopXMLNS), - _els = encode_muc_password_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"password">>, _attrs, _els}. - -decode_muc_password_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_muc_password_cdata(__TopXMLNS, _val) -> _val. - -encode_muc_password_cdata(<<>>, _acc) -> _acc; -encode_muc_password_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_muc_user(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Status_codes, Items, Invites, Password, Decline, - Destroy} = - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, [], - [], [], undefined, undefined, undefined), - {muc_user, Decline, Destroy, Invites, Items, - Status_codes, Password}. - -decode_muc_user_els(__TopXMLNS, __IgnoreEls, [], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - {lists:reverse(Status_codes), lists:reverse(Items), - lists:reverse(Invites), Password, Decline, Destroy}; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"decline">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, - decode_muc_user_decline(__TopXMLNS, __IgnoreEls, - _el), - Destroy); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, - decode_muc_user_decline(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Destroy); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"destroy">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - decode_muc_destroy(__TopXMLNS, __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - decode_muc_destroy(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - decode_muc_destroy(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, - decode_muc_password(__TopXMLNS, __IgnoreEls, _el), - Decline, Destroy); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, - decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el), - Decline, Destroy); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, - decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Decline, Destroy); - <<"http://jabber.org/protocol/muc">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, - decode_muc_password(<<"http://jabber.org/protocol/muc">>, - __IgnoreEls, _el), - Decline, Destroy); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invite">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, - [decode_muc_user_invite(__TopXMLNS, __IgnoreEls, - _el) - | Invites], - Password, Decline, Destroy); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, - [decode_muc_user_invite(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el) - | Invites], - Password, Decline, Destroy); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, - [decode_muc_user_item(__TopXMLNS, __IgnoreEls, - _el) - | Items], - Invites, Password, Decline, Destroy); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, - [decode_muc_user_item(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el) - | Items], - Invites, Password, Decline, Destroy); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"status">>, _attrs, _} = _el | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - case decode_muc_user_status(__TopXMLNS, - __IgnoreEls, _el) - of - undefined -> Status_codes; - _new_el -> [_new_el | Status_codes] - end, - Items, Invites, Password, Decline, Destroy); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - case - decode_muc_user_status(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el) - of - undefined -> Status_codes; - _new_el -> [_new_el | Status_codes] - end, - Items, Invites, Password, Decline, Destroy); - _ -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy) - end; -decode_muc_user_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Status_codes, Items, Invites, Password, Decline, - Destroy) -> - decode_muc_user_els(__TopXMLNS, __IgnoreEls, _els, - Status_codes, Items, Invites, Password, Decline, - Destroy). - -encode_muc_user({muc_user, Decline, Destroy, Invites, - Items, Status_codes, Password}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_user_$status_codes'(Status_codes, - __NewTopXMLNS, - 'encode_muc_user_$items'(Items, - __NewTopXMLNS, - 'encode_muc_user_$invites'(Invites, - __NewTopXMLNS, - 'encode_muc_user_$password'(Password, - __NewTopXMLNS, - 'encode_muc_user_$decline'(Decline, - __NewTopXMLNS, - 'encode_muc_user_$destroy'(Destroy, - __NewTopXMLNS, - []))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_muc_user_$status_codes'([], __TopXMLNS, _acc) -> - _acc; -'encode_muc_user_$status_codes'([Status_codes | _els], - __TopXMLNS, _acc) -> - 'encode_muc_user_$status_codes'(_els, __TopXMLNS, - [encode_muc_user_status(Status_codes, - __TopXMLNS) - | _acc]). - -'encode_muc_user_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_muc_user_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_muc_user_$items'(_els, __TopXMLNS, - [encode_muc_user_item(Items, __TopXMLNS) | _acc]). - -'encode_muc_user_$invites'([], __TopXMLNS, _acc) -> - _acc; -'encode_muc_user_$invites'([Invites | _els], __TopXMLNS, - _acc) -> - 'encode_muc_user_$invites'(_els, __TopXMLNS, - [encode_muc_user_invite(Invites, __TopXMLNS) - | _acc]). - -'encode_muc_user_$password'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_$password'(Password, __TopXMLNS, - _acc) -> - [encode_muc_password(Password, __TopXMLNS) | _acc]. - -'encode_muc_user_$decline'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_$decline'(Decline, __TopXMLNS, _acc) -> - [encode_muc_user_decline(Decline, __TopXMLNS) | _acc]. - -'encode_muc_user_$destroy'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_$destroy'(Destroy, __TopXMLNS, _acc) -> - [encode_muc_destroy(Destroy, __TopXMLNS) | _acc]. - -decode_muc_user_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Actor, Continue, Reason} = - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, <<>>), - {Affiliation, Role, Jid, Nick} = - decode_muc_user_item_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, undefined), - {muc_item, Actor, Continue, Reason, Affiliation, Role, - Jid, Nick}. - -decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, [], - Actor, Continue, Reason) -> - {Actor, Continue, Reason}; -decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"actor">>, _attrs, _} = _el | _els], Actor, - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_actor(__TopXMLNS, - __IgnoreEls, _el), - Continue, Reason); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_user_actor(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Continue, Reason); - _ -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"continue">>, _attrs, _} = _el | _els], - Actor, Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, - decode_muc_user_continue(__TopXMLNS, - __IgnoreEls, _el), - Reason); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, - decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], Actor, - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason) - end; -decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Actor, Continue, Reason) -> - decode_muc_user_item_els(__TopXMLNS, __IgnoreEls, _els, - Actor, Continue, Reason). - -decode_muc_user_item_attrs(__TopXMLNS, - [{<<"affiliation">>, _val} | _attrs], _Affiliation, - Role, Jid, Nick) -> - decode_muc_user_item_attrs(__TopXMLNS, _attrs, _val, - Role, Jid, Nick); -decode_muc_user_item_attrs(__TopXMLNS, - [{<<"role">>, _val} | _attrs], Affiliation, _Role, - Jid, Nick) -> - decode_muc_user_item_attrs(__TopXMLNS, _attrs, - Affiliation, _val, Jid, Nick); -decode_muc_user_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Affiliation, Role, - _Jid, Nick) -> - decode_muc_user_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, _val, Nick); -decode_muc_user_item_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Affiliation, Role, - Jid, _Nick) -> - decode_muc_user_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, _val); -decode_muc_user_item_attrs(__TopXMLNS, [_ | _attrs], - Affiliation, Role, Jid, Nick) -> - decode_muc_user_item_attrs(__TopXMLNS, _attrs, - Affiliation, Role, Jid, Nick); -decode_muc_user_item_attrs(__TopXMLNS, [], Affiliation, - Role, Jid, Nick) -> - {decode_muc_user_item_attr_affiliation(__TopXMLNS, - Affiliation), - decode_muc_user_item_attr_role(__TopXMLNS, Role), - decode_muc_user_item_attr_jid(__TopXMLNS, Jid), - decode_muc_user_item_attr_nick(__TopXMLNS, Nick)}. - -encode_muc_user_item({muc_item, Actor, Continue, Reason, - Affiliation, Role, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_user_item_$actor'(Actor, - __NewTopXMLNS, - 'encode_muc_user_item_$continue'(Continue, - __NewTopXMLNS, - 'encode_muc_user_item_$reason'(Reason, - __NewTopXMLNS, - [])))), - _attrs = encode_muc_user_item_attr_nick(Nick, - encode_muc_user_item_attr_jid(Jid, - encode_muc_user_item_attr_role(Role, - encode_muc_user_item_attr_affiliation(Affiliation, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_muc_user_item_$actor'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_item_$actor'(Actor, __TopXMLNS, - _acc) -> - [encode_muc_user_actor(Actor, __TopXMLNS) | _acc]. - -'encode_muc_user_item_$continue'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_item_$continue'(Continue, __TopXMLNS, - _acc) -> - [encode_muc_user_continue(Continue, __TopXMLNS) | _acc]. - -'encode_muc_user_item_$reason'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_item_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_user_item_attr_affiliation(__TopXMLNS, - undefined) -> - undefined; -decode_muc_user_item_attr_affiliation(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - [admin, member, none, outcast, owner]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"affiliation">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_item_attr_affiliation(undefined, - _acc) -> - _acc; -encode_muc_user_item_attr_affiliation(_val, _acc) -> - [{<<"affiliation">>, enc_enum(_val)} | _acc]. - -decode_muc_user_item_attr_role(__TopXMLNS, undefined) -> - undefined; -decode_muc_user_item_attr_role(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [moderator, none, participant, visitor]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"role">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_item_attr_role(undefined, _acc) -> _acc; -encode_muc_user_item_attr_role(_val, _acc) -> - [{<<"role">>, enc_enum(_val)} | _acc]. - -decode_muc_user_item_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_muc_user_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_item_attr_jid(undefined, _acc) -> _acc; -encode_muc_user_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_user_item_attr_nick(__TopXMLNS, undefined) -> - <<>>; -decode_muc_user_item_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_user_item_attr_nick(<<>>, _acc) -> _acc; -encode_muc_user_item_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_user_status(__TopXMLNS, __IgnoreEls, - {xmlel, <<"status">>, _attrs, _els}) -> - Code = decode_muc_user_status_attrs(__TopXMLNS, _attrs, - undefined), - Code. - -decode_muc_user_status_attrs(__TopXMLNS, - [{<<"code">>, _val} | _attrs], _Code) -> - decode_muc_user_status_attrs(__TopXMLNS, _attrs, _val); -decode_muc_user_status_attrs(__TopXMLNS, [_ | _attrs], - Code) -> - decode_muc_user_status_attrs(__TopXMLNS, _attrs, Code); -decode_muc_user_status_attrs(__TopXMLNS, [], Code) -> - decode_muc_user_status_attr_code(__TopXMLNS, Code). - -encode_muc_user_status(Code, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_user_status_attr_code(Code, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"status">>, _attrs, _els}. - -decode_muc_user_status_attr_code(__TopXMLNS, - undefined) -> - undefined; -decode_muc_user_status_attr_code(__TopXMLNS, _val) -> - case catch dec_int(_val, 100, 999) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"code">>, <<"status">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_status_attr_code(undefined, _acc) -> - _acc; -encode_muc_user_status_attr_code(_val, _acc) -> - [{<<"code">>, enc_int(_val)} | _acc]. - -decode_muc_user_continue(__TopXMLNS, __IgnoreEls, - {xmlel, <<"continue">>, _attrs, _els}) -> - Thread = decode_muc_user_continue_attrs(__TopXMLNS, - _attrs, undefined), - Thread. - -decode_muc_user_continue_attrs(__TopXMLNS, - [{<<"thread">>, _val} | _attrs], _Thread) -> - decode_muc_user_continue_attrs(__TopXMLNS, _attrs, - _val); -decode_muc_user_continue_attrs(__TopXMLNS, [_ | _attrs], - Thread) -> - decode_muc_user_continue_attrs(__TopXMLNS, _attrs, - Thread); -decode_muc_user_continue_attrs(__TopXMLNS, [], - Thread) -> - decode_muc_user_continue_attr_thread(__TopXMLNS, - Thread). - -encode_muc_user_continue(Thread, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_user_continue_attr_thread(Thread, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"continue">>, _attrs, _els}. - -decode_muc_user_continue_attr_thread(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_user_continue_attr_thread(__TopXMLNS, - _val) -> - _val. - -encode_muc_user_continue_attr_thread(<<>>, _acc) -> - _acc; -encode_muc_user_continue_attr_thread(_val, _acc) -> - [{<<"thread">>, _val} | _acc]. - -decode_muc_user_actor(__TopXMLNS, __IgnoreEls, - {xmlel, <<"actor">>, _attrs, _els}) -> - {Jid, Nick} = decode_muc_user_actor_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {muc_actor, Jid, Nick}. - -decode_muc_user_actor_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Nick) -> - decode_muc_user_actor_attrs(__TopXMLNS, _attrs, _val, - Nick); -decode_muc_user_actor_attrs(__TopXMLNS, - [{<<"nick">>, _val} | _attrs], Jid, _Nick) -> - decode_muc_user_actor_attrs(__TopXMLNS, _attrs, Jid, - _val); -decode_muc_user_actor_attrs(__TopXMLNS, [_ | _attrs], - Jid, Nick) -> - decode_muc_user_actor_attrs(__TopXMLNS, _attrs, Jid, - Nick); -decode_muc_user_actor_attrs(__TopXMLNS, [], Jid, - Nick) -> - {decode_muc_user_actor_attr_jid(__TopXMLNS, Jid), - decode_muc_user_actor_attr_nick(__TopXMLNS, Nick)}. - -encode_muc_user_actor({muc_actor, Jid, Nick}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_user_actor_attr_nick(Nick, - encode_muc_user_actor_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"actor">>, _attrs, _els}. - -decode_muc_user_actor_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_muc_user_actor_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"actor">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_actor_attr_jid(undefined, _acc) -> _acc; -encode_muc_user_actor_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_user_actor_attr_nick(__TopXMLNS, - undefined) -> - <<>>; -decode_muc_user_actor_attr_nick(__TopXMLNS, _val) -> - _val. - -encode_muc_user_actor_attr_nick(<<>>, _acc) -> _acc; -encode_muc_user_actor_attr_nick(_val, _acc) -> - [{<<"nick">>, _val} | _acc]. - -decode_muc_user_invite(__TopXMLNS, __IgnoreEls, - {xmlel, <<"invite">>, _attrs, _els}) -> - {Continue, Reason} = - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, undefined, <<>>), - {To, From} = decode_muc_user_invite_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {muc_invite, Reason, From, To, Continue}. - -decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, [], - Continue, Reason) -> - {Continue, Reason}; -decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, Reason) - end; -decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"continue">>, _attrs, _} = _el | _els], - Continue, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_user_continue(__TopXMLNS, - __IgnoreEls, _el), - Reason); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_user_continue(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, Reason) - end; -decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Continue, Reason) -> - decode_muc_user_invite_els(__TopXMLNS, __IgnoreEls, - _els, Continue, Reason). - -decode_muc_user_invite_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], _To, From) -> - decode_muc_user_invite_attrs(__TopXMLNS, _attrs, _val, - From); -decode_muc_user_invite_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], To, _From) -> - decode_muc_user_invite_attrs(__TopXMLNS, _attrs, To, - _val); -decode_muc_user_invite_attrs(__TopXMLNS, [_ | _attrs], - To, From) -> - decode_muc_user_invite_attrs(__TopXMLNS, _attrs, To, - From); -decode_muc_user_invite_attrs(__TopXMLNS, [], To, - From) -> - {decode_muc_user_invite_attr_to(__TopXMLNS, To), - decode_muc_user_invite_attr_from(__TopXMLNS, From)}. - -encode_muc_user_invite({muc_invite, Reason, From, To, - Continue}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_user_invite_$continue'(Continue, - __NewTopXMLNS, - 'encode_muc_user_invite_$reason'(Reason, - __NewTopXMLNS, - []))), - _attrs = encode_muc_user_invite_attr_from(From, - encode_muc_user_invite_attr_to(To, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"invite">>, _attrs, _els}. - -'encode_muc_user_invite_$continue'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_muc_user_invite_$continue'(Continue, __TopXMLNS, - _acc) -> - [encode_muc_user_continue(Continue, __TopXMLNS) | _acc]. - -'encode_muc_user_invite_$reason'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_invite_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_user_invite_attr_to(__TopXMLNS, undefined) -> - undefined; -decode_muc_user_invite_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"invite">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_invite_attr_to(undefined, _acc) -> _acc; -encode_muc_user_invite_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -decode_muc_user_invite_attr_from(__TopXMLNS, - undefined) -> - undefined; -decode_muc_user_invite_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"invite">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_invite_attr_from(undefined, _acc) -> - _acc; -encode_muc_user_invite_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_muc_destroy(__TopXMLNS, __IgnoreEls, - {xmlel, <<"destroy">>, _attrs, _els}) -> - {Password, Reason} = decode_muc_destroy_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - <<>>), - {Jid, Xmlns} = decode_muc_destroy_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {muc_destroy, Xmlns, Jid, Reason, Password}. - -decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, [], - Password, Reason) -> - {Password, Reason}; -decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Password, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">>; - __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, Reason) - end; -decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], - Password, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">>; - __TopXMLNS == - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(__TopXMLNS, __IgnoreEls, - _el), - Reason); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el), - Reason); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el), - Reason); - <<"http://jabber.org/protocol/muc">> -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - decode_muc_password(<<"http://jabber.org/protocol/muc">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, Reason) - end; -decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Password, Reason) -> - decode_muc_destroy_els(__TopXMLNS, __IgnoreEls, _els, - Password, Reason). - -decode_muc_destroy_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Xmlns) -> - decode_muc_destroy_attrs(__TopXMLNS, _attrs, _val, - Xmlns); -decode_muc_destroy_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Jid, _Xmlns) -> - decode_muc_destroy_attrs(__TopXMLNS, _attrs, Jid, _val); -decode_muc_destroy_attrs(__TopXMLNS, [_ | _attrs], Jid, - Xmlns) -> - decode_muc_destroy_attrs(__TopXMLNS, _attrs, Jid, - Xmlns); -decode_muc_destroy_attrs(__TopXMLNS, [], Jid, Xmlns) -> - {decode_muc_destroy_attr_jid(__TopXMLNS, Jid), - decode_muc_destroy_attr_xmlns(__TopXMLNS, Xmlns)}. - -encode_muc_destroy({muc_destroy, Xmlns, Jid, Reason, - Password}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/muc#user">>, - <<"http://jabber.org/protocol/muc#owner">>], - __TopXMLNS), - _els = - lists:reverse('encode_muc_destroy_$password'(Password, - __NewTopXMLNS, - 'encode_muc_destroy_$reason'(Reason, - __NewTopXMLNS, - []))), - _attrs = encode_muc_destroy_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"destroy">>, _attrs, _els}. - -'encode_muc_destroy_$password'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_destroy_$password'(Password, __TopXMLNS, - _acc) -> - [encode_muc_password(Password, __TopXMLNS) | _acc]. - -'encode_muc_destroy_$reason'(<<>>, __TopXMLNS, _acc) -> - _acc; -'encode_muc_destroy_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_destroy_attr_jid(__TopXMLNS, undefined) -> - undefined; -decode_muc_destroy_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"destroy">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_destroy_attr_jid(undefined, _acc) -> _acc; -encode_muc_destroy_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_muc_destroy_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_muc_destroy_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_muc_user_decline(__TopXMLNS, __IgnoreEls, - {xmlel, <<"decline">>, _attrs, _els}) -> - Reason = decode_muc_user_decline_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - {To, From} = decode_muc_user_decline_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {muc_decline, Reason, From, To}. - -decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - Reason; -decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reason">>, _attrs, _} = _el | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_reason(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/muc#user">> -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_reason(<<"http://jabber.org/protocol/muc#user">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#admin">> -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_reason(<<"http://jabber.org/protocol/muc#admin">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/muc#owner">> -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, - decode_muc_reason(<<"http://jabber.org/protocol/muc#owner">>, - __IgnoreEls, _el)); - _ -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, Reason) - end; -decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> - decode_muc_user_decline_els(__TopXMLNS, __IgnoreEls, - _els, Reason). - -decode_muc_user_decline_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], _To, From) -> - decode_muc_user_decline_attrs(__TopXMLNS, _attrs, _val, - From); -decode_muc_user_decline_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], To, _From) -> - decode_muc_user_decline_attrs(__TopXMLNS, _attrs, To, - _val); -decode_muc_user_decline_attrs(__TopXMLNS, [_ | _attrs], - To, From) -> - decode_muc_user_decline_attrs(__TopXMLNS, _attrs, To, - From); -decode_muc_user_decline_attrs(__TopXMLNS, [], To, - From) -> - {decode_muc_user_decline_attr_to(__TopXMLNS, To), - decode_muc_user_decline_attr_from(__TopXMLNS, From)}. - -encode_muc_user_decline({muc_decline, Reason, From, To}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc#user">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_muc_user_decline_$reason'(Reason, - __NewTopXMLNS, [])), - _attrs = encode_muc_user_decline_attr_from(From, - encode_muc_user_decline_attr_to(To, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"decline">>, _attrs, _els}. - -'encode_muc_user_decline_$reason'(<<>>, __TopXMLNS, - _acc) -> - _acc; -'encode_muc_user_decline_$reason'(Reason, __TopXMLNS, - _acc) -> - [encode_muc_reason(Reason, __TopXMLNS) | _acc]. - -decode_muc_user_decline_attr_to(__TopXMLNS, - undefined) -> - undefined; -decode_muc_user_decline_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"decline">>, __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_decline_attr_to(undefined, _acc) -> - _acc; -encode_muc_user_decline_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -decode_muc_user_decline_attr_from(__TopXMLNS, - undefined) -> - undefined; -decode_muc_user_decline_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"decline">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_user_decline_attr_from(undefined, _acc) -> - _acc; -encode_muc_user_decline_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_muc_reason(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reason">>, _attrs, _els}) -> - Cdata = decode_muc_reason_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_muc_reason_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_muc_reason_cdata(__TopXMLNS, Cdata); -decode_muc_reason_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_muc_reason_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_muc_reason_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_muc_reason_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_muc_reason(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/muc#user">>, - <<"http://jabber.org/protocol/muc#admin">>, - <<"http://jabber.org/protocol/muc#owner">>], - __TopXMLNS), - _els = encode_muc_reason_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"reason">>, _attrs, _els}. - -decode_muc_reason_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_muc_reason_cdata(__TopXMLNS, _val) -> _val. - -encode_muc_reason_cdata(<<>>, _acc) -> _acc; -encode_muc_reason_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_muc_history(__TopXMLNS, __IgnoreEls, - {xmlel, <<"history">>, _attrs, _els}) -> - {Maxchars, Maxstanzas, Seconds, Since} = - decode_muc_history_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {muc_history, Maxchars, Maxstanzas, Seconds, Since}. - -decode_muc_history_attrs(__TopXMLNS, - [{<<"maxchars">>, _val} | _attrs], _Maxchars, - Maxstanzas, Seconds, Since) -> - decode_muc_history_attrs(__TopXMLNS, _attrs, _val, - Maxstanzas, Seconds, Since); -decode_muc_history_attrs(__TopXMLNS, - [{<<"maxstanzas">>, _val} | _attrs], Maxchars, - _Maxstanzas, Seconds, Since) -> - decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, - _val, Seconds, Since); -decode_muc_history_attrs(__TopXMLNS, - [{<<"seconds">>, _val} | _attrs], Maxchars, Maxstanzas, - _Seconds, Since) -> - decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, - Maxstanzas, _val, Since); -decode_muc_history_attrs(__TopXMLNS, - [{<<"since">>, _val} | _attrs], Maxchars, Maxstanzas, - Seconds, _Since) -> - decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, - Maxstanzas, Seconds, _val); -decode_muc_history_attrs(__TopXMLNS, [_ | _attrs], - Maxchars, Maxstanzas, Seconds, Since) -> - decode_muc_history_attrs(__TopXMLNS, _attrs, Maxchars, - Maxstanzas, Seconds, Since); -decode_muc_history_attrs(__TopXMLNS, [], Maxchars, - Maxstanzas, Seconds, Since) -> - {decode_muc_history_attr_maxchars(__TopXMLNS, Maxchars), - decode_muc_history_attr_maxstanzas(__TopXMLNS, - Maxstanzas), - decode_muc_history_attr_seconds(__TopXMLNS, Seconds), - decode_muc_history_attr_since(__TopXMLNS, Since)}. - -encode_muc_history({muc_history, Maxchars, Maxstanzas, - Seconds, Since}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/muc">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_muc_history_attr_since(Since, - encode_muc_history_attr_seconds(Seconds, - encode_muc_history_attr_maxstanzas(Maxstanzas, - encode_muc_history_attr_maxchars(Maxchars, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"history">>, _attrs, _els}. - -decode_muc_history_attr_maxchars(__TopXMLNS, - undefined) -> - undefined; -decode_muc_history_attr_maxchars(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"maxchars">>, <<"history">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_history_attr_maxchars(undefined, _acc) -> - _acc; -encode_muc_history_attr_maxchars(_val, _acc) -> - [{<<"maxchars">>, enc_int(_val)} | _acc]. - -decode_muc_history_attr_maxstanzas(__TopXMLNS, - undefined) -> - undefined; -decode_muc_history_attr_maxstanzas(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"maxstanzas">>, <<"history">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_history_attr_maxstanzas(undefined, _acc) -> - _acc; -encode_muc_history_attr_maxstanzas(_val, _acc) -> - [{<<"maxstanzas">>, enc_int(_val)} | _acc]. - -decode_muc_history_attr_seconds(__TopXMLNS, - undefined) -> - undefined; -decode_muc_history_attr_seconds(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"seconds">>, <<"history">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_history_attr_seconds(undefined, _acc) -> - _acc; -encode_muc_history_attr_seconds(_val, _acc) -> - [{<<"seconds">>, enc_int(_val)} | _acc]. - -decode_muc_history_attr_since(__TopXMLNS, undefined) -> - undefined; -decode_muc_history_attr_since(__TopXMLNS, _val) -> - case catch dec_utc(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"since">>, <<"history">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_muc_history_attr_since(undefined, _acc) -> _acc; -encode_muc_history_attr_since(_val, _acc) -> - [{<<"since">>, enc_utc(_val)} | _acc]. - -decode_bytestreams(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Hosts, Used, Activate} = - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - [], undefined, undefined), - {Dstaddr, Sid, Mode} = - decode_bytestreams_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined), - {bytestreams, Hosts, Used, Activate, Dstaddr, Mode, - Sid}. - -decode_bytestreams_els(__TopXMLNS, __IgnoreEls, [], - Hosts, Used, Activate) -> - {lists:reverse(Hosts), Used, Activate}; -decode_bytestreams_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"streamhost">>, _attrs, _} = _el | _els], - Hosts, Used, Activate) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - [decode_bytestreams_streamhost(__TopXMLNS, - __IgnoreEls, - _el) - | Hosts], - Used, Activate); - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - [decode_bytestreams_streamhost(<<"http://jabber.org/protocol/bytestreams">>, - __IgnoreEls, - _el) - | Hosts], - Used, Activate); - _ -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, Activate) - end; -decode_bytestreams_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"streamhost-used">>, _attrs, _} = _el - | _els], - Hosts, Used, Activate) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, - decode_bytestreams_streamhost_used(__TopXMLNS, - __IgnoreEls, - _el), - Activate); - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, - decode_bytestreams_streamhost_used(<<"http://jabber.org/protocol/bytestreams">>, - __IgnoreEls, - _el), - Activate); - _ -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, Activate) - end; -decode_bytestreams_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"activate">>, _attrs, _} = _el | _els], - Hosts, Used, Activate) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, - decode_bytestreams_activate(__TopXMLNS, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/bytestreams">> -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, - decode_bytestreams_activate(<<"http://jabber.org/protocol/bytestreams">>, - __IgnoreEls, _el)); - _ -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, Activate) - end; -decode_bytestreams_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Hosts, Used, Activate) -> - decode_bytestreams_els(__TopXMLNS, __IgnoreEls, _els, - Hosts, Used, Activate). - -decode_bytestreams_attrs(__TopXMLNS, - [{<<"dstaddr">>, _val} | _attrs], _Dstaddr, Sid, - Mode) -> - decode_bytestreams_attrs(__TopXMLNS, _attrs, _val, Sid, - Mode); -decode_bytestreams_attrs(__TopXMLNS, - [{<<"sid">>, _val} | _attrs], Dstaddr, _Sid, Mode) -> - decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, - _val, Mode); -decode_bytestreams_attrs(__TopXMLNS, - [{<<"mode">>, _val} | _attrs], Dstaddr, Sid, _Mode) -> - decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, - Sid, _val); -decode_bytestreams_attrs(__TopXMLNS, [_ | _attrs], - Dstaddr, Sid, Mode) -> - decode_bytestreams_attrs(__TopXMLNS, _attrs, Dstaddr, - Sid, Mode); -decode_bytestreams_attrs(__TopXMLNS, [], Dstaddr, Sid, - Mode) -> - {decode_bytestreams_attr_dstaddr(__TopXMLNS, Dstaddr), - decode_bytestreams_attr_sid(__TopXMLNS, Sid), - decode_bytestreams_attr_mode(__TopXMLNS, Mode)}. - -encode_bytestreams({bytestreams, Hosts, Used, Activate, - Dstaddr, Mode, Sid}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, - [], __TopXMLNS), - _els = lists:reverse('encode_bytestreams_$hosts'(Hosts, - __NewTopXMLNS, - 'encode_bytestreams_$used'(Used, - __NewTopXMLNS, - 'encode_bytestreams_$activate'(Activate, - __NewTopXMLNS, - [])))), - _attrs = encode_bytestreams_attr_mode(Mode, - encode_bytestreams_attr_sid(Sid, - encode_bytestreams_attr_dstaddr(Dstaddr, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_bytestreams_$hosts'([], __TopXMLNS, _acc) -> - _acc; -'encode_bytestreams_$hosts'([Hosts | _els], __TopXMLNS, - _acc) -> - 'encode_bytestreams_$hosts'(_els, __TopXMLNS, - [encode_bytestreams_streamhost(Hosts, - __TopXMLNS) - | _acc]). - -'encode_bytestreams_$used'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_bytestreams_$used'(Used, __TopXMLNS, _acc) -> - [encode_bytestreams_streamhost_used(Used, __TopXMLNS) - | _acc]. - -'encode_bytestreams_$activate'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_bytestreams_$activate'(Activate, __TopXMLNS, - _acc) -> - [encode_bytestreams_activate(Activate, __TopXMLNS) - | _acc]. - -decode_bytestreams_attr_dstaddr(__TopXMLNS, - undefined) -> - <<>>; -decode_bytestreams_attr_dstaddr(__TopXMLNS, _val) -> - _val. - -encode_bytestreams_attr_dstaddr(<<>>, _acc) -> _acc; -encode_bytestreams_attr_dstaddr(_val, _acc) -> - [{<<"dstaddr">>, _val} | _acc]. - -decode_bytestreams_attr_sid(__TopXMLNS, undefined) -> - <<>>; -decode_bytestreams_attr_sid(__TopXMLNS, _val) -> _val. - -encode_bytestreams_attr_sid(<<>>, _acc) -> _acc; -encode_bytestreams_attr_sid(_val, _acc) -> - [{<<"sid">>, _val} | _acc]. - -decode_bytestreams_attr_mode(__TopXMLNS, undefined) -> - tcp; -decode_bytestreams_attr_mode(__TopXMLNS, _val) -> - case catch dec_enum(_val, [tcp, udp]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"mode">>, <<"query">>, __TopXMLNS}}); - _res -> _res - end. - -encode_bytestreams_attr_mode(tcp, _acc) -> _acc; -encode_bytestreams_attr_mode(_val, _acc) -> - [{<<"mode">>, enc_enum(_val)} | _acc]. - -decode_bytestreams_activate(__TopXMLNS, __IgnoreEls, - {xmlel, <<"activate">>, _attrs, _els}) -> - Cdata = decode_bytestreams_activate_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_bytestreams_activate_cdata(__TopXMLNS, Cdata); -decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_bytestreams_activate_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_bytestreams_activate(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, - [], __TopXMLNS), - _els = encode_bytestreams_activate_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"activate">>, _attrs, _els}. - -decode_bytestreams_activate_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_bytestreams_activate_cdata(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"activate">>, __TopXMLNS}}); - _res -> _res - end. - -encode_bytestreams_activate_cdata(undefined, _acc) -> - _acc; -encode_bytestreams_activate_cdata(_val, _acc) -> - [{xmlcdata, enc_jid(_val)} | _acc]. - -decode_bytestreams_streamhost_used(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"streamhost-used">>, _attrs, - _els}) -> - Jid = - decode_bytestreams_streamhost_used_attrs(__TopXMLNS, - _attrs, undefined), - Jid. - -decode_bytestreams_streamhost_used_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_bytestreams_streamhost_used_attrs(__TopXMLNS, - _attrs, _val); -decode_bytestreams_streamhost_used_attrs(__TopXMLNS, - [_ | _attrs], Jid) -> - decode_bytestreams_streamhost_used_attrs(__TopXMLNS, - _attrs, Jid); -decode_bytestreams_streamhost_used_attrs(__TopXMLNS, [], - Jid) -> - decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, - Jid). - -encode_bytestreams_streamhost_used(Jid, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, - [], __TopXMLNS), - _els = [], - _attrs = - encode_bytestreams_streamhost_used_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"streamhost-used">>, _attrs, _els}. - -decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"streamhost-used">>, - __TopXMLNS}}); -decode_bytestreams_streamhost_used_attr_jid(__TopXMLNS, - _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"streamhost-used">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_bytestreams_streamhost_used_attr_jid(_val, - _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_bytestreams_streamhost(__TopXMLNS, __IgnoreEls, - {xmlel, <<"streamhost">>, _attrs, _els}) -> - {Jid, Host, Port} = - decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {streamhost, Jid, Host, Port}. - -decode_bytestreams_streamhost_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Host, - Port) -> - decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, - _val, Host, Port); -decode_bytestreams_streamhost_attrs(__TopXMLNS, - [{<<"host">>, _val} | _attrs], Jid, _Host, - Port) -> - decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, - Jid, _val, Port); -decode_bytestreams_streamhost_attrs(__TopXMLNS, - [{<<"port">>, _val} | _attrs], Jid, Host, - _Port) -> - decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, - Jid, Host, _val); -decode_bytestreams_streamhost_attrs(__TopXMLNS, - [_ | _attrs], Jid, Host, Port) -> - decode_bytestreams_streamhost_attrs(__TopXMLNS, _attrs, - Jid, Host, Port); -decode_bytestreams_streamhost_attrs(__TopXMLNS, [], Jid, - Host, Port) -> - {decode_bytestreams_streamhost_attr_jid(__TopXMLNS, - Jid), - decode_bytestreams_streamhost_attr_host(__TopXMLNS, - Host), - decode_bytestreams_streamhost_attr_port(__TopXMLNS, - Port)}. - -encode_bytestreams_streamhost({streamhost, Jid, Host, - Port}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/bytestreams">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_bytestreams_streamhost_attr_port(Port, - encode_bytestreams_streamhost_attr_host(Host, - encode_bytestreams_streamhost_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"streamhost">>, _attrs, _els}. - -decode_bytestreams_streamhost_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"streamhost">>, - __TopXMLNS}}); -decode_bytestreams_streamhost_attr_jid(__TopXMLNS, - _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"streamhost">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_bytestreams_streamhost_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_bytestreams_streamhost_attr_host(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"host">>, <<"streamhost">>, - __TopXMLNS}}); -decode_bytestreams_streamhost_attr_host(__TopXMLNS, - _val) -> - _val. - -encode_bytestreams_streamhost_attr_host(_val, _acc) -> - [{<<"host">>, _val} | _acc]. - -decode_bytestreams_streamhost_attr_port(__TopXMLNS, - undefined) -> - 1080; -decode_bytestreams_streamhost_attr_port(__TopXMLNS, - _val) -> - case catch dec_int(_val, 0, 65535) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"port">>, <<"streamhost">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_bytestreams_streamhost_attr_port(1080, _acc) -> - _acc; -encode_bytestreams_streamhost_attr_port(_val, _acc) -> - [{<<"port">>, enc_int(_val)} | _acc]. - -decode_delay(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delay">>, _attrs, _els}) -> - Desc = decode_delay_els(__TopXMLNS, __IgnoreEls, _els, - <<>>), - {Stamp, From} = decode_delay_attrs(__TopXMLNS, _attrs, - undefined, undefined), - {delay, Stamp, From, Desc}. - -decode_delay_els(__TopXMLNS, __IgnoreEls, [], Desc) -> - decode_delay_cdata(__TopXMLNS, Desc); -decode_delay_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Desc) -> - decode_delay_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_delay_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Desc) -> - decode_delay_els(__TopXMLNS, __IgnoreEls, _els, Desc). - -decode_delay_attrs(__TopXMLNS, - [{<<"stamp">>, _val} | _attrs], _Stamp, From) -> - decode_delay_attrs(__TopXMLNS, _attrs, _val, From); -decode_delay_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], Stamp, _From) -> - decode_delay_attrs(__TopXMLNS, _attrs, Stamp, _val); -decode_delay_attrs(__TopXMLNS, [_ | _attrs], Stamp, - From) -> - decode_delay_attrs(__TopXMLNS, _attrs, Stamp, From); -decode_delay_attrs(__TopXMLNS, [], Stamp, From) -> - {decode_delay_attr_stamp(__TopXMLNS, Stamp), - decode_delay_attr_from(__TopXMLNS, From)}. - -encode_delay({delay, Stamp, From, Desc}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:delay">>, - [], __TopXMLNS), - _els = encode_delay_cdata(Desc, []), - _attrs = encode_delay_attr_from(From, - encode_delay_attr_stamp(Stamp, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"delay">>, _attrs, _els}. - -decode_delay_attr_stamp(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"stamp">>, <<"delay">>, __TopXMLNS}}); -decode_delay_attr_stamp(__TopXMLNS, _val) -> - case catch dec_utc(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"stamp">>, <<"delay">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_delay_attr_stamp(_val, _acc) -> - [{<<"stamp">>, enc_utc(_val)} | _acc]. - -decode_delay_attr_from(__TopXMLNS, undefined) -> - undefined; -decode_delay_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"delay">>, __TopXMLNS}}); - _res -> _res - end. - -encode_delay_attr_from(undefined, _acc) -> _acc; -encode_delay_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_delay_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_delay_cdata(__TopXMLNS, _val) -> _val. - -encode_delay_cdata(<<>>, _acc) -> _acc; -encode_delay_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_chatstate_paused(__TopXMLNS, __IgnoreEls, - {xmlel, <<"paused">>, _attrs, _els}) -> - {chatstate, paused}. - -encode_chatstate_paused({chatstate, paused}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"paused">>, _attrs, _els}. - -decode_chatstate_inactive(__TopXMLNS, __IgnoreEls, - {xmlel, <<"inactive">>, _attrs, _els}) -> - {chatstate, inactive}. - -encode_chatstate_inactive({chatstate, inactive}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"inactive">>, _attrs, _els}. - -decode_chatstate_gone(__TopXMLNS, __IgnoreEls, - {xmlel, <<"gone">>, _attrs, _els}) -> - {chatstate, gone}. - -encode_chatstate_gone({chatstate, gone}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"gone">>, _attrs, _els}. - -decode_chatstate_composing(__TopXMLNS, __IgnoreEls, - {xmlel, <<"composing">>, _attrs, _els}) -> - {chatstate, composing}. - -encode_chatstate_composing({chatstate, composing}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"composing">>, _attrs, _els}. - -decode_chatstate_active(__TopXMLNS, __IgnoreEls, - {xmlel, <<"active">>, _attrs, _els}) -> - {chatstate, active}. - -encode_chatstate_active({chatstate, active}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/chatstates">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"active">>, _attrs, _els}. - -decode_shim_headers(__TopXMLNS, __IgnoreEls, - {xmlel, <<"headers">>, _attrs, _els}) -> - Headers = decode_shim_headers_els(__TopXMLNS, - __IgnoreEls, _els, []), - {shim, Headers}. - -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, [], - Headers) -> - lists:reverse(Headers); -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"header">>, _attrs, _} = _el | _els], - Headers) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/shim">> -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - [decode_shim_header(__TopXMLNS, __IgnoreEls, - _el) - | Headers]); - <<"http://jabber.org/protocol/shim">> -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - [decode_shim_header(<<"http://jabber.org/protocol/shim">>, - __IgnoreEls, _el) - | Headers]); - _ -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - Headers) - end; -decode_shim_headers_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Headers) -> - decode_shim_headers_els(__TopXMLNS, __IgnoreEls, _els, - Headers). - -encode_shim_headers({shim, Headers}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/shim">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_shim_headers_$headers'(Headers, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"headers">>, _attrs, _els}. - -'encode_shim_headers_$headers'([], __TopXMLNS, _acc) -> - _acc; -'encode_shim_headers_$headers'([Headers | _els], - __TopXMLNS, _acc) -> - 'encode_shim_headers_$headers'(_els, __TopXMLNS, - [encode_shim_header(Headers, __TopXMLNS) - | _acc]). - -decode_shim_header(__TopXMLNS, __IgnoreEls, - {xmlel, <<"header">>, _attrs, _els}) -> - Cdata = decode_shim_header_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Name = decode_shim_header_attrs(__TopXMLNS, _attrs, - undefined), - {Name, Cdata}. - -decode_shim_header_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_shim_header_cdata(__TopXMLNS, Cdata); -decode_shim_header_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_shim_header_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_shim_header_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -decode_shim_header_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_shim_header_attrs(__TopXMLNS, _attrs, _val); -decode_shim_header_attrs(__TopXMLNS, [_ | _attrs], - Name) -> - decode_shim_header_attrs(__TopXMLNS, _attrs, Name); -decode_shim_header_attrs(__TopXMLNS, [], Name) -> - decode_shim_header_attr_name(__TopXMLNS, Name). - -encode_shim_header({Name, Cdata}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/shim">>, - [], __TopXMLNS), - _els = encode_shim_header_cdata(Cdata, []), - _attrs = encode_shim_header_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"header">>, _attrs, _els}. - -decode_shim_header_attr_name(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"header">>, __TopXMLNS}}); -decode_shim_header_attr_name(__TopXMLNS, _val) -> _val. - -encode_shim_header_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_shim_header_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_shim_header_cdata(__TopXMLNS, _val) -> _val. - -encode_shim_header_cdata(<<>>, _acc) -> _acc; -encode_shim_header_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_pubsub_error_unsupported_access_model(__TopXMLNS, - __IgnoreEls, - {xmlel, - <<"unsupported-access-model">>, - _attrs, _els}) -> - {ps_error, 'unsupported-access-model', undefined}. - -encode_pubsub_error_unsupported_access_model({ps_error, - 'unsupported-access-model', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsupported-access-model">>, _attrs, _els}. - -decode_pubsub_error_unsupported(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unsupported">>, _attrs, _els}) -> - Feature = - decode_pubsub_error_unsupported_attrs(__TopXMLNS, - _attrs, undefined), - {ps_error, unsupported, Feature}. - -decode_pubsub_error_unsupported_attrs(__TopXMLNS, - [{<<"feature">>, _val} | _attrs], - _Feature) -> - decode_pubsub_error_unsupported_attrs(__TopXMLNS, - _attrs, _val); -decode_pubsub_error_unsupported_attrs(__TopXMLNS, - [_ | _attrs], Feature) -> - decode_pubsub_error_unsupported_attrs(__TopXMLNS, - _attrs, Feature); -decode_pubsub_error_unsupported_attrs(__TopXMLNS, [], - Feature) -> - decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, - Feature). - -encode_pubsub_error_unsupported({ps_error, unsupported, - Feature}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = - encode_pubsub_error_unsupported_attr_feature(Feature, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"unsupported">>, _attrs, _els}. - -decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"feature">>, <<"unsupported">>, - __TopXMLNS}}); -decode_pubsub_error_unsupported_attr_feature(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - ['access-authorize', 'access-open', 'access-presence', - 'access-roster', 'access-whitelist', 'auto-create', - 'auto-subscribe', collections, 'config-node', - 'create-and-configure', 'create-nodes', 'delete-items', - 'delete-nodes', 'filtered-notifications', - 'get-pending', 'instant-nodes', 'item-ids', - 'last-published', 'leased-subscription', - 'manage-subscriptions', 'member-affiliation', - 'meta-data', 'modify-affiliations', 'multi-collection', - 'multi-subscribe', 'outcast-affiliation', - 'persistent-items', 'presence-notifications', - 'presence-subscribe', publish, 'publish-options', - 'publish-only-affiliation', 'publisher-affiliation', - 'purge-nodes', 'retract-items', - 'retrieve-affiliations', 'retrieve-default', - 'retrieve-items', 'retrieve-subscriptions', subscribe, - 'subscription-options', 'subscription-notifications']) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"feature">>, <<"unsupported">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_error_unsupported_attr_feature(_val, - _acc) -> - [{<<"feature">>, enc_enum(_val)} | _acc]. - -decode_pubsub_error_too_many_subscriptions(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"too-many-subscriptions">>, - _attrs, _els}) -> - {ps_error, 'too-many-subscriptions', undefined}. - -encode_pubsub_error_too_many_subscriptions({ps_error, - 'too-many-subscriptions', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"too-many-subscriptions">>, _attrs, _els}. - -decode_pubsub_error_subid_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"subid-required">>, _attrs, - _els}) -> - {ps_error, 'subid-required', undefined}. - -encode_pubsub_error_subid_required({ps_error, - 'subid-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"subid-required">>, _attrs, _els}. - -decode_pubsub_error_presence_subscription_required(__TopXMLNS, - __IgnoreEls, - {xmlel, - <<"presence-subscription-required">>, - _attrs, _els}) -> - {ps_error, 'presence-subscription-required', undefined}. - -encode_pubsub_error_presence_subscription_required({ps_error, - 'presence-subscription-required', - _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"presence-subscription-required">>, _attrs, - _els}. - -decode_pubsub_error_pending_subscription(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"pending-subscription">>, - _attrs, _els}) -> - {ps_error, 'pending-subscription', undefined}. - -encode_pubsub_error_pending_subscription({ps_error, - 'pending-subscription', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"pending-subscription">>, _attrs, _els}. - -decode_pubsub_error_payload_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"payload-required">>, _attrs, - _els}) -> - {ps_error, 'payload-required', undefined}. - -encode_pubsub_error_payload_required({ps_error, - 'payload-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"payload-required">>, _attrs, _els}. - -decode_pubsub_error_payload_too_big(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"payload-too-big">>, _attrs, - _els}) -> - {ps_error, 'payload-too-big', undefined}. - -encode_pubsub_error_payload_too_big({ps_error, - 'payload-too-big', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"payload-too-big">>, _attrs, _els}. - -decode_pubsub_error_not_subscribed(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"not-subscribed">>, _attrs, - _els}) -> - {ps_error, 'not-subscribed', undefined}. - -encode_pubsub_error_not_subscribed({ps_error, - 'not-subscribed', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-subscribed">>, _attrs, _els}. - -decode_pubsub_error_not_in_roster_group(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"not-in-roster-group">>, - _attrs, _els}) -> - {ps_error, 'not-in-roster-group', undefined}. - -encode_pubsub_error_not_in_roster_group({ps_error, - 'not-in-roster-group', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-in-roster-group">>, _attrs, _els}. - -decode_pubsub_error_nodeid_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"nodeid-required">>, _attrs, - _els}) -> - {ps_error, 'nodeid-required', undefined}. - -encode_pubsub_error_nodeid_required({ps_error, - 'nodeid-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"nodeid-required">>, _attrs, _els}. - -decode_pubsub_error_max_nodes_exceeded(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"max-nodes-exceeded">>, _attrs, - _els}) -> - {ps_error, 'max-nodes-exceeded', undefined}. - -encode_pubsub_error_max_nodes_exceeded({ps_error, - 'max-nodes-exceeded', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"max-nodes-exceeded">>, _attrs, _els}. - -decode_pubsub_error_max_items_exceeded(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"max-items-exceeded">>, _attrs, - _els}) -> - {ps_error, 'max-items-exceeded', undefined}. - -encode_pubsub_error_max_items_exceeded({ps_error, - 'max-items-exceeded', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"max-items-exceeded">>, _attrs, _els}. - -decode_pubsub_error_jid_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"jid-required">>, _attrs, _els}) -> - {ps_error, 'jid-required', undefined}. - -encode_pubsub_error_jid_required({ps_error, - 'jid-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"jid-required">>, _attrs, _els}. - -decode_pubsub_error_item_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"item-required">>, _attrs, _els}) -> - {ps_error, 'item-required', undefined}. - -encode_pubsub_error_item_required({ps_error, - 'item-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"item-required">>, _attrs, _els}. - -decode_pubsub_error_item_forbidden(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"item-forbidden">>, _attrs, - _els}) -> - {ps_error, 'item-forbidden', undefined}. - -encode_pubsub_error_item_forbidden({ps_error, - 'item-forbidden', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"item-forbidden">>, _attrs, _els}. - -decode_pubsub_error_invalid_subid(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-subid">>, _attrs, _els}) -> - {ps_error, 'invalid-subid', undefined}. - -encode_pubsub_error_invalid_subid({ps_error, - 'invalid-subid', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-subid">>, _attrs, _els}. - -decode_pubsub_error_invalid_payload(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-payload">>, _attrs, - _els}) -> - {ps_error, 'invalid-payload', undefined}. - -encode_pubsub_error_invalid_payload({ps_error, - 'invalid-payload', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-payload">>, _attrs, _els}. - -decode_pubsub_error_invalid_options(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-options">>, _attrs, - _els}) -> - {ps_error, 'invalid-options', undefined}. - -encode_pubsub_error_invalid_options({ps_error, - 'invalid-options', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-options">>, _attrs, _els}. - -decode_pubsub_error_invalid_jid(__TopXMLNS, __IgnoreEls, - {xmlel, <<"invalid-jid">>, _attrs, _els}) -> - {ps_error, 'invalid-jid', undefined}. - -encode_pubsub_error_invalid_jid({ps_error, - 'invalid-jid', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-jid">>, _attrs, _els}. - -decode_pubsub_error_configuration_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"configuration-required">>, - _attrs, _els}) -> - {ps_error, 'configuration-required', undefined}. - -encode_pubsub_error_configuration_required({ps_error, - 'configuration-required', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"configuration-required">>, _attrs, _els}. - -decode_pubsub_error_closed_node(__TopXMLNS, __IgnoreEls, - {xmlel, <<"closed-node">>, _attrs, _els}) -> - {ps_error, 'closed-node', undefined}. - -encode_pubsub_error_closed_node({ps_error, - 'closed-node', _}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#errors">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"closed-node">>, _attrs, _els}. - -decode_pubsub_owner(__TopXMLNS, __IgnoreEls, - {xmlel, <<"pubsub">>, _attrs, _els}) -> - {Subscriptions, Affiliations, Default, Purge, Delete, - Configure} = - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, - undefined, undefined), - {pubsub_owner, Affiliations, Configure, Default, Delete, - Purge, Subscriptions}. - -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, [], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - {Subscriptions, Affiliations, Default, Purge, Delete, - Configure}; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, - decode_pubsub_owner_affiliations(__TopXMLNS, - __IgnoreEls, - _el), - Default, Purge, Delete, Configure); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, - decode_pubsub_owner_affiliations(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, - _el), - Default, Purge, Delete, Configure); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"configure">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, - decode_pubsub_configure(__TopXMLNS, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"default">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, - decode_pubsub_default(__TopXMLNS, __IgnoreEls, - _el), - Purge, Delete, Configure); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Purge, Delete, Configure); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Purge, Delete, Configure); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delete">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - decode_pubsub_delete(__TopXMLNS, __IgnoreEls, - _el), - Configure); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Configure); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Configure); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Configure); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"purge">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, - decode_pubsub_purge(__TopXMLNS, __IgnoreEls, - _el), - Delete, Configure); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Delete, Configure); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Delete, Configure); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Delete, Configure); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], - Subscriptions, Affiliations, Default, Purge, Delete, - Configure) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_subscriptions(__TopXMLNS, - __IgnoreEls, _el), - Affiliations, Default, Purge, Delete, - Configure); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Affiliations, Default, Purge, Delete, - Configure); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Affiliations, Default, Purge, Delete, - Configure); - _ -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, - Delete, Configure) - end; -decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Subscriptions, Affiliations, Default, Purge, - Delete, Configure) -> - decode_pubsub_owner_els(__TopXMLNS, __IgnoreEls, _els, - Subscriptions, Affiliations, Default, Purge, Delete, - Configure). - -encode_pubsub_owner({pubsub_owner, Affiliations, - Configure, Default, Delete, Purge, Subscriptions}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#owner">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_owner_$subscriptions'(Subscriptions, - __NewTopXMLNS, - 'encode_pubsub_owner_$affiliations'(Affiliations, - __NewTopXMLNS, - 'encode_pubsub_owner_$default'(Default, - __NewTopXMLNS, - 'encode_pubsub_owner_$purge'(Purge, - __NewTopXMLNS, - 'encode_pubsub_owner_$delete'(Delete, - __NewTopXMLNS, - 'encode_pubsub_owner_$configure'(Configure, - __NewTopXMLNS, - []))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"pubsub">>, _attrs, _els}. - -'encode_pubsub_owner_$subscriptions'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_owner_$subscriptions'(Subscriptions, - __TopXMLNS, _acc) -> - [encode_pubsub_subscriptions(Subscriptions, __TopXMLNS) - | _acc]. - -'encode_pubsub_owner_$affiliations'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_owner_$affiliations'(Affiliations, - __TopXMLNS, _acc) -> - [encode_pubsub_owner_affiliations(Affiliations, - __TopXMLNS) - | _acc]. - -'encode_pubsub_owner_$default'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_owner_$default'(Default, __TopXMLNS, - _acc) -> - [encode_pubsub_default(Default, __TopXMLNS) | _acc]. - -'encode_pubsub_owner_$purge'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_owner_$purge'(Purge, __TopXMLNS, _acc) -> - [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. - -'encode_pubsub_owner_$delete'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_owner_$delete'(Delete, __TopXMLNS, - _acc) -> - [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. - -'encode_pubsub_owner_$configure'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_owner_$configure'(Configure, __TopXMLNS, - _acc) -> - [encode_pubsub_configure(Configure, __TopXMLNS) | _acc]. - -decode_pubsub(__TopXMLNS, __IgnoreEls, - {xmlel, <<"pubsub">>, _attrs, _els}) -> - {Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription} = - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, - undefined), - {pubsub, Subscriptions, Subscription, Affiliations, - Publish, Publish_options, Subscribe, Unsubscribe, - Options, Items, Retract, Create, Configure, Default, - Delete, Purge, Rsm}. - -decode_pubsub_els(__TopXMLNS, __IgnoreEls, [], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - {Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription}; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscriptions">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, - _el), - Default, Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Default, Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - decode_pubsub_subscriptions(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Default, Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"affiliations">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, - decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, - _el), - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, - decode_pubsub_affiliations(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscribe">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, - decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, - _el), - Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, - decode_pubsub_subscribe(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsubscribe">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, - decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, - _el), - Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, - decode_pubsub_unsubscribe(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"options">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, - decode_pubsub_options(__TopXMLNS, __IgnoreEls, _el), - Affiliations, Subscriptions, Default, Retract, - Purge, Delete, Configure, Create, Unsubscribe, - Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, - decode_pubsub_options(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Affiliations, Subscriptions, Default, Retract, - Purge, Delete, Configure, Create, Unsubscribe, - Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"items">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, - decode_pubsub_items(__TopXMLNS, __IgnoreEls, _el), - Options, Affiliations, Subscriptions, Default, - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Options, Affiliations, Subscriptions, Default, - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Options, Affiliations, Subscriptions, Default, - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"retract">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, - decode_pubsub_retract(__TopXMLNS, __IgnoreEls, _el), - Purge, Delete, Configure, Create, Unsubscribe, - Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, - decode_pubsub_retract(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Purge, Delete, Configure, Create, Unsubscribe, - Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"create">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, - decode_pubsub_create(__TopXMLNS, __IgnoreEls, _el), - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"configure">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - decode_pubsub_configure(__TopXMLNS, __IgnoreEls, - _el), - Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - decode_pubsub_configure(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"publish-options">>, _attrs, _} = _el - | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_publish_options(__TopXMLNS, - __IgnoreEls, _el), - Items, Options, Affiliations, Subscriptions, - Default, Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_publish_options(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Items, Options, Affiliations, Subscriptions, - Default, Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"default">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, - decode_pubsub_default(__TopXMLNS, __IgnoreEls, _el), - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, - decode_pubsub_default(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Retract, Purge, Delete, Configure, Create, - Unsubscribe, Subscribe, Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delete">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, - decode_pubsub_delete(__TopXMLNS, __IgnoreEls, _el), - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"purge">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, - decode_pubsub_purge(__TopXMLNS, __IgnoreEls, _el), - Delete, Configure, Create, Unsubscribe, Subscribe, - Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Delete, Configure, Create, Unsubscribe, Subscribe, - Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Delete, Configure, Create, Unsubscribe, Subscribe, - Publish, Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Delete, Configure, Create, Unsubscribe, Subscribe, - Publish, Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, - decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"set">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/rsm">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el), - Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"publish">>, _attrs, _} = _el | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, - decode_pubsub_publish(__TopXMLNS, __IgnoreEls, _el), - Rsm, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, - decode_pubsub_publish(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Rsm, Subscription); - _ -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, - Rsm, Subscription) - end; -decode_pubsub_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription) -> - decode_pubsub_els(__TopXMLNS, __IgnoreEls, _els, - Publish_options, Items, Options, Affiliations, - Subscriptions, Default, Retract, Purge, Delete, - Configure, Create, Unsubscribe, Subscribe, Publish, Rsm, - Subscription). - -encode_pubsub({pubsub, Subscriptions, Subscription, - Affiliations, Publish, Publish_options, Subscribe, - Unsubscribe, Options, Items, Retract, Create, Configure, - Default, Delete, Purge, Rsm}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_$publish_options'(Publish_options, - __NewTopXMLNS, - 'encode_pubsub_$items'(Items, - __NewTopXMLNS, - 'encode_pubsub_$options'(Options, - __NewTopXMLNS, - 'encode_pubsub_$affiliations'(Affiliations, - __NewTopXMLNS, - 'encode_pubsub_$subscriptions'(Subscriptions, - __NewTopXMLNS, - 'encode_pubsub_$default'(Default, - __NewTopXMLNS, - 'encode_pubsub_$retract'(Retract, - __NewTopXMLNS, - 'encode_pubsub_$purge'(Purge, - __NewTopXMLNS, - 'encode_pubsub_$delete'(Delete, - __NewTopXMLNS, - 'encode_pubsub_$configure'(Configure, - __NewTopXMLNS, - 'encode_pubsub_$create'(Create, - __NewTopXMLNS, - 'encode_pubsub_$unsubscribe'(Unsubscribe, - __NewTopXMLNS, - 'encode_pubsub_$subscribe'(Subscribe, - __NewTopXMLNS, - 'encode_pubsub_$publish'(Publish, - __NewTopXMLNS, - 'encode_pubsub_$rsm'(Rsm, - __NewTopXMLNS, - 'encode_pubsub_$subscription'(Subscription, - __NewTopXMLNS, - []))))))))))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"pubsub">>, _attrs, _els}. - -'encode_pubsub_$publish_options'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$publish_options'(Publish_options, - __TopXMLNS, _acc) -> - [encode_pubsub_publish_options(Publish_options, - __TopXMLNS) - | _acc]. - -'encode_pubsub_$items'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$items'(Items, __TopXMLNS, _acc) -> - [encode_pubsub_items(Items, __TopXMLNS) | _acc]. - -'encode_pubsub_$options'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$options'(Options, __TopXMLNS, _acc) -> - [encode_pubsub_options(Options, __TopXMLNS) | _acc]. - -'encode_pubsub_$affiliations'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$affiliations'(Affiliations, __TopXMLNS, - _acc) -> - [encode_pubsub_affiliations(Affiliations, __TopXMLNS) - | _acc]. - -'encode_pubsub_$subscriptions'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$subscriptions'(Subscriptions, - __TopXMLNS, _acc) -> - [encode_pubsub_subscriptions(Subscriptions, __TopXMLNS) - | _acc]. - -'encode_pubsub_$default'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$default'(Default, __TopXMLNS, _acc) -> - [encode_pubsub_default(Default, __TopXMLNS) | _acc]. - -'encode_pubsub_$retract'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$retract'(Retract, __TopXMLNS, _acc) -> - [encode_pubsub_retract(Retract, __TopXMLNS) | _acc]. - -'encode_pubsub_$purge'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$purge'(Purge, __TopXMLNS, _acc) -> - [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. - -'encode_pubsub_$delete'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$delete'(Delete, __TopXMLNS, _acc) -> - [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. - -'encode_pubsub_$configure'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$configure'(Configure, __TopXMLNS, - _acc) -> - [encode_pubsub_configure(Configure, __TopXMLNS) | _acc]. - -'encode_pubsub_$create'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$create'(Create, __TopXMLNS, _acc) -> - [encode_pubsub_create(Create, __TopXMLNS) | _acc]. - -'encode_pubsub_$unsubscribe'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$unsubscribe'(Unsubscribe, __TopXMLNS, - _acc) -> - [encode_pubsub_unsubscribe(Unsubscribe, __TopXMLNS) - | _acc]. - -'encode_pubsub_$subscribe'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$subscribe'(Subscribe, __TopXMLNS, - _acc) -> - [encode_pubsub_subscribe(Subscribe, __TopXMLNS) | _acc]. - -'encode_pubsub_$publish'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$publish'(Publish, __TopXMLNS, _acc) -> - [encode_pubsub_publish(Publish, __TopXMLNS) | _acc]. - -'encode_pubsub_$rsm'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_$rsm'(Rsm, __TopXMLNS, _acc) -> - [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. - -'encode_pubsub_$subscription'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_$subscription'(Subscription, __TopXMLNS, - _acc) -> - [encode_pubsub_subscription(Subscription, __TopXMLNS) - | _acc]. - -decode_pubsub_purge(__TopXMLNS, __IgnoreEls, - {xmlel, <<"purge">>, _attrs, _els}) -> - Node = decode_pubsub_purge_attrs(__TopXMLNS, _attrs, - undefined), - Node. - -decode_pubsub_purge_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_purge_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_purge_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_purge_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_purge_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_purge_attr_node(__TopXMLNS, Node). - -encode_pubsub_purge(Node, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = [], - _attrs = encode_pubsub_purge_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"purge">>, _attrs, _els}. - -decode_pubsub_purge_attr_node(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"purge">>, __TopXMLNS}}); -decode_pubsub_purge_attr_node(__TopXMLNS, _val) -> _val. - -encode_pubsub_purge_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_delete(__TopXMLNS, __IgnoreEls, - {xmlel, <<"delete">>, _attrs, _els}) -> - Uri = decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Node = decode_pubsub_delete_attrs(__TopXMLNS, _attrs, - undefined), - {Node, Uri}. - -decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, [], - Uri) -> - Uri; -decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], - Uri) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">>; - __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">>; - __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_redirect(__TopXMLNS, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_redirect(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - Uri) - end; -decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Uri) -> - decode_pubsub_delete_els(__TopXMLNS, __IgnoreEls, _els, - Uri). - -decode_pubsub_delete_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_delete_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_delete_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_delete_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_delete_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_delete_attr_node(__TopXMLNS, Node). - -encode_pubsub_delete({Node, Uri}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = lists:reverse('encode_pubsub_delete_$uri'(Uri, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_delete_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"delete">>, _attrs, _els}. - -'encode_pubsub_delete_$uri'(<<>>, __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_delete_$uri'(Uri, __TopXMLNS, _acc) -> - [encode_pubsub_redirect(Uri, __TopXMLNS) | _acc]. - -decode_pubsub_delete_attr_node(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"delete">>, __TopXMLNS}}); -decode_pubsub_delete_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_delete_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_redirect(__TopXMLNS, __IgnoreEls, - {xmlel, <<"redirect">>, _attrs, _els}) -> - Uri = decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, - undefined), - Uri. - -decode_pubsub_redirect_attrs(__TopXMLNS, - [{<<"uri">>, _val} | _attrs], _Uri) -> - decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_redirect_attrs(__TopXMLNS, [_ | _attrs], - Uri) -> - decode_pubsub_redirect_attrs(__TopXMLNS, _attrs, Uri); -decode_pubsub_redirect_attrs(__TopXMLNS, [], Uri) -> - decode_pubsub_redirect_attr_uri(__TopXMLNS, Uri). - -encode_pubsub_redirect(Uri, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = [], - _attrs = encode_pubsub_redirect_attr_uri(Uri, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"redirect">>, _attrs, _els}. - -decode_pubsub_redirect_attr_uri(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"uri">>, <<"redirect">>, __TopXMLNS}}); -decode_pubsub_redirect_attr_uri(__TopXMLNS, _val) -> - _val. - -encode_pubsub_redirect_attr_uri(_val, _acc) -> - [{<<"uri">>, _val} | _acc]. - -decode_pubsub_default(__TopXMLNS, __IgnoreEls, - {xmlel, <<"default">>, _attrs, _els}) -> - Xdata = decode_pubsub_default_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - Node = decode_pubsub_default_attrs(__TopXMLNS, _attrs, - undefined), - {Node, Xdata}. - -decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, [], - Xdata) -> - Xdata; -decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, - Xdata) - end; -decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata) -> - decode_pubsub_default_els(__TopXMLNS, __IgnoreEls, _els, - Xdata). - -decode_pubsub_default_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_default_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_default_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_default_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_default_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_default_attr_node(__TopXMLNS, Node). - -encode_pubsub_default({Node, Xdata}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>], - __TopXMLNS), - _els = - lists:reverse('encode_pubsub_default_$xdata'(Xdata, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_default_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"default">>, _attrs, _els}. - -'encode_pubsub_default_$xdata'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_default_$xdata'(Xdata, __TopXMLNS, - _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_pubsub_default_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_default_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_default_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_default_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_publish_options(__TopXMLNS, __IgnoreEls, - {xmlel, <<"publish-options">>, _attrs, _els}) -> - Xdata = decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - Xdata. - -decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, [], Xdata) -> - Xdata; -decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], - Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, _els, Xdata) - end; -decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Xdata) -> - decode_pubsub_publish_options_els(__TopXMLNS, - __IgnoreEls, _els, Xdata). - -encode_pubsub_publish_options(Xdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_publish_options_$xdata'(Xdata, - __NewTopXMLNS, - [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"publish-options">>, _attrs, _els}. - -'encode_pubsub_publish_options_$xdata'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_publish_options_$xdata'(Xdata, - __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_pubsub_configure(__TopXMLNS, __IgnoreEls, - {xmlel, <<"configure">>, _attrs, _els}) -> - Xdata = decode_pubsub_configure_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - Node = decode_pubsub_configure_attrs(__TopXMLNS, _attrs, - undefined), - {Node, Xdata}. - -decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, [], - Xdata) -> - Xdata; -decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], - Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, - _els, Xdata) - end; -decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata) -> - decode_pubsub_configure_els(__TopXMLNS, __IgnoreEls, - _els, Xdata). - -decode_pubsub_configure_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_configure_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_configure_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_configure_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_configure_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_configure_attr_node(__TopXMLNS, Node). - -encode_pubsub_configure({Node, Xdata}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>], - __TopXMLNS), - _els = - lists:reverse('encode_pubsub_configure_$xdata'(Xdata, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_configure_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"configure">>, _attrs, _els}. - -'encode_pubsub_configure_$xdata'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_configure_$xdata'(Xdata, __TopXMLNS, - _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_pubsub_configure_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_configure_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_configure_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_configure_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_create(__TopXMLNS, __IgnoreEls, - {xmlel, <<"create">>, _attrs, _els}) -> - Node = decode_pubsub_create_attrs(__TopXMLNS, _attrs, - undefined), - Node. - -decode_pubsub_create_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_create_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_create_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_create_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_create_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_create_attr_node(__TopXMLNS, Node). - -encode_pubsub_create(Node, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = [], - _attrs = encode_pubsub_create_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"create">>, _attrs, _els}. - -decode_pubsub_create_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_create_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_create_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_create_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_retract(__TopXMLNS, __IgnoreEls, - {xmlel, <<"retract">>, _attrs, _els}) -> - Items = decode_pubsub_retract_els(__TopXMLNS, - __IgnoreEls, _els, []), - {Node, Notify} = decode_pubsub_retract_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {ps_retract, Node, Notify, Items}. - -decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], - Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(__TopXMLNS, __IgnoreEls, - _el) - | Items]); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el) - | Items]); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_pubsub_retract_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -decode_pubsub_retract_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Notify) -> - decode_pubsub_retract_attrs(__TopXMLNS, _attrs, _val, - Notify); -decode_pubsub_retract_attrs(__TopXMLNS, - [{<<"notify">>, _val} | _attrs], Node, _Notify) -> - decode_pubsub_retract_attrs(__TopXMLNS, _attrs, Node, - _val); -decode_pubsub_retract_attrs(__TopXMLNS, [_ | _attrs], - Node, Notify) -> - decode_pubsub_retract_attrs(__TopXMLNS, _attrs, Node, - Notify); -decode_pubsub_retract_attrs(__TopXMLNS, [], Node, - Notify) -> - {decode_pubsub_retract_attr_node(__TopXMLNS, Node), - decode_pubsub_retract_attr_notify(__TopXMLNS, Notify)}. - -encode_pubsub_retract({ps_retract, Node, Notify, Items}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_retract_$items'(Items, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_retract_attr_notify(Notify, - encode_pubsub_retract_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"retract">>, _attrs, _els}. - -'encode_pubsub_retract_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_retract_$items'([Items | _els], - __TopXMLNS, _acc) -> - 'encode_pubsub_retract_$items'(_els, __TopXMLNS, - [encode_pubsub_item(Items, __TopXMLNS) - | _acc]). - -decode_pubsub_retract_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"retract">>, __TopXMLNS}}); -decode_pubsub_retract_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_retract_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_retract_attr_notify(__TopXMLNS, - undefined) -> - false; -decode_pubsub_retract_attr_notify(__TopXMLNS, _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"notify">>, <<"retract">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_retract_attr_notify(false, _acc) -> _acc; -encode_pubsub_retract_attr_notify(_val, _acc) -> - [{<<"notify">>, enc_bool(_val)} | _acc]. - -decode_pubsub_options(__TopXMLNS, __IgnoreEls, - {xmlel, <<"options">>, _attrs, _els}) -> - Xdata = decode_pubsub_options_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - {Node, Subid, Jid} = - decode_pubsub_options_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {ps_options, Node, Jid, Subid, Xdata}. - -decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, [], - Xdata) -> - Xdata; -decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, - Xdata) - end; -decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata) -> - decode_pubsub_options_els(__TopXMLNS, __IgnoreEls, _els, - Xdata). - -decode_pubsub_options_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Subid, Jid) -> - decode_pubsub_options_attrs(__TopXMLNS, _attrs, _val, - Subid, Jid); -decode_pubsub_options_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Node, _Subid, - Jid) -> - decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, - _val, Jid); -decode_pubsub_options_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Node, Subid, _Jid) -> - decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, - Subid, _val); -decode_pubsub_options_attrs(__TopXMLNS, [_ | _attrs], - Node, Subid, Jid) -> - decode_pubsub_options_attrs(__TopXMLNS, _attrs, Node, - Subid, Jid); -decode_pubsub_options_attrs(__TopXMLNS, [], Node, Subid, - Jid) -> - {decode_pubsub_options_attr_node(__TopXMLNS, Node), - decode_pubsub_options_attr_subid(__TopXMLNS, Subid), - decode_pubsub_options_attr_jid(__TopXMLNS, Jid)}. - -encode_pubsub_options({ps_options, Node, Jid, Subid, - Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_options_$xdata'(Xdata, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_options_attr_jid(Jid, - encode_pubsub_options_attr_subid(Subid, - encode_pubsub_options_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"options">>, _attrs, _els}. - -'encode_pubsub_options_$xdata'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_options_$xdata'(Xdata, __TopXMLNS, - _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_pubsub_options_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_options_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_options_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_options_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_options_attr_subid(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_options_attr_subid(__TopXMLNS, _val) -> - _val. - -encode_pubsub_options_attr_subid(<<>>, _acc) -> _acc; -encode_pubsub_options_attr_subid(_val, _acc) -> - [{<<"subid">>, _val} | _acc]. - -decode_pubsub_options_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"options">>, __TopXMLNS}}); -decode_pubsub_options_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"options">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_options_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_pubsub_publish(__TopXMLNS, __IgnoreEls, - {xmlel, <<"publish">>, _attrs, _els}) -> - Items = decode_pubsub_publish_els(__TopXMLNS, - __IgnoreEls, _els, []), - Node = decode_pubsub_publish_attrs(__TopXMLNS, _attrs, - undefined), - {ps_publish, Node, Items}. - -decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], - Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(__TopXMLNS, __IgnoreEls, - _el) - | Items]); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el) - | Items]); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_pubsub_publish_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -decode_pubsub_publish_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_publish_attrs(__TopXMLNS, _attrs, _val); -decode_pubsub_publish_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_pubsub_publish_attrs(__TopXMLNS, _attrs, Node); -decode_pubsub_publish_attrs(__TopXMLNS, [], Node) -> - decode_pubsub_publish_attr_node(__TopXMLNS, Node). - -encode_pubsub_publish({ps_publish, Node, Items}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_publish_$items'(Items, - __NewTopXMLNS, [])), - _attrs = encode_pubsub_publish_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"publish">>, _attrs, _els}. - -'encode_pubsub_publish_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_publish_$items'([Items | _els], - __TopXMLNS, _acc) -> - 'encode_pubsub_publish_$items'(_els, __TopXMLNS, - [encode_pubsub_item(Items, __TopXMLNS) - | _acc]). - -decode_pubsub_publish_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"publish">>, __TopXMLNS}}); -decode_pubsub_publish_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_publish_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_unsubscribe(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unsubscribe">>, _attrs, _els}) -> - {Node, Subid, Jid} = - decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {ps_unsubscribe, Node, Jid, Subid}. - -decode_pubsub_unsubscribe_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Subid, - Jid) -> - decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, - _val, Subid, Jid); -decode_pubsub_unsubscribe_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Node, _Subid, - Jid) -> - decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, - Node, _val, Jid); -decode_pubsub_unsubscribe_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Node, Subid, - _Jid) -> - decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, - Node, Subid, _val); -decode_pubsub_unsubscribe_attrs(__TopXMLNS, - [_ | _attrs], Node, Subid, Jid) -> - decode_pubsub_unsubscribe_attrs(__TopXMLNS, _attrs, - Node, Subid, Jid); -decode_pubsub_unsubscribe_attrs(__TopXMLNS, [], Node, - Subid, Jid) -> - {decode_pubsub_unsubscribe_attr_node(__TopXMLNS, Node), - decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, Subid), - decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, Jid)}. - -encode_pubsub_unsubscribe({ps_unsubscribe, Node, Jid, - Subid}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_pubsub_unsubscribe_attr_jid(Jid, - encode_pubsub_unsubscribe_attr_subid(Subid, - encode_pubsub_unsubscribe_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"unsubscribe">>, _attrs, _els}. - -decode_pubsub_unsubscribe_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_unsubscribe_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_unsubscribe_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_unsubscribe_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_unsubscribe_attr_subid(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_unsubscribe_attr_subid(<<>>, _acc) -> - _acc; -encode_pubsub_unsubscribe_attr_subid(_val, _acc) -> - [{<<"subid">>, _val} | _acc]. - -decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"unsubscribe">>, - __TopXMLNS}}); -decode_pubsub_unsubscribe_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"unsubscribe">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_unsubscribe_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_pubsub_subscribe(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscribe">>, _attrs, _els}) -> - {Node, Jid} = decode_pubsub_subscribe_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {ps_subscribe, Node, Jid}. - -decode_pubsub_subscribe_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Jid) -> - decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, _val, - Jid); -decode_pubsub_subscribe_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Node, _Jid) -> - decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, Node, - _val); -decode_pubsub_subscribe_attrs(__TopXMLNS, [_ | _attrs], - Node, Jid) -> - decode_pubsub_subscribe_attrs(__TopXMLNS, _attrs, Node, - Jid); -decode_pubsub_subscribe_attrs(__TopXMLNS, [], Node, - Jid) -> - {decode_pubsub_subscribe_attr_node(__TopXMLNS, Node), - decode_pubsub_subscribe_attr_jid(__TopXMLNS, Jid)}. - -encode_pubsub_subscribe({ps_subscribe, Node, Jid}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_pubsub_subscribe_attr_jid(Jid, - encode_pubsub_subscribe_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"subscribe">>, _attrs, _els}. - -decode_pubsub_subscribe_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_subscribe_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_subscribe_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_subscribe_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_subscribe_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"subscribe">>, - __TopXMLNS}}); -decode_pubsub_subscribe_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"subscribe">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_subscribe_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_pubsub_owner_affiliations(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"affiliations">>, _attrs, _els}) -> - Affiliations = - decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, _els, []), - Node = - decode_pubsub_owner_affiliations_attrs(__TopXMLNS, - _attrs, undefined), - {Node, Affiliations}. - -decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, [], Affiliations) -> - lists:reverse(Affiliations); -decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"affiliation">>, _attrs, _} = - _el - | _els], - Affiliations) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, _els, - [decode_pubsub_owner_affiliation(__TopXMLNS, - __IgnoreEls, - _el) - | Affiliations]); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, _els, - [decode_pubsub_owner_affiliation(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, - _el) - | Affiliations]); - _ -> - decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, _els, Affiliations) - end; -decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Affiliations) -> - decode_pubsub_owner_affiliations_els(__TopXMLNS, - __IgnoreEls, _els, Affiliations). - -decode_pubsub_owner_affiliations_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_owner_affiliations_attrs(__TopXMLNS, - _attrs, _val); -decode_pubsub_owner_affiliations_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_pubsub_owner_affiliations_attrs(__TopXMLNS, - _attrs, Node); -decode_pubsub_owner_affiliations_attrs(__TopXMLNS, [], - Node) -> - decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, - Node). - -encode_pubsub_owner_affiliations({Node, Affiliations}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#owner">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_owner_affiliations_$affiliations'(Affiliations, - __NewTopXMLNS, - [])), - _attrs = - encode_pubsub_owner_affiliations_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"affiliations">>, _attrs, _els}. - -'encode_pubsub_owner_affiliations_$affiliations'([], - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_owner_affiliations_$affiliations'([Affiliations - | _els], - __TopXMLNS, _acc) -> - 'encode_pubsub_owner_affiliations_$affiliations'(_els, - __TopXMLNS, - [encode_pubsub_owner_affiliation(Affiliations, - __TopXMLNS) - | _acc]). - -decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_owner_affiliations_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_owner_affiliations_attr_node(<<>>, - _acc) -> - _acc; -encode_pubsub_owner_affiliations_attr_node(_val, - _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_affiliations(__TopXMLNS, __IgnoreEls, - {xmlel, <<"affiliations">>, _attrs, _els}) -> - Affiliations = - decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - _els, []), - Node = decode_pubsub_affiliations_attrs(__TopXMLNS, - _attrs, undefined), - {Node, Affiliations}. - -decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - [], Affiliations) -> - lists:reverse(Affiliations); -decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"affiliation">>, _attrs, _} = _el - | _els], - Affiliations) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_affiliation(__TopXMLNS, - __IgnoreEls, - _el) - | Affiliations]); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_affiliation(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, - _el) - | Affiliations]); - _ -> - decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - _els, Affiliations) - end; -decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Affiliations) -> - decode_pubsub_affiliations_els(__TopXMLNS, __IgnoreEls, - _els, Affiliations). - -decode_pubsub_affiliations_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_affiliations_attrs(__TopXMLNS, _attrs, - _val); -decode_pubsub_affiliations_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_pubsub_affiliations_attrs(__TopXMLNS, _attrs, - Node); -decode_pubsub_affiliations_attrs(__TopXMLNS, [], - Node) -> - decode_pubsub_affiliations_attr_node(__TopXMLNS, Node). - -encode_pubsub_affiliations({Node, Affiliations}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_affiliations_$affiliations'(Affiliations, - __NewTopXMLNS, - [])), - _attrs = encode_pubsub_affiliations_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"affiliations">>, _attrs, _els}. - -'encode_pubsub_affiliations_$affiliations'([], - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_affiliations_$affiliations'([Affiliations - | _els], - __TopXMLNS, _acc) -> - 'encode_pubsub_affiliations_$affiliations'(_els, - __TopXMLNS, - [encode_pubsub_affiliation(Affiliations, - __TopXMLNS) - | _acc]). - -decode_pubsub_affiliations_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_affiliations_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_affiliations_attr_node(<<>>, _acc) -> - _acc; -encode_pubsub_affiliations_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_subscriptions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscriptions">>, _attrs, _els}) -> - Subscriptions = - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, []), - Node = decode_pubsub_subscriptions_attrs(__TopXMLNS, - _attrs, undefined), - {Node, Subscriptions}. - -decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - [], Subscriptions) -> - lists:reverse(Subscriptions); -decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription">>, _attrs, _} = _el - | _els], - Subscriptions) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">>; - __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_subscription(__TopXMLNS, - __IgnoreEls, - _el) - | Subscriptions]); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, - _el) - | Subscriptions]); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, - _el) - | Subscriptions]); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, - _el) - | Subscriptions]); - _ -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, Subscriptions) - end; -decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Subscriptions) -> - decode_pubsub_subscriptions_els(__TopXMLNS, __IgnoreEls, - _els, Subscriptions). - -decode_pubsub_subscriptions_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_subscriptions_attrs(__TopXMLNS, _attrs, - _val); -decode_pubsub_subscriptions_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_pubsub_subscriptions_attrs(__TopXMLNS, _attrs, - Node); -decode_pubsub_subscriptions_attrs(__TopXMLNS, [], - Node) -> - decode_pubsub_subscriptions_attr_node(__TopXMLNS, Node). - -encode_pubsub_subscriptions({Node, Subscriptions}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>], - __TopXMLNS), - _els = - lists:reverse('encode_pubsub_subscriptions_$subscriptions'(Subscriptions, - __NewTopXMLNS, - [])), - _attrs = encode_pubsub_subscriptions_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"subscriptions">>, _attrs, _els}. - -'encode_pubsub_subscriptions_$subscriptions'([], - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_subscriptions_$subscriptions'([Subscriptions - | _els], - __TopXMLNS, _acc) -> - 'encode_pubsub_subscriptions_$subscriptions'(_els, - __TopXMLNS, - [encode_pubsub_subscription(Subscriptions, - __TopXMLNS) - | _acc]). - -decode_pubsub_subscriptions_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_subscriptions_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_subscriptions_attr_node(<<>>, _acc) -> - _acc; -encode_pubsub_subscriptions_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_event(__TopXMLNS, __IgnoreEls, - {xmlel, <<"event">>, _attrs, _els}) -> - {Items, Create, Delete, Purge, Configuration, - Subscription} = - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, - undefined, undefined), - {ps_event, Items, Purge, Subscription, Delete, Create, - Configuration}. - -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, [], - Items, Create, Delete, Purge, Configuration, - Subscription) -> - {Items, Create, Delete, Purge, Configuration, - Subscription}; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"items">>, _attrs, _} = _el | _els], Items, - Create, Delete, Purge, Configuration, Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_items(__TopXMLNS, __IgnoreEls, - _el), - Create, Delete, Purge, Configuration, - Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Create, Delete, Purge, Configuration, - Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - decode_pubsub_items(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Create, Delete, Purge, Configuration, - Subscription); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription">>, _attrs, _} = _el | _els], - Items, Create, Delete, Purge, Configuration, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - decode_pubsub_subscription(__TopXMLNS, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el)); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - decode_pubsub_subscription(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"purge">>, _attrs, _} = _el | _els], Items, - Create, Delete, Purge, Configuration, Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, - decode_pubsub_purge(__TopXMLNS, __IgnoreEls, - _el), - Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, - decode_pubsub_purge(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Configuration, Subscription); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"delete">>, _attrs, _} = _el | _els], Items, - Create, Delete, Purge, Configuration, Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, - decode_pubsub_delete(__TopXMLNS, __IgnoreEls, - _el), - Purge, Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Purge, Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub#owner">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#owner">>, - __IgnoreEls, _el), - Purge, Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, - decode_pubsub_delete(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Purge, Configuration, Subscription); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"create">>, _attrs, _} = _el | _els], Items, - Create, Delete, Purge, Configuration, Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_pubsub_create(__TopXMLNS, __IgnoreEls, - _el), - Delete, Purge, Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el), - Delete, Purge, Configuration, Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_pubsub_create(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el), - Delete, Purge, Configuration, Subscription); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"configuration">>, _attrs, _} = _el | _els], - Items, Create, Delete, Purge, Configuration, - Subscription) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, - decode_pubsub_event_configuration(__TopXMLNS, - __IgnoreEls, - _el), - Subscription); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, - decode_pubsub_event_configuration(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, - _el), - Subscription); - _ -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription) - end; -decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items, Create, Delete, Purge, Configuration, - Subscription) -> - decode_pubsub_event_els(__TopXMLNS, __IgnoreEls, _els, - Items, Create, Delete, Purge, Configuration, - Subscription). - -encode_pubsub_event({ps_event, Items, Purge, - Subscription, Delete, Create, Configuration}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, - [], __TopXMLNS), - _els = lists:reverse('encode_pubsub_event_$items'(Items, - __NewTopXMLNS, - 'encode_pubsub_event_$create'(Create, - __NewTopXMLNS, - 'encode_pubsub_event_$delete'(Delete, - __NewTopXMLNS, - 'encode_pubsub_event_$purge'(Purge, - __NewTopXMLNS, - 'encode_pubsub_event_$configuration'(Configuration, - __NewTopXMLNS, - 'encode_pubsub_event_$subscription'(Subscription, - __NewTopXMLNS, - []))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"event">>, _attrs, _els}. - -'encode_pubsub_event_$items'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_event_$items'(Items, __TopXMLNS, _acc) -> - [encode_pubsub_items(Items, __TopXMLNS) | _acc]. - -'encode_pubsub_event_$create'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_event_$create'(Create, __TopXMLNS, - _acc) -> - [encode_pubsub_create(Create, __TopXMLNS) | _acc]. - -'encode_pubsub_event_$delete'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_event_$delete'(Delete, __TopXMLNS, - _acc) -> - [encode_pubsub_delete(Delete, __TopXMLNS) | _acc]. - -'encode_pubsub_event_$purge'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_event_$purge'(Purge, __TopXMLNS, _acc) -> - [encode_pubsub_purge(Purge, __TopXMLNS) | _acc]. - -'encode_pubsub_event_$configuration'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_event_$configuration'(Configuration, - __TopXMLNS, _acc) -> - [encode_pubsub_event_configuration(Configuration, - __TopXMLNS) - | _acc]. - -'encode_pubsub_event_$subscription'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_event_$subscription'(Subscription, - __TopXMLNS, _acc) -> - [encode_pubsub_subscription(Subscription, __TopXMLNS) - | _acc]. - -decode_pubsub_items(__TopXMLNS, __IgnoreEls, - {xmlel, <<"items">>, _attrs, _els}) -> - {Items, Retract} = decode_pubsub_items_els(__TopXMLNS, - __IgnoreEls, _els, [], - undefined), - {Xmlns, Max_items, Node, Subid} = - decode_pubsub_items_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {ps_items, Xmlns, Node, Items, Max_items, Subid, - Retract}. - -decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, [], - Items, Retract) -> - {lists:reverse(Items), Retract}; -decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"retract">>, _attrs, _} = _el | _els], Items, - Retract) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_pubsub_event_retract(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_pubsub_event_retract(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, - _el)); - _ -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Retract) - end; -decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, - Retract) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/pubsub">>; - __TopXMLNS == - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(__TopXMLNS, __IgnoreEls, - _el) - | Items], - Retract); - <<"http://jabber.org/protocol/pubsub">> -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub">>, - __IgnoreEls, _el) - | Items], - Retract); - <<"http://jabber.org/protocol/pubsub#event">> -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - [decode_pubsub_item(<<"http://jabber.org/protocol/pubsub#event">>, - __IgnoreEls, _el) - | Items], - Retract); - _ -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Retract) - end; -decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items, Retract) -> - decode_pubsub_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Retract). - -decode_pubsub_items_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns, Max_items, - Node, Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, _val, - Max_items, Node, Subid); -decode_pubsub_items_attrs(__TopXMLNS, - [{<<"max_items">>, _val} | _attrs], Xmlns, _Max_items, - Node, Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, - _val, Node, Subid); -decode_pubsub_items_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Xmlns, Max_items, - _Node, Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, - Max_items, _val, Subid); -decode_pubsub_items_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Xmlns, Max_items, - Node, _Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, - Max_items, Node, _val); -decode_pubsub_items_attrs(__TopXMLNS, [_ | _attrs], - Xmlns, Max_items, Node, Subid) -> - decode_pubsub_items_attrs(__TopXMLNS, _attrs, Xmlns, - Max_items, Node, Subid); -decode_pubsub_items_attrs(__TopXMLNS, [], Xmlns, - Max_items, Node, Subid) -> - {decode_pubsub_items_attr_xmlns(__TopXMLNS, Xmlns), - decode_pubsub_items_attr_max_items(__TopXMLNS, - Max_items), - decode_pubsub_items_attr_node(__TopXMLNS, Node), - decode_pubsub_items_attr_subid(__TopXMLNS, Subid)}. - -encode_pubsub_items({ps_items, Xmlns, Node, Items, - Max_items, Subid, Retract}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = lists:reverse('encode_pubsub_items_$items'(Items, - __NewTopXMLNS, - 'encode_pubsub_items_$retract'(Retract, - __NewTopXMLNS, - []))), - _attrs = encode_pubsub_items_attr_subid(Subid, - encode_pubsub_items_attr_node(Node, - encode_pubsub_items_attr_max_items(Max_items, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"items">>, _attrs, _els}. - -'encode_pubsub_items_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_items_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_pubsub_items_$items'(_els, __TopXMLNS, - [encode_pubsub_item(Items, __TopXMLNS) - | _acc]). - -'encode_pubsub_items_$retract'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_pubsub_items_$retract'(Retract, __TopXMLNS, - _acc) -> - [encode_pubsub_event_retract(Retract, __TopXMLNS) - | _acc]. - -decode_pubsub_items_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_items_attr_xmlns(__TopXMLNS, _val) -> - _val. - -decode_pubsub_items_attr_max_items(__TopXMLNS, - undefined) -> - undefined; -decode_pubsub_items_attr_max_items(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"max_items">>, <<"items">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_items_attr_max_items(undefined, _acc) -> - _acc; -encode_pubsub_items_attr_max_items(_val, _acc) -> - [{<<"max_items">>, enc_int(_val)} | _acc]. - -decode_pubsub_items_attr_node(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"items">>, __TopXMLNS}}); -decode_pubsub_items_attr_node(__TopXMLNS, _val) -> _val. - -encode_pubsub_items_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_items_attr_subid(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_items_attr_subid(__TopXMLNS, _val) -> - _val. - -encode_pubsub_items_attr_subid(<<>>, _acc) -> _acc; -encode_pubsub_items_attr_subid(_val, _acc) -> - [{<<"subid">>, _val} | _acc]. - -decode_pubsub_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - __Xmls = decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, - _els, []), - {Id, Xmlns, Node, Publisher} = - decode_pubsub_item_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {ps_item, Xmlns, Id, __Xmls, Node, Publisher}. - -decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, [], - __Xmls) -> - lists:reverse(__Xmls); -decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], __Xmls) -> - decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, _els, - [_el | __Xmls]); -decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], __Xmls) -> - decode_pubsub_item_els(__TopXMLNS, __IgnoreEls, _els, - __Xmls). - -decode_pubsub_item_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, Xmlns, Node, - Publisher) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, _val, - Xmlns, Node, Publisher); -decode_pubsub_item_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Id, _Xmlns, Node, - Publisher) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, _val, - Node, Publisher); -decode_pubsub_item_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Id, Xmlns, _Node, - Publisher) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, - _val, Publisher); -decode_pubsub_item_attrs(__TopXMLNS, - [{<<"publisher">>, _val} | _attrs], Id, Xmlns, Node, - _Publisher) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, - Node, _val); -decode_pubsub_item_attrs(__TopXMLNS, [_ | _attrs], Id, - Xmlns, Node, Publisher) -> - decode_pubsub_item_attrs(__TopXMLNS, _attrs, Id, Xmlns, - Node, Publisher); -decode_pubsub_item_attrs(__TopXMLNS, [], Id, Xmlns, - Node, Publisher) -> - {decode_pubsub_item_attr_id(__TopXMLNS, Id), - decode_pubsub_item_attr_xmlns(__TopXMLNS, Xmlns), - decode_pubsub_item_attr_node(__TopXMLNS, Node), - decode_pubsub_item_attr_publisher(__TopXMLNS, - Publisher)}. - -encode_pubsub_item({ps_item, Xmlns, Id, __Xmls, Node, - Publisher}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = __Xmls, - _attrs = encode_pubsub_item_attr_publisher(Publisher, - encode_pubsub_item_attr_node(Node, - encode_pubsub_item_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"item">>, _attrs, _els}. - -decode_pubsub_item_attr_id(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_item_attr_id(__TopXMLNS, _val) -> _val. - -encode_pubsub_item_attr_id(<<>>, _acc) -> _acc; -encode_pubsub_item_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_pubsub_item_attr_xmlns(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_item_attr_xmlns(__TopXMLNS, _val) -> _val. - -decode_pubsub_item_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_pubsub_item_attr_node(__TopXMLNS, _val) -> _val. - -encode_pubsub_item_attr_node(<<>>, _acc) -> _acc; -encode_pubsub_item_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_item_attr_publisher(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_item_attr_publisher(__TopXMLNS, _val) -> - _val. - -encode_pubsub_item_attr_publisher(<<>>, _acc) -> _acc; -encode_pubsub_item_attr_publisher(_val, _acc) -> - [{<<"publisher">>, _val} | _acc]. - -decode_pubsub_event_retract(__TopXMLNS, __IgnoreEls, - {xmlel, <<"retract">>, _attrs, _els}) -> - Id = decode_pubsub_event_retract_attrs(__TopXMLNS, - _attrs, undefined), - Id. - -decode_pubsub_event_retract_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id) -> - decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, - _val); -decode_pubsub_event_retract_attrs(__TopXMLNS, - [_ | _attrs], Id) -> - decode_pubsub_event_retract_attrs(__TopXMLNS, _attrs, - Id); -decode_pubsub_event_retract_attrs(__TopXMLNS, [], Id) -> - decode_pubsub_event_retract_attr_id(__TopXMLNS, Id). - -encode_pubsub_event_retract(Id, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_pubsub_event_retract_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"retract">>, _attrs, _els}. - -decode_pubsub_event_retract_attr_id(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"retract">>, __TopXMLNS}}); -decode_pubsub_event_retract_attr_id(__TopXMLNS, _val) -> - _val. - -encode_pubsub_event_retract_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_pubsub_event_configuration(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"configuration">>, _attrs, _els}) -> - Xdata = - decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - Node = - decode_pubsub_event_configuration_attrs(__TopXMLNS, - _attrs, undefined), - {Node, Xdata}. - -decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, [], Xdata) -> - Xdata; -decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el - | _els], - Xdata) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, _els, - decode_xdata(<<"jabber:x:data">>, - __IgnoreEls, _el)); - _ -> - decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, _els, Xdata) - end; -decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Xdata) -> - decode_pubsub_event_configuration_els(__TopXMLNS, - __IgnoreEls, _els, Xdata). - -decode_pubsub_event_configuration_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_pubsub_event_configuration_attrs(__TopXMLNS, - _attrs, _val); -decode_pubsub_event_configuration_attrs(__TopXMLNS, - [_ | _attrs], Node) -> - decode_pubsub_event_configuration_attrs(__TopXMLNS, - _attrs, Node); -decode_pubsub_event_configuration_attrs(__TopXMLNS, [], - Node) -> - decode_pubsub_event_configuration_attr_node(__TopXMLNS, - Node). - -encode_pubsub_event_configuration({Node, Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/pubsub#event">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_pubsub_event_configuration_$xdata'(Xdata, - __NewTopXMLNS, - [])), - _attrs = - encode_pubsub_event_configuration_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"configuration">>, _attrs, _els}. - -'encode_pubsub_event_configuration_$xdata'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_pubsub_event_configuration_$xdata'(Xdata, - __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -decode_pubsub_event_configuration_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"configuration">>, - __TopXMLNS}}); -decode_pubsub_event_configuration_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_event_configuration_attr_node(_val, - _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_owner_affiliation(__TopXMLNS, __IgnoreEls, - {xmlel, <<"affiliation">>, _attrs, _els}) -> - {Jid, Xmlns, Type} = - decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {ps_affiliation, Xmlns, <<>>, Type, Jid}. - -decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Xmlns, - Type) -> - decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - _attrs, _val, Xmlns, Type); -decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Jid, - _Xmlns, Type) -> - decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - _attrs, Jid, _val, Type); -decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - [{<<"affiliation">>, _val} | _attrs], Jid, - Xmlns, _Type) -> - decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - _attrs, Jid, Xmlns, _val); -decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - [_ | _attrs], Jid, Xmlns, Type) -> - decode_pubsub_owner_affiliation_attrs(__TopXMLNS, - _attrs, Jid, Xmlns, Type); -decode_pubsub_owner_affiliation_attrs(__TopXMLNS, [], - Jid, Xmlns, Type) -> - {decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, - Jid), - decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, - Xmlns), - decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, - Type)}. - -encode_pubsub_owner_affiliation({ps_affiliation, Xmlns, - _, Type, Jid}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/pubsub#owner">>], - __TopXMLNS), - _els = [], - _attrs = - encode_pubsub_owner_affiliation_attr_affiliation(Type, - encode_pubsub_owner_affiliation_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"affiliation">>, _attrs, _els}. - -decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"affiliation">>, - __TopXMLNS}}); -decode_pubsub_owner_affiliation_attr_jid(__TopXMLNS, - _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"affiliation">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_owner_affiliation_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_owner_affiliation_attr_xmlns(__TopXMLNS, - _val) -> - _val. - -decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"affiliation">>, <<"affiliation">>, - __TopXMLNS}}); -decode_pubsub_owner_affiliation_attr_affiliation(__TopXMLNS, - _val) -> - case catch dec_ps_aff(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"affiliation">>, <<"affiliation">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_owner_affiliation_attr_affiliation(_val, - _acc) -> - [{<<"affiliation">>, enc_ps_aff(_val)} | _acc]. - -decode_pubsub_affiliation(__TopXMLNS, __IgnoreEls, - {xmlel, <<"affiliation">>, _attrs, _els}) -> - {Node, Xmlns, Type} = - decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {ps_affiliation, Xmlns, Node, Type, undefined}. - -decode_pubsub_affiliation_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node, Xmlns, - Type) -> - decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - _val, Xmlns, Type); -decode_pubsub_affiliation_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], Node, _Xmlns, - Type) -> - decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - Node, _val, Type); -decode_pubsub_affiliation_attrs(__TopXMLNS, - [{<<"affiliation">>, _val} | _attrs], Node, - Xmlns, _Type) -> - decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - Node, Xmlns, _val); -decode_pubsub_affiliation_attrs(__TopXMLNS, - [_ | _attrs], Node, Xmlns, Type) -> - decode_pubsub_affiliation_attrs(__TopXMLNS, _attrs, - Node, Xmlns, Type); -decode_pubsub_affiliation_attrs(__TopXMLNS, [], Node, - Xmlns, Type) -> - {decode_pubsub_affiliation_attr_node(__TopXMLNS, Node), - decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, Xmlns), - decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, - Type)}. - -encode_pubsub_affiliation({ps_affiliation, Xmlns, Node, - Type, _}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/pubsub">>], - __TopXMLNS), - _els = [], - _attrs = - encode_pubsub_affiliation_attr_affiliation(Type, - encode_pubsub_affiliation_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"affiliation">>, _attrs, _els}. - -decode_pubsub_affiliation_attr_node(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"node">>, <<"affiliation">>, - __TopXMLNS}}); -decode_pubsub_affiliation_attr_node(__TopXMLNS, _val) -> - _val. - -encode_pubsub_affiliation_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_affiliation_attr_xmlns(__TopXMLNS, - _val) -> - _val. - -decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"affiliation">>, <<"affiliation">>, - __TopXMLNS}}); -decode_pubsub_affiliation_attr_affiliation(__TopXMLNS, - _val) -> - case catch dec_ps_aff(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"affiliation">>, <<"affiliation">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_affiliation_attr_affiliation(_val, - _acc) -> - [{<<"affiliation">>, enc_ps_aff(_val)} | _acc]. - -decode_pubsub_subscription(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subscription">>, _attrs, _els}) -> - {Xmlns, Jid, Node, Subid, Type, Expiry} = - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, - undefined, undefined, undefined), - {ps_subscription, Xmlns, Jid, Type, Node, Subid, - Expiry}. - -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"xmlns">>, _val} | _attrs], _Xmlns, Jid, - Node, Subid, Type, Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - _val, Jid, Node, Subid, Type, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Xmlns, _Jid, - Node, Subid, Type, Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, _val, Node, Subid, Type, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Xmlns, Jid, - _Node, Subid, Type, Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, Jid, _val, Subid, Type, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"subid">>, _val} | _attrs], Xmlns, Jid, - Node, _Subid, Type, Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, Jid, Node, _val, Type, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"subscription">>, _val} | _attrs], Xmlns, - Jid, Node, Subid, _Type, Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, Jid, Node, Subid, _val, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, - [{<<"expiry">>, _val} | _attrs], Xmlns, Jid, - Node, Subid, Type, _Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, Jid, Node, Subid, Type, _val); -decode_pubsub_subscription_attrs(__TopXMLNS, - [_ | _attrs], Xmlns, Jid, Node, Subid, Type, - Expiry) -> - decode_pubsub_subscription_attrs(__TopXMLNS, _attrs, - Xmlns, Jid, Node, Subid, Type, Expiry); -decode_pubsub_subscription_attrs(__TopXMLNS, [], Xmlns, - Jid, Node, Subid, Type, Expiry) -> - {decode_pubsub_subscription_attr_xmlns(__TopXMLNS, - Xmlns), - decode_pubsub_subscription_attr_jid(__TopXMLNS, Jid), - decode_pubsub_subscription_attr_node(__TopXMLNS, Node), - decode_pubsub_subscription_attr_subid(__TopXMLNS, - Subid), - decode_pubsub_subscription_attr_subscription(__TopXMLNS, - Type), - decode_pubsub_subscription_attr_expiry(__TopXMLNS, - Expiry)}. - -encode_pubsub_subscription({ps_subscription, Xmlns, Jid, - Type, Node, Subid, Expiry}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(Xmlns, - [<<"http://jabber.org/protocol/pubsub">>, - <<"http://jabber.org/protocol/pubsub#owner">>, - <<"http://jabber.org/protocol/pubsub#event">>], - __TopXMLNS), - _els = [], - _attrs = encode_pubsub_subscription_attr_expiry(Expiry, - encode_pubsub_subscription_attr_subscription(Type, - encode_pubsub_subscription_attr_subid(Subid, - encode_pubsub_subscription_attr_node(Node, - encode_pubsub_subscription_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"subscription">>, _attrs, _els}. - -decode_pubsub_subscription_attr_xmlns(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_subscription_attr_xmlns(__TopXMLNS, - _val) -> - _val. - -decode_pubsub_subscription_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"subscription">>, - __TopXMLNS}}); -decode_pubsub_subscription_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"subscription">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_subscription_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_pubsub_subscription_attr_node(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_subscription_attr_node(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_subscription_attr_node(<<>>, _acc) -> - _acc; -encode_pubsub_subscription_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_pubsub_subscription_attr_subid(__TopXMLNS, - undefined) -> - <<>>; -decode_pubsub_subscription_attr_subid(__TopXMLNS, - _val) -> - _val. - -encode_pubsub_subscription_attr_subid(<<>>, _acc) -> - _acc; -encode_pubsub_subscription_attr_subid(_val, _acc) -> - [{<<"subid">>, _val} | _acc]. - -decode_pubsub_subscription_attr_subscription(__TopXMLNS, - undefined) -> - undefined; -decode_pubsub_subscription_attr_subscription(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - [none, pending, subscribed, unconfigured]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"subscription">>, <<"subscription">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_subscription_attr_subscription(undefined, - _acc) -> - _acc; -encode_pubsub_subscription_attr_subscription(_val, - _acc) -> - [{<<"subscription">>, enc_enum(_val)} | _acc]. - -decode_pubsub_subscription_attr_expiry(__TopXMLNS, - undefined) -> - undefined; -decode_pubsub_subscription_attr_expiry(__TopXMLNS, - _val) -> - case catch dec_utc(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"expiry">>, <<"subscription">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_pubsub_subscription_attr_expiry(undefined, - _acc) -> - _acc; -encode_pubsub_subscription_attr_expiry(_val, _acc) -> - [{<<"expiry">>, enc_utc(_val)} | _acc]. - -decode_xdata(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - {Fields, Items, Instructions, Reported, Title} = - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, [], [], - [], undefined, undefined), - Type = decode_xdata_attrs(__TopXMLNS, _attrs, - undefined), - {xdata, Type, Instructions, Title, Reported, Items, - Fields}. - -decode_xdata_els(__TopXMLNS, __IgnoreEls, [], Fields, - Items, Instructions, Reported, Title) -> - {lists:reverse(Fields), lists:reverse(Items), - lists:reverse(Instructions), Reported, Title}; -decode_xdata_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], - Fields, Items, Instructions, Reported, Title) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, - [decode_xdata_instructions(__TopXMLNS, __IgnoreEls, - _el) - | Instructions], - Reported, Title); - <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, - [decode_xdata_instructions(<<"jabber:x:data">>, - __IgnoreEls, _el) - | Instructions], - Reported, Title); - _ -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title) - end; -decode_xdata_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"title">>, _attrs, _} = _el | _els], Fields, - Items, Instructions, Reported, Title) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, - decode_xdata_title(__TopXMLNS, __IgnoreEls, _el)); - <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, - decode_xdata_title(<<"jabber:x:data">>, __IgnoreEls, - _el)); - _ -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title) - end; -decode_xdata_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reported">>, _attrs, _} = _el | _els], - Fields, Items, Instructions, Reported, Title) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, - decode_xdata_reported(__TopXMLNS, __IgnoreEls, _el), - Title); - <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, - decode_xdata_reported(<<"jabber:x:data">>, - __IgnoreEls, _el), - Title); - _ -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title) - end; -decode_xdata_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Fields, - Items, Instructions, Reported, Title) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - [decode_xdata_item(__TopXMLNS, __IgnoreEls, _el) - | Items], - Instructions, Reported, Title); - <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - [decode_xdata_item(<<"jabber:x:data">>, __IgnoreEls, - _el) - | Items], - Instructions, Reported, Title); - _ -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title) - end; -decode_xdata_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"field">>, _attrs, _} = _el | _els], Fields, - Items, Instructions, Reported, Title) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(__TopXMLNS, __IgnoreEls, _el) - | Fields], - Items, Instructions, Reported, Title); - <<"jabber:x:data">> -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(<<"jabber:x:data">>, __IgnoreEls, - _el) - | Fields], - Items, Instructions, Reported, Title); - _ -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title) - end; -decode_xdata_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Fields, Items, Instructions, Reported, Title) -> - decode_xdata_els(__TopXMLNS, __IgnoreEls, _els, Fields, - Items, Instructions, Reported, Title). - -decode_xdata_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], _Type) -> - decode_xdata_attrs(__TopXMLNS, _attrs, _val); -decode_xdata_attrs(__TopXMLNS, [_ | _attrs], Type) -> - decode_xdata_attrs(__TopXMLNS, _attrs, Type); -decode_xdata_attrs(__TopXMLNS, [], Type) -> - decode_xdata_attr_type(__TopXMLNS, Type). - -encode_xdata({xdata, Type, Instructions, Title, - Reported, Items, Fields}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = lists:reverse('encode_xdata_$fields'(Fields, - __NewTopXMLNS, - 'encode_xdata_$items'(Items, - __NewTopXMLNS, - 'encode_xdata_$instructions'(Instructions, - __NewTopXMLNS, - 'encode_xdata_$reported'(Reported, - __NewTopXMLNS, - 'encode_xdata_$title'(Title, - __NewTopXMLNS, - [])))))), - _attrs = encode_xdata_attr_type(Type, - enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_xdata_$fields'([], __TopXMLNS, _acc) -> _acc; -'encode_xdata_$fields'([Fields | _els], __TopXMLNS, - _acc) -> - 'encode_xdata_$fields'(_els, __TopXMLNS, - [encode_xdata_field(Fields, __TopXMLNS) | _acc]). - -'encode_xdata_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_xdata_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_xdata_$items'(_els, __TopXMLNS, - [encode_xdata_item(Items, __TopXMLNS) | _acc]). - -'encode_xdata_$instructions'([], __TopXMLNS, _acc) -> - _acc; -'encode_xdata_$instructions'([Instructions | _els], - __TopXMLNS, _acc) -> - 'encode_xdata_$instructions'(_els, __TopXMLNS, - [encode_xdata_instructions(Instructions, - __TopXMLNS) - | _acc]). - -'encode_xdata_$reported'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_xdata_$reported'(Reported, __TopXMLNS, _acc) -> - [encode_xdata_reported(Reported, __TopXMLNS) | _acc]. - -'encode_xdata_$title'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_xdata_$title'(Title, __TopXMLNS, _acc) -> - [encode_xdata_title(Title, __TopXMLNS) | _acc]. - -decode_xdata_attr_type(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"x">>, __TopXMLNS}}); -decode_xdata_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [cancel, form, result, submit]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"x">>, __TopXMLNS}}); - _res -> _res - end. - -encode_xdata_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_xdata_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - Fields = decode_xdata_item_els(__TopXMLNS, __IgnoreEls, - _els, []), - Fields. - -decode_xdata_item_els(__TopXMLNS, __IgnoreEls, [], - Fields) -> - lists:reverse(Fields); -decode_xdata_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"field">>, _attrs, _} = _el | _els], - Fields) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(__TopXMLNS, __IgnoreEls, - _el) - | Fields]); - <<"jabber:x:data">> -> - decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(<<"jabber:x:data">>, - __IgnoreEls, _el) - | Fields]); - _ -> - decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, - Fields) - end; -decode_xdata_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Fields) -> - decode_xdata_item_els(__TopXMLNS, __IgnoreEls, _els, - Fields). - -encode_xdata_item(Fields, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = lists:reverse('encode_xdata_item_$fields'(Fields, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_xdata_item_$fields'([], __TopXMLNS, _acc) -> - _acc; -'encode_xdata_item_$fields'([Fields | _els], __TopXMLNS, - _acc) -> - 'encode_xdata_item_$fields'(_els, __TopXMLNS, - [encode_xdata_field(Fields, __TopXMLNS) - | _acc]). - -decode_xdata_reported(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reported">>, _attrs, _els}) -> - Fields = decode_xdata_reported_els(__TopXMLNS, - __IgnoreEls, _els, []), - Fields. - -decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, [], - Fields) -> - lists:reverse(Fields); -decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"field">>, _attrs, _} = _el | _els], - Fields) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(__TopXMLNS, __IgnoreEls, - _el) - | Fields]); - <<"jabber:x:data">> -> - decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field(<<"jabber:x:data">>, - __IgnoreEls, _el) - | Fields]); - _ -> - decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, - Fields) - end; -decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Fields) -> - decode_xdata_reported_els(__TopXMLNS, __IgnoreEls, _els, - Fields). - -encode_xdata_reported(Fields, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_xdata_reported_$fields'(Fields, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"reported">>, _attrs, _els}. - -'encode_xdata_reported_$fields'([], __TopXMLNS, _acc) -> - _acc; -'encode_xdata_reported_$fields'([Fields | _els], - __TopXMLNS, _acc) -> - 'encode_xdata_reported_$fields'(_els, __TopXMLNS, - [encode_xdata_field(Fields, __TopXMLNS) - | _acc]). - -decode_xdata_title(__TopXMLNS, __IgnoreEls, - {xmlel, <<"title">>, _attrs, _els}) -> - Cdata = decode_xdata_title_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_xdata_title_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_xdata_title_cdata(__TopXMLNS, Cdata); -decode_xdata_title_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_xdata_title_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_xdata_title_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_xdata_title_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_xdata_title(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = encode_xdata_title_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"title">>, _attrs, _els}. - -decode_xdata_title_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_xdata_title_cdata(__TopXMLNS, _val) -> _val. - -encode_xdata_title_cdata(<<>>, _acc) -> _acc; -encode_xdata_title_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_xdata_instructions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"instructions">>, _attrs, _els}) -> - Cdata = decode_xdata_instructions_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_xdata_instructions_cdata(__TopXMLNS, Cdata); -decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_xdata_instructions_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_xdata_instructions(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = encode_xdata_instructions_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"instructions">>, _attrs, _els}. - -decode_xdata_instructions_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_xdata_instructions_cdata(__TopXMLNS, _val) -> - _val. - -encode_xdata_instructions_cdata(<<>>, _acc) -> _acc; -encode_xdata_instructions_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_xdata_field(__TopXMLNS, __IgnoreEls, - {xmlel, <<"field">>, _attrs, _els}) -> - {Options, Values, Desc, Required, __Els} = - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - [], [], <<>>, false, []), - {Label, Type, Var} = - decode_xdata_field_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined), - {xdata_field, Label, Type, Var, Required, Desc, Values, - Options, __Els}. - -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, [], - Options, Values, Desc, Required, __Els) -> - {lists:reverse(Options), lists:reverse(Values), Desc, - Required, lists:reverse(__Els)}; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"required">>, _attrs, _} = _el | _els], - Options, Values, Desc, Required, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, - decode_xdata_field_required(__TopXMLNS, - __IgnoreEls, _el), - __Els); - <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, - decode_xdata_field_required(<<"jabber:x:data">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els) - end; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"desc">>, _attrs, _} = _el | _els], Options, - Values, Desc, Required, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, - decode_xdata_field_desc(__TopXMLNS, - __IgnoreEls, _el), - Required, __Els); - <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, - decode_xdata_field_desc(<<"jabber:x:data">>, - __IgnoreEls, _el), - Required, __Els); - _ -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els) - end; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"value">>, _attrs, _} = _el | _els], Options, - Values, Desc, Required, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, - [decode_xdata_field_value(__TopXMLNS, - __IgnoreEls, _el) - | Values], - Desc, Required, __Els); - <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, - [decode_xdata_field_value(<<"jabber:x:data">>, - __IgnoreEls, _el) - | Values], - Desc, Required, __Els); - _ -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els) - end; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"option">>, _attrs, _} = _el | _els], - Options, Values, Desc, Required, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field_option(__TopXMLNS, - __IgnoreEls, _el) - | Options], - Values, Desc, Required, __Els); - <<"jabber:x:data">> -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata_field_option(<<"jabber:x:data">>, - __IgnoreEls, _el) - | Options], - Values, Desc, Required, __Els); - _ -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els) - end; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Options, Values, Desc, - Required, __Els) -> - if __IgnoreEls -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, - [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els) - end - end; -decode_xdata_field_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Options, Values, Desc, Required, __Els) -> - decode_xdata_field_els(__TopXMLNS, __IgnoreEls, _els, - Options, Values, Desc, Required, __Els). - -decode_xdata_field_attrs(__TopXMLNS, - [{<<"label">>, _val} | _attrs], _Label, Type, Var) -> - decode_xdata_field_attrs(__TopXMLNS, _attrs, _val, Type, - Var); -decode_xdata_field_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Label, _Type, Var) -> - decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, - _val, Var); -decode_xdata_field_attrs(__TopXMLNS, - [{<<"var">>, _val} | _attrs], Label, Type, _Var) -> - decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, - Type, _val); -decode_xdata_field_attrs(__TopXMLNS, [_ | _attrs], - Label, Type, Var) -> - decode_xdata_field_attrs(__TopXMLNS, _attrs, Label, - Type, Var); -decode_xdata_field_attrs(__TopXMLNS, [], Label, Type, - Var) -> - {decode_xdata_field_attr_label(__TopXMLNS, Label), - decode_xdata_field_attr_type(__TopXMLNS, Type), - decode_xdata_field_attr_var(__TopXMLNS, Var)}. - -encode_xdata_field({xdata_field, Label, Type, Var, - Required, Desc, Values, Options, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ - lists:reverse('encode_xdata_field_$options'(Options, - __NewTopXMLNS, - 'encode_xdata_field_$values'(Values, - __NewTopXMLNS, - 'encode_xdata_field_$desc'(Desc, - __NewTopXMLNS, - 'encode_xdata_field_$required'(Required, - __NewTopXMLNS, - []))))), - _attrs = encode_xdata_field_attr_var(Var, - encode_xdata_field_attr_type(Type, - encode_xdata_field_attr_label(Label, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"field">>, _attrs, _els}. - -'encode_xdata_field_$options'([], __TopXMLNS, _acc) -> - _acc; -'encode_xdata_field_$options'([Options | _els], - __TopXMLNS, _acc) -> - 'encode_xdata_field_$options'(_els, __TopXMLNS, - [encode_xdata_field_option(Options, - __TopXMLNS) - | _acc]). - -'encode_xdata_field_$values'([], __TopXMLNS, _acc) -> - _acc; -'encode_xdata_field_$values'([Values | _els], - __TopXMLNS, _acc) -> - 'encode_xdata_field_$values'(_els, __TopXMLNS, - [encode_xdata_field_value(Values, __TopXMLNS) - | _acc]). - -'encode_xdata_field_$desc'(<<>>, __TopXMLNS, _acc) -> - _acc; -'encode_xdata_field_$desc'(Desc, __TopXMLNS, _acc) -> - [encode_xdata_field_desc(Desc, __TopXMLNS) | _acc]. - -'encode_xdata_field_$required'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_xdata_field_$required'(Required, __TopXMLNS, - _acc) -> - [encode_xdata_field_required(Required, __TopXMLNS) - | _acc]. - -decode_xdata_field_attr_label(__TopXMLNS, undefined) -> - <<>>; -decode_xdata_field_attr_label(__TopXMLNS, _val) -> _val. - -encode_xdata_field_attr_label(<<>>, _acc) -> _acc; -encode_xdata_field_attr_label(_val, _acc) -> - [{<<"label">>, _val} | _acc]. - -decode_xdata_field_attr_type(__TopXMLNS, undefined) -> - undefined; -decode_xdata_field_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [boolean, fixed, hidden, 'jid-multi', 'jid-single', - 'list-multi', 'list-single', 'text-multi', - 'text-private', 'text-single']) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"field">>, __TopXMLNS}}); - _res -> _res - end. - -encode_xdata_field_attr_type(undefined, _acc) -> _acc; -encode_xdata_field_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_xdata_field_attr_var(__TopXMLNS, undefined) -> - <<>>; -decode_xdata_field_attr_var(__TopXMLNS, _val) -> _val. - -encode_xdata_field_attr_var(<<>>, _acc) -> _acc; -encode_xdata_field_attr_var(_val, _acc) -> - [{<<"var">>, _val} | _acc]. - -decode_xdata_field_option(__TopXMLNS, __IgnoreEls, - {xmlel, <<"option">>, _attrs, _els}) -> - Value = decode_xdata_field_option_els(__TopXMLNS, - __IgnoreEls, _els, error), - Label = decode_xdata_field_option_attrs(__TopXMLNS, - _attrs, undefined), - {xdata_option, Label, Value}. - -decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - [], Value) -> - case Value of - error -> - erlang:error({xmpp_codec, - {missing_tag, <<"value">>, __TopXMLNS}}); - {value, Value1} -> Value1 - end; -decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"value">>, _attrs, _} = _el | _els], - Value) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:x:data">> -> - decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - _els, - {value, - decode_xdata_field_value(__TopXMLNS, - __IgnoreEls, - _el)}); - <<"jabber:x:data">> -> - decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - _els, - {value, - decode_xdata_field_value(<<"jabber:x:data">>, - __IgnoreEls, - _el)}); - _ -> - decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - _els, Value) - end; -decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Value) -> - decode_xdata_field_option_els(__TopXMLNS, __IgnoreEls, - _els, Value). - -decode_xdata_field_option_attrs(__TopXMLNS, - [{<<"label">>, _val} | _attrs], _Label) -> - decode_xdata_field_option_attrs(__TopXMLNS, _attrs, - _val); -decode_xdata_field_option_attrs(__TopXMLNS, - [_ | _attrs], Label) -> - decode_xdata_field_option_attrs(__TopXMLNS, _attrs, - Label); -decode_xdata_field_option_attrs(__TopXMLNS, [], - Label) -> - decode_xdata_field_option_attr_label(__TopXMLNS, Label). - -encode_xdata_field_option({xdata_option, Label, Value}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_xdata_field_option_$value'(Value, - __NewTopXMLNS, [])), - _attrs = encode_xdata_field_option_attr_label(Label, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"option">>, _attrs, _els}. - -'encode_xdata_field_option_$value'(Value, __TopXMLNS, - _acc) -> - [encode_xdata_field_value(Value, __TopXMLNS) | _acc]. - -decode_xdata_field_option_attr_label(__TopXMLNS, - undefined) -> - <<>>; -decode_xdata_field_option_attr_label(__TopXMLNS, - _val) -> - _val. - -encode_xdata_field_option_attr_label(<<>>, _acc) -> - _acc; -encode_xdata_field_option_attr_label(_val, _acc) -> - [{<<"label">>, _val} | _acc]. - -decode_xdata_field_value(__TopXMLNS, __IgnoreEls, - {xmlel, <<"value">>, _attrs, _els}) -> - Cdata = decode_xdata_field_value_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_xdata_field_value_cdata(__TopXMLNS, Cdata); -decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_xdata_field_value_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_xdata_field_value(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = encode_xdata_field_value_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"value">>, _attrs, _els}. - -decode_xdata_field_value_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_xdata_field_value_cdata(__TopXMLNS, _val) -> - _val. - -encode_xdata_field_value_cdata(<<>>, _acc) -> _acc; -encode_xdata_field_value_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_xdata_field_desc(__TopXMLNS, __IgnoreEls, - {xmlel, <<"desc">>, _attrs, _els}) -> - Cdata = decode_xdata_field_desc_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_xdata_field_desc_cdata(__TopXMLNS, Cdata); -decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_xdata_field_desc_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_xdata_field_desc(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = encode_xdata_field_desc_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"desc">>, _attrs, _els}. - -decode_xdata_field_desc_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_xdata_field_desc_cdata(__TopXMLNS, _val) -> _val. - -encode_xdata_field_desc_cdata(<<>>, _acc) -> _acc; -encode_xdata_field_desc_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_xdata_field_required(__TopXMLNS, __IgnoreEls, - {xmlel, <<"required">>, _attrs, _els}) -> - true. - -encode_xdata_field_required(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:x:data">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"required">>, _attrs, _els}. - -decode_vcard_xupdate(__TopXMLNS, __IgnoreEls, - {xmlel, <<"x">>, _attrs, _els}) -> - Hash = decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, - _els, undefined), - {vcard_xupdate, {<<>>, <<>>}, Hash}. - -decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, [], - Hash) -> - Hash; -decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"photo">>, _attrs, _} = _el | _els], - Hash) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp:x:update">> -> - decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_xupdate_photo(__TopXMLNS, - __IgnoreEls, - _el)); - <<"vcard-temp:x:update">> -> - decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_xupdate_photo(<<"vcard-temp:x:update">>, - __IgnoreEls, - _el)); - _ -> - decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, - Hash) - end; -decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Hash) -> - decode_vcard_xupdate_els(__TopXMLNS, __IgnoreEls, _els, - Hash). - -encode_vcard_xupdate({vcard_xupdate, _, Hash}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"vcard-temp:x:update">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_xupdate_$hash'(Hash, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"x">>, _attrs, _els}. - -'encode_vcard_xupdate_$hash'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_xupdate_$hash'(Hash, __TopXMLNS, _acc) -> - [encode_vcard_xupdate_photo(Hash, __TopXMLNS) | _acc]. - -decode_vcard_xupdate_photo(__TopXMLNS, __IgnoreEls, - {xmlel, <<"photo">>, _attrs, _els}) -> - Cdata = decode_vcard_xupdate_photo_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_vcard_xupdate_photo_cdata(__TopXMLNS, Cdata); -decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_xupdate_photo_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_vcard_xupdate_photo(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"vcard-temp:x:update">>, [], - __TopXMLNS), - _els = encode_vcard_xupdate_photo_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"photo">>, _attrs, _els}. - -decode_vcard_xupdate_photo_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_vcard_xupdate_photo_cdata(__TopXMLNS, _val) -> - _val. - -encode_vcard_xupdate_photo_cdata(<<>>, _acc) -> _acc; -encode_vcard_xupdate_photo_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_temp(__TopXMLNS, __IgnoreEls, - {xmlel, <<"vCard">>, _attrs, _els}) -> - {Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo} = - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - undefined, [], undefined, [], undefined, - undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, - undefined, undefined, undefined, [], [], [], - undefined, undefined, undefined, undefined, - undefined, undefined), - {vcard_temp, Version, Fn, N, Nickname, Photo, Bday, Adr, - Label, Tel, Email, Jabberid, Mailer, Tz, Geo, Title, - Role, Logo, Org, Categories, Note, Prodid, Rev, - Sort_string, Sound, Uid, Url, Class, Key, Desc}. - -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, [], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - {Mailer, lists:reverse(Adr), Class, Categories, Desc, - Uid, Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url, - lists:reverse(Email), lists:reverse(Tel), - lists:reverse(Label), Fn, Version, N, Photo, Logo, Geo}; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"N">>, _attrs, _} = _el | _els], Mailer, Adr, - Class, Categories, Desc, Uid, Prodid, Jabberid, Sound, - Note, Role, Title, Nickname, Rev, Sort_string, Org, - Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, - decode_vcard_N(__TopXMLNS, __IgnoreEls, _el), - Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, - decode_vcard_N(<<"vcard-temp">>, __IgnoreEls, - _el), - Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ADR">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, - [decode_vcard_ADR(__TopXMLNS, __IgnoreEls, _el) - | Adr], - Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, - [decode_vcard_ADR(<<"vcard-temp">>, __IgnoreEls, - _el) - | Adr], - Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LABEL">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, - [decode_vcard_LABEL(__TopXMLNS, __IgnoreEls, - _el) - | Label], - Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, - [decode_vcard_LABEL(<<"vcard-temp">>, - __IgnoreEls, _el) - | Label], - Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TEL">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, - [decode_vcard_TEL(__TopXMLNS, __IgnoreEls, _el) - | Tel], - Label, Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, - [decode_vcard_TEL(<<"vcard-temp">>, __IgnoreEls, - _el) - | Tel], - Label, Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"EMAIL">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, - [decode_vcard_EMAIL(__TopXMLNS, __IgnoreEls, - _el) - | Email], - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, - [decode_vcard_EMAIL(<<"vcard-temp">>, - __IgnoreEls, _el) - | Email], - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"GEO">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, - decode_vcard_GEO(__TopXMLNS, __IgnoreEls, _el)); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, - decode_vcard_GEO(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LOGO">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - decode_vcard_LOGO(__TopXMLNS, __IgnoreEls, _el), - Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - decode_vcard_LOGO(<<"vcard-temp">>, __IgnoreEls, - _el), - Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PHOTO">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, - decode_vcard_PHOTO(__TopXMLNS, __IgnoreEls, - _el), - Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, - decode_vcard_PHOTO(<<"vcard-temp">>, - __IgnoreEls, _el), - Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ORG">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, - decode_vcard_ORG(__TopXMLNS, __IgnoreEls, _el), - Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, - decode_vcard_ORG(<<"vcard-temp">>, __IgnoreEls, - _el), - Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"SOUND">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, - decode_vcard_SOUND(__TopXMLNS, __IgnoreEls, - _el), - Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, - decode_vcard_SOUND(<<"vcard-temp">>, - __IgnoreEls, _el), - Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"KEY">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, - decode_vcard_KEY(__TopXMLNS, __IgnoreEls, _el), - Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, - decode_vcard_KEY(<<"vcard-temp">>, __IgnoreEls, - _el), - Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"VERSION">>, _attrs, _} = _el | _els], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, - decode_vcard_VERSION(__TopXMLNS, __IgnoreEls, - _el), - N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, - decode_vcard_VERSION(<<"vcard-temp">>, - __IgnoreEls, _el), - N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"FN">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, - decode_vcard_FN(__TopXMLNS, __IgnoreEls, _el), - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, - decode_vcard_FN(<<"vcard-temp">>, __IgnoreEls, - _el), - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"NICKNAME">>, _attrs, _} = _el | _els], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - decode_vcard_NICKNAME(__TopXMLNS, __IgnoreEls, - _el), - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - decode_vcard_NICKNAME(<<"vcard-temp">>, - __IgnoreEls, _el), - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"BDAY">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, - decode_vcard_BDAY(__TopXMLNS, __IgnoreEls, _el), - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, - decode_vcard_BDAY(<<"vcard-temp">>, __IgnoreEls, - _el), - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"JABBERID">>, _attrs, _} = _el | _els], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, - decode_vcard_JABBERID(__TopXMLNS, __IgnoreEls, - _el), - Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, - decode_vcard_JABBERID(<<"vcard-temp">>, - __IgnoreEls, _el), - Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"MAILER">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_MAILER(__TopXMLNS, __IgnoreEls, - _el), - Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_MAILER(<<"vcard-temp">>, - __IgnoreEls, _el), - Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TZ">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, - decode_vcard_TZ(__TopXMLNS, __IgnoreEls, _el), - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, - decode_vcard_TZ(<<"vcard-temp">>, __IgnoreEls, - _el), - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TITLE">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, - decode_vcard_TITLE(__TopXMLNS, __IgnoreEls, - _el), - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, - decode_vcard_TITLE(<<"vcard-temp">>, - __IgnoreEls, _el), - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ROLE">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, - decode_vcard_ROLE(__TopXMLNS, __IgnoreEls, _el), - Title, Nickname, Rev, Sort_string, Org, Bday, - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, - decode_vcard_ROLE(<<"vcard-temp">>, __IgnoreEls, - _el), - Title, Nickname, Rev, Sort_string, Org, Bday, - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"NOTE">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, - decode_vcard_NOTE(__TopXMLNS, __IgnoreEls, _el), - Role, Title, Nickname, Rev, Sort_string, Org, - Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, - decode_vcard_NOTE(<<"vcard-temp">>, __IgnoreEls, - _el), - Role, Title, Nickname, Rev, Sort_string, Org, - Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PRODID">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - decode_vcard_PRODID(__TopXMLNS, __IgnoreEls, - _el), - Jabberid, Sound, Note, Role, Title, Nickname, - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - decode_vcard_PRODID(<<"vcard-temp">>, - __IgnoreEls, _el), - Jabberid, Sound, Note, Role, Title, Nickname, - Rev, Sort_string, Org, Bday, Key, Tz, Url, - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"REV">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, - decode_vcard_REV(__TopXMLNS, __IgnoreEls, _el), - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, - decode_vcard_REV(<<"vcard-temp">>, __IgnoreEls, - _el), - Sort_string, Org, Bday, Key, Tz, Url, Email, - Tel, Label, Fn, Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"SORT-STRING">>, _attrs, _} = _el | _els], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, - decode_vcard_SORT_STRING(__TopXMLNS, - __IgnoreEls, _el), - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, - decode_vcard_SORT_STRING(<<"vcard-temp">>, - __IgnoreEls, _el), - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"UID">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, - decode_vcard_UID(__TopXMLNS, __IgnoreEls, _el), - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, - decode_vcard_UID(<<"vcard-temp">>, __IgnoreEls, - _el), - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"URL">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - decode_vcard_URL(__TopXMLNS, __IgnoreEls, _el), - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - decode_vcard_URL(<<"vcard-temp">>, __IgnoreEls, - _el), - Email, Tel, Label, Fn, Version, N, Photo, Logo, - Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"DESC">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, - decode_vcard_DESC(__TopXMLNS, __IgnoreEls, _el), - Uid, Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, - decode_vcard_DESC(<<"vcard-temp">>, __IgnoreEls, - _el), - Uid, Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CATEGORIES">>, _attrs, _} = _el | _els], - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label, - Fn, Version, N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, - decode_vcard_CATEGORIES(__TopXMLNS, __IgnoreEls, - _el), - Desc, Uid, Prodid, Jabberid, Sound, Note, Role, - Title, Nickname, Rev, Sort_string, Org, Bday, - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, - decode_vcard_CATEGORIES(<<"vcard-temp">>, - __IgnoreEls, _el), - Desc, Uid, Prodid, Jabberid, Sound, Note, Role, - Title, Nickname, Rev, Sort_string, Org, Bday, - Key, Tz, Url, Email, Tel, Label, Fn, Version, N, - Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CLASS">>, _attrs, _} = _el | _els], Mailer, - Adr, Class, Categories, Desc, Uid, Prodid, Jabberid, - Sound, Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, - N, Photo, Logo, Geo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, - decode_vcard_CLASS(__TopXMLNS, __IgnoreEls, - _el), - Categories, Desc, Uid, Prodid, Jabberid, Sound, - Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - <<"vcard-temp">> -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, - decode_vcard_CLASS(<<"vcard-temp">>, - __IgnoreEls, _el), - Categories, Desc, Uid, Prodid, Jabberid, Sound, - Note, Role, Title, Nickname, Rev, Sort_string, - Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn, - Version, N, Photo, Logo, Geo); - _ -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, - Nickname, Rev, Sort_string, Org, Bday, Key, Tz, - Url, Email, Tel, Label, Fn, Version, N, Photo, - Logo, Geo) - end; -decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Mailer, Adr, Class, Categories, Desc, Uid, - Prodid, Jabberid, Sound, Note, Role, Title, Nickname, - Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, - Label, Fn, Version, N, Photo, Logo, Geo) -> - decode_vcard_temp_els(__TopXMLNS, __IgnoreEls, _els, - Mailer, Adr, Class, Categories, Desc, Uid, Prodid, - Jabberid, Sound, Note, Role, Title, Nickname, Rev, - Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, - Label, Fn, Version, N, Photo, Logo, Geo). - -encode_vcard_temp({vcard_temp, Version, Fn, N, Nickname, - Photo, Bday, Adr, Label, Tel, Email, Jabberid, Mailer, - Tz, Geo, Title, Role, Logo, Org, Categories, Note, - Prodid, Rev, Sort_string, Sound, Uid, Url, Class, Key, - Desc}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_temp_$mailer'(Mailer, - __NewTopXMLNS, - 'encode_vcard_temp_$adr'(Adr, - __NewTopXMLNS, - 'encode_vcard_temp_$class'(Class, - __NewTopXMLNS, - 'encode_vcard_temp_$categories'(Categories, - __NewTopXMLNS, - 'encode_vcard_temp_$desc'(Desc, - __NewTopXMLNS, - 'encode_vcard_temp_$uid'(Uid, - __NewTopXMLNS, - 'encode_vcard_temp_$prodid'(Prodid, - __NewTopXMLNS, - 'encode_vcard_temp_$jabberid'(Jabberid, - __NewTopXMLNS, - 'encode_vcard_temp_$sound'(Sound, - __NewTopXMLNS, - 'encode_vcard_temp_$note'(Note, - __NewTopXMLNS, - 'encode_vcard_temp_$role'(Role, - __NewTopXMLNS, - 'encode_vcard_temp_$title'(Title, - __NewTopXMLNS, - 'encode_vcard_temp_$nickname'(Nickname, - __NewTopXMLNS, - 'encode_vcard_temp_$rev'(Rev, - __NewTopXMLNS, - 'encode_vcard_temp_$sort_string'(Sort_string, - __NewTopXMLNS, - 'encode_vcard_temp_$org'(Org, - __NewTopXMLNS, - 'encode_vcard_temp_$bday'(Bday, - __NewTopXMLNS, - 'encode_vcard_temp_$key'(Key, - __NewTopXMLNS, - 'encode_vcard_temp_$tz'(Tz, - __NewTopXMLNS, - 'encode_vcard_temp_$url'(Url, - __NewTopXMLNS, - 'encode_vcard_temp_$email'(Email, - __NewTopXMLNS, - 'encode_vcard_temp_$tel'(Tel, - __NewTopXMLNS, - 'encode_vcard_temp_$label'(Label, - __NewTopXMLNS, - 'encode_vcard_temp_$fn'(Fn, - __NewTopXMLNS, - 'encode_vcard_temp_$version'(Version, - __NewTopXMLNS, - 'encode_vcard_temp_$n'(N, - __NewTopXMLNS, - 'encode_vcard_temp_$photo'(Photo, - __NewTopXMLNS, - 'encode_vcard_temp_$logo'(Logo, - __NewTopXMLNS, - 'encode_vcard_temp_$geo'(Geo, - __NewTopXMLNS, - [])))))))))))))))))))))))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"vCard">>, _attrs, _els}. - -'encode_vcard_temp_$mailer'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$mailer'(Mailer, __TopXMLNS, _acc) -> - [encode_vcard_MAILER(Mailer, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$adr'([], __TopXMLNS, _acc) -> _acc; -'encode_vcard_temp_$adr'([Adr | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_temp_$adr'(_els, __TopXMLNS, - [encode_vcard_ADR(Adr, __TopXMLNS) | _acc]). - -'encode_vcard_temp_$class'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$class'(Class, __TopXMLNS, _acc) -> - [encode_vcard_CLASS(Class, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$categories'([], __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$categories'(Categories, __TopXMLNS, - _acc) -> - [encode_vcard_CATEGORIES(Categories, __TopXMLNS) - | _acc]. - -'encode_vcard_temp_$desc'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$desc'(Desc, __TopXMLNS, _acc) -> - [encode_vcard_DESC(Desc, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$uid'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$uid'(Uid, __TopXMLNS, _acc) -> - [encode_vcard_UID(Uid, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$prodid'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$prodid'(Prodid, __TopXMLNS, _acc) -> - [encode_vcard_PRODID(Prodid, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$jabberid'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$jabberid'(Jabberid, __TopXMLNS, - _acc) -> - [encode_vcard_JABBERID(Jabberid, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$sound'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$sound'(Sound, __TopXMLNS, _acc) -> - [encode_vcard_SOUND(Sound, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$note'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$note'(Note, __TopXMLNS, _acc) -> - [encode_vcard_NOTE(Note, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$role'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$role'(Role, __TopXMLNS, _acc) -> - [encode_vcard_ROLE(Role, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$title'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$title'(Title, __TopXMLNS, _acc) -> - [encode_vcard_TITLE(Title, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$nickname'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$nickname'(Nickname, __TopXMLNS, - _acc) -> - [encode_vcard_NICKNAME(Nickname, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$rev'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$rev'(Rev, __TopXMLNS, _acc) -> - [encode_vcard_REV(Rev, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$sort_string'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$sort_string'(Sort_string, - __TopXMLNS, _acc) -> - [encode_vcard_SORT_STRING(Sort_string, __TopXMLNS) - | _acc]. - -'encode_vcard_temp_$org'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$org'(Org, __TopXMLNS, _acc) -> - [encode_vcard_ORG(Org, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$bday'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$bday'(Bday, __TopXMLNS, _acc) -> - [encode_vcard_BDAY(Bday, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$key'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$key'(Key, __TopXMLNS, _acc) -> - [encode_vcard_KEY(Key, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$tz'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$tz'(Tz, __TopXMLNS, _acc) -> - [encode_vcard_TZ(Tz, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$url'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$url'(Url, __TopXMLNS, _acc) -> - [encode_vcard_URL(Url, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$email'([], __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$email'([Email | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_temp_$email'(_els, __TopXMLNS, - [encode_vcard_EMAIL(Email, __TopXMLNS) | _acc]). - -'encode_vcard_temp_$tel'([], __TopXMLNS, _acc) -> _acc; -'encode_vcard_temp_$tel'([Tel | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_temp_$tel'(_els, __TopXMLNS, - [encode_vcard_TEL(Tel, __TopXMLNS) | _acc]). - -'encode_vcard_temp_$label'([], __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$label'([Label | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_temp_$label'(_els, __TopXMLNS, - [encode_vcard_LABEL(Label, __TopXMLNS) | _acc]). - -'encode_vcard_temp_$fn'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$fn'(Fn, __TopXMLNS, _acc) -> - [encode_vcard_FN(Fn, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$version'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$version'(Version, __TopXMLNS, - _acc) -> - [encode_vcard_VERSION(Version, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$n'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$n'(N, __TopXMLNS, _acc) -> - [encode_vcard_N(N, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$photo'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$photo'(Photo, __TopXMLNS, _acc) -> - [encode_vcard_PHOTO(Photo, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$logo'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_temp_$logo'(Logo, __TopXMLNS, _acc) -> - [encode_vcard_LOGO(Logo, __TopXMLNS) | _acc]. - -'encode_vcard_temp_$geo'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_temp_$geo'(Geo, __TopXMLNS, _acc) -> - [encode_vcard_GEO(Geo, __TopXMLNS) | _acc]. - -decode_vcard_CLASS(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CLASS">>, _attrs, _els}) -> - Class = decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, - _els, undefined), - Class. - -decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, [], - Class) -> - Class; -decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PUBLIC">>, _attrs, _} = _el | _els], - Class) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PUBLIC(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PUBLIC(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - Class) - end; -decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PRIVATE">>, _attrs, _} = _el | _els], - Class) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PRIVATE(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PRIVATE(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - Class) - end; -decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CONFIDENTIAL">>, _attrs, _} = _el | _els], - Class) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_CONFIDENTIAL(__TopXMLNS, - __IgnoreEls, _el)); - <<"vcard-temp">> -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_CONFIDENTIAL(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - Class) - end; -decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Class) -> - decode_vcard_CLASS_els(__TopXMLNS, __IgnoreEls, _els, - Class). - -encode_vcard_CLASS(Class, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_CLASS_$class'(Class, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CLASS">>, _attrs, _els}. - -'encode_vcard_CLASS_$class'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_CLASS_$class'(public = Class, __TopXMLNS, - _acc) -> - [encode_vcard_PUBLIC(Class, __TopXMLNS) | _acc]; -'encode_vcard_CLASS_$class'(private = Class, __TopXMLNS, - _acc) -> - [encode_vcard_PRIVATE(Class, __TopXMLNS) | _acc]; -'encode_vcard_CLASS_$class'(confidential = Class, - __TopXMLNS, _acc) -> - [encode_vcard_CONFIDENTIAL(Class, __TopXMLNS) | _acc]. - -decode_vcard_CATEGORIES(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CATEGORIES">>, _attrs, _els}) -> - Keywords = decode_vcard_CATEGORIES_els(__TopXMLNS, - __IgnoreEls, _els, []), - Keywords. - -decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, [], - Keywords) -> - lists:reverse(Keywords); -decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"KEYWORD">>, _attrs, _} = _el | _els], - Keywords) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_vcard_KEYWORD(__TopXMLNS, - __IgnoreEls, _el) - | Keywords]); - <<"vcard-temp">> -> - decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_vcard_KEYWORD(<<"vcard-temp">>, - __IgnoreEls, _el) - | Keywords]); - _ -> - decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - _els, Keywords) - end; -decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Keywords) -> - decode_vcard_CATEGORIES_els(__TopXMLNS, __IgnoreEls, - _els, Keywords). - -encode_vcard_CATEGORIES(Keywords, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_vcard_CATEGORIES_$keywords'(Keywords, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CATEGORIES">>, _attrs, _els}. - -'encode_vcard_CATEGORIES_$keywords'([], __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_CATEGORIES_$keywords'([Keywords | _els], - __TopXMLNS, _acc) -> - 'encode_vcard_CATEGORIES_$keywords'(_els, __TopXMLNS, - [encode_vcard_KEYWORD(Keywords, - __TopXMLNS) - | _acc]). - -decode_vcard_KEY(__TopXMLNS, __IgnoreEls, - {xmlel, <<"KEY">>, _attrs, _els}) -> - {Cred, Type} = decode_vcard_KEY_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - {vcard_key, Type, Cred}. - -decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, [], Cred, - Type) -> - {Cred, Type}; -decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Cred, - Type) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - Cred, - decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, _el)); - <<"vcard-temp">> -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - Cred, - decode_vcard_TYPE(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - Cred, Type) - end; -decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CRED">>, _attrs, _} = _el | _els], Cred, - Type) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_CRED(__TopXMLNS, __IgnoreEls, _el), - Type); - <<"vcard-temp">> -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_CRED(<<"vcard-temp">>, __IgnoreEls, - _el), - Type); - _ -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - Cred, Type) - end; -decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cred, Type) -> - decode_vcard_KEY_els(__TopXMLNS, __IgnoreEls, _els, - Cred, Type). - -encode_vcard_KEY({vcard_key, Type, Cred}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_KEY_$cred'(Cred, - __NewTopXMLNS, - 'encode_vcard_KEY_$type'(Type, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"KEY">>, _attrs, _els}. - -'encode_vcard_KEY_$cred'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_KEY_$cred'(Cred, __TopXMLNS, _acc) -> - [encode_vcard_CRED(Cred, __TopXMLNS) | _acc]. - -'encode_vcard_KEY_$type'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_KEY_$type'(Type, __TopXMLNS, _acc) -> - [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. - -decode_vcard_SOUND(__TopXMLNS, __IgnoreEls, - {xmlel, <<"SOUND">>, _attrs, _els}) -> - {Phonetic, Extval, Binval} = - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined), - {vcard_sound, Phonetic, Binval, Extval}. - -decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, [], - Phonetic, Extval, Binval) -> - {Phonetic, Extval, Binval}; -decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], - Phonetic, Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, - decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, - decode_vcard_BINVAL(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, Binval) - end; -decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], - Phonetic, Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, - decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, - _el), - Binval); - <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, - decode_vcard_EXTVAL(<<"vcard-temp">>, - __IgnoreEls, _el), - Binval); - _ -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, Binval) - end; -decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PHONETIC">>, _attrs, _} = _el | _els], - Phonetic, Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PHONETIC(__TopXMLNS, __IgnoreEls, - _el), - Extval, Binval); - <<"vcard-temp">> -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_PHONETIC(<<"vcard-temp">>, - __IgnoreEls, _el), - Extval, Binval); - _ -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, Binval) - end; -decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Phonetic, Extval, Binval) -> - decode_vcard_SOUND_els(__TopXMLNS, __IgnoreEls, _els, - Phonetic, Extval, Binval). - -encode_vcard_SOUND({vcard_sound, Phonetic, Binval, - Extval}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_vcard_SOUND_$phonetic'(Phonetic, - __NewTopXMLNS, - 'encode_vcard_SOUND_$extval'(Extval, - __NewTopXMLNS, - 'encode_vcard_SOUND_$binval'(Binval, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"SOUND">>, _attrs, _els}. - -'encode_vcard_SOUND_$phonetic'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_SOUND_$phonetic'(Phonetic, __TopXMLNS, - _acc) -> - [encode_vcard_PHONETIC(Phonetic, __TopXMLNS) | _acc]. - -'encode_vcard_SOUND_$extval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_SOUND_$extval'(Extval, __TopXMLNS, - _acc) -> - [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. - -'encode_vcard_SOUND_$binval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_SOUND_$binval'(Binval, __TopXMLNS, - _acc) -> - [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. - -decode_vcard_ORG(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ORG">>, _attrs, _els}) -> - {Units, Name} = decode_vcard_ORG_els(__TopXMLNS, - __IgnoreEls, _els, [], undefined), - {vcard_org, Name, Units}. - -decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, [], Units, - Name) -> - {lists:reverse(Units), Name}; -decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ORGNAME">>, _attrs, _} = _el | _els], Units, - Name) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - Units, - decode_vcard_ORGNAME(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - Units, - decode_vcard_ORGNAME(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - Units, Name) - end; -decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ORGUNIT">>, _attrs, _} = _el | _els], Units, - Name) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - [decode_vcard_ORGUNIT(__TopXMLNS, __IgnoreEls, - _el) - | Units], - Name); - <<"vcard-temp">> -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - [decode_vcard_ORGUNIT(<<"vcard-temp">>, - __IgnoreEls, _el) - | Units], - Name); - _ -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - Units, Name) - end; -decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Units, Name) -> - decode_vcard_ORG_els(__TopXMLNS, __IgnoreEls, _els, - Units, Name). - -encode_vcard_ORG({vcard_org, Name, Units}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_ORG_$units'(Units, - __NewTopXMLNS, - 'encode_vcard_ORG_$name'(Name, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ORG">>, _attrs, _els}. - -'encode_vcard_ORG_$units'([], __TopXMLNS, _acc) -> _acc; -'encode_vcard_ORG_$units'([Units | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_ORG_$units'(_els, __TopXMLNS, - [encode_vcard_ORGUNIT(Units, __TopXMLNS) | _acc]). - -'encode_vcard_ORG_$name'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ORG_$name'(Name, __TopXMLNS, _acc) -> - [encode_vcard_ORGNAME(Name, __TopXMLNS) | _acc]. - -decode_vcard_PHOTO(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PHOTO">>, _attrs, _els}) -> - {Type, Extval, Binval} = - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined), - {vcard_photo, Type, Binval, Extval}. - -decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, [], - Type, Extval, Binval) -> - {Type, Extval, Binval}; -decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, - _el), - Extval, Binval); - <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_TYPE(<<"vcard-temp">>, - __IgnoreEls, _el), - Extval, Binval); - _ -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, - decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, - decode_vcard_BINVAL(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, - decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, - _el), - Binval); - <<"vcard-temp">> -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, - decode_vcard_EXTVAL(<<"vcard-temp">>, - __IgnoreEls, _el), - Binval); - _ -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Type, Extval, Binval) -> - decode_vcard_PHOTO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval). - -encode_vcard_PHOTO({vcard_photo, Type, Binval, Extval}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_PHOTO_$type'(Type, - __NewTopXMLNS, - 'encode_vcard_PHOTO_$extval'(Extval, - __NewTopXMLNS, - 'encode_vcard_PHOTO_$binval'(Binval, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PHOTO">>, _attrs, _els}. - -'encode_vcard_PHOTO_$type'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_PHOTO_$type'(Type, __TopXMLNS, _acc) -> - [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. - -'encode_vcard_PHOTO_$extval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_PHOTO_$extval'(Extval, __TopXMLNS, - _acc) -> - [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. - -'encode_vcard_PHOTO_$binval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_PHOTO_$binval'(Binval, __TopXMLNS, - _acc) -> - [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. - -decode_vcard_LOGO(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LOGO">>, _attrs, _els}) -> - {Type, Extval, Binval} = - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined), - {vcard_logo, Type, Binval, Extval}. - -decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, [], Type, - Extval, Binval) -> - {Type, Extval, Binval}; -decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"TYPE">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, _el), - Extval, Binval); - <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_TYPE(<<"vcard-temp">>, __IgnoreEls, - _el), - Extval, Binval); - _ -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"BINVAL">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, - decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, - decode_vcard_BINVAL(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"EXTVAL">>, _attrs, _} = _el | _els], Type, - Extval, Binval) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, - decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, - _el), - Binval); - <<"vcard-temp">> -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, - decode_vcard_EXTVAL(<<"vcard-temp">>, - __IgnoreEls, _el), - Binval); - _ -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval) - end; -decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Type, Extval, Binval) -> - decode_vcard_LOGO_els(__TopXMLNS, __IgnoreEls, _els, - Type, Extval, Binval). - -encode_vcard_LOGO({vcard_logo, Type, Binval, Extval}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_LOGO_$type'(Type, - __NewTopXMLNS, - 'encode_vcard_LOGO_$extval'(Extval, - __NewTopXMLNS, - 'encode_vcard_LOGO_$binval'(Binval, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LOGO">>, _attrs, _els}. - -'encode_vcard_LOGO_$type'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_LOGO_$type'(Type, __TopXMLNS, _acc) -> - [encode_vcard_TYPE(Type, __TopXMLNS) | _acc]. - -'encode_vcard_LOGO_$extval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_LOGO_$extval'(Extval, __TopXMLNS, _acc) -> - [encode_vcard_EXTVAL(Extval, __TopXMLNS) | _acc]. - -'encode_vcard_LOGO_$binval'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_LOGO_$binval'(Binval, __TopXMLNS, _acc) -> - [encode_vcard_BINVAL(Binval, __TopXMLNS) | _acc]. - -decode_vcard_BINVAL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"BINVAL">>, _attrs, _els}) -> - Cdata = decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_BINVAL_cdata(__TopXMLNS, Cdata); -decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_BINVAL_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_BINVAL(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_BINVAL_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"BINVAL">>, _attrs, _els}. - -decode_vcard_BINVAL_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_BINVAL_cdata(__TopXMLNS, _val) -> - case catch base64:decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"BINVAL">>, __TopXMLNS}}); - _res -> _res - end. - -encode_vcard_BINVAL_cdata(<<>>, _acc) -> _acc; -encode_vcard_BINVAL_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_vcard_GEO(__TopXMLNS, __IgnoreEls, - {xmlel, <<"GEO">>, _attrs, _els}) -> - {Lat, Lon} = decode_vcard_GEO_els(__TopXMLNS, - __IgnoreEls, _els, undefined, undefined), - {vcard_geo, Lat, Lon}. - -decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, [], Lat, - Lon) -> - {Lat, Lon}; -decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LAT">>, _attrs, _} = _el | _els], Lat, - Lon) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_LAT(__TopXMLNS, __IgnoreEls, _el), - Lon); - <<"vcard-temp">> -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_LAT(<<"vcard-temp">>, __IgnoreEls, - _el), - Lon); - _ -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, - Lon) - end; -decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LON">>, _attrs, _} = _el | _els], Lat, - Lon) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, - decode_vcard_LON(__TopXMLNS, __IgnoreEls, _el)); - <<"vcard-temp">> -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, - decode_vcard_LON(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, - Lon) - end; -decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Lat, Lon) -> - decode_vcard_GEO_els(__TopXMLNS, __IgnoreEls, _els, Lat, - Lon). - -encode_vcard_GEO({vcard_geo, Lat, Lon}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_GEO_$lat'(Lat, - __NewTopXMLNS, - 'encode_vcard_GEO_$lon'(Lon, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"GEO">>, _attrs, _els}. - -'encode_vcard_GEO_$lat'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_GEO_$lat'(Lat, __TopXMLNS, _acc) -> - [encode_vcard_LAT(Lat, __TopXMLNS) | _acc]. - -'encode_vcard_GEO_$lon'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_GEO_$lon'(Lon, __TopXMLNS, _acc) -> - [encode_vcard_LON(Lon, __TopXMLNS) | _acc]. - -decode_vcard_EMAIL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"EMAIL">>, _attrs, _els}) -> - {X400, Userid, Internet, Home, Pref, Work} = - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - false, undefined, false, false, false, false), - {vcard_email, Home, Work, Internet, Pref, X400, Userid}. - -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, [], - X400, Userid, Internet, Home, Pref, Work) -> - {X400, Userid, Internet, Home, Pref, Work}; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, - decode_vcard_HOME(__TopXMLNS, __IgnoreEls, - _el), - Pref, Work); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, - decode_vcard_HOME(<<"vcard-temp">>, - __IgnoreEls, _el), - Pref, Work); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, - decode_vcard_WORK(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, - decode_vcard_WORK(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"INTERNET">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, - decode_vcard_INTERNET(__TopXMLNS, __IgnoreEls, - _el), - Home, Pref, Work); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, - decode_vcard_INTERNET(<<"vcard-temp">>, - __IgnoreEls, _el), - Home, Pref, Work); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, - decode_vcard_PREF(__TopXMLNS, __IgnoreEls, - _el), - Work); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, - decode_vcard_PREF(<<"vcard-temp">>, - __IgnoreEls, _el), - Work); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"X400">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_X400(__TopXMLNS, __IgnoreEls, - _el), - Userid, Internet, Home, Pref, Work); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_X400(<<"vcard-temp">>, - __IgnoreEls, _el), - Userid, Internet, Home, Pref, Work); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"USERID">>, _attrs, _} = _el | _els], X400, - Userid, Internet, Home, Pref, Work) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, - decode_vcard_USERID(__TopXMLNS, __IgnoreEls, - _el), - Internet, Home, Pref, Work); - <<"vcard-temp">> -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, - decode_vcard_USERID(<<"vcard-temp">>, - __IgnoreEls, _el), - Internet, Home, Pref, Work); - _ -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work) - end; -decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], X400, Userid, Internet, Home, Pref, Work) -> - decode_vcard_EMAIL_els(__TopXMLNS, __IgnoreEls, _els, - X400, Userid, Internet, Home, Pref, Work). - -encode_vcard_EMAIL({vcard_email, Home, Work, Internet, - Pref, X400, Userid}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_EMAIL_$x400'(X400, - __NewTopXMLNS, - 'encode_vcard_EMAIL_$userid'(Userid, - __NewTopXMLNS, - 'encode_vcard_EMAIL_$internet'(Internet, - __NewTopXMLNS, - 'encode_vcard_EMAIL_$home'(Home, - __NewTopXMLNS, - 'encode_vcard_EMAIL_$pref'(Pref, - __NewTopXMLNS, - 'encode_vcard_EMAIL_$work'(Work, - __NewTopXMLNS, - []))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"EMAIL">>, _attrs, _els}. - -'encode_vcard_EMAIL_$x400'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_EMAIL_$x400'(X400, __TopXMLNS, _acc) -> - [encode_vcard_X400(X400, __TopXMLNS) | _acc]. - -'encode_vcard_EMAIL_$userid'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_EMAIL_$userid'(Userid, __TopXMLNS, - _acc) -> - [encode_vcard_USERID(Userid, __TopXMLNS) | _acc]. - -'encode_vcard_EMAIL_$internet'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_EMAIL_$internet'(Internet, __TopXMLNS, - _acc) -> - [encode_vcard_INTERNET(Internet, __TopXMLNS) | _acc]. - -'encode_vcard_EMAIL_$home'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_EMAIL_$home'(Home, __TopXMLNS, _acc) -> - [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. - -'encode_vcard_EMAIL_$pref'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_EMAIL_$pref'(Pref, __TopXMLNS, _acc) -> - [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. - -'encode_vcard_EMAIL_$work'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_EMAIL_$work'(Work, __TopXMLNS, _acc) -> - [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. - -decode_vcard_TEL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"TEL">>, _attrs, _els}) -> - {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video} = - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - undefined, false, false, false, false, false, - false, false, false, false, false, false, false, - false), - {vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell, - Video, Bbs, Modem, Isdn, Pcs, Pref, Number}. - -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, [], - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video) -> - {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video}; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, - decode_vcard_HOME(__TopXMLNS, __IgnoreEls, _el), - Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, - decode_vcard_HOME(<<"vcard-temp">>, __IgnoreEls, - _el), - Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, - decode_vcard_WORK(__TopXMLNS, __IgnoreEls, _el), - Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, - decode_vcard_WORK(<<"vcard-temp">>, __IgnoreEls, - _el), - Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"VOICE">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, - decode_vcard_VOICE(__TopXMLNS, __IgnoreEls, _el), - Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn, - Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, - decode_vcard_VOICE(<<"vcard-temp">>, __IgnoreEls, - _el), - Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn, - Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"FAX">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - decode_vcard_FAX(__TopXMLNS, __IgnoreEls, _el), - Work, Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - decode_vcard_FAX(<<"vcard-temp">>, __IgnoreEls, - _el), - Work, Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PAGER">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, - decode_vcard_PAGER(__TopXMLNS, __IgnoreEls, _el), - Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, - decode_vcard_PAGER(<<"vcard-temp">>, __IgnoreEls, - _el), - Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"MSG">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, - decode_vcard_MSG(__TopXMLNS, __IgnoreEls, _el), - Fax, Work, Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, - decode_vcard_MSG(<<"vcard-temp">>, __IgnoreEls, - _el), - Fax, Work, Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CELL">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, - decode_vcard_CELL(__TopXMLNS, __IgnoreEls, _el), - Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, - decode_vcard_CELL(<<"vcard-temp">>, __IgnoreEls, - _el), - Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"VIDEO">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, - decode_vcard_VIDEO(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, - decode_vcard_VIDEO(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"BBS">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, - decode_vcard_BBS(__TopXMLNS, __IgnoreEls, _el), - Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, - Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, - decode_vcard_BBS(<<"vcard-temp">>, __IgnoreEls, - _el), - Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, - Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"MODEM">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, - decode_vcard_MODEM(__TopXMLNS, __IgnoreEls, _el), - Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, - decode_vcard_MODEM(<<"vcard-temp">>, __IgnoreEls, - _el), - Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"ISDN">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, - decode_vcard_ISDN(__TopXMLNS, __IgnoreEls, _el), - Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, - decode_vcard_ISDN(<<"vcard-temp">>, __IgnoreEls, - _el), - Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PCS">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, - decode_vcard_PCS(__TopXMLNS, __IgnoreEls, _el), - Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, - Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, - decode_vcard_PCS(<<"vcard-temp">>, __IgnoreEls, - _el), - Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, - Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, - decode_vcard_PREF(__TopXMLNS, __IgnoreEls, _el), - Msg, Fax, Work, Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, - decode_vcard_PREF(<<"vcard-temp">>, __IgnoreEls, - _el), - Msg, Fax, Work, Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"NUMBER">>, _attrs, _} = _el | _els], Number, - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, Work, - Cell, Modem, Isdn, Video) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_NUMBER(__TopXMLNS, __IgnoreEls, - _el), - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video); - <<"vcard-temp">> -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_NUMBER(<<"vcard-temp">>, - __IgnoreEls, _el), - Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video); - _ -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, - Fax, Work, Cell, Modem, Isdn, Video) - end; -decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Number, Pager, Pcs, Bbs, Voice, Home, Pref, - Msg, Fax, Work, Cell, Modem, Isdn, Video) -> - decode_vcard_TEL_els(__TopXMLNS, __IgnoreEls, _els, - Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax, - Work, Cell, Modem, Isdn, Video). - -encode_vcard_TEL({vcard_tel, Home, Work, Voice, Fax, - Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs, Pref, - Number}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_TEL_$number'(Number, - __NewTopXMLNS, - 'encode_vcard_TEL_$pager'(Pager, - __NewTopXMLNS, - 'encode_vcard_TEL_$pcs'(Pcs, - __NewTopXMLNS, - 'encode_vcard_TEL_$bbs'(Bbs, - __NewTopXMLNS, - 'encode_vcard_TEL_$voice'(Voice, - __NewTopXMLNS, - 'encode_vcard_TEL_$home'(Home, - __NewTopXMLNS, - 'encode_vcard_TEL_$pref'(Pref, - __NewTopXMLNS, - 'encode_vcard_TEL_$msg'(Msg, - __NewTopXMLNS, - 'encode_vcard_TEL_$fax'(Fax, - __NewTopXMLNS, - 'encode_vcard_TEL_$work'(Work, - __NewTopXMLNS, - 'encode_vcard_TEL_$cell'(Cell, - __NewTopXMLNS, - 'encode_vcard_TEL_$modem'(Modem, - __NewTopXMLNS, - 'encode_vcard_TEL_$isdn'(Isdn, - __NewTopXMLNS, - 'encode_vcard_TEL_$video'(Video, - __NewTopXMLNS, - []))))))))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"TEL">>, _attrs, _els}. - -'encode_vcard_TEL_$number'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_TEL_$number'(Number, __TopXMLNS, _acc) -> - [encode_vcard_NUMBER(Number, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$pager'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$pager'(Pager, __TopXMLNS, _acc) -> - [encode_vcard_PAGER(Pager, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$pcs'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$pcs'(Pcs, __TopXMLNS, _acc) -> - [encode_vcard_PCS(Pcs, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$bbs'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$bbs'(Bbs, __TopXMLNS, _acc) -> - [encode_vcard_BBS(Bbs, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$voice'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$voice'(Voice, __TopXMLNS, _acc) -> - [encode_vcard_VOICE(Voice, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$home'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$home'(Home, __TopXMLNS, _acc) -> - [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$pref'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$pref'(Pref, __TopXMLNS, _acc) -> - [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$msg'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$msg'(Msg, __TopXMLNS, _acc) -> - [encode_vcard_MSG(Msg, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$fax'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$fax'(Fax, __TopXMLNS, _acc) -> - [encode_vcard_FAX(Fax, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$work'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$work'(Work, __TopXMLNS, _acc) -> - [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$cell'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$cell'(Cell, __TopXMLNS, _acc) -> - [encode_vcard_CELL(Cell, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$modem'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$modem'(Modem, __TopXMLNS, _acc) -> - [encode_vcard_MODEM(Modem, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$isdn'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$isdn'(Isdn, __TopXMLNS, _acc) -> - [encode_vcard_ISDN(Isdn, __TopXMLNS) | _acc]. - -'encode_vcard_TEL_$video'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_TEL_$video'(Video, __TopXMLNS, _acc) -> - [encode_vcard_VIDEO(Video, __TopXMLNS) | _acc]. - -decode_vcard_LABEL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LABEL">>, _attrs, _els}) -> - {Line, Home, Pref, Work, Intl, Parcel, Postal, Dom} = - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - [], false, false, false, false, false, false, - false), - {vcard_label, Home, Work, Postal, Parcel, Dom, Intl, - Pref, Line}. - -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, [], - Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - {lists:reverse(Line), Home, Pref, Work, Intl, Parcel, - Postal, Dom}; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, - decode_vcard_HOME(__TopXMLNS, __IgnoreEls, - _el), - Pref, Work, Intl, Parcel, Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, - decode_vcard_HOME(<<"vcard-temp">>, - __IgnoreEls, _el), - Pref, Work, Intl, Parcel, Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, - decode_vcard_WORK(__TopXMLNS, __IgnoreEls, - _el), - Intl, Parcel, Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, - decode_vcard_WORK(<<"vcard-temp">>, - __IgnoreEls, _el), - Intl, Parcel, Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"POSTAL">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, - decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, - _el), - Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, - decode_vcard_POSTAL(<<"vcard-temp">>, - __IgnoreEls, _el), - Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PARCEL">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, - decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, - _el), - Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, - decode_vcard_PARCEL(<<"vcard-temp">>, - __IgnoreEls, _el), - Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"DOM">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - decode_vcard_DOM(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - decode_vcard_DOM(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"INTL">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, - decode_vcard_INTL(__TopXMLNS, __IgnoreEls, - _el), - Parcel, Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, - decode_vcard_INTL(<<"vcard-temp">>, - __IgnoreEls, _el), - Parcel, Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, - decode_vcard_PREF(__TopXMLNS, __IgnoreEls, - _el), - Work, Intl, Parcel, Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, - decode_vcard_PREF(<<"vcard-temp">>, - __IgnoreEls, _el), - Work, Intl, Parcel, Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LINE">>, _attrs, _} = _el | _els], Line, - Home, Pref, Work, Intl, Parcel, Postal, Dom) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - [decode_vcard_LINE(__TopXMLNS, __IgnoreEls, - _el) - | Line], - Home, Pref, Work, Intl, Parcel, Postal, Dom); - <<"vcard-temp">> -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - [decode_vcard_LINE(<<"vcard-temp">>, - __IgnoreEls, _el) - | Line], - Home, Pref, Work, Intl, Parcel, Postal, Dom); - _ -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, - Dom) - end; -decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Line, Home, Pref, Work, Intl, Parcel, - Postal, Dom) -> - decode_vcard_LABEL_els(__TopXMLNS, __IgnoreEls, _els, - Line, Home, Pref, Work, Intl, Parcel, Postal, Dom). - -encode_vcard_LABEL({vcard_label, Home, Work, Postal, - Parcel, Dom, Intl, Pref, Line}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_LABEL_$line'(Line, - __NewTopXMLNS, - 'encode_vcard_LABEL_$home'(Home, - __NewTopXMLNS, - 'encode_vcard_LABEL_$pref'(Pref, - __NewTopXMLNS, - 'encode_vcard_LABEL_$work'(Work, - __NewTopXMLNS, - 'encode_vcard_LABEL_$intl'(Intl, - __NewTopXMLNS, - 'encode_vcard_LABEL_$parcel'(Parcel, - __NewTopXMLNS, - 'encode_vcard_LABEL_$postal'(Postal, - __NewTopXMLNS, - 'encode_vcard_LABEL_$dom'(Dom, - __NewTopXMLNS, - []))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LABEL">>, _attrs, _els}. - -'encode_vcard_LABEL_$line'([], __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$line'([Line | _els], __TopXMLNS, - _acc) -> - 'encode_vcard_LABEL_$line'(_els, __TopXMLNS, - [encode_vcard_LINE(Line, __TopXMLNS) | _acc]). - -'encode_vcard_LABEL_$home'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$home'(Home, __TopXMLNS, _acc) -> - [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$pref'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$pref'(Pref, __TopXMLNS, _acc) -> - [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$work'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$work'(Work, __TopXMLNS, _acc) -> - [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$intl'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$intl'(Intl, __TopXMLNS, _acc) -> - [encode_vcard_INTL(Intl, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$parcel'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$parcel'(Parcel, __TopXMLNS, - _acc) -> - [encode_vcard_PARCEL(Parcel, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$postal'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$postal'(Postal, __TopXMLNS, - _acc) -> - [encode_vcard_POSTAL(Postal, __TopXMLNS) | _acc]. - -'encode_vcard_LABEL_$dom'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_LABEL_$dom'(Dom, __TopXMLNS, _acc) -> - [encode_vcard_DOM(Dom, __TopXMLNS) | _acc]. - -decode_vcard_ADR(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ADR">>, _attrs, _els}) -> - {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, Region} = - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, false, false, - undefined, undefined, undefined, false, false, - false, false, false, undefined), - {vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref, - Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}. - -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, [], - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, Region) -> - {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, Region}; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"HOME">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, - decode_vcard_HOME(__TopXMLNS, __IgnoreEls, _el), - Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, - Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, - decode_vcard_HOME(<<"vcard-temp">>, __IgnoreEls, - _el), - Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, - Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"WORK">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, - decode_vcard_WORK(__TopXMLNS, __IgnoreEls, _el), - Intl, Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, - decode_vcard_WORK(<<"vcard-temp">>, __IgnoreEls, - _el), - Intl, Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"POSTAL">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, - decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, - _el), - Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, - decode_vcard_POSTAL(<<"vcard-temp">>, - __IgnoreEls, _el), - Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PARCEL">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, - decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, - _el), - Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, - decode_vcard_PARCEL(<<"vcard-temp">>, - __IgnoreEls, _el), - Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"DOM">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, - decode_vcard_DOM(__TopXMLNS, __IgnoreEls, _el), - Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, - decode_vcard_DOM(<<"vcard-temp">>, __IgnoreEls, - _el), - Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"INTL">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, - decode_vcard_INTL(__TopXMLNS, __IgnoreEls, _el), - Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, - decode_vcard_INTL(<<"vcard-temp">>, __IgnoreEls, - _el), - Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PREF">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, - decode_vcard_PREF(__TopXMLNS, __IgnoreEls, _el), - Pobox, Ctry, Locality, Work, Intl, Parcel, - Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, - decode_vcard_PREF(<<"vcard-temp">>, __IgnoreEls, - _el), - Pobox, Ctry, Locality, Work, Intl, Parcel, - Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"POBOX">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, - decode_vcard_POBOX(__TopXMLNS, __IgnoreEls, _el), - Ctry, Locality, Work, Intl, Parcel, Postal, Dom, - Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, - decode_vcard_POBOX(<<"vcard-temp">>, __IgnoreEls, - _el), - Ctry, Locality, Work, Intl, Parcel, Postal, Dom, - Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"EXTADD">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, - decode_vcard_EXTADD(__TopXMLNS, __IgnoreEls, - _el), - Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, - decode_vcard_EXTADD(<<"vcard-temp">>, - __IgnoreEls, _el), - Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"STREET">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_STREET(__TopXMLNS, __IgnoreEls, - _el), - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, - Work, Intl, Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_STREET(<<"vcard-temp">>, - __IgnoreEls, _el), - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, - Work, Intl, Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"LOCALITY">>, _attrs, _} = _el | _els], - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - decode_vcard_LOCALITY(__TopXMLNS, __IgnoreEls, - _el), - Work, Intl, Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - decode_vcard_LOCALITY(<<"vcard-temp">>, - __IgnoreEls, _el), - Work, Intl, Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"REGION">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - decode_vcard_REGION(__TopXMLNS, __IgnoreEls, - _el)); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - decode_vcard_REGION(<<"vcard-temp">>, - __IgnoreEls, _el)); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PCODE">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, - decode_vcard_PCODE(__TopXMLNS, __IgnoreEls, _el), - Home, Pref, Pobox, Ctry, Locality, Work, Intl, - Parcel, Postal, Dom, Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, - decode_vcard_PCODE(<<"vcard-temp">>, __IgnoreEls, - _el), - Home, Pref, Pobox, Ctry, Locality, Work, Intl, - Parcel, Postal, Dom, Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"CTRY">>, _attrs, _} = _el | _els], Street, - Extadd, Pcode, Home, Pref, Pobox, Ctry, Locality, Work, - Intl, Parcel, Postal, Dom, Region) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, - decode_vcard_CTRY(__TopXMLNS, __IgnoreEls, _el), - Locality, Work, Intl, Parcel, Postal, Dom, - Region); - <<"vcard-temp">> -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, - decode_vcard_CTRY(<<"vcard-temp">>, __IgnoreEls, - _el), - Locality, Work, Intl, Parcel, Postal, Dom, - Region); - _ -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, - Region) - end; -decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Street, Extadd, Pcode, Home, Pref, Pobox, - Ctry, Locality, Work, Intl, Parcel, Postal, Dom, - Region) -> - decode_vcard_ADR_els(__TopXMLNS, __IgnoreEls, _els, - Street, Extadd, Pcode, Home, Pref, Pobox, Ctry, - Locality, Work, Intl, Parcel, Postal, Dom, Region). - -encode_vcard_ADR({vcard_adr, Home, Work, Postal, Parcel, - Dom, Intl, Pref, Pobox, Extadd, Street, Locality, - Region, Pcode, Ctry}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_ADR_$street'(Street, - __NewTopXMLNS, - 'encode_vcard_ADR_$extadd'(Extadd, - __NewTopXMLNS, - 'encode_vcard_ADR_$pcode'(Pcode, - __NewTopXMLNS, - 'encode_vcard_ADR_$home'(Home, - __NewTopXMLNS, - 'encode_vcard_ADR_$pref'(Pref, - __NewTopXMLNS, - 'encode_vcard_ADR_$pobox'(Pobox, - __NewTopXMLNS, - 'encode_vcard_ADR_$ctry'(Ctry, - __NewTopXMLNS, - 'encode_vcard_ADR_$locality'(Locality, - __NewTopXMLNS, - 'encode_vcard_ADR_$work'(Work, - __NewTopXMLNS, - 'encode_vcard_ADR_$intl'(Intl, - __NewTopXMLNS, - 'encode_vcard_ADR_$parcel'(Parcel, - __NewTopXMLNS, - 'encode_vcard_ADR_$postal'(Postal, - __NewTopXMLNS, - 'encode_vcard_ADR_$dom'(Dom, - __NewTopXMLNS, - 'encode_vcard_ADR_$region'(Region, - __NewTopXMLNS, - []))))))))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ADR">>, _attrs, _els}. - -'encode_vcard_ADR_$street'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$street'(Street, __TopXMLNS, _acc) -> - [encode_vcard_STREET(Street, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$extadd'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$extadd'(Extadd, __TopXMLNS, _acc) -> - [encode_vcard_EXTADD(Extadd, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$pcode'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$pcode'(Pcode, __TopXMLNS, _acc) -> - [encode_vcard_PCODE(Pcode, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$home'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$home'(Home, __TopXMLNS, _acc) -> - [encode_vcard_HOME(Home, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$pref'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$pref'(Pref, __TopXMLNS, _acc) -> - [encode_vcard_PREF(Pref, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$pobox'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$pobox'(Pobox, __TopXMLNS, _acc) -> - [encode_vcard_POBOX(Pobox, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$ctry'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$ctry'(Ctry, __TopXMLNS, _acc) -> - [encode_vcard_CTRY(Ctry, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$locality'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$locality'(Locality, __TopXMLNS, - _acc) -> - [encode_vcard_LOCALITY(Locality, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$work'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$work'(Work, __TopXMLNS, _acc) -> - [encode_vcard_WORK(Work, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$intl'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$intl'(Intl, __TopXMLNS, _acc) -> - [encode_vcard_INTL(Intl, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$parcel'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$parcel'(Parcel, __TopXMLNS, _acc) -> - [encode_vcard_PARCEL(Parcel, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$postal'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$postal'(Postal, __TopXMLNS, _acc) -> - [encode_vcard_POSTAL(Postal, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$dom'(false, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_ADR_$dom'(Dom, __TopXMLNS, _acc) -> - [encode_vcard_DOM(Dom, __TopXMLNS) | _acc]. - -'encode_vcard_ADR_$region'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_vcard_ADR_$region'(Region, __TopXMLNS, _acc) -> - [encode_vcard_REGION(Region, __TopXMLNS) | _acc]. - -decode_vcard_N(__TopXMLNS, __IgnoreEls, - {xmlel, <<"N">>, _attrs, _els}) -> - {Middle, Suffix, Prefix, Family, Given} = - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, - undefined), - {vcard_name, Family, Given, Middle, Prefix, Suffix}. - -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, [], Middle, - Suffix, Prefix, Family, Given) -> - {Middle, Suffix, Prefix, Family, Given}; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"FAMILY">>, _attrs, _} = _el | _els], Middle, - Suffix, Prefix, Family, Given) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, - decode_vcard_FAMILY(__TopXMLNS, __IgnoreEls, _el), - Given); - <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, - decode_vcard_FAMILY(<<"vcard-temp">>, __IgnoreEls, - _el), - Given); - _ -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given) - end; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"GIVEN">>, _attrs, _} = _el | _els], Middle, - Suffix, Prefix, Family, Given) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, - decode_vcard_GIVEN(__TopXMLNS, __IgnoreEls, _el)); - <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, - decode_vcard_GIVEN(<<"vcard-temp">>, __IgnoreEls, - _el)); - _ -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given) - end; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"MIDDLE">>, _attrs, _} = _el | _els], Middle, - Suffix, Prefix, Family, Given) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_MIDDLE(__TopXMLNS, __IgnoreEls, _el), - Suffix, Prefix, Family, Given); - <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - decode_vcard_MIDDLE(<<"vcard-temp">>, __IgnoreEls, - _el), - Suffix, Prefix, Family, Given); - _ -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given) - end; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"PREFIX">>, _attrs, _} = _el | _els], Middle, - Suffix, Prefix, Family, Given) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, - decode_vcard_PREFIX(__TopXMLNS, __IgnoreEls, _el), - Family, Given); - <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, - decode_vcard_PREFIX(<<"vcard-temp">>, __IgnoreEls, - _el), - Family, Given); - _ -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given) - end; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"SUFFIX">>, _attrs, _} = _el | _els], Middle, - Suffix, Prefix, Family, Given) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, - decode_vcard_SUFFIX(__TopXMLNS, __IgnoreEls, _el), - Prefix, Family, Given); - <<"vcard-temp">> -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, - decode_vcard_SUFFIX(<<"vcard-temp">>, __IgnoreEls, - _el), - Prefix, Family, Given); - _ -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given) - end; -decode_vcard_N_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Middle, Suffix, Prefix, Family, Given) -> - decode_vcard_N_els(__TopXMLNS, __IgnoreEls, _els, - Middle, Suffix, Prefix, Family, Given). - -encode_vcard_N({vcard_name, Family, Given, Middle, - Prefix, Suffix}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = lists:reverse('encode_vcard_N_$middle'(Middle, - __NewTopXMLNS, - 'encode_vcard_N_$suffix'(Suffix, - __NewTopXMLNS, - 'encode_vcard_N_$prefix'(Prefix, - __NewTopXMLNS, - 'encode_vcard_N_$family'(Family, - __NewTopXMLNS, - 'encode_vcard_N_$given'(Given, - __NewTopXMLNS, - [])))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"N">>, _attrs, _els}. - -'encode_vcard_N_$middle'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_N_$middle'(Middle, __TopXMLNS, _acc) -> - [encode_vcard_MIDDLE(Middle, __TopXMLNS) | _acc]. - -'encode_vcard_N_$suffix'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_N_$suffix'(Suffix, __TopXMLNS, _acc) -> - [encode_vcard_SUFFIX(Suffix, __TopXMLNS) | _acc]. - -'encode_vcard_N_$prefix'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_N_$prefix'(Prefix, __TopXMLNS, _acc) -> - [encode_vcard_PREFIX(Prefix, __TopXMLNS) | _acc]. - -'encode_vcard_N_$family'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_N_$family'(Family, __TopXMLNS, _acc) -> - [encode_vcard_FAMILY(Family, __TopXMLNS) | _acc]. - -'encode_vcard_N_$given'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_vcard_N_$given'(Given, __TopXMLNS, _acc) -> - [encode_vcard_GIVEN(Given, __TopXMLNS) | _acc]. - -decode_vcard_CONFIDENTIAL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}) -> - confidential. - -encode_vcard_CONFIDENTIAL(confidential, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}. - -decode_vcard_PRIVATE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PRIVATE">>, _attrs, _els}) -> - private. - -encode_vcard_PRIVATE(private, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PRIVATE">>, _attrs, _els}. - -decode_vcard_PUBLIC(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PUBLIC">>, _attrs, _els}) -> - public. - -encode_vcard_PUBLIC(public, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PUBLIC">>, _attrs, _els}. - -decode_vcard_EXTVAL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"EXTVAL">>, _attrs, _els}) -> - Cdata = decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_EXTVAL_cdata(__TopXMLNS, Cdata); -decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_EXTVAL_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_EXTVAL(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_EXTVAL_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"EXTVAL">>, _attrs, _els}. - -decode_vcard_EXTVAL_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_EXTVAL_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_EXTVAL_cdata(<<>>, _acc) -> _acc; -encode_vcard_EXTVAL_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_TYPE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"TYPE">>, _attrs, _els}) -> - Cdata = decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_TYPE_cdata(__TopXMLNS, Cdata); -decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_TYPE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_TYPE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_TYPE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"TYPE">>, _attrs, _els}. - -decode_vcard_TYPE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_TYPE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_TYPE_cdata(<<>>, _acc) -> _acc; -encode_vcard_TYPE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_DESC(__TopXMLNS, __IgnoreEls, - {xmlel, <<"DESC">>, _attrs, _els}) -> - Cdata = decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_DESC_cdata(__TopXMLNS, Cdata); -decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_DESC_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_DESC(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_DESC_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"DESC">>, _attrs, _els}. - -decode_vcard_DESC_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_DESC_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_DESC_cdata(<<>>, _acc) -> _acc; -encode_vcard_DESC_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_URL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"URL">>, _attrs, _els}) -> - Cdata = decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_URL_cdata(__TopXMLNS, Cdata); -decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_URL_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_URL(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_URL_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"URL">>, _attrs, _els}. - -decode_vcard_URL_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_URL_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_URL_cdata(<<>>, _acc) -> _acc; -encode_vcard_URL_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_UID(__TopXMLNS, __IgnoreEls, - {xmlel, <<"UID">>, _attrs, _els}) -> - Cdata = decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_UID_cdata(__TopXMLNS, Cdata); -decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_UID_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_UID(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_UID_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"UID">>, _attrs, _els}. - -decode_vcard_UID_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_UID_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_UID_cdata(<<>>, _acc) -> _acc; -encode_vcard_UID_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_SORT_STRING(__TopXMLNS, __IgnoreEls, - {xmlel, <<"SORT-STRING">>, _attrs, _els}) -> - Cdata = decode_vcard_SORT_STRING_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_vcard_SORT_STRING_cdata(__TopXMLNS, Cdata); -decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_SORT_STRING_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_vcard_SORT_STRING(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_SORT_STRING_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"SORT-STRING">>, _attrs, _els}. - -decode_vcard_SORT_STRING_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_vcard_SORT_STRING_cdata(__TopXMLNS, _val) -> - _val. - -encode_vcard_SORT_STRING_cdata(<<>>, _acc) -> _acc; -encode_vcard_SORT_STRING_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_REV(__TopXMLNS, __IgnoreEls, - {xmlel, <<"REV">>, _attrs, _els}) -> - Cdata = decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_REV_cdata(__TopXMLNS, Cdata); -decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_REV_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_REV(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_REV_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"REV">>, _attrs, _els}. - -decode_vcard_REV_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_REV_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_REV_cdata(<<>>, _acc) -> _acc; -encode_vcard_REV_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_PRODID(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PRODID">>, _attrs, _els}) -> - Cdata = decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_PRODID_cdata(__TopXMLNS, Cdata); -decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_PRODID_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_PRODID(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_PRODID_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PRODID">>, _attrs, _els}. - -decode_vcard_PRODID_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_PRODID_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_PRODID_cdata(<<>>, _acc) -> _acc; -encode_vcard_PRODID_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_NOTE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"NOTE">>, _attrs, _els}) -> - Cdata = decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_NOTE_cdata(__TopXMLNS, Cdata); -decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_NOTE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_NOTE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_NOTE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"NOTE">>, _attrs, _els}. - -decode_vcard_NOTE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_NOTE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_NOTE_cdata(<<>>, _acc) -> _acc; -encode_vcard_NOTE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_KEYWORD(__TopXMLNS, __IgnoreEls, - {xmlel, <<"KEYWORD">>, _attrs, _els}) -> - Cdata = decode_vcard_KEYWORD_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_KEYWORD_cdata(__TopXMLNS, Cdata); -decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_KEYWORD_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_KEYWORD(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_KEYWORD_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"KEYWORD">>, _attrs, _els}. - -decode_vcard_KEYWORD_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_KEYWORD_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_KEYWORD_cdata(<<>>, _acc) -> _acc; -encode_vcard_KEYWORD_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_ROLE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ROLE">>, _attrs, _els}) -> - Cdata = decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_ROLE_cdata(__TopXMLNS, Cdata); -decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_ROLE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_ROLE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_ROLE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ROLE">>, _attrs, _els}. - -decode_vcard_ROLE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_ROLE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_ROLE_cdata(<<>>, _acc) -> _acc; -encode_vcard_ROLE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_TITLE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"TITLE">>, _attrs, _els}) -> - Cdata = decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_TITLE_cdata(__TopXMLNS, Cdata); -decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_TITLE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_TITLE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_TITLE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"TITLE">>, _attrs, _els}. - -decode_vcard_TITLE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_TITLE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_TITLE_cdata(<<>>, _acc) -> _acc; -encode_vcard_TITLE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_TZ(__TopXMLNS, __IgnoreEls, - {xmlel, <<"TZ">>, _attrs, _els}) -> - Cdata = decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_TZ_cdata(__TopXMLNS, Cdata); -decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_vcard_TZ_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_TZ(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_TZ_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"TZ">>, _attrs, _els}. - -decode_vcard_TZ_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_TZ_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_TZ_cdata(<<>>, _acc) -> _acc; -encode_vcard_TZ_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_MAILER(__TopXMLNS, __IgnoreEls, - {xmlel, <<"MAILER">>, _attrs, _els}) -> - Cdata = decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_MAILER_cdata(__TopXMLNS, Cdata); -decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_MAILER_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_MAILER(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_MAILER_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"MAILER">>, _attrs, _els}. - -decode_vcard_MAILER_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_MAILER_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_MAILER_cdata(<<>>, _acc) -> _acc; -encode_vcard_MAILER_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_JABBERID(__TopXMLNS, __IgnoreEls, - {xmlel, <<"JABBERID">>, _attrs, _els}) -> - Cdata = decode_vcard_JABBERID_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_JABBERID_cdata(__TopXMLNS, Cdata); -decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_JABBERID_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_JABBERID(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_JABBERID_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"JABBERID">>, _attrs, _els}. - -decode_vcard_JABBERID_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_JABBERID_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_JABBERID_cdata(<<>>, _acc) -> _acc; -encode_vcard_JABBERID_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_BDAY(__TopXMLNS, __IgnoreEls, - {xmlel, <<"BDAY">>, _attrs, _els}) -> - Cdata = decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_BDAY_cdata(__TopXMLNS, Cdata); -decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_BDAY_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_BDAY(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_BDAY_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"BDAY">>, _attrs, _els}. - -decode_vcard_BDAY_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_BDAY_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_BDAY_cdata(<<>>, _acc) -> _acc; -encode_vcard_BDAY_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_NICKNAME(__TopXMLNS, __IgnoreEls, - {xmlel, <<"NICKNAME">>, _attrs, _els}) -> - Cdata = decode_vcard_NICKNAME_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_NICKNAME_cdata(__TopXMLNS, Cdata); -decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_NICKNAME_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_NICKNAME(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_NICKNAME_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"NICKNAME">>, _attrs, _els}. - -decode_vcard_NICKNAME_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_NICKNAME_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_NICKNAME_cdata(<<>>, _acc) -> _acc; -encode_vcard_NICKNAME_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_FN(__TopXMLNS, __IgnoreEls, - {xmlel, <<"FN">>, _attrs, _els}) -> - Cdata = decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_FN_cdata(__TopXMLNS, Cdata); -decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_vcard_FN_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_FN(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_FN_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"FN">>, _attrs, _els}. - -decode_vcard_FN_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_FN_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_FN_cdata(<<>>, _acc) -> _acc; -encode_vcard_FN_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_VERSION(__TopXMLNS, __IgnoreEls, - {xmlel, <<"VERSION">>, _attrs, _els}) -> - Cdata = decode_vcard_VERSION_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_VERSION_cdata(__TopXMLNS, Cdata); -decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_VERSION_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_VERSION(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_VERSION_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"VERSION">>, _attrs, _els}. - -decode_vcard_VERSION_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_VERSION_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_VERSION_cdata(<<>>, _acc) -> _acc; -encode_vcard_VERSION_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_CRED(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CRED">>, _attrs, _els}) -> - Cdata = decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_CRED_cdata(__TopXMLNS, Cdata); -decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_CRED_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_CRED(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_CRED_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CRED">>, _attrs, _els}. - -decode_vcard_CRED_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_CRED_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_CRED_cdata(<<>>, _acc) -> _acc; -encode_vcard_CRED_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_PHONETIC(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PHONETIC">>, _attrs, _els}) -> - Cdata = decode_vcard_PHONETIC_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_PHONETIC_cdata(__TopXMLNS, Cdata); -decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_PHONETIC_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_PHONETIC(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_PHONETIC_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PHONETIC">>, _attrs, _els}. - -decode_vcard_PHONETIC_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_PHONETIC_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_PHONETIC_cdata(<<>>, _acc) -> _acc; -encode_vcard_PHONETIC_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_ORGUNIT(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ORGUNIT">>, _attrs, _els}) -> - Cdata = decode_vcard_ORGUNIT_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_ORGUNIT_cdata(__TopXMLNS, Cdata); -decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_ORGUNIT_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_ORGUNIT(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_ORGUNIT_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ORGUNIT">>, _attrs, _els}. - -decode_vcard_ORGUNIT_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_ORGUNIT_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_ORGUNIT_cdata(<<>>, _acc) -> _acc; -encode_vcard_ORGUNIT_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_ORGNAME(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ORGNAME">>, _attrs, _els}) -> - Cdata = decode_vcard_ORGNAME_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_ORGNAME_cdata(__TopXMLNS, Cdata); -decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_ORGNAME_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_ORGNAME(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_ORGNAME_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ORGNAME">>, _attrs, _els}. - -decode_vcard_ORGNAME_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_ORGNAME_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_ORGNAME_cdata(<<>>, _acc) -> _acc; -encode_vcard_ORGNAME_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_LON(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LON">>, _attrs, _els}) -> - Cdata = decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_LON_cdata(__TopXMLNS, Cdata); -decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_LON_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_LON(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_LON_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LON">>, _attrs, _els}. - -decode_vcard_LON_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_LON_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_LON_cdata(<<>>, _acc) -> _acc; -encode_vcard_LON_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_LAT(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LAT">>, _attrs, _els}) -> - Cdata = decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_LAT_cdata(__TopXMLNS, Cdata); -decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_LAT_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_LAT(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_LAT_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LAT">>, _attrs, _els}. - -decode_vcard_LAT_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_LAT_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_LAT_cdata(<<>>, _acc) -> _acc; -encode_vcard_LAT_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_USERID(__TopXMLNS, __IgnoreEls, - {xmlel, <<"USERID">>, _attrs, _els}) -> - Cdata = decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_USERID_cdata(__TopXMLNS, Cdata); -decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_USERID_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_USERID(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_USERID_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"USERID">>, _attrs, _els}. - -decode_vcard_USERID_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_USERID_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_USERID_cdata(<<>>, _acc) -> _acc; -encode_vcard_USERID_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_NUMBER(__TopXMLNS, __IgnoreEls, - {xmlel, <<"NUMBER">>, _attrs, _els}) -> - Cdata = decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_NUMBER_cdata(__TopXMLNS, Cdata); -decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_NUMBER_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_NUMBER(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_NUMBER_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"NUMBER">>, _attrs, _els}. - -decode_vcard_NUMBER_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_NUMBER_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_NUMBER_cdata(<<>>, _acc) -> _acc; -encode_vcard_NUMBER_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_LINE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LINE">>, _attrs, _els}) -> - Cdata = decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_LINE_cdata(__TopXMLNS, Cdata); -decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_LINE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_LINE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_LINE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LINE">>, _attrs, _els}. - -decode_vcard_LINE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_LINE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_LINE_cdata(<<>>, _acc) -> _acc; -encode_vcard_LINE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_CTRY(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CTRY">>, _attrs, _els}) -> - Cdata = decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_CTRY_cdata(__TopXMLNS, Cdata); -decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_CTRY_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_CTRY(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_CTRY_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CTRY">>, _attrs, _els}. - -decode_vcard_CTRY_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_CTRY_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_CTRY_cdata(<<>>, _acc) -> _acc; -encode_vcard_CTRY_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_PCODE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PCODE">>, _attrs, _els}) -> - Cdata = decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_PCODE_cdata(__TopXMLNS, Cdata); -decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_PCODE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_PCODE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_PCODE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PCODE">>, _attrs, _els}. - -decode_vcard_PCODE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_PCODE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_PCODE_cdata(<<>>, _acc) -> _acc; -encode_vcard_PCODE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_REGION(__TopXMLNS, __IgnoreEls, - {xmlel, <<"REGION">>, _attrs, _els}) -> - Cdata = decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_REGION_cdata(__TopXMLNS, Cdata); -decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_REGION_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_REGION(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_REGION_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"REGION">>, _attrs, _els}. - -decode_vcard_REGION_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_REGION_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_REGION_cdata(<<>>, _acc) -> _acc; -encode_vcard_REGION_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_LOCALITY(__TopXMLNS, __IgnoreEls, - {xmlel, <<"LOCALITY">>, _attrs, _els}) -> - Cdata = decode_vcard_LOCALITY_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_LOCALITY_cdata(__TopXMLNS, Cdata); -decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_LOCALITY_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_LOCALITY(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_LOCALITY_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"LOCALITY">>, _attrs, _els}. - -decode_vcard_LOCALITY_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_LOCALITY_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_LOCALITY_cdata(<<>>, _acc) -> _acc; -encode_vcard_LOCALITY_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_STREET(__TopXMLNS, __IgnoreEls, - {xmlel, <<"STREET">>, _attrs, _els}) -> - Cdata = decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_STREET_cdata(__TopXMLNS, Cdata); -decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_STREET_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_STREET(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_STREET_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"STREET">>, _attrs, _els}. - -decode_vcard_STREET_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_STREET_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_STREET_cdata(<<>>, _acc) -> _acc; -encode_vcard_STREET_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_EXTADD(__TopXMLNS, __IgnoreEls, - {xmlel, <<"EXTADD">>, _attrs, _els}) -> - Cdata = decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_EXTADD_cdata(__TopXMLNS, Cdata); -decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_EXTADD_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_EXTADD(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_EXTADD_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"EXTADD">>, _attrs, _els}. - -decode_vcard_EXTADD_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_EXTADD_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_EXTADD_cdata(<<>>, _acc) -> _acc; -encode_vcard_EXTADD_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_POBOX(__TopXMLNS, __IgnoreEls, - {xmlel, <<"POBOX">>, _attrs, _els}) -> - Cdata = decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_POBOX_cdata(__TopXMLNS, Cdata); -decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_POBOX_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_POBOX(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_POBOX_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"POBOX">>, _attrs, _els}. - -decode_vcard_POBOX_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_POBOX_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_POBOX_cdata(<<>>, _acc) -> _acc; -encode_vcard_POBOX_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_SUFFIX(__TopXMLNS, __IgnoreEls, - {xmlel, <<"SUFFIX">>, _attrs, _els}) -> - Cdata = decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_SUFFIX_cdata(__TopXMLNS, Cdata); -decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_SUFFIX_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_SUFFIX(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_SUFFIX_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"SUFFIX">>, _attrs, _els}. - -decode_vcard_SUFFIX_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_SUFFIX_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_SUFFIX_cdata(<<>>, _acc) -> _acc; -encode_vcard_SUFFIX_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_PREFIX(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PREFIX">>, _attrs, _els}) -> - Cdata = decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_PREFIX_cdata(__TopXMLNS, Cdata); -decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_PREFIX_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_PREFIX(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_PREFIX_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PREFIX">>, _attrs, _els}. - -decode_vcard_PREFIX_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_PREFIX_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_PREFIX_cdata(<<>>, _acc) -> _acc; -encode_vcard_PREFIX_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_MIDDLE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"MIDDLE">>, _attrs, _els}) -> - Cdata = decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_MIDDLE_cdata(__TopXMLNS, Cdata); -decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_MIDDLE_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_MIDDLE(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_MIDDLE_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"MIDDLE">>, _attrs, _els}. - -decode_vcard_MIDDLE_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_MIDDLE_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_MIDDLE_cdata(<<>>, _acc) -> _acc; -encode_vcard_MIDDLE_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_GIVEN(__TopXMLNS, __IgnoreEls, - {xmlel, <<"GIVEN">>, _attrs, _els}) -> - Cdata = decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_GIVEN_cdata(__TopXMLNS, Cdata); -decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_GIVEN_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_GIVEN(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_GIVEN_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"GIVEN">>, _attrs, _els}. - -decode_vcard_GIVEN_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_GIVEN_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_GIVEN_cdata(<<>>, _acc) -> _acc; -encode_vcard_GIVEN_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_FAMILY(__TopXMLNS, __IgnoreEls, - {xmlel, <<"FAMILY">>, _attrs, _els}) -> - Cdata = decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_vcard_FAMILY_cdata(__TopXMLNS, Cdata); -decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_vcard_FAMILY_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_vcard_FAMILY(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = encode_vcard_FAMILY_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"FAMILY">>, _attrs, _els}. - -decode_vcard_FAMILY_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_vcard_FAMILY_cdata(__TopXMLNS, _val) -> _val. - -encode_vcard_FAMILY_cdata(<<>>, _acc) -> _acc; -encode_vcard_FAMILY_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_vcard_X400(__TopXMLNS, __IgnoreEls, - {xmlel, <<"X400">>, _attrs, _els}) -> - true. - -encode_vcard_X400(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"X400">>, _attrs, _els}. - -decode_vcard_INTERNET(__TopXMLNS, __IgnoreEls, - {xmlel, <<"INTERNET">>, _attrs, _els}) -> - true. - -encode_vcard_INTERNET(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"INTERNET">>, _attrs, _els}. - -decode_vcard_PREF(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PREF">>, _attrs, _els}) -> - true. - -encode_vcard_PREF(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PREF">>, _attrs, _els}. - -decode_vcard_INTL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"INTL">>, _attrs, _els}) -> - true. - -encode_vcard_INTL(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"INTL">>, _attrs, _els}. - -decode_vcard_DOM(__TopXMLNS, __IgnoreEls, - {xmlel, <<"DOM">>, _attrs, _els}) -> - true. - -encode_vcard_DOM(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"DOM">>, _attrs, _els}. - -decode_vcard_PARCEL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PARCEL">>, _attrs, _els}) -> - true. - -encode_vcard_PARCEL(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PARCEL">>, _attrs, _els}. - -decode_vcard_POSTAL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"POSTAL">>, _attrs, _els}) -> - true. - -encode_vcard_POSTAL(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"POSTAL">>, _attrs, _els}. - -decode_vcard_PCS(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PCS">>, _attrs, _els}) -> - true. - -encode_vcard_PCS(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PCS">>, _attrs, _els}. - -decode_vcard_ISDN(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ISDN">>, _attrs, _els}) -> - true. - -encode_vcard_ISDN(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ISDN">>, _attrs, _els}. - -decode_vcard_MODEM(__TopXMLNS, __IgnoreEls, - {xmlel, <<"MODEM">>, _attrs, _els}) -> - true. - -encode_vcard_MODEM(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"MODEM">>, _attrs, _els}. - -decode_vcard_BBS(__TopXMLNS, __IgnoreEls, - {xmlel, <<"BBS">>, _attrs, _els}) -> - true. - -encode_vcard_BBS(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"BBS">>, _attrs, _els}. - -decode_vcard_VIDEO(__TopXMLNS, __IgnoreEls, - {xmlel, <<"VIDEO">>, _attrs, _els}) -> - true. - -encode_vcard_VIDEO(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"VIDEO">>, _attrs, _els}. - -decode_vcard_CELL(__TopXMLNS, __IgnoreEls, - {xmlel, <<"CELL">>, _attrs, _els}) -> - true. - -encode_vcard_CELL(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"CELL">>, _attrs, _els}. - -decode_vcard_MSG(__TopXMLNS, __IgnoreEls, - {xmlel, <<"MSG">>, _attrs, _els}) -> - true. - -encode_vcard_MSG(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"MSG">>, _attrs, _els}. - -decode_vcard_PAGER(__TopXMLNS, __IgnoreEls, - {xmlel, <<"PAGER">>, _attrs, _els}) -> - true. - -encode_vcard_PAGER(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"PAGER">>, _attrs, _els}. - -decode_vcard_FAX(__TopXMLNS, __IgnoreEls, - {xmlel, <<"FAX">>, _attrs, _els}) -> - true. - -encode_vcard_FAX(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"FAX">>, _attrs, _els}. - -decode_vcard_VOICE(__TopXMLNS, __IgnoreEls, - {xmlel, <<"VOICE">>, _attrs, _els}) -> - true. - -encode_vcard_VOICE(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"VOICE">>, _attrs, _els}. - -decode_vcard_WORK(__TopXMLNS, __IgnoreEls, - {xmlel, <<"WORK">>, _attrs, _els}) -> - true. - -encode_vcard_WORK(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"WORK">>, _attrs, _els}. - -decode_vcard_HOME(__TopXMLNS, __IgnoreEls, - {xmlel, <<"HOME">>, _attrs, _els}) -> - true. - -encode_vcard_HOME(true, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"vcard-temp">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"HOME">>, _attrs, _els}. - -decode_stream_error(__TopXMLNS, __IgnoreEls, - {xmlel, <<"stream:error">>, _attrs, _els}) -> - {Text, Reason} = decode_stream_error_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined), - {stream_error, Reason, Text}. - -decode_stream_error_els(__TopXMLNS, __IgnoreEls, [], - Text, Reason) -> - {Text, Reason}; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - decode_stream_error_text(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, _el), - Reason); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"bad-format">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_bad_format(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"bad-namespace-prefix">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_bad_namespace_prefix(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], Text, - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"connection-timeout">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_connection_timeout(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"host-gone">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_host_gone(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"host-unknown">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_host_unknown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"improper-addressing">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_improper_addressing(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"internal-server-error">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-from">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_invalid_from(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-id">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_invalid_id(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-namespace">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_invalid_namespace(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-xml">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_invalid_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-well-formed">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_not_well_formed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"policy-violation">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remote-connection-failed">>, _attrs, _} = - _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_remote_connection_failed(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"reset">>, _attrs, _} = _el | _els], Text, - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_reset(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"resource-constraint">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"restricted-xml">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_restricted_xml(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"see-other-host">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_see_other_host(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"system-shutdown">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_system_shutdown(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"undefined-condition">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsupported-encoding">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_unsupported_encoding(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsupported-stanza-type">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_unsupported_stanza_type(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsupported-version">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"urn:ietf:params:xml:ns:xmpp-streams">> -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_stream_error_unsupported_version(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - __IgnoreEls, - _el)); - _ -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_stream_error_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text, Reason) -> - decode_stream_error_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason). - -encode_stream_error({stream_error, Reason, Text}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = lists:reverse('encode_stream_error_$text'(Text, - __NewTopXMLNS, - 'encode_stream_error_$reason'(Reason, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"stream:error">>, _attrs, _els}. - -'encode_stream_error_$text'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_stream_error_$text'(Text, __TopXMLNS, _acc) -> - [encode_stream_error_text(Text, __TopXMLNS) | _acc]. - -'encode_stream_error_$reason'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_stream_error_$reason'('bad-format' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_bad_format(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('bad-namespace-prefix' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_bad_namespace_prefix(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'(conflict = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_conflict(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('connection-timeout' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_connection_timeout(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('host-gone' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_host_gone(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('host-unknown' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_host_unknown(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('improper-addressing' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_improper_addressing(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('internal-server-error' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_internal_server_error(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('invalid-from' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_invalid_from(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('invalid-id' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_invalid_id(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('invalid-namespace' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_invalid_namespace(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('invalid-xml' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_invalid_xml(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('not-authorized' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_not_authorized(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('not-well-formed' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_not_well_formed(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('policy-violation' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_policy_violation(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('remote-connection-failed' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_remote_connection_failed(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'(reset = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_reset(Reason, __TopXMLNS) | _acc]; -'encode_stream_error_$reason'('resource-constraint' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_resource_constraint(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('restricted-xml' = Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_restricted_xml(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'({'see-other-host', _} = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_see_other_host(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('system-shutdown' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_system_shutdown(Reason, __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('undefined-condition' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_undefined_condition(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('unsupported-encoding' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_unsupported_encoding(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('unsupported-stanza-type' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_unsupported_stanza_type(Reason, - __TopXMLNS) - | _acc]; -'encode_stream_error_$reason'('unsupported-version' = - Reason, - __TopXMLNS, _acc) -> - [encode_stream_error_unsupported_version(Reason, - __TopXMLNS) - | _acc]. - -decode_stream_error_unsupported_version(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"unsupported-version">>, - _attrs, _els}) -> - 'unsupported-version'. - -encode_stream_error_unsupported_version('unsupported-version', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsupported-version">>, _attrs, _els}. - -decode_stream_error_unsupported_stanza_type(__TopXMLNS, - __IgnoreEls, - {xmlel, - <<"unsupported-stanza-type">>, - _attrs, _els}) -> - 'unsupported-stanza-type'. - -encode_stream_error_unsupported_stanza_type('unsupported-stanza-type', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsupported-stanza-type">>, _attrs, _els}. - -decode_stream_error_unsupported_encoding(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"unsupported-encoding">>, - _attrs, _els}) -> - 'unsupported-encoding'. - -encode_stream_error_unsupported_encoding('unsupported-encoding', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsupported-encoding">>, _attrs, _els}. - -decode_stream_error_undefined_condition(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"undefined-condition">>, - _attrs, _els}) -> - 'undefined-condition'. - -encode_stream_error_undefined_condition('undefined-condition', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"undefined-condition">>, _attrs, _els}. - -decode_stream_error_system_shutdown(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"system-shutdown">>, _attrs, - _els}) -> - 'system-shutdown'. - -encode_stream_error_system_shutdown('system-shutdown', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"system-shutdown">>, _attrs, _els}. - -decode_stream_error_see_other_host(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"see-other-host">>, _attrs, - _els}) -> - Host = - decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - {'see-other-host', Host}. - -decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, [], Host) -> - decode_stream_error_see_other_host_cdata(__TopXMLNS, - Host); -decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, [{xmlcdata, _data} | _els], - Host) -> - decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, _els, - <>); -decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Host) -> - decode_stream_error_see_other_host_els(__TopXMLNS, - __IgnoreEls, _els, Host). - -encode_stream_error_see_other_host({'see-other-host', - Host}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = encode_stream_error_see_other_host_cdata(Host, - []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"see-other-host">>, _attrs, _els}. - -decode_stream_error_see_other_host_cdata(__TopXMLNS, - <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"see-other-host">>, - __TopXMLNS}}); -decode_stream_error_see_other_host_cdata(__TopXMLNS, - _val) -> - case catch dec_host_port(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"see-other-host">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_stream_error_see_other_host_cdata(_val, _acc) -> - [{xmlcdata, enc_host_port(_val)} | _acc]. - -decode_stream_error_restricted_xml(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"restricted-xml">>, _attrs, - _els}) -> - 'restricted-xml'. - -encode_stream_error_restricted_xml('restricted-xml', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"restricted-xml">>, _attrs, _els}. - -decode_stream_error_resource_constraint(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"resource-constraint">>, - _attrs, _els}) -> - 'resource-constraint'. - -encode_stream_error_resource_constraint('resource-constraint', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"resource-constraint">>, _attrs, _els}. - -decode_stream_error_reset(__TopXMLNS, __IgnoreEls, - {xmlel, <<"reset">>, _attrs, _els}) -> - reset. - -encode_stream_error_reset(reset, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"reset">>, _attrs, _els}. - -decode_stream_error_remote_connection_failed(__TopXMLNS, - __IgnoreEls, - {xmlel, - <<"remote-connection-failed">>, - _attrs, _els}) -> - 'remote-connection-failed'. - -encode_stream_error_remote_connection_failed('remote-connection-failed', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"remote-connection-failed">>, _attrs, _els}. - -decode_stream_error_policy_violation(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"policy-violation">>, _attrs, - _els}) -> - 'policy-violation'. - -encode_stream_error_policy_violation('policy-violation', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"policy-violation">>, _attrs, _els}. - -decode_stream_error_not_well_formed(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"not-well-formed">>, _attrs, - _els}) -> - 'not-well-formed'. - -encode_stream_error_not_well_formed('not-well-formed', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-well-formed">>, _attrs, _els}. - -decode_stream_error_not_authorized(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"not-authorized">>, _attrs, - _els}) -> - 'not-authorized'. - -encode_stream_error_not_authorized('not-authorized', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-authorized">>, _attrs, _els}. - -decode_stream_error_invalid_xml(__TopXMLNS, __IgnoreEls, - {xmlel, <<"invalid-xml">>, _attrs, _els}) -> - 'invalid-xml'. - -encode_stream_error_invalid_xml('invalid-xml', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-xml">>, _attrs, _els}. - -decode_stream_error_invalid_namespace(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-namespace">>, _attrs, - _els}) -> - 'invalid-namespace'. - -encode_stream_error_invalid_namespace('invalid-namespace', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-namespace">>, _attrs, _els}. - -decode_stream_error_invalid_id(__TopXMLNS, __IgnoreEls, - {xmlel, <<"invalid-id">>, _attrs, _els}) -> - 'invalid-id'. - -encode_stream_error_invalid_id('invalid-id', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-id">>, _attrs, _els}. - -decode_stream_error_invalid_from(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-from">>, _attrs, _els}) -> - 'invalid-from'. - -encode_stream_error_invalid_from('invalid-from', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-from">>, _attrs, _els}. - -decode_stream_error_internal_server_error(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"internal-server-error">>, - _attrs, _els}) -> - 'internal-server-error'. - -encode_stream_error_internal_server_error('internal-server-error', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"internal-server-error">>, _attrs, _els}. - -decode_stream_error_improper_addressing(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"improper-addressing">>, - _attrs, _els}) -> - 'improper-addressing'. - -encode_stream_error_improper_addressing('improper-addressing', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"improper-addressing">>, _attrs, _els}. - -decode_stream_error_host_unknown(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"host-unknown">>, _attrs, _els}) -> - 'host-unknown'. - -encode_stream_error_host_unknown('host-unknown', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"host-unknown">>, _attrs, _els}. - -decode_stream_error_host_gone(__TopXMLNS, __IgnoreEls, - {xmlel, <<"host-gone">>, _attrs, _els}) -> - 'host-gone'. - -encode_stream_error_host_gone('host-gone', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"host-gone">>, _attrs, _els}. - -decode_stream_error_connection_timeout(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"connection-timeout">>, _attrs, - _els}) -> - 'connection-timeout'. - -encode_stream_error_connection_timeout('connection-timeout', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"connection-timeout">>, _attrs, _els}. - -decode_stream_error_conflict(__TopXMLNS, __IgnoreEls, - {xmlel, <<"conflict">>, _attrs, _els}) -> - conflict. - -encode_stream_error_conflict(conflict, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"conflict">>, _attrs, _els}. - -decode_stream_error_bad_namespace_prefix(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"bad-namespace-prefix">>, - _attrs, _els}) -> - 'bad-namespace-prefix'. - -encode_stream_error_bad_namespace_prefix('bad-namespace-prefix', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"bad-namespace-prefix">>, _attrs, _els}. - -decode_stream_error_bad_format(__TopXMLNS, __IgnoreEls, - {xmlel, <<"bad-format">>, _attrs, _els}) -> - 'bad-format'. - -encode_stream_error_bad_format('bad-format', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"bad-format">>, _attrs, _els}. - -decode_stream_error_text(__TopXMLNS, __IgnoreEls, - {xmlel, <<"text">>, _attrs, _els}) -> - Data = decode_stream_error_text_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Lang = decode_stream_error_text_attrs(__TopXMLNS, - _attrs, undefined), - {text, Lang, Data}. - -decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, - [], Data) -> - decode_stream_error_text_cdata(__TopXMLNS, Data); -decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_stream_error_text_els(__TopXMLNS, __IgnoreEls, - _els, Data). - -decode_stream_error_text_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_stream_error_text_attrs(__TopXMLNS, _attrs, - _val); -decode_stream_error_text_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_stream_error_text_attrs(__TopXMLNS, _attrs, - Lang); -decode_stream_error_text_attrs(__TopXMLNS, [], Lang) -> - 'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, - Lang). - -encode_stream_error_text({text, Lang, Data}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-streams">>, - [], __TopXMLNS), - _els = encode_stream_error_text_cdata(Data, []), - _attrs = 'encode_stream_error_text_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"text">>, _attrs, _els}. - -'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_stream_error_text_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_stream_error_text_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_stream_error_text_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_stream_error_text_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_stream_error_text_cdata(__TopXMLNS, _val) -> - _val. - -encode_stream_error_text_cdata(<<>>, _acc) -> _acc; -encode_stream_error_text_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_time(__TopXMLNS, __IgnoreEls, - {xmlel, <<"time">>, _attrs, _els}) -> - {Utc, Tzo} = decode_time_els(__TopXMLNS, __IgnoreEls, - _els, undefined, undefined), - {time, Tzo, Utc}. - -decode_time_els(__TopXMLNS, __IgnoreEls, [], Utc, - Tzo) -> - {Utc, Tzo}; -decode_time_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"tzo">>, _attrs, _} = _el | _els], Utc, - Tzo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:time">> -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, - decode_time_tzo(__TopXMLNS, __IgnoreEls, _el)); - <<"urn:xmpp:time">> -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, - decode_time_tzo(<<"urn:xmpp:time">>, __IgnoreEls, - _el)); - _ -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, Tzo) - end; -decode_time_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"utc">>, _attrs, _} = _el | _els], Utc, - Tzo) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:time">> -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, - decode_time_utc(__TopXMLNS, __IgnoreEls, _el), Tzo); - <<"urn:xmpp:time">> -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, - decode_time_utc(<<"urn:xmpp:time">>, __IgnoreEls, - _el), - Tzo); - _ -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, Tzo) - end; -decode_time_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Utc, Tzo) -> - decode_time_els(__TopXMLNS, __IgnoreEls, _els, Utc, - Tzo). - -encode_time({time, Tzo, Utc}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, - [], __TopXMLNS), - _els = lists:reverse('encode_time_$utc'(Utc, - __NewTopXMLNS, - 'encode_time_$tzo'(Tzo, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"time">>, _attrs, _els}. - -'encode_time_$utc'(undefined, __TopXMLNS, _acc) -> _acc; -'encode_time_$utc'(Utc, __TopXMLNS, _acc) -> - [encode_time_utc(Utc, __TopXMLNS) | _acc]. - -'encode_time_$tzo'(undefined, __TopXMLNS, _acc) -> _acc; -'encode_time_$tzo'(Tzo, __TopXMLNS, _acc) -> - [encode_time_tzo(Tzo, __TopXMLNS) | _acc]. - -decode_time_tzo(__TopXMLNS, __IgnoreEls, - {xmlel, <<"tzo">>, _attrs, _els}) -> - Cdata = decode_time_tzo_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_time_tzo_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_time_tzo_cdata(__TopXMLNS, Cdata); -decode_time_tzo_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_time_tzo_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_time_tzo_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_time_tzo_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_time_tzo(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, - [], __TopXMLNS), - _els = encode_time_tzo_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"tzo">>, _attrs, _els}. - -decode_time_tzo_cdata(__TopXMLNS, <<>>) -> undefined; -decode_time_tzo_cdata(__TopXMLNS, _val) -> - case catch dec_tzo(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"tzo">>, __TopXMLNS}}); - _res -> _res - end. - -encode_time_tzo_cdata(undefined, _acc) -> _acc; -encode_time_tzo_cdata(_val, _acc) -> - [{xmlcdata, enc_tzo(_val)} | _acc]. - -decode_time_utc(__TopXMLNS, __IgnoreEls, - {xmlel, <<"utc">>, _attrs, _els}) -> - Cdata = decode_time_utc_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_time_utc_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_time_utc_cdata(__TopXMLNS, Cdata); -decode_time_utc_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_time_utc_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_time_utc_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_time_utc_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_time_utc(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:time">>, - [], __TopXMLNS), - _els = encode_time_utc_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"utc">>, _attrs, _els}. - -decode_time_utc_cdata(__TopXMLNS, <<>>) -> undefined; -decode_time_utc_cdata(__TopXMLNS, _val) -> - case catch dec_utc(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"utc">>, __TopXMLNS}}); - _res -> _res - end. - -encode_time_utc_cdata(undefined, _acc) -> _acc; -encode_time_utc_cdata(_val, _acc) -> - [{xmlcdata, enc_utc(_val)} | _acc]. - -decode_ping(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ping">>, _attrs, _els}) -> - {ping}. - -encode_ping({ping}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"urn:xmpp:ping">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ping">>, _attrs, _els}. - -decode_session(__TopXMLNS, __IgnoreEls, - {xmlel, <<"session">>, _attrs, _els}) -> - Optional = decode_session_els(__TopXMLNS, __IgnoreEls, - _els, false), - {xmpp_session, Optional}. - -decode_session_els(__TopXMLNS, __IgnoreEls, [], - Optional) -> - Optional; -decode_session_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"optional">>, _attrs, _} = _el | _els], - Optional) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-session">> -> - decode_session_els(__TopXMLNS, __IgnoreEls, _els, - decode_session_optional(__TopXMLNS, __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-session">> -> - decode_session_els(__TopXMLNS, __IgnoreEls, _els, - decode_session_optional(<<"urn:ietf:params:xml:ns:xmpp-session">>, - __IgnoreEls, _el)); - _ -> - decode_session_els(__TopXMLNS, __IgnoreEls, _els, - Optional) - end; -decode_session_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Optional) -> - decode_session_els(__TopXMLNS, __IgnoreEls, _els, - Optional). - -encode_session({xmpp_session, Optional}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-session">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_session_$optional'(Optional, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"session">>, _attrs, _els}. - -'encode_session_$optional'(false, __TopXMLNS, _acc) -> - _acc; -'encode_session_$optional'(Optional, __TopXMLNS, - _acc) -> - [encode_session_optional(Optional, __TopXMLNS) | _acc]. - -decode_session_optional(__TopXMLNS, __IgnoreEls, - {xmlel, <<"optional">>, _attrs, _els}) -> - true. - -encode_session_optional(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-session">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"optional">>, _attrs, _els}. - -decode_register(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Zip, Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els} = - decode_register_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, - undefined, false, undefined, undefined, undefined, - undefined, undefined, false, undefined, undefined, - undefined, undefined, undefined, []), - {register, Registered, Remove, Instructions, Username, - Nick, Password, Name, First, Last, Email, Address, City, - State, Zip, Phone, Url, Date, Misc, Text, Key, Xdata, - __Els}. - -decode_register_els(__TopXMLNS, __IgnoreEls, [], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - {Zip, Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - lists:reverse(__Els)}; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Zip, Xdata, - Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - decode_xdata(<<"jabber:x:data">>, __IgnoreEls, - _el), - Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"registered">>, _attrs, _} = _el | _els], - Zip, Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, - decode_register_registered(__TopXMLNS, - __IgnoreEls, _el), - Date, Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, - decode_register_registered(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Date, Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remove">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, - decode_register_remove(__TopXMLNS, __IgnoreEls, - _el), - Key, City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, - decode_register_remove(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Key, City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"instructions">>, _attrs, _} = _el | _els], - Zip, Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, - decode_register_instructions(__TopXMLNS, - __IgnoreEls, _el), - Text, Last, First, Password, Registered, Date, - Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, - decode_register_instructions(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Text, Last, First, Password, Registered, Date, - Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"username">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, - decode_register_username(__TopXMLNS, __IgnoreEls, - _el), - Remove, Key, City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, - decode_register_username(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Remove, Key, City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"nick">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, - decode_register_nick(__TopXMLNS, __IgnoreEls, - _el), - Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, - decode_register_nick(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, - decode_register_password(__TopXMLNS, __IgnoreEls, - _el), - Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, - decode_register_password(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"name">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - decode_register_name(__TopXMLNS, __IgnoreEls, - _el), - Username, Remove, Key, City, Nick, Url, Email, - __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - decode_register_name(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Username, Remove, Key, City, Nick, Url, Email, - __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"first">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - decode_register_first(__TopXMLNS, __IgnoreEls, - _el), - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - decode_register_first(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"last">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, - decode_register_last(__TopXMLNS, __IgnoreEls, - _el), - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, - decode_register_last(<<"jabber:iq:register">>, - __IgnoreEls, _el), - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"email">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - decode_register_email(__TopXMLNS, __IgnoreEls, - _el), - __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - decode_register_email(<<"jabber:iq:register">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"address">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, - decode_register_address(__TopXMLNS, __IgnoreEls, - _el), - Instructions, Text, Last, First, Password, - Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, - decode_register_address(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Instructions, Text, Last, First, Password, - Registered, Date, Phone, State, Name, Username, - Remove, Key, City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"city">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, - decode_register_city(__TopXMLNS, __IgnoreEls, - _el), - Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, - decode_register_city(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"state">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, - decode_register_state(__TopXMLNS, __IgnoreEls, - _el), - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, - decode_register_state(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"zip">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, - decode_register_zip(__TopXMLNS, __IgnoreEls, _el), - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, - decode_register_zip(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"phone">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, - decode_register_phone(__TopXMLNS, __IgnoreEls, - _el), - State, Name, Username, Remove, Key, City, Nick, - Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, - decode_register_phone(<<"jabber:iq:register">>, - __IgnoreEls, _el), - State, Name, Username, Remove, Key, City, Nick, - Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"url">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, - decode_register_url(__TopXMLNS, __IgnoreEls, _el), - Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, - decode_register_url(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"date">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, - decode_register_date(__TopXMLNS, __IgnoreEls, - _el), - Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, - decode_register_date(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Phone, State, Name, Username, Remove, Key, City, - Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"misc">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, - decode_register_misc(__TopXMLNS, __IgnoreEls, - _el), - Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, - decode_register_misc(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, - __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"text">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, - decode_register_text(__TopXMLNS, __IgnoreEls, - _el), - Last, First, Password, Registered, Date, Phone, - State, Name, Username, Remove, Key, City, Nick, - Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, - decode_register_text(<<"jabber:iq:register">>, - __IgnoreEls, _el), - Last, First, Password, Registered, Date, Phone, - State, Name, Username, Remove, Key, City, Nick, - Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"key">>, _attrs, _} = _el | _els], Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, - decode_register_key(__TopXMLNS, __IgnoreEls, _el), - City, Nick, Url, Email, __Els); - <<"jabber:iq:register">> -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, - decode_register_key(<<"jabber:iq:register">>, - __IgnoreEls, _el), - City, Nick, Url, Email, __Els); - _ -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, __Els) - end; -decode_register_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Zip, Xdata, Misc, - Address, Instructions, Text, Last, First, Password, - Registered, Date, Phone, State, Name, Username, Remove, - Key, City, Nick, Url, Email, __Els) -> - if __IgnoreEls -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, - Name, Username, Remove, Key, City, Nick, Url, - Email, [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, - Last, First, Password, Registered, Date, - Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, - Last, First, Password, Registered, Date, - Phone, State, Name, Username, Remove, Key, - City, Nick, Url, Email, __Els) - end - end; -decode_register_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Zip, Xdata, Misc, Address, Instructions, Text, Last, - First, Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els) -> - decode_register_els(__TopXMLNS, __IgnoreEls, _els, Zip, - Xdata, Misc, Address, Instructions, Text, Last, First, - Password, Registered, Date, Phone, State, Name, - Username, Remove, Key, City, Nick, Url, Email, __Els). - -encode_register({register, Registered, Remove, - Instructions, Username, Nick, Password, Name, First, - Last, Email, Address, City, State, Zip, Phone, Url, - Date, Misc, Text, Key, Xdata, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ - lists:reverse('encode_register_$zip'(Zip, __NewTopXMLNS, - 'encode_register_$xdata'(Xdata, - __NewTopXMLNS, - 'encode_register_$misc'(Misc, - __NewTopXMLNS, - 'encode_register_$address'(Address, - __NewTopXMLNS, - 'encode_register_$instructions'(Instructions, - __NewTopXMLNS, - 'encode_register_$text'(Text, - __NewTopXMLNS, - 'encode_register_$last'(Last, - __NewTopXMLNS, - 'encode_register_$first'(First, - __NewTopXMLNS, - 'encode_register_$password'(Password, - __NewTopXMLNS, - 'encode_register_$registered'(Registered, - __NewTopXMLNS, - 'encode_register_$date'(Date, - __NewTopXMLNS, - 'encode_register_$phone'(Phone, - __NewTopXMLNS, - 'encode_register_$state'(State, - __NewTopXMLNS, - 'encode_register_$name'(Name, - __NewTopXMLNS, - 'encode_register_$username'(Username, - __NewTopXMLNS, - 'encode_register_$remove'(Remove, - __NewTopXMLNS, - 'encode_register_$key'(Key, - __NewTopXMLNS, - 'encode_register_$city'(City, - __NewTopXMLNS, - 'encode_register_$nick'(Nick, - __NewTopXMLNS, - 'encode_register_$url'(Url, - __NewTopXMLNS, - 'encode_register_$email'(Email, - __NewTopXMLNS, - [])))))))))))))))))))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_register_$zip'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$zip'(Zip, __TopXMLNS, _acc) -> - [encode_register_zip(Zip, __TopXMLNS) | _acc]. - -'encode_register_$xdata'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$xdata'(Xdata, __TopXMLNS, _acc) -> - [encode_xdata(Xdata, __TopXMLNS) | _acc]. - -'encode_register_$misc'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$misc'(Misc, __TopXMLNS, _acc) -> - [encode_register_misc(Misc, __TopXMLNS) | _acc]. - -'encode_register_$address'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_register_$address'(Address, __TopXMLNS, _acc) -> - [encode_register_address(Address, __TopXMLNS) | _acc]. - -'encode_register_$instructions'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_register_$instructions'(Instructions, - __TopXMLNS, _acc) -> - [encode_register_instructions(Instructions, __TopXMLNS) - | _acc]. - -'encode_register_$text'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$text'(Text, __TopXMLNS, _acc) -> - [encode_register_text(Text, __TopXMLNS) | _acc]. - -'encode_register_$last'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$last'(Last, __TopXMLNS, _acc) -> - [encode_register_last(Last, __TopXMLNS) | _acc]. - -'encode_register_$first'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$first'(First, __TopXMLNS, _acc) -> - [encode_register_first(First, __TopXMLNS) | _acc]. - -'encode_register_$password'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_register_$password'(Password, __TopXMLNS, - _acc) -> - [encode_register_password(Password, __TopXMLNS) | _acc]. - -'encode_register_$registered'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_register_$registered'(Registered, __TopXMLNS, - _acc) -> - [encode_register_registered(Registered, __TopXMLNS) - | _acc]. - -'encode_register_$date'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$date'(Date, __TopXMLNS, _acc) -> - [encode_register_date(Date, __TopXMLNS) | _acc]. - -'encode_register_$phone'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$phone'(Phone, __TopXMLNS, _acc) -> - [encode_register_phone(Phone, __TopXMLNS) | _acc]. - -'encode_register_$state'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$state'(State, __TopXMLNS, _acc) -> - [encode_register_state(State, __TopXMLNS) | _acc]. - -'encode_register_$name'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$name'(Name, __TopXMLNS, _acc) -> - [encode_register_name(Name, __TopXMLNS) | _acc]. - -'encode_register_$username'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_register_$username'(Username, __TopXMLNS, - _acc) -> - [encode_register_username(Username, __TopXMLNS) | _acc]. - -'encode_register_$remove'(false, __TopXMLNS, _acc) -> - _acc; -'encode_register_$remove'(Remove, __TopXMLNS, _acc) -> - [encode_register_remove(Remove, __TopXMLNS) | _acc]. - -'encode_register_$key'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$key'(Key, __TopXMLNS, _acc) -> - [encode_register_key(Key, __TopXMLNS) | _acc]. - -'encode_register_$city'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$city'(City, __TopXMLNS, _acc) -> - [encode_register_city(City, __TopXMLNS) | _acc]. - -'encode_register_$nick'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$nick'(Nick, __TopXMLNS, _acc) -> - [encode_register_nick(Nick, __TopXMLNS) | _acc]. - -'encode_register_$url'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$url'(Url, __TopXMLNS, _acc) -> - [encode_register_url(Url, __TopXMLNS) | _acc]. - -'encode_register_$email'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_register_$email'(Email, __TopXMLNS, _acc) -> - [encode_register_email(Email, __TopXMLNS) | _acc]. - -decode_register_key(__TopXMLNS, __IgnoreEls, - {xmlel, <<"key">>, _attrs, _els}) -> - Cdata = decode_register_key_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_register_key_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_key_cdata(__TopXMLNS, Cdata); -decode_register_key_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_key_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_key_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_key_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_key(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_key_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"key">>, _attrs, _els}. - -decode_register_key_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_key_cdata(__TopXMLNS, _val) -> _val. - -encode_register_key_cdata(<<>>, _acc) -> _acc; -encode_register_key_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_text(__TopXMLNS, __IgnoreEls, - {xmlel, <<"text">>, _attrs, _els}) -> - Cdata = decode_register_text_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_text_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_text_cdata(__TopXMLNS, Cdata); -decode_register_text_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_text_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_text_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_text_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_text(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_text_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"text">>, _attrs, _els}. - -decode_register_text_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_text_cdata(__TopXMLNS, _val) -> _val. - -encode_register_text_cdata(<<>>, _acc) -> _acc; -encode_register_text_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_misc(__TopXMLNS, __IgnoreEls, - {xmlel, <<"misc">>, _attrs, _els}) -> - Cdata = decode_register_misc_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_misc_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_misc_cdata(__TopXMLNS, Cdata); -decode_register_misc_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_misc_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_misc_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_misc_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_misc(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_misc_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"misc">>, _attrs, _els}. - -decode_register_misc_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_misc_cdata(__TopXMLNS, _val) -> _val. - -encode_register_misc_cdata(<<>>, _acc) -> _acc; -encode_register_misc_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_date(__TopXMLNS, __IgnoreEls, - {xmlel, <<"date">>, _attrs, _els}) -> - Cdata = decode_register_date_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_date_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_date_cdata(__TopXMLNS, Cdata); -decode_register_date_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_date_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_date_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_date_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_date(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_date_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"date">>, _attrs, _els}. - -decode_register_date_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_date_cdata(__TopXMLNS, _val) -> _val. - -encode_register_date_cdata(<<>>, _acc) -> _acc; -encode_register_date_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_url(__TopXMLNS, __IgnoreEls, - {xmlel, <<"url">>, _attrs, _els}) -> - Cdata = decode_register_url_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_register_url_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_url_cdata(__TopXMLNS, Cdata); -decode_register_url_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_url_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_url_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_url_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_url(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_url_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"url">>, _attrs, _els}. - -decode_register_url_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_url_cdata(__TopXMLNS, _val) -> _val. - -encode_register_url_cdata(<<>>, _acc) -> _acc; -encode_register_url_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_phone(__TopXMLNS, __IgnoreEls, - {xmlel, <<"phone">>, _attrs, _els}) -> - Cdata = decode_register_phone_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_phone_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_phone_cdata(__TopXMLNS, Cdata); -decode_register_phone_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_phone_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_phone_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_phone_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_phone(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_phone_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"phone">>, _attrs, _els}. - -decode_register_phone_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_phone_cdata(__TopXMLNS, _val) -> _val. - -encode_register_phone_cdata(<<>>, _acc) -> _acc; -encode_register_phone_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_zip(__TopXMLNS, __IgnoreEls, - {xmlel, <<"zip">>, _attrs, _els}) -> - Cdata = decode_register_zip_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_register_zip_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_zip_cdata(__TopXMLNS, Cdata); -decode_register_zip_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_zip_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_zip_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_zip_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_zip(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_zip_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"zip">>, _attrs, _els}. - -decode_register_zip_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_zip_cdata(__TopXMLNS, _val) -> _val. - -encode_register_zip_cdata(<<>>, _acc) -> _acc; -encode_register_zip_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_state(__TopXMLNS, __IgnoreEls, - {xmlel, <<"state">>, _attrs, _els}) -> - Cdata = decode_register_state_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_state_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_state_cdata(__TopXMLNS, Cdata); -decode_register_state_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_state_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_state_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_state_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_state(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_state_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"state">>, _attrs, _els}. - -decode_register_state_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_state_cdata(__TopXMLNS, _val) -> _val. - -encode_register_state_cdata(<<>>, _acc) -> _acc; -encode_register_state_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_city(__TopXMLNS, __IgnoreEls, - {xmlel, <<"city">>, _attrs, _els}) -> - Cdata = decode_register_city_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_city_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_city_cdata(__TopXMLNS, Cdata); -decode_register_city_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_city_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_city_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_city_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_city(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_city_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"city">>, _attrs, _els}. - -decode_register_city_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_city_cdata(__TopXMLNS, _val) -> _val. - -encode_register_city_cdata(<<>>, _acc) -> _acc; -encode_register_city_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_address(__TopXMLNS, __IgnoreEls, - {xmlel, <<"address">>, _attrs, _els}) -> - Cdata = decode_register_address_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_address_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_address_cdata(__TopXMLNS, Cdata); -decode_register_address_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_address_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_register_address_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_address_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_register_address(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_address_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"address">>, _attrs, _els}. - -decode_register_address_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_address_cdata(__TopXMLNS, _val) -> _val. - -encode_register_address_cdata(<<>>, _acc) -> _acc; -encode_register_address_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_email(__TopXMLNS, __IgnoreEls, - {xmlel, <<"email">>, _attrs, _els}) -> - Cdata = decode_register_email_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_email_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_email_cdata(__TopXMLNS, Cdata); -decode_register_email_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_email_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_email_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_email_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_email(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_email_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"email">>, _attrs, _els}. - -decode_register_email_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_email_cdata(__TopXMLNS, _val) -> _val. - -encode_register_email_cdata(<<>>, _acc) -> _acc; -encode_register_email_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_last(__TopXMLNS, __IgnoreEls, - {xmlel, <<"last">>, _attrs, _els}) -> - Cdata = decode_register_last_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_last_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_last_cdata(__TopXMLNS, Cdata); -decode_register_last_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_last_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_last_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_last_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_last(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_last_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"last">>, _attrs, _els}. - -decode_register_last_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_last_cdata(__TopXMLNS, _val) -> _val. - -encode_register_last_cdata(<<>>, _acc) -> _acc; -encode_register_last_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_first(__TopXMLNS, __IgnoreEls, - {xmlel, <<"first">>, _attrs, _els}) -> - Cdata = decode_register_first_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_first_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_first_cdata(__TopXMLNS, Cdata); -decode_register_first_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_first_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_first_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_first_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_first(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_first_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"first">>, _attrs, _els}. - -decode_register_first_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_first_cdata(__TopXMLNS, _val) -> _val. - -encode_register_first_cdata(<<>>, _acc) -> _acc; -encode_register_first_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_name(__TopXMLNS, __IgnoreEls, - {xmlel, <<"name">>, _attrs, _els}) -> - Cdata = decode_register_name_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_name_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_name_cdata(__TopXMLNS, Cdata); -decode_register_name_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_name_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_name_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_name_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_name(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_name_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"name">>, _attrs, _els}. - -decode_register_name_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_name_cdata(__TopXMLNS, _val) -> _val. - -encode_register_name_cdata(<<>>, _acc) -> _acc; -encode_register_name_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_password(__TopXMLNS, __IgnoreEls, - {xmlel, <<"password">>, _attrs, _els}) -> - Cdata = decode_register_password_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_password_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_register_password_cdata(__TopXMLNS, Cdata); -decode_register_password_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_password_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_register_password_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_password_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_register_password(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_password_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"password">>, _attrs, _els}. - -decode_register_password_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_register_password_cdata(__TopXMLNS, _val) -> - _val. - -encode_register_password_cdata(<<>>, _acc) -> _acc; -encode_register_password_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_nick(__TopXMLNS, __IgnoreEls, - {xmlel, <<"nick">>, _attrs, _els}) -> - Cdata = decode_register_nick_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_nick_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_register_nick_cdata(__TopXMLNS, Cdata); -decode_register_nick_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_nick_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_register_nick_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_nick_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_register_nick(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_nick_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"nick">>, _attrs, _els}. - -decode_register_nick_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_register_nick_cdata(__TopXMLNS, _val) -> _val. - -encode_register_nick_cdata(<<>>, _acc) -> _acc; -encode_register_nick_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_username(__TopXMLNS, __IgnoreEls, - {xmlel, <<"username">>, _attrs, _els}) -> - Cdata = decode_register_username_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_username_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_register_username_cdata(__TopXMLNS, Cdata); -decode_register_username_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_register_username_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_register_username_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_register_username_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_register_username(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_username_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"username">>, _attrs, _els}. - -decode_register_username_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_register_username_cdata(__TopXMLNS, _val) -> - _val. - -encode_register_username_cdata(<<>>, _acc) -> _acc; -encode_register_username_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_instructions(__TopXMLNS, __IgnoreEls, - {xmlel, <<"instructions">>, _attrs, _els}) -> - Cdata = decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, [], Cdata) -> - decode_register_instructions_cdata(__TopXMLNS, Cdata); -decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, [{xmlcdata, _data} | _els], - Cdata) -> - decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, _els, - <>); -decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, [_ | _els], Cdata) -> - decode_register_instructions_els(__TopXMLNS, - __IgnoreEls, _els, Cdata). - -encode_register_instructions(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = encode_register_instructions_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"instructions">>, _attrs, _els}. - -decode_register_instructions_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_register_instructions_cdata(__TopXMLNS, _val) -> - _val. - -encode_register_instructions_cdata(<<>>, _acc) -> _acc; -encode_register_instructions_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_register_remove(__TopXMLNS, __IgnoreEls, - {xmlel, <<"remove">>, _attrs, _els}) -> - true. - -encode_register_remove(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"remove">>, _attrs, _els}. - -decode_register_registered(__TopXMLNS, __IgnoreEls, - {xmlel, <<"registered">>, _attrs, _els}) -> - true. - -encode_register_registered(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:register">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"registered">>, _attrs, _els}. - -decode_feature_register(__TopXMLNS, __IgnoreEls, - {xmlel, <<"register">>, _attrs, _els}) -> - {feature_register}. - -encode_feature_register({feature_register}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/features/iq-register">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"register">>, _attrs, _els}. - -decode_caps(__TopXMLNS, __IgnoreEls, - {xmlel, <<"c">>, _attrs, _els}) -> - {Hash, Node, Exts, Version} = - decode_caps_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {caps, Node, Version, Hash, Exts}. - -decode_caps_attrs(__TopXMLNS, - [{<<"hash">>, _val} | _attrs], _Hash, Node, Exts, - Version) -> - decode_caps_attrs(__TopXMLNS, _attrs, _val, Node, Exts, - Version); -decode_caps_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Hash, _Node, Exts, - Version) -> - decode_caps_attrs(__TopXMLNS, _attrs, Hash, _val, Exts, - Version); -decode_caps_attrs(__TopXMLNS, - [{<<"ext">>, _val} | _attrs], Hash, Node, _Exts, - Version) -> - decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, _val, - Version); -decode_caps_attrs(__TopXMLNS, - [{<<"ver">>, _val} | _attrs], Hash, Node, Exts, - _Version) -> - decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, Exts, - _val); -decode_caps_attrs(__TopXMLNS, [_ | _attrs], Hash, Node, - Exts, Version) -> - decode_caps_attrs(__TopXMLNS, _attrs, Hash, Node, Exts, - Version); -decode_caps_attrs(__TopXMLNS, [], Hash, Node, Exts, - Version) -> - {decode_caps_attr_hash(__TopXMLNS, Hash), - decode_caps_attr_node(__TopXMLNS, Node), - decode_caps_attr_ext(__TopXMLNS, Exts), - decode_caps_attr_ver(__TopXMLNS, Version)}. - -encode_caps({caps, Node, Version, Hash, Exts}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/caps">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_caps_attr_ver(Version, - encode_caps_attr_ext(Exts, - encode_caps_attr_node(Node, - encode_caps_attr_hash(Hash, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"c">>, _attrs, _els}. - -decode_caps_attr_hash(__TopXMLNS, undefined) -> <<>>; -decode_caps_attr_hash(__TopXMLNS, _val) -> _val. - -encode_caps_attr_hash(<<>>, _acc) -> _acc; -encode_caps_attr_hash(_val, _acc) -> - [{<<"hash">>, _val} | _acc]. - -decode_caps_attr_node(__TopXMLNS, undefined) -> <<>>; -decode_caps_attr_node(__TopXMLNS, _val) -> _val. - -encode_caps_attr_node(<<>>, _acc) -> _acc; -encode_caps_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_caps_attr_ext(__TopXMLNS, undefined) -> []; -decode_caps_attr_ext(__TopXMLNS, _val) -> - case catch re:split(_val, "\\h+") of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"ext">>, <<"c">>, __TopXMLNS}}); - _res -> _res - end. - -encode_caps_attr_ext([], _acc) -> _acc; -encode_caps_attr_ext(_val, _acc) -> - [{<<"ext">>, join(_val, 32)} | _acc]. - -decode_caps_attr_ver(__TopXMLNS, undefined) -> <<>>; -decode_caps_attr_ver(__TopXMLNS, _val) -> _val. - -encode_caps_attr_ver(<<>>, _acc) -> _acc; -encode_caps_attr_ver(_val, _acc) -> - [{<<"ver">>, _val} | _acc]. - -decode_p1_ack(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ack">>, _attrs, _els}) -> - {p1_ack}. - -encode_p1_ack({p1_ack}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"p1:ack">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ack">>, _attrs, _els}. - -decode_p1_rebind(__TopXMLNS, __IgnoreEls, - {xmlel, <<"rebind">>, _attrs, _els}) -> - {p1_rebind}. - -encode_p1_rebind({p1_rebind}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"p1:rebind">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"rebind">>, _attrs, _els}. - -decode_p1_push(__TopXMLNS, __IgnoreEls, - {xmlel, <<"push">>, _attrs, _els}) -> - {p1_push}. - -encode_p1_push({p1_push}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"p1:push">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"push">>, _attrs, _els}. - -decode_stream_features(__TopXMLNS, __IgnoreEls, - {xmlel, <<"stream:features">>, _attrs, _els}) -> - __Els = decode_stream_features_els(__TopXMLNS, - __IgnoreEls, _els, []), - {stream_features, __Els}. - -decode_stream_features_els(__TopXMLNS, __IgnoreEls, [], - __Els) -> - lists:reverse(__Els); -decode_stream_features_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], __Els) -> - if __IgnoreEls -> - decode_stream_features_els(__TopXMLNS, __IgnoreEls, - _els, [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_stream_features_els(__TopXMLNS, __IgnoreEls, - _els, - [decode(_el, __TopXMLNS, []) - | __Els]); - false -> - decode_stream_features_els(__TopXMLNS, __IgnoreEls, - _els, __Els) - end - end; -decode_stream_features_els(__TopXMLNS, __IgnoreEls, - [_ | _els], __Els) -> - decode_stream_features_els(__TopXMLNS, __IgnoreEls, - _els, __Els). - -encode_stream_features({stream_features, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"stream:features">>, _attrs, _els}. - -decode_compression(__TopXMLNS, __IgnoreEls, - {xmlel, <<"compression">>, _attrs, _els}) -> - Methods = decode_compression_els(__TopXMLNS, - __IgnoreEls, _els, []), - {compression, Methods}. - -decode_compression_els(__TopXMLNS, __IgnoreEls, [], - Methods) -> - lists:reverse(Methods); -decode_compression_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"method">>, _attrs, _} = _el | _els], - Methods) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/features/compress">> -> - decode_compression_els(__TopXMLNS, __IgnoreEls, _els, - [decode_compression_method(__TopXMLNS, - __IgnoreEls, _el) - | Methods]); - <<"http://jabber.org/features/compress">> -> - decode_compression_els(__TopXMLNS, __IgnoreEls, _els, - [decode_compression_method(<<"http://jabber.org/features/compress">>, - __IgnoreEls, _el) - | Methods]); - _ -> - decode_compression_els(__TopXMLNS, __IgnoreEls, _els, - Methods) - end; -decode_compression_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Methods) -> - decode_compression_els(__TopXMLNS, __IgnoreEls, _els, - Methods). - -encode_compression({compression, Methods}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/features/compress">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_compression_$methods'(Methods, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"compression">>, _attrs, _els}. - -'encode_compression_$methods'([], __TopXMLNS, _acc) -> - _acc; -'encode_compression_$methods'([Methods | _els], - __TopXMLNS, _acc) -> - 'encode_compression_$methods'(_els, __TopXMLNS, - [encode_compression_method(Methods, - __TopXMLNS) - | _acc]). - -decode_compression_method(__TopXMLNS, __IgnoreEls, - {xmlel, <<"method">>, _attrs, _els}) -> - Cdata = decode_compression_method_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_compression_method_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_compression_method_cdata(__TopXMLNS, Cdata); -decode_compression_method_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_compression_method_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_compression_method_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_compression_method_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_compression_method(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/features/compress">>, - [], __TopXMLNS), - _els = encode_compression_method_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"method">>, _attrs, _els}. - -decode_compression_method_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_compression_method_cdata(__TopXMLNS, _val) -> - _val. - -encode_compression_method_cdata(<<>>, _acc) -> _acc; -encode_compression_method_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_compressed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"compressed">>, _attrs, _els}) -> - {compressed}. - -encode_compressed({compressed}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"compressed">>, _attrs, _els}. - -decode_compress(__TopXMLNS, __IgnoreEls, - {xmlel, <<"compress">>, _attrs, _els}) -> - Methods = decode_compress_els(__TopXMLNS, __IgnoreEls, - _els, []), - {compress, Methods}. - -decode_compress_els(__TopXMLNS, __IgnoreEls, [], - Methods) -> - lists:reverse(Methods); -decode_compress_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"method">>, _attrs, _} = _el | _els], - Methods) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/compress">> -> - decode_compress_els(__TopXMLNS, __IgnoreEls, _els, - [decode_compress_method(__TopXMLNS, __IgnoreEls, - _el) - | Methods]); - <<"http://jabber.org/protocol/compress">> -> - decode_compress_els(__TopXMLNS, __IgnoreEls, _els, - [decode_compress_method(<<"http://jabber.org/protocol/compress">>, - __IgnoreEls, _el) - | Methods]); - _ -> - decode_compress_els(__TopXMLNS, __IgnoreEls, _els, - Methods) - end; -decode_compress_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Methods) -> - decode_compress_els(__TopXMLNS, __IgnoreEls, _els, - Methods). - -encode_compress({compress, Methods}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = lists:reverse('encode_compress_$methods'(Methods, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"compress">>, _attrs, _els}. - -'encode_compress_$methods'([], __TopXMLNS, _acc) -> - _acc; -'encode_compress_$methods'([Methods | _els], __TopXMLNS, - _acc) -> - 'encode_compress_$methods'(_els, __TopXMLNS, - [encode_compress_method(Methods, __TopXMLNS) - | _acc]). - -decode_compress_method(__TopXMLNS, __IgnoreEls, - {xmlel, <<"method">>, _attrs, _els}) -> - Cdata = decode_compress_method_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_compress_method_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_compress_method_cdata(__TopXMLNS, Cdata); -decode_compress_method_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_compress_method_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_compress_method_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_compress_method_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_compress_method(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = encode_compress_method_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"method">>, _attrs, _els}. - -decode_compress_method_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_compress_method_cdata(__TopXMLNS, _val) -> _val. - -encode_compress_method_cdata(<<>>, _acc) -> _acc; -encode_compress_method_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_compress_failure(__TopXMLNS, __IgnoreEls, - {xmlel, <<"failure">>, _attrs, _els}) -> - Reason = decode_compress_failure_els(__TopXMLNS, - __IgnoreEls, _els, undefined), - {compress_failure, Reason}. - -decode_compress_failure_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - Reason; -decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"setup-failed">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_setup_failed(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_setup_failed(<<"http://jabber.org/protocol/compress">>, - __IgnoreEls, - _el)); - _ -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, Reason) - end; -decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"processing-failed">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_processing_failed(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_processing_failed(<<"http://jabber.org/protocol/compress">>, - __IgnoreEls, - _el)); - _ -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, Reason) - end; -decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unsupported-method">>, _attrs, _} = _el - | _els], - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_unsupported_method(__TopXMLNS, - __IgnoreEls, - _el)); - <<"http://jabber.org/protocol/compress">> -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, - decode_compress_failure_unsupported_method(<<"http://jabber.org/protocol/compress">>, - __IgnoreEls, - _el)); - _ -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, Reason) - end; -decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> - decode_compress_failure_els(__TopXMLNS, __IgnoreEls, - _els, Reason). - -encode_compress_failure({compress_failure, Reason}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_compress_failure_$reason'(Reason, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"failure">>, _attrs, _els}. - -'encode_compress_failure_$reason'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_compress_failure_$reason'('setup-failed' = - Reason, - __TopXMLNS, _acc) -> - [encode_compress_failure_setup_failed(Reason, - __TopXMLNS) - | _acc]; -'encode_compress_failure_$reason'('processing-failed' = - Reason, - __TopXMLNS, _acc) -> - [encode_compress_failure_processing_failed(Reason, - __TopXMLNS) - | _acc]; -'encode_compress_failure_$reason'('unsupported-method' = - Reason, - __TopXMLNS, _acc) -> - [encode_compress_failure_unsupported_method(Reason, - __TopXMLNS) - | _acc]. - -decode_compress_failure_unsupported_method(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"unsupported-method">>, - _attrs, _els}) -> - 'unsupported-method'. - -encode_compress_failure_unsupported_method('unsupported-method', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unsupported-method">>, _attrs, _els}. - -decode_compress_failure_processing_failed(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"processing-failed">>, - _attrs, _els}) -> - 'processing-failed'. - -encode_compress_failure_processing_failed('processing-failed', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"processing-failed">>, _attrs, _els}. - -decode_compress_failure_setup_failed(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"setup-failed">>, _attrs, - _els}) -> - 'setup-failed'. - -encode_compress_failure_setup_failed('setup-failed', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/compress">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"setup-failed">>, _attrs, _els}. - -decode_starttls_failure(__TopXMLNS, __IgnoreEls, - {xmlel, <<"failure">>, _attrs, _els}) -> - {starttls_failure}. - -encode_starttls_failure({starttls_failure}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"failure">>, _attrs, _els}. - -decode_starttls_proceed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"proceed">>, _attrs, _els}) -> - {starttls_proceed}. - -encode_starttls_proceed({starttls_proceed}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"proceed">>, _attrs, _els}. - -decode_starttls(__TopXMLNS, __IgnoreEls, - {xmlel, <<"starttls">>, _attrs, _els}) -> - Required = decode_starttls_els(__TopXMLNS, __IgnoreEls, - _els, false), - {starttls, Required}. - -decode_starttls_els(__TopXMLNS, __IgnoreEls, [], - Required) -> - Required; -decode_starttls_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"required">>, _attrs, _} = _el | _els], - Required) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-tls">> -> - decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, - decode_starttls_required(__TopXMLNS, __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-tls">> -> - decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, - decode_starttls_required(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - __IgnoreEls, _el)); - _ -> - decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, - Required) - end; -decode_starttls_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Required) -> - decode_starttls_els(__TopXMLNS, __IgnoreEls, _els, - Required). - -encode_starttls({starttls, Required}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_starttls_$required'(Required, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"starttls">>, _attrs, _els}. - -'encode_starttls_$required'(false, __TopXMLNS, _acc) -> - _acc; -'encode_starttls_$required'(Required, __TopXMLNS, - _acc) -> - [encode_starttls_required(Required, __TopXMLNS) | _acc]. - -decode_starttls_required(__TopXMLNS, __IgnoreEls, - {xmlel, <<"required">>, _attrs, _els}) -> - true. - -encode_starttls_required(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-tls">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"required">>, _attrs, _els}. - -decode_sasl_mechanisms(__TopXMLNS, __IgnoreEls, - {xmlel, <<"mechanisms">>, _attrs, _els}) -> - List = decode_sasl_mechanisms_els(__TopXMLNS, - __IgnoreEls, _els, []), - {sasl_mechanisms, List}. - -decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, [], - List) -> - lists:reverse(List); -decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"mechanism">>, _attrs, _} = _el | _els], - List) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_sasl_mechanism(__TopXMLNS, - __IgnoreEls, _el) - | List]); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_sasl_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, _el) - | List]); - _ -> - decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - _els, List) - end; -decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - [_ | _els], List) -> - decode_sasl_mechanisms_els(__TopXMLNS, __IgnoreEls, - _els, List). - -encode_sasl_mechanisms({sasl_mechanisms, List}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_sasl_mechanisms_$list'(List, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"mechanisms">>, _attrs, _els}. - -'encode_sasl_mechanisms_$list'([], __TopXMLNS, _acc) -> - _acc; -'encode_sasl_mechanisms_$list'([List | _els], - __TopXMLNS, _acc) -> - 'encode_sasl_mechanisms_$list'(_els, __TopXMLNS, - [encode_sasl_mechanism(List, __TopXMLNS) - | _acc]). - -decode_sasl_mechanism(__TopXMLNS, __IgnoreEls, - {xmlel, <<"mechanism">>, _attrs, _els}) -> - Cdata = decode_sasl_mechanism_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_sasl_mechanism_cdata(__TopXMLNS, Cdata); -decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_sasl_mechanism_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_sasl_mechanism(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_mechanism_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"mechanism">>, _attrs, _els}. - -decode_sasl_mechanism_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_sasl_mechanism_cdata(__TopXMLNS, _val) -> _val. - -encode_sasl_mechanism_cdata(<<>>, _acc) -> _acc; -encode_sasl_mechanism_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_sasl_failure(__TopXMLNS, __IgnoreEls, - {xmlel, <<"failure">>, _attrs, _els}) -> - {Text, Reason} = decode_sasl_failure_els(__TopXMLNS, - __IgnoreEls, _els, [], undefined), - {sasl_failure, Reason, Text}. - -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, [], - Text, Reason) -> - {lists:reverse(Text), Reason}; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - [decode_sasl_failure_text(__TopXMLNS, - __IgnoreEls, _el) - | Text], - Reason); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - [decode_sasl_failure_text(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, _el) - | Text], - Reason); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"aborted">>, _attrs, _} = _el | _els], Text, - Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_aborted(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_aborted(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"account-disabled">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_account_disabled(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_account_disabled(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"credentials-expired">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_credentials_expired(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_credentials_expired(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"encryption-required">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_encryption_required(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_encryption_required(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"incorrect-encoding">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_incorrect_encoding(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_incorrect_encoding(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-authzid">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_invalid_authzid(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_invalid_authzid(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"invalid-mechanism">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_invalid_mechanism(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_invalid_mechanism(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"malformed-request">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_malformed_request(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_malformed_request(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"mechanism-too-weak">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_mechanism_too_weak(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_mechanism_too_weak(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_not_authorized(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"bad-protocol">>, _attrs, _} = _el | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_bad_protocol(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_bad_protocol(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"temporary-auth-failure">>, _attrs, _} = _el - | _els], - Text, Reason) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_temporary_auth_failure(__TopXMLNS, - __IgnoreEls, - _el)); - <<"urn:ietf:params:xml:ns:xmpp-sasl">> -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, - decode_sasl_failure_temporary_auth_failure(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - __IgnoreEls, - _el)); - _ -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason) - end; -decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text, Reason) -> - decode_sasl_failure_els(__TopXMLNS, __IgnoreEls, _els, - Text, Reason). - -encode_sasl_failure({sasl_failure, Reason, Text}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = lists:reverse('encode_sasl_failure_$text'(Text, - __NewTopXMLNS, - 'encode_sasl_failure_$reason'(Reason, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"failure">>, _attrs, _els}. - -'encode_sasl_failure_$text'([], __TopXMLNS, _acc) -> - _acc; -'encode_sasl_failure_$text'([Text | _els], __TopXMLNS, - _acc) -> - 'encode_sasl_failure_$text'(_els, __TopXMLNS, - [encode_sasl_failure_text(Text, __TopXMLNS) - | _acc]). - -'encode_sasl_failure_$reason'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_sasl_failure_$reason'(aborted = Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_aborted(Reason, __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('account-disabled' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_account_disabled(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('credentials-expired' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_credentials_expired(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('encryption-required' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_encryption_required(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('incorrect-encoding' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_incorrect_encoding(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('invalid-authzid' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_invalid_authzid(Reason, __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('invalid-mechanism' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_invalid_mechanism(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('malformed-request' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_malformed_request(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('mechanism-too-weak' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_mechanism_too_weak(Reason, - __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('not-authorized' = Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_not_authorized(Reason, __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('bad-protocol' = Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_bad_protocol(Reason, __TopXMLNS) - | _acc]; -'encode_sasl_failure_$reason'('temporary-auth-failure' = - Reason, - __TopXMLNS, _acc) -> - [encode_sasl_failure_temporary_auth_failure(Reason, - __TopXMLNS) - | _acc]. - -decode_sasl_failure_temporary_auth_failure(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"temporary-auth-failure">>, - _attrs, _els}) -> - 'temporary-auth-failure'. - -encode_sasl_failure_temporary_auth_failure('temporary-auth-failure', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"temporary-auth-failure">>, _attrs, _els}. - -decode_sasl_failure_bad_protocol(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"bad-protocol">>, _attrs, _els}) -> - 'bad-protocol'. - -encode_sasl_failure_bad_protocol('bad-protocol', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"bad-protocol">>, _attrs, _els}. - -decode_sasl_failure_not_authorized(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"not-authorized">>, _attrs, - _els}) -> - 'not-authorized'. - -encode_sasl_failure_not_authorized('not-authorized', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-authorized">>, _attrs, _els}. - -decode_sasl_failure_mechanism_too_weak(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"mechanism-too-weak">>, _attrs, - _els}) -> - 'mechanism-too-weak'. - -encode_sasl_failure_mechanism_too_weak('mechanism-too-weak', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"mechanism-too-weak">>, _attrs, _els}. - -decode_sasl_failure_malformed_request(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"malformed-request">>, _attrs, - _els}) -> - 'malformed-request'. - -encode_sasl_failure_malformed_request('malformed-request', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"malformed-request">>, _attrs, _els}. - -decode_sasl_failure_invalid_mechanism(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-mechanism">>, _attrs, - _els}) -> - 'invalid-mechanism'. - -encode_sasl_failure_invalid_mechanism('invalid-mechanism', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-mechanism">>, _attrs, _els}. - -decode_sasl_failure_invalid_authzid(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"invalid-authzid">>, _attrs, - _els}) -> - 'invalid-authzid'. - -encode_sasl_failure_invalid_authzid('invalid-authzid', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"invalid-authzid">>, _attrs, _els}. - -decode_sasl_failure_incorrect_encoding(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"incorrect-encoding">>, _attrs, - _els}) -> - 'incorrect-encoding'. - -encode_sasl_failure_incorrect_encoding('incorrect-encoding', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"incorrect-encoding">>, _attrs, _els}. - -decode_sasl_failure_encryption_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"encryption-required">>, - _attrs, _els}) -> - 'encryption-required'. - -encode_sasl_failure_encryption_required('encryption-required', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"encryption-required">>, _attrs, _els}. - -decode_sasl_failure_credentials_expired(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"credentials-expired">>, - _attrs, _els}) -> - 'credentials-expired'. - -encode_sasl_failure_credentials_expired('credentials-expired', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"credentials-expired">>, _attrs, _els}. - -decode_sasl_failure_account_disabled(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"account-disabled">>, _attrs, - _els}) -> - 'account-disabled'. - -encode_sasl_failure_account_disabled('account-disabled', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"account-disabled">>, _attrs, _els}. - -decode_sasl_failure_aborted(__TopXMLNS, __IgnoreEls, - {xmlel, <<"aborted">>, _attrs, _els}) -> - aborted. - -encode_sasl_failure_aborted(aborted, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"aborted">>, _attrs, _els}. - -decode_sasl_failure_text(__TopXMLNS, __IgnoreEls, - {xmlel, <<"text">>, _attrs, _els}) -> - Data = decode_sasl_failure_text_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Lang = decode_sasl_failure_text_attrs(__TopXMLNS, - _attrs, undefined), - {text, Lang, Data}. - -decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, - [], Data) -> - decode_sasl_failure_text_cdata(__TopXMLNS, Data); -decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_sasl_failure_text_els(__TopXMLNS, __IgnoreEls, - _els, Data). - -decode_sasl_failure_text_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_sasl_failure_text_attrs(__TopXMLNS, _attrs, - _val); -decode_sasl_failure_text_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_sasl_failure_text_attrs(__TopXMLNS, _attrs, - Lang); -decode_sasl_failure_text_attrs(__TopXMLNS, [], Lang) -> - 'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, - Lang). - -encode_sasl_failure_text({text, Lang, Data}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_failure_text_cdata(Data, []), - _attrs = 'encode_sasl_failure_text_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"text">>, _attrs, _els}. - -'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_sasl_failure_text_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_sasl_failure_text_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_sasl_failure_text_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_sasl_failure_text_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_sasl_failure_text_cdata(__TopXMLNS, _val) -> - _val. - -encode_sasl_failure_text_cdata(<<>>, _acc) -> _acc; -encode_sasl_failure_text_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_sasl_success(__TopXMLNS, __IgnoreEls, - {xmlel, <<"success">>, _attrs, _els}) -> - Text = decode_sasl_success_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {sasl_success, Text}. - -decode_sasl_success_els(__TopXMLNS, __IgnoreEls, [], - Text) -> - decode_sasl_success_cdata(__TopXMLNS, Text); -decode_sasl_success_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Text) -> - decode_sasl_success_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sasl_success_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text) -> - decode_sasl_success_els(__TopXMLNS, __IgnoreEls, _els, - Text). - -encode_sasl_success({sasl_success, Text}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_success_cdata(Text, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"success">>, _attrs, _els}. - -decode_sasl_success_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_sasl_success_cdata(__TopXMLNS, _val) -> - case catch base64:mime_decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"success">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sasl_success_cdata(<<>>, _acc) -> _acc; -encode_sasl_success_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_sasl_response(__TopXMLNS, __IgnoreEls, - {xmlel, <<"response">>, _attrs, _els}) -> - Text = decode_sasl_response_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {sasl_response, Text}. - -decode_sasl_response_els(__TopXMLNS, __IgnoreEls, [], - Text) -> - decode_sasl_response_cdata(__TopXMLNS, Text); -decode_sasl_response_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Text) -> - decode_sasl_response_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sasl_response_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text) -> - decode_sasl_response_els(__TopXMLNS, __IgnoreEls, _els, - Text). - -encode_sasl_response({sasl_response, Text}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_response_cdata(Text, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"response">>, _attrs, _els}. - -decode_sasl_response_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_sasl_response_cdata(__TopXMLNS, _val) -> - case catch base64:mime_decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"response">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sasl_response_cdata(<<>>, _acc) -> _acc; -encode_sasl_response_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_sasl_challenge(__TopXMLNS, __IgnoreEls, - {xmlel, <<"challenge">>, _attrs, _els}) -> - Text = decode_sasl_challenge_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - {sasl_challenge, Text}. - -decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, [], - Text) -> - decode_sasl_challenge_cdata(__TopXMLNS, Text); -decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Text) -> - decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text) -> - decode_sasl_challenge_els(__TopXMLNS, __IgnoreEls, _els, - Text). - -encode_sasl_challenge({sasl_challenge, Text}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_challenge_cdata(Text, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"challenge">>, _attrs, _els}. - -decode_sasl_challenge_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_sasl_challenge_cdata(__TopXMLNS, _val) -> - case catch base64:mime_decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"challenge">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sasl_challenge_cdata(<<>>, _acc) -> _acc; -encode_sasl_challenge_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_sasl_abort(__TopXMLNS, __IgnoreEls, - {xmlel, <<"abort">>, _attrs, _els}) -> - {sasl_abort}. - -encode_sasl_abort({sasl_abort}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"abort">>, _attrs, _els}. - -decode_sasl_auth(__TopXMLNS, __IgnoreEls, - {xmlel, <<"auth">>, _attrs, _els}) -> - Text = decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Mechanism = decode_sasl_auth_attrs(__TopXMLNS, _attrs, - undefined), - {sasl_auth, Mechanism, Text}. - -decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, [], - Text) -> - decode_sasl_auth_cdata(__TopXMLNS, Text); -decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Text) -> - decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Text) -> - decode_sasl_auth_els(__TopXMLNS, __IgnoreEls, _els, - Text). - -decode_sasl_auth_attrs(__TopXMLNS, - [{<<"mechanism">>, _val} | _attrs], _Mechanism) -> - decode_sasl_auth_attrs(__TopXMLNS, _attrs, _val); -decode_sasl_auth_attrs(__TopXMLNS, [_ | _attrs], - Mechanism) -> - decode_sasl_auth_attrs(__TopXMLNS, _attrs, Mechanism); -decode_sasl_auth_attrs(__TopXMLNS, [], Mechanism) -> - decode_sasl_auth_attr_mechanism(__TopXMLNS, Mechanism). - -encode_sasl_auth({sasl_auth, Mechanism, Text}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-sasl">>, - [], __TopXMLNS), - _els = encode_sasl_auth_cdata(Text, []), - _attrs = encode_sasl_auth_attr_mechanism(Mechanism, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"auth">>, _attrs, _els}. - -decode_sasl_auth_attr_mechanism(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"mechanism">>, <<"auth">>, - __TopXMLNS}}); -decode_sasl_auth_attr_mechanism(__TopXMLNS, _val) -> - _val. - -encode_sasl_auth_attr_mechanism(_val, _acc) -> - [{<<"mechanism">>, _val} | _acc]. - -decode_sasl_auth_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_sasl_auth_cdata(__TopXMLNS, _val) -> - case catch base64:mime_decode(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"auth">>, __TopXMLNS}}); - _res -> _res - end. - -encode_sasl_auth_cdata(<<>>, _acc) -> _acc; -encode_sasl_auth_cdata(_val, _acc) -> - [{xmlcdata, base64:encode(_val)} | _acc]. - -decode_legacy_auth(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Digest, Password, Resource, Username} = - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, undefined, undefined), - {legacy_auth, Username, Password, Digest, Resource}. - -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, [], - Digest, Password, Resource, Username) -> - {Digest, Password, Resource, Username}; -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"username">>, _attrs, _} = _el | _els], - Digest, Password, Resource, Username) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, - decode_legacy_auth_username(__TopXMLNS, - __IgnoreEls, _el)); - <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, - decode_legacy_auth_username(<<"jabber:iq:auth">>, - __IgnoreEls, _el)); - _ -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, Username) - end; -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el | _els], - Digest, Password, Resource, Username) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, - decode_legacy_auth_password(__TopXMLNS, - __IgnoreEls, _el), - Resource, Username); - <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, - decode_legacy_auth_password(<<"jabber:iq:auth">>, - __IgnoreEls, _el), - Resource, Username); - _ -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, Username) - end; -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"digest">>, _attrs, _} = _el | _els], Digest, - Password, Resource, Username) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - decode_legacy_auth_digest(__TopXMLNS, - __IgnoreEls, _el), - Password, Resource, Username); - <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - decode_legacy_auth_digest(<<"jabber:iq:auth">>, - __IgnoreEls, _el), - Password, Resource, Username); - _ -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, Username) - end; -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"resource">>, _attrs, _} = _el | _els], - Digest, Password, Resource, Username) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, - decode_legacy_auth_resource(__TopXMLNS, - __IgnoreEls, _el), - Username); - <<"jabber:iq:auth">> -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, - decode_legacy_auth_resource(<<"jabber:iq:auth">>, - __IgnoreEls, _el), - Username); - _ -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, Username) - end; -decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Digest, Password, Resource, Username) -> - decode_legacy_auth_els(__TopXMLNS, __IgnoreEls, _els, - Digest, Password, Resource, Username). - -encode_legacy_auth({legacy_auth, Username, Password, - Digest, Resource}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_legacy_auth_$digest'(Digest, - __NewTopXMLNS, - 'encode_legacy_auth_$password'(Password, - __NewTopXMLNS, - 'encode_legacy_auth_$resource'(Resource, - __NewTopXMLNS, - 'encode_legacy_auth_$username'(Username, - __NewTopXMLNS, - []))))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_legacy_auth_$digest'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_legacy_auth_$digest'(Digest, __TopXMLNS, - _acc) -> - [encode_legacy_auth_digest(Digest, __TopXMLNS) | _acc]. - -'encode_legacy_auth_$password'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_legacy_auth_$password'(Password, __TopXMLNS, - _acc) -> - [encode_legacy_auth_password(Password, __TopXMLNS) - | _acc]. - -'encode_legacy_auth_$resource'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_legacy_auth_$resource'(Resource, __TopXMLNS, - _acc) -> - [encode_legacy_auth_resource(Resource, __TopXMLNS) - | _acc]. - -'encode_legacy_auth_$username'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_legacy_auth_$username'(Username, __TopXMLNS, - _acc) -> - [encode_legacy_auth_username(Username, __TopXMLNS) - | _acc]. - -decode_legacy_auth_resource(__TopXMLNS, __IgnoreEls, - {xmlel, <<"resource">>, _attrs, _els}) -> - Cdata = decode_legacy_auth_resource_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_legacy_auth_resource_cdata(__TopXMLNS, Cdata); -decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_legacy_auth_resource_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_legacy_auth_resource(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, - [], __TopXMLNS), - _els = encode_legacy_auth_resource_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"resource">>, _attrs, _els}. - -decode_legacy_auth_resource_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_legacy_auth_resource_cdata(__TopXMLNS, _val) -> - _val. - -encode_legacy_auth_resource_cdata(<<>>, _acc) -> _acc; -encode_legacy_auth_resource_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_legacy_auth_digest(__TopXMLNS, __IgnoreEls, - {xmlel, <<"digest">>, _attrs, _els}) -> - Cdata = decode_legacy_auth_digest_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_legacy_auth_digest_cdata(__TopXMLNS, Cdata); -decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_legacy_auth_digest_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_legacy_auth_digest(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, - [], __TopXMLNS), - _els = encode_legacy_auth_digest_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"digest">>, _attrs, _els}. - -decode_legacy_auth_digest_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_legacy_auth_digest_cdata(__TopXMLNS, _val) -> - _val. - -encode_legacy_auth_digest_cdata(<<>>, _acc) -> _acc; -encode_legacy_auth_digest_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_legacy_auth_password(__TopXMLNS, __IgnoreEls, - {xmlel, <<"password">>, _attrs, _els}) -> - Cdata = decode_legacy_auth_password_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_legacy_auth_password_cdata(__TopXMLNS, Cdata); -decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_legacy_auth_password_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_legacy_auth_password(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, - [], __TopXMLNS), - _els = encode_legacy_auth_password_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"password">>, _attrs, _els}. - -decode_legacy_auth_password_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_legacy_auth_password_cdata(__TopXMLNS, _val) -> - _val. - -encode_legacy_auth_password_cdata(<<>>, _acc) -> _acc; -encode_legacy_auth_password_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_legacy_auth_username(__TopXMLNS, __IgnoreEls, - {xmlel, <<"username">>, _attrs, _els}) -> - Cdata = decode_legacy_auth_username_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_legacy_auth_username_cdata(__TopXMLNS, Cdata); -decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_legacy_auth_username_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_legacy_auth_username(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:auth">>, - [], __TopXMLNS), - _els = encode_legacy_auth_username_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"username">>, _attrs, _els}. - -decode_legacy_auth_username_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_legacy_auth_username_cdata(__TopXMLNS, _val) -> - _val. - -encode_legacy_auth_username_cdata(<<>>, _acc) -> _acc; -encode_legacy_auth_username_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_bind(__TopXMLNS, __IgnoreEls, - {xmlel, <<"bind">>, _attrs, _els}) -> - {Jid, Resource} = decode_bind_els(__TopXMLNS, - __IgnoreEls, _els, undefined, <<>>), - {bind, Jid, Resource}. - -decode_bind_els(__TopXMLNS, __IgnoreEls, [], Jid, - Resource) -> - {Jid, Resource}; -decode_bind_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jid, - Resource) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-bind">> -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, - decode_bind_jid(__TopXMLNS, __IgnoreEls, _el), - Resource); - <<"urn:ietf:params:xml:ns:xmpp-bind">> -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, - decode_bind_jid(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - __IgnoreEls, _el), - Resource); - _ -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, - Resource) - end; -decode_bind_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"resource">>, _attrs, _} = _el | _els], Jid, - Resource) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"urn:ietf:params:xml:ns:xmpp-bind">> -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, - decode_bind_resource(__TopXMLNS, __IgnoreEls, _el)); - <<"urn:ietf:params:xml:ns:xmpp-bind">> -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, - decode_bind_resource(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - __IgnoreEls, _el)); - _ -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, - Resource) - end; -decode_bind_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Jid, Resource) -> - decode_bind_els(__TopXMLNS, __IgnoreEls, _els, Jid, - Resource). - -encode_bind({bind, Jid, Resource}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - [], __TopXMLNS), - _els = lists:reverse('encode_bind_$jid'(Jid, - __NewTopXMLNS, - 'encode_bind_$resource'(Resource, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"bind">>, _attrs, _els}. - -'encode_bind_$jid'(undefined, __TopXMLNS, _acc) -> _acc; -'encode_bind_$jid'(Jid, __TopXMLNS, _acc) -> - [encode_bind_jid(Jid, __TopXMLNS) | _acc]. - -'encode_bind_$resource'(<<>>, __TopXMLNS, _acc) -> _acc; -'encode_bind_$resource'(Resource, __TopXMLNS, _acc) -> - [encode_bind_resource(Resource, __TopXMLNS) | _acc]. - -decode_bind_resource(__TopXMLNS, __IgnoreEls, - {xmlel, <<"resource">>, _attrs, _els}) -> - Cdata = decode_bind_resource_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_bind_resource_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_bind_resource_cdata(__TopXMLNS, Cdata); -decode_bind_resource_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_bind_resource_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_bind_resource_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_bind_resource_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_bind_resource(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - [], __TopXMLNS), - _els = encode_bind_resource_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"resource">>, _attrs, _els}. - -decode_bind_resource_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_bind_resource_cdata(__TopXMLNS, _val) -> - case catch resourceprep(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"resource">>, __TopXMLNS}}); - _res -> _res - end. - -encode_bind_resource_cdata(<<>>, _acc) -> _acc; -encode_bind_resource_cdata(_val, _acc) -> - [{xmlcdata, resourceprep(_val)} | _acc]. - -decode_bind_jid(__TopXMLNS, __IgnoreEls, - {xmlel, <<"jid">>, _attrs, _els}) -> - Cdata = decode_bind_jid_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_bind_jid_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_bind_jid_cdata(__TopXMLNS, Cdata); -decode_bind_jid_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_bind_jid_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_bind_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Cdata) -> - decode_bind_jid_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_bind_jid(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-bind">>, - [], __TopXMLNS), - _els = encode_bind_jid_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"jid">>, _attrs, _els}. - -decode_bind_jid_cdata(__TopXMLNS, <<>>) -> undefined; -decode_bind_jid_cdata(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"jid">>, __TopXMLNS}}); - _res -> _res - end. - -encode_bind_jid_cdata(undefined, _acc) -> _acc; -encode_bind_jid_cdata(_val, _acc) -> - [{xmlcdata, enc_jid(_val)} | _acc]. - -decode_error(__TopXMLNS, __IgnoreEls, - {xmlel, <<"error">>, _attrs, _els}) -> - {Text, Reason, __Els} = decode_error_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined, []), - {Type, Code, By} = decode_error_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {stanza_error, Type, Code, By, Reason, Text, __Els}. - -decode_error_els(__TopXMLNS, __IgnoreEls, [], Text, - Reason, __Els) -> - {Text, Reason, lists:reverse(__Els)}; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, - 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, __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"bad-request">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], 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_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"feature-not-implemented">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"forbidden">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"gone">>, _attrs, _} = _el | _els], 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_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"internal-server-error">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item-not-found">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"jid-malformed">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-acceptable">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-allowed">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"payment-required">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"policy-violation">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"recipient-unavailable">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], 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_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"registration-required">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remote-server-not-found">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"remote-server-timeout">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"resource-constraint">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"service-unavailable">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subscription-required">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"undefined-condition">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end; -decode_error_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"unexpected-request">>, _attrs, _} = _el - | _els], - 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), - __Els); - _ -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - 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, __TopXMLNS) of - true -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els) - end - end; -decode_error_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Text, Reason, __Els) -> - decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason, __Els). - -decode_error_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], _Type, Code, By) -> - decode_error_attrs(__TopXMLNS, _attrs, _val, Code, By); -decode_error_attrs(__TopXMLNS, - [{<<"code">>, _val} | _attrs], Type, _Code, By) -> - decode_error_attrs(__TopXMLNS, _attrs, Type, _val, By); -decode_error_attrs(__TopXMLNS, - [{<<"by">>, _val} | _attrs], Type, Code, _By) -> - decode_error_attrs(__TopXMLNS, _attrs, Type, Code, - _val); -decode_error_attrs(__TopXMLNS, [_ | _attrs], Type, Code, - By) -> - decode_error_attrs(__TopXMLNS, _attrs, Type, Code, By); -decode_error_attrs(__TopXMLNS, [], Type, Code, By) -> - {decode_error_attr_type(__TopXMLNS, Type), - decode_error_attr_code(__TopXMLNS, Code), - decode_error_attr_by(__TopXMLNS, By)}. - -encode_error({stanza_error, Type, Code, By, Reason, - Text, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ - lists:reverse('encode_error_$text'(Text, __NewTopXMLNS, - 'encode_error_$reason'(Reason, - __NewTopXMLNS, - []))), - _attrs = encode_error_attr_by(By, - encode_error_attr_code(Code, - encode_error_attr_type(Type, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"error">>, _attrs, _els}. - -'encode_error_$text'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_error_$text'(Text, __TopXMLNS, _acc) -> - [encode_error_text(Text, __TopXMLNS) | _acc]. - -'encode_error_$reason'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_error_$reason'('bad-request' = Reason, - __TopXMLNS, _acc) -> - [encode_error_bad_request(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'(conflict = Reason, __TopXMLNS, - _acc) -> - [encode_error_conflict(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'('feature-not-implemented' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_feature_not_implemented(Reason, - __TopXMLNS) - | _acc]; -'encode_error_$reason'(forbidden = Reason, __TopXMLNS, - _acc) -> - [encode_error_forbidden(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'({gone, _} = Reason, __TopXMLNS, - _acc) -> - [encode_error_gone(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'('internal-server-error' = Reason, - __TopXMLNS, _acc) -> - [encode_error_internal_server_error(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('item-not-found' = Reason, - __TopXMLNS, _acc) -> - [encode_error_item_not_found(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('jid-malformed' = Reason, - __TopXMLNS, _acc) -> - [encode_error_jid_malformed(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'('not-acceptable' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_acceptable(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('not-allowed' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_allowed(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'('not-authorized' = Reason, - __TopXMLNS, _acc) -> - [encode_error_not_authorized(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('payment-required' = Reason, - __TopXMLNS, _acc) -> - [encode_error_payment_required(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('policy-violation' = Reason, - __TopXMLNS, _acc) -> - [encode_error_policy_violation(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('recipient-unavailable' = Reason, - __TopXMLNS, _acc) -> - [encode_error_recipient_unavailable(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'({redirect, _} = Reason, - __TopXMLNS, _acc) -> - [encode_error_redirect(Reason, __TopXMLNS) | _acc]; -'encode_error_$reason'('registration-required' = Reason, - __TopXMLNS, _acc) -> - [encode_error_registration_required(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('remote-server-not-found' = - Reason, - __TopXMLNS, _acc) -> - [encode_error_remote_server_not_found(Reason, - __TopXMLNS) - | _acc]; -'encode_error_$reason'('remote-server-timeout' = Reason, - __TopXMLNS, _acc) -> - [encode_error_remote_server_timeout(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('resource-constraint' = Reason, - __TopXMLNS, _acc) -> - [encode_error_resource_constraint(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('service-unavailable' = Reason, - __TopXMLNS, _acc) -> - [encode_error_service_unavailable(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('subscription-required' = Reason, - __TopXMLNS, _acc) -> - [encode_error_subscription_required(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('undefined-condition' = Reason, - __TopXMLNS, _acc) -> - [encode_error_undefined_condition(Reason, __TopXMLNS) - | _acc]; -'encode_error_$reason'('unexpected-request' = Reason, - __TopXMLNS, _acc) -> - [encode_error_unexpected_request(Reason, __TopXMLNS) - | _acc]. - -decode_error_attr_type(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"error">>, __TopXMLNS}}); -decode_error_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [auth, cancel, continue, modify, wait]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"error">>, __TopXMLNS}}); - _res -> _res - end. - -encode_error_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_error_attr_code(__TopXMLNS, undefined) -> - undefined; -decode_error_attr_code(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"code">>, <<"error">>, __TopXMLNS}}); - _res -> _res - end. - -encode_error_attr_code(undefined, _acc) -> _acc; -encode_error_attr_code(_val, _acc) -> - [{<<"code">>, enc_int(_val)} | _acc]. - -decode_error_attr_by(__TopXMLNS, undefined) -> <<>>; -decode_error_attr_by(__TopXMLNS, _val) -> _val. - -encode_error_attr_by(<<>>, _acc) -> _acc; -encode_error_attr_by(_val, _acc) -> - [{<<"by">>, _val} | _acc]. - -decode_error_text(__TopXMLNS, __IgnoreEls, - {xmlel, <<"text">>, _attrs, _els}) -> - Data = decode_error_text_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Lang = decode_error_text_attrs(__TopXMLNS, _attrs, - undefined), - {text, Lang, Data}. - -decode_error_text_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_error_text_cdata(__TopXMLNS, Data); -decode_error_text_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_error_text_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_error_text_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_error_text_els(__TopXMLNS, __IgnoreEls, _els, - Data). - -decode_error_text_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_error_text_attrs(__TopXMLNS, _attrs, _val); -decode_error_text_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_error_text_attrs(__TopXMLNS, _attrs, Lang); -decode_error_text_attrs(__TopXMLNS, [], Lang) -> - 'decode_error_text_attr_xml:lang'(__TopXMLNS, Lang). - -encode_error_text({text, Lang, Data}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = encode_error_text_cdata(Data, []), - _attrs = 'encode_error_text_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"text">>, _attrs, _els}. - -'decode_error_text_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_error_text_attr_xml:lang'(__TopXMLNS, _val) -> - _val. - -'encode_error_text_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_error_text_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_error_text_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_error_text_cdata(__TopXMLNS, _val) -> _val. - -encode_error_text_cdata(<<>>, _acc) -> _acc; -encode_error_text_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_error_unexpected_request(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unexpected-request">>, _attrs, - _els}) -> - 'unexpected-request'. - -encode_error_unexpected_request('unexpected-request', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unexpected-request">>, _attrs, _els}. - -decode_error_undefined_condition(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"undefined-condition">>, _attrs, - _els}) -> - 'undefined-condition'. - -encode_error_undefined_condition('undefined-condition', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"undefined-condition">>, _attrs, _els}. - -decode_error_subscription_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"subscription-required">>, _attrs, - _els}) -> - 'subscription-required'. - -encode_error_subscription_required('subscription-required', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"subscription-required">>, _attrs, _els}. - -decode_error_service_unavailable(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"service-unavailable">>, _attrs, - _els}) -> - 'service-unavailable'. - -encode_error_service_unavailable('service-unavailable', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"service-unavailable">>, _attrs, _els}. - -decode_error_resource_constraint(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"resource-constraint">>, _attrs, - _els}) -> - 'resource-constraint'. - -encode_error_resource_constraint('resource-constraint', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"resource-constraint">>, _attrs, _els}. - -decode_error_remote_server_timeout(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"remote-server-timeout">>, _attrs, - _els}) -> - 'remote-server-timeout'. - -encode_error_remote_server_timeout('remote-server-timeout', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"remote-server-timeout">>, _attrs, _els}. - -decode_error_remote_server_not_found(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"remote-server-not-found">>, - _attrs, _els}) -> - 'remote-server-not-found'. - -encode_error_remote_server_not_found('remote-server-not-found', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"remote-server-not-found">>, _attrs, _els}. - -decode_error_registration_required(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"registration-required">>, _attrs, - _els}) -> - 'registration-required'. - -encode_error_registration_required('registration-required', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"registration-required">>, _attrs, _els}. - -decode_error_redirect(__TopXMLNS, __IgnoreEls, - {xmlel, <<"redirect">>, _attrs, _els}) -> - Uri = decode_error_redirect_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {redirect, Uri}. - -decode_error_redirect_els(__TopXMLNS, __IgnoreEls, [], - Uri) -> - decode_error_redirect_cdata(__TopXMLNS, Uri); -decode_error_redirect_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Uri) -> - decode_error_redirect_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_error_redirect_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Uri) -> - decode_error_redirect_els(__TopXMLNS, __IgnoreEls, _els, - Uri). - -encode_error_redirect({redirect, Uri}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = encode_error_redirect_cdata(Uri, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"redirect">>, _attrs, _els}. - -decode_error_redirect_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_error_redirect_cdata(__TopXMLNS, _val) -> _val. - -encode_error_redirect_cdata(<<>>, _acc) -> _acc; -encode_error_redirect_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_error_recipient_unavailable(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"recipient-unavailable">>, _attrs, - _els}) -> - 'recipient-unavailable'. - -encode_error_recipient_unavailable('recipient-unavailable', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"recipient-unavailable">>, _attrs, _els}. - -decode_error_policy_violation(__TopXMLNS, __IgnoreEls, - {xmlel, <<"policy-violation">>, _attrs, _els}) -> - 'policy-violation'. - -encode_error_policy_violation('policy-violation', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"policy-violation">>, _attrs, _els}. - -decode_error_payment_required(__TopXMLNS, __IgnoreEls, - {xmlel, <<"payment-required">>, _attrs, _els}) -> - 'payment-required'. - -encode_error_payment_required('payment-required', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"payment-required">>, _attrs, _els}. - -decode_error_not_authorized(__TopXMLNS, __IgnoreEls, - {xmlel, <<"not-authorized">>, _attrs, _els}) -> - 'not-authorized'. - -encode_error_not_authorized('not-authorized', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-authorized">>, _attrs, _els}. - -decode_error_not_allowed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"not-allowed">>, _attrs, _els}) -> - 'not-allowed'. - -encode_error_not_allowed('not-allowed', __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-allowed">>, _attrs, _els}. - -decode_error_not_acceptable(__TopXMLNS, __IgnoreEls, - {xmlel, <<"not-acceptable">>, _attrs, _els}) -> - 'not-acceptable'. - -encode_error_not_acceptable('not-acceptable', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"not-acceptable">>, _attrs, _els}. - -decode_error_jid_malformed(__TopXMLNS, __IgnoreEls, - {xmlel, <<"jid-malformed">>, _attrs, _els}) -> - 'jid-malformed'. - -encode_error_jid_malformed('jid-malformed', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"jid-malformed">>, _attrs, _els}. - -decode_error_item_not_found(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item-not-found">>, _attrs, _els}) -> - 'item-not-found'. - -encode_error_item_not_found('item-not-found', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"item-not-found">>, _attrs, _els}. - -decode_error_internal_server_error(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"internal-server-error">>, _attrs, - _els}) -> - 'internal-server-error'. - -encode_error_internal_server_error('internal-server-error', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"internal-server-error">>, _attrs, _els}. - -decode_error_gone(__TopXMLNS, __IgnoreEls, - {xmlel, <<"gone">>, _attrs, _els}) -> - Uri = decode_error_gone_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - {gone, Uri}. - -decode_error_gone_els(__TopXMLNS, __IgnoreEls, [], - Uri) -> - decode_error_gone_cdata(__TopXMLNS, Uri); -decode_error_gone_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Uri) -> - decode_error_gone_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_error_gone_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Uri) -> - decode_error_gone_els(__TopXMLNS, __IgnoreEls, _els, - Uri). - -encode_error_gone({gone, Uri}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = encode_error_gone_cdata(Uri, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"gone">>, _attrs, _els}. - -decode_error_gone_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_error_gone_cdata(__TopXMLNS, _val) -> _val. - -encode_error_gone_cdata(<<>>, _acc) -> _acc; -encode_error_gone_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_error_forbidden(__TopXMLNS, __IgnoreEls, - {xmlel, <<"forbidden">>, _attrs, _els}) -> - forbidden. - -encode_error_forbidden(forbidden, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"forbidden">>, _attrs, _els}. - -decode_error_feature_not_implemented(__TopXMLNS, - __IgnoreEls, - {xmlel, <<"feature-not-implemented">>, - _attrs, _els}) -> - 'feature-not-implemented'. - -encode_error_feature_not_implemented('feature-not-implemented', - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"feature-not-implemented">>, _attrs, _els}. - -decode_error_conflict(__TopXMLNS, __IgnoreEls, - {xmlel, <<"conflict">>, _attrs, _els}) -> - conflict. - -encode_error_conflict(conflict, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"conflict">>, _attrs, _els}. - -decode_error_bad_request(__TopXMLNS, __IgnoreEls, - {xmlel, <<"bad-request">>, _attrs, _els}) -> - 'bad-request'. - -encode_error_bad_request('bad-request', __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - [], __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"bad-request">>, _attrs, _els}. - -decode_presence(__TopXMLNS, __IgnoreEls, - {xmlel, <<"presence">>, _attrs, _els}) -> - {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, __Els}. - -decode_presence_els(__TopXMLNS, __IgnoreEls, [], Status, - Show, Priority, __Els) -> - {lists:reverse(Status), Show, Priority, - lists:reverse(__Els)}; -decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"show">>, _attrs, _} = _el | _els], Status, - Show, Priority, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, - decode_presence_show(__TopXMLNS, __IgnoreEls, - _el), - Priority, __Els); - <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, - decode_presence_show(<<"jabber:client">>, - __IgnoreEls, _el), - Priority, __Els); - <<"jabber:server">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, - decode_presence_show(<<"jabber:server">>, - __IgnoreEls, _el), - Priority, __Els); - <<"jabber:component:accept">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, - decode_presence_show(<<"jabber:component:accept">>, - __IgnoreEls, _el), - Priority, __Els); - _ -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, __Els) - end; -decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"status">>, _attrs, _} = _el | _els], Status, - Show, Priority, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - [decode_presence_status(__TopXMLNS, __IgnoreEls, - _el) - | Status], - Show, Priority, __Els); - <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - [decode_presence_status(<<"jabber:client">>, - __IgnoreEls, _el) - | Status], - Show, Priority, __Els); - <<"jabber:server">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - [decode_presence_status(<<"jabber:server">>, - __IgnoreEls, _el) - | Status], - Show, Priority, __Els); - <<"jabber:component:accept">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - [decode_presence_status(<<"jabber:component:accept">>, - __IgnoreEls, _el) - | Status], - Show, Priority, __Els); - _ -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, __Els) - end; -decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"priority">>, _attrs, _} = _el | _els], - Status, Show, Priority, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, - decode_presence_priority(__TopXMLNS, __IgnoreEls, - _el), - __Els); - <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, - decode_presence_priority(<<"jabber:client">>, - __IgnoreEls, _el), - __Els); - <<"jabber:server">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, - decode_presence_priority(<<"jabber:server">>, - __IgnoreEls, _el), - __Els); - <<"jabber:component:accept">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, - decode_presence_priority(<<"jabber:component:accept">>, - __IgnoreEls, _el), - __Els); - _ -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, __Els) - end; -decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Status, Show, Priority, - __Els) -> - if __IgnoreEls -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, __Els) - end - end; -decode_presence_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Status, Show, Priority, __Els) -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Status, Show, Priority, __Els). - -decode_presence_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, Type, From, To, - Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, _val, Type, - From, To, Lang); -decode_presence_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Id, _Type, From, To, - Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, Id, _val, - From, To, Lang); -decode_presence_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], Id, Type, _From, To, - Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, - _val, To, Lang); -decode_presence_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], Id, Type, From, _To, - Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, - From, _val, Lang); -decode_presence_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, - _Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, - From, To, _val); -decode_presence_attrs(__TopXMLNS, [_ | _attrs], Id, - Type, From, To, Lang) -> - decode_presence_attrs(__TopXMLNS, _attrs, Id, Type, - From, To, Lang); -decode_presence_attrs(__TopXMLNS, [], Id, Type, From, - To, Lang) -> - {decode_presence_attr_id(__TopXMLNS, Id), - decode_presence_attr_type(__TopXMLNS, Type), - decode_presence_attr_from(__TopXMLNS, From), - decode_presence_attr_to(__TopXMLNS, To), - 'decode_presence_attr_xml:lang'(__TopXMLNS, Lang)}. - -encode_presence({presence, Id, Type, Lang, From, To, - Show, Status, Priority, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ - lists:reverse('encode_presence_$status'(Status, - __NewTopXMLNS, - 'encode_presence_$show'(Show, - __NewTopXMLNS, - 'encode_presence_$priority'(Priority, - __NewTopXMLNS, - [])))), - _attrs = 'encode_presence_attr_xml:lang'(Lang, - encode_presence_attr_to(To, - encode_presence_attr_from(From, - encode_presence_attr_type(Type, - encode_presence_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"presence">>, _attrs, _els}. - -'encode_presence_$status'([], __TopXMLNS, _acc) -> _acc; -'encode_presence_$status'([Status | _els], __TopXMLNS, - _acc) -> - 'encode_presence_$status'(_els, __TopXMLNS, - [encode_presence_status(Status, __TopXMLNS) - | _acc]). - -'encode_presence_$show'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_presence_$show'(Show, __TopXMLNS, _acc) -> - [encode_presence_show(Show, __TopXMLNS) | _acc]. - -'encode_presence_$priority'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_presence_$priority'(Priority, __TopXMLNS, - _acc) -> - [encode_presence_priority(Priority, __TopXMLNS) | _acc]. - -decode_presence_attr_id(__TopXMLNS, undefined) -> <<>>; -decode_presence_attr_id(__TopXMLNS, _val) -> _val. - -encode_presence_attr_id(<<>>, _acc) -> _acc; -encode_presence_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_presence_attr_type(__TopXMLNS, undefined) -> - available; -decode_presence_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [unavailable, subscribe, subscribed, unsubscribe, - unsubscribed, available, probe, error]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"presence">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_presence_attr_type(available, _acc) -> _acc; -encode_presence_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_presence_attr_from(__TopXMLNS, undefined) -> - undefined; -decode_presence_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"presence">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_presence_attr_from(undefined, _acc) -> _acc; -encode_presence_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_presence_attr_to(__TopXMLNS, undefined) -> - undefined; -decode_presence_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"presence">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_presence_attr_to(undefined, _acc) -> _acc; -encode_presence_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -'decode_presence_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_presence_attr_xml:lang'(__TopXMLNS, _val) -> - _val. - -'encode_presence_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_presence_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_presence_priority(__TopXMLNS, __IgnoreEls, - {xmlel, <<"priority">>, _attrs, _els}) -> - Cdata = decode_presence_priority_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_presence_priority_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_presence_priority_cdata(__TopXMLNS, Cdata); -decode_presence_priority_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_presence_priority_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_presence_priority_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_presence_priority_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_presence_priority(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_presence_priority_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"priority">>, _attrs, _els}. - -decode_presence_priority_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_presence_priority_cdata(__TopXMLNS, _val) -> - case catch dec_int(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"priority">>, __TopXMLNS}}); - _res -> _res - end. - -encode_presence_priority_cdata(undefined, _acc) -> _acc; -encode_presence_priority_cdata(_val, _acc) -> - [{xmlcdata, enc_int(_val)} | _acc]. - -decode_presence_status(__TopXMLNS, __IgnoreEls, - {xmlel, <<"status">>, _attrs, _els}) -> - Data = decode_presence_status_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Lang = decode_presence_status_attrs(__TopXMLNS, _attrs, - undefined), - {text, Lang, Data}. - -decode_presence_status_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_presence_status_cdata(__TopXMLNS, Data); -decode_presence_status_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_presence_status_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_presence_status_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_presence_status_els(__TopXMLNS, __IgnoreEls, - _els, Data). - -decode_presence_status_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_presence_status_attrs(__TopXMLNS, _attrs, _val); -decode_presence_status_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_presence_status_attrs(__TopXMLNS, _attrs, Lang); -decode_presence_status_attrs(__TopXMLNS, [], Lang) -> - 'decode_presence_status_attr_xml:lang'(__TopXMLNS, - Lang). - -encode_presence_status({text, Lang, Data}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_presence_status_cdata(Data, []), - _attrs = 'encode_presence_status_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"status">>, _attrs, _els}. - -'decode_presence_status_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_presence_status_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_presence_status_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_presence_status_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_presence_status_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_presence_status_cdata(__TopXMLNS, _val) -> _val. - -encode_presence_status_cdata(<<>>, _acc) -> _acc; -encode_presence_status_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_presence_show(__TopXMLNS, __IgnoreEls, - {xmlel, <<"show">>, _attrs, _els}) -> - Cdata = decode_presence_show_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_presence_show_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_presence_show_cdata(__TopXMLNS, Cdata); -decode_presence_show_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_presence_show_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_presence_show_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_presence_show_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_presence_show(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_presence_show_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"show">>, _attrs, _els}. - -decode_presence_show_cdata(__TopXMLNS, <<>>) -> - undefined; -decode_presence_show_cdata(__TopXMLNS, _val) -> - case catch dec_enum(_val, [away, chat, dnd, xa]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_cdata_value, <<>>, <<"show">>, __TopXMLNS}}); - _res -> _res - end. - -encode_presence_show_cdata(undefined, _acc) -> _acc; -encode_presence_show_cdata(_val, _acc) -> - [{xmlcdata, enc_enum(_val)} | _acc]. - -decode_message(__TopXMLNS, __IgnoreEls, - {xmlel, <<"message">>, _attrs, _els}) -> - {Thread, Subject, Body, __Els} = - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - 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, __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, <<"subject">>, _attrs, _} = _el | _els], - Thread, Subject, Body, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, - [decode_message_subject(__TopXMLNS, __IgnoreEls, - _el) - | Subject], - Body, __Els); - <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, - [decode_message_subject(<<"jabber:client">>, - __IgnoreEls, _el) - | Subject], - Body, __Els); - <<"jabber:server">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, - [decode_message_subject(<<"jabber:server">>, - __IgnoreEls, _el) - | Subject], - Body, __Els); - <<"jabber:component:accept">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, - [decode_message_subject(<<"jabber:component:accept">>, - __IgnoreEls, _el) - | Subject], - Body, __Els); - _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, __Els) - end; -decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"thread">>, _attrs, _} = _el | _els], Thread, - Subject, Body, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_message_thread(__TopXMLNS, __IgnoreEls, - _el), - Subject, Body, __Els); - <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_message_thread(<<"jabber:client">>, - __IgnoreEls, _el), - Subject, Body, __Els); - <<"jabber:server">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_message_thread(<<"jabber:server">>, - __IgnoreEls, _el), - Subject, Body, __Els); - <<"jabber:component:accept">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_message_thread(<<"jabber:component:accept">>, - __IgnoreEls, _el), - Subject, Body, __Els); - _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, __Els) - end; -decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"body">>, _attrs, _} = _el | _els], Thread, - Subject, Body, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == <<"jabber:server">>; - __TopXMLNS == <<"jabber:component:accept">>; - __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, - [decode_message_body(__TopXMLNS, __IgnoreEls, _el) - | Body], - __Els); - <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, - [decode_message_body(<<"jabber:client">>, - __IgnoreEls, _el) - | Body], - __Els); - <<"jabber:server">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, - [decode_message_body(<<"jabber:server">>, - __IgnoreEls, _el) - | Body], - __Els); - <<"jabber:component:accept">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, - [decode_message_body(<<"jabber:component:accept">>, - __IgnoreEls, _el) - | Body], - __Els); - _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, __Els) - end; -decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Thread, Subject, Body, - __Els) -> - if __IgnoreEls -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, __Els) - end - end; -decode_message_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Thread, Subject, Body, __Els) -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - Thread, Subject, Body, __Els). - -decode_message_attrs(__TopXMLNS, - [{<<"id">>, _val} | _attrs], _Id, Type, From, To, - Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, _val, Type, - From, To, Lang); -decode_message_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Id, _Type, From, To, - Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, Id, _val, From, - To, Lang); -decode_message_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], Id, Type, _From, To, - Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, Id, Type, _val, - To, Lang); -decode_message_attrs(__TopXMLNS, - [{<<"to">>, _val} | _attrs], Id, Type, From, _To, - Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, - _val, Lang); -decode_message_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, - _Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, - To, _val); -decode_message_attrs(__TopXMLNS, [_ | _attrs], Id, Type, - From, To, Lang) -> - decode_message_attrs(__TopXMLNS, _attrs, Id, Type, From, - To, Lang); -decode_message_attrs(__TopXMLNS, [], Id, Type, From, To, - Lang) -> - {decode_message_attr_id(__TopXMLNS, Id), - decode_message_attr_type(__TopXMLNS, Type), - decode_message_attr_from(__TopXMLNS, From), - decode_message_attr_to(__TopXMLNS, To), - 'decode_message_attr_xml:lang'(__TopXMLNS, Lang)}. - -encode_message({message, Id, Type, Lang, From, To, - Subject, Body, Thread, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++ - lists:reverse('encode_message_$thread'(Thread, - __NewTopXMLNS, - 'encode_message_$subject'(Subject, - __NewTopXMLNS, - 'encode_message_$body'(Body, - __NewTopXMLNS, - [])))), - _attrs = 'encode_message_attr_xml:lang'(Lang, - encode_message_attr_to(To, - encode_message_attr_from(From, - encode_message_attr_type(Type, - encode_message_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"message">>, _attrs, _els}. - -'encode_message_$thread'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_message_$thread'(Thread, __TopXMLNS, _acc) -> - [encode_message_thread(Thread, __TopXMLNS) | _acc]. - -'encode_message_$subject'([], __TopXMLNS, _acc) -> _acc; -'encode_message_$subject'([Subject | _els], __TopXMLNS, - _acc) -> - 'encode_message_$subject'(_els, __TopXMLNS, - [encode_message_subject(Subject, __TopXMLNS) - | _acc]). - -'encode_message_$body'([], __TopXMLNS, _acc) -> _acc; -'encode_message_$body'([Body | _els], __TopXMLNS, - _acc) -> - 'encode_message_$body'(_els, __TopXMLNS, - [encode_message_body(Body, __TopXMLNS) | _acc]). - -decode_message_attr_id(__TopXMLNS, undefined) -> <<>>; -decode_message_attr_id(__TopXMLNS, _val) -> _val. - -encode_message_attr_id(<<>>, _acc) -> _acc; -encode_message_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_message_attr_type(__TopXMLNS, undefined) -> - normal; -decode_message_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, - [chat, normal, groupchat, headline, error]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"message">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_message_attr_type(normal, _acc) -> _acc; -encode_message_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_message_attr_from(__TopXMLNS, undefined) -> - undefined; -decode_message_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"message">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_message_attr_from(undefined, _acc) -> _acc; -encode_message_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_message_attr_to(__TopXMLNS, undefined) -> - undefined; -decode_message_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"message">>, __TopXMLNS}}); - _res -> _res - end. - -encode_message_attr_to(undefined, _acc) -> _acc; -encode_message_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -'decode_message_attr_xml:lang'(__TopXMLNS, undefined) -> - <<>>; -'decode_message_attr_xml:lang'(__TopXMLNS, _val) -> - _val. - -'encode_message_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_message_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_message_thread(__TopXMLNS, __IgnoreEls, - {xmlel, <<"thread">>, _attrs, _els}) -> - Cdata = decode_message_thread_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_message_thread_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_message_thread_cdata(__TopXMLNS, Cdata); -decode_message_thread_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_message_thread_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_message_thread_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_message_thread_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_message_thread(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_message_thread_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"thread">>, _attrs, _els}. - -decode_message_thread_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_message_thread_cdata(__TopXMLNS, _val) -> _val. - -encode_message_thread_cdata(<<>>, _acc) -> _acc; -encode_message_thread_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_message_body(__TopXMLNS, __IgnoreEls, - {xmlel, <<"body">>, _attrs, _els}) -> - Data = decode_message_body_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Lang = decode_message_body_attrs(__TopXMLNS, _attrs, - undefined), - {text, Lang, Data}. - -decode_message_body_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_message_body_cdata(__TopXMLNS, Data); -decode_message_body_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_message_body_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_message_body_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_message_body_els(__TopXMLNS, __IgnoreEls, _els, - Data). - -decode_message_body_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_message_body_attrs(__TopXMLNS, _attrs, _val); -decode_message_body_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_message_body_attrs(__TopXMLNS, _attrs, Lang); -decode_message_body_attrs(__TopXMLNS, [], Lang) -> - 'decode_message_body_attr_xml:lang'(__TopXMLNS, Lang). - -encode_message_body({text, Lang, Data}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_message_body_cdata(Data, []), - _attrs = 'encode_message_body_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"body">>, _attrs, _els}. - -'decode_message_body_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_message_body_attr_xml:lang'(__TopXMLNS, _val) -> - _val. - -'encode_message_body_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_message_body_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_message_body_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_message_body_cdata(__TopXMLNS, _val) -> _val. - -encode_message_body_cdata(<<>>, _acc) -> _acc; -encode_message_body_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_message_subject(__TopXMLNS, __IgnoreEls, - {xmlel, <<"subject">>, _attrs, _els}) -> - Data = decode_message_subject_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Lang = decode_message_subject_attrs(__TopXMLNS, _attrs, - undefined), - {text, Lang, Data}. - -decode_message_subject_els(__TopXMLNS, __IgnoreEls, [], - Data) -> - decode_message_subject_cdata(__TopXMLNS, Data); -decode_message_subject_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Data) -> - decode_message_subject_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_message_subject_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Data) -> - decode_message_subject_els(__TopXMLNS, __IgnoreEls, - _els, Data). - -decode_message_subject_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], _Lang) -> - decode_message_subject_attrs(__TopXMLNS, _attrs, _val); -decode_message_subject_attrs(__TopXMLNS, [_ | _attrs], - Lang) -> - decode_message_subject_attrs(__TopXMLNS, _attrs, Lang); -decode_message_subject_attrs(__TopXMLNS, [], Lang) -> - 'decode_message_subject_attr_xml:lang'(__TopXMLNS, - Lang). - -encode_message_subject({text, Lang, Data}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = encode_message_subject_cdata(Data, []), - _attrs = 'encode_message_subject_attr_xml:lang'(Lang, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"subject">>, _attrs, _els}. - -'decode_message_subject_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_message_subject_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_message_subject_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_message_subject_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_message_subject_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_message_subject_cdata(__TopXMLNS, _val) -> _val. - -encode_message_subject_cdata(<<>>, _acc) -> _acc; -encode_message_subject_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_iq(__TopXMLNS, __IgnoreEls, - {xmlel, <<"iq">>, _attrs, _els}) -> - __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, __Els}. - -decode_iq_els(__TopXMLNS, __IgnoreEls, [], __Els) -> - lists:reverse(__Els); -decode_iq_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], __Els) -> - if __IgnoreEls -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, - [_el | __Els]); - true -> - case is_known_tag(_el, __TopXMLNS) of - true -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, - [decode(_el, __TopXMLNS, []) | __Els]); - false -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, __Els) - end - end; -decode_iq_els(__TopXMLNS, __IgnoreEls, [_ | _els], - __Els) -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, __Els). - -decode_iq_attrs(__TopXMLNS, [{<<"id">>, _val} | _attrs], - _Id, Type, From, To, Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, _val, Type, From, - To, Lang); -decode_iq_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Id, _Type, From, To, - Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, Id, _val, From, To, - Lang); -decode_iq_attrs(__TopXMLNS, - [{<<"from">>, _val} | _attrs], Id, Type, _From, To, - Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, _val, To, - Lang); -decode_iq_attrs(__TopXMLNS, [{<<"to">>, _val} | _attrs], - Id, Type, From, _To, Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, - _val, Lang); -decode_iq_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], Id, Type, From, To, - _Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, To, - _val); -decode_iq_attrs(__TopXMLNS, [_ | _attrs], Id, Type, - From, To, Lang) -> - decode_iq_attrs(__TopXMLNS, _attrs, Id, Type, From, To, - Lang); -decode_iq_attrs(__TopXMLNS, [], Id, Type, From, To, - Lang) -> - {decode_iq_attr_id(__TopXMLNS, Id), - decode_iq_attr_type(__TopXMLNS, Type), - decode_iq_attr_from(__TopXMLNS, From), - decode_iq_attr_to(__TopXMLNS, To), - 'decode_iq_attr_xml:lang'(__TopXMLNS, Lang)}. - -encode_iq({iq, Id, Type, Lang, From, To, __Els}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<>>, - [<<"jabber:client">>, <<"jabber:server">>, - <<"jabber:component:accept">>], - __TopXMLNS), - _els = [encode(_el, __NewTopXMLNS) || _el <- __Els], - _attrs = 'encode_iq_attr_xml:lang'(Lang, - encode_iq_attr_to(To, - encode_iq_attr_from(From, - encode_iq_attr_type(Type, - encode_iq_attr_id(Id, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))))), - {xmlel, <<"iq">>, _attrs, _els}. - -decode_iq_attr_id(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"id">>, <<"iq">>, __TopXMLNS}}); -decode_iq_attr_id(__TopXMLNS, _val) -> _val. - -encode_iq_attr_id(_val, _acc) -> - [{<<"id">>, _val} | _acc]. - -decode_iq_attr_type(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"iq">>, __TopXMLNS}}); -decode_iq_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, [get, set, result, error]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"iq">>, __TopXMLNS}}); - _res -> _res - end. - -encode_iq_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_iq_attr_from(__TopXMLNS, undefined) -> undefined; -decode_iq_attr_from(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"from">>, <<"iq">>, __TopXMLNS}}); - _res -> _res - end. - -encode_iq_attr_from(undefined, _acc) -> _acc; -encode_iq_attr_from(_val, _acc) -> - [{<<"from">>, enc_jid(_val)} | _acc]. - -decode_iq_attr_to(__TopXMLNS, undefined) -> undefined; -decode_iq_attr_to(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"to">>, <<"iq">>, __TopXMLNS}}); - _res -> _res - end. - -encode_iq_attr_to(undefined, _acc) -> _acc; -encode_iq_attr_to(_val, _acc) -> - [{<<"to">>, enc_jid(_val)} | _acc]. - -'decode_iq_attr_xml:lang'(__TopXMLNS, undefined) -> - <<>>; -'decode_iq_attr_xml:lang'(__TopXMLNS, _val) -> _val. - -'encode_iq_attr_xml:lang'(<<>>, _acc) -> _acc; -'encode_iq_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_stats(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - List = decode_stats_els(__TopXMLNS, __IgnoreEls, _els, - []), - Node = decode_stats_attrs(__TopXMLNS, _attrs, - undefined), - {stats, List, Node}. - -decode_stats_els(__TopXMLNS, __IgnoreEls, [], List) -> - lists:reverse(List); -decode_stats_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"stat">>, _attrs, _} = _el | _els], List) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/stats">> -> - decode_stats_els(__TopXMLNS, __IgnoreEls, _els, - [decode_stat(__TopXMLNS, __IgnoreEls, _el) | List]); - <<"http://jabber.org/protocol/stats">> -> - decode_stats_els(__TopXMLNS, __IgnoreEls, _els, - [decode_stat(<<"http://jabber.org/protocol/stats">>, - __IgnoreEls, _el) - | List]); - _ -> - decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List) - end; -decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els], - List) -> - decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List). - -decode_stats_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_stats_attrs(__TopXMLNS, _attrs, _val); -decode_stats_attrs(__TopXMLNS, [_ | _attrs], Node) -> - decode_stats_attrs(__TopXMLNS, _attrs, Node); -decode_stats_attrs(__TopXMLNS, [], Node) -> - decode_stats_attr_node(__TopXMLNS, Node). - -encode_stats({stats, List, Node}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, - [], __TopXMLNS), - _els = lists:reverse('encode_stats_$list'(List, - __NewTopXMLNS, [])), - _attrs = encode_stats_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_stats_$list'([], __TopXMLNS, _acc) -> _acc; -'encode_stats_$list'([List | _els], __TopXMLNS, _acc) -> - 'encode_stats_$list'(_els, __TopXMLNS, - [encode_stat(List, __TopXMLNS) | _acc]). - -decode_stats_attr_node(__TopXMLNS, undefined) -> <<>>; -decode_stats_attr_node(__TopXMLNS, _val) -> _val. - -encode_stats_attr_node(<<>>, _acc) -> _acc; -encode_stats_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_stat(__TopXMLNS, __IgnoreEls, - {xmlel, <<"stat">>, _attrs, _els}) -> - Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els, - undefined), - {Name, Units, Value} = decode_stat_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {stat, Name, Units, Value, Error}. - -decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) -> - Error; -decode_stat_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], - Error) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/stats">> -> - decode_stat_els(__TopXMLNS, __IgnoreEls, _els, - decode_stat_error(__TopXMLNS, __IgnoreEls, _el)); - <<"http://jabber.org/protocol/stats">> -> - decode_stat_els(__TopXMLNS, __IgnoreEls, _els, - decode_stat_error(<<"http://jabber.org/protocol/stats">>, - __IgnoreEls, _el)); - _ -> - decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error) - end; -decode_stat_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Error) -> - decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error). - -decode_stat_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name, Units, Value) -> - decode_stat_attrs(__TopXMLNS, _attrs, _val, Units, - Value); -decode_stat_attrs(__TopXMLNS, - [{<<"units">>, _val} | _attrs], Name, _Units, Value) -> - decode_stat_attrs(__TopXMLNS, _attrs, Name, _val, - Value); -decode_stat_attrs(__TopXMLNS, - [{<<"value">>, _val} | _attrs], Name, Units, _Value) -> - decode_stat_attrs(__TopXMLNS, _attrs, Name, Units, - _val); -decode_stat_attrs(__TopXMLNS, [_ | _attrs], Name, Units, - Value) -> - decode_stat_attrs(__TopXMLNS, _attrs, Name, Units, - Value); -decode_stat_attrs(__TopXMLNS, [], Name, Units, Value) -> - {decode_stat_attr_name(__TopXMLNS, Name), - decode_stat_attr_units(__TopXMLNS, Units), - decode_stat_attr_value(__TopXMLNS, Value)}. - -encode_stat({stat, Name, Units, Value, Error}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, - [], __TopXMLNS), - _els = lists:reverse('encode_stat_$error'(Error, - __NewTopXMLNS, [])), - _attrs = encode_stat_attr_value(Value, - encode_stat_attr_units(Units, - encode_stat_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"stat">>, _attrs, _els}. - -'encode_stat_$error'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_stat_$error'(Error, __TopXMLNS, _acc) -> - [encode_stat_error(Error, __TopXMLNS) | _acc]. - -decode_stat_attr_name(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"stat">>, __TopXMLNS}}); -decode_stat_attr_name(__TopXMLNS, _val) -> _val. - -encode_stat_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_stat_attr_units(__TopXMLNS, undefined) -> <<>>; -decode_stat_attr_units(__TopXMLNS, _val) -> _val. - -encode_stat_attr_units(<<>>, _acc) -> _acc; -encode_stat_attr_units(_val, _acc) -> - [{<<"units">>, _val} | _acc]. - -decode_stat_attr_value(__TopXMLNS, undefined) -> <<>>; -decode_stat_attr_value(__TopXMLNS, _val) -> _val. - -encode_stat_attr_value(<<>>, _acc) -> _acc; -encode_stat_attr_value(_val, _acc) -> - [{<<"value">>, _val} | _acc]. - -decode_stat_error(__TopXMLNS, __IgnoreEls, - {xmlel, <<"error">>, _attrs, _els}) -> - Reason = decode_stat_error_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Code = decode_stat_error_attrs(__TopXMLNS, _attrs, - undefined), - {stat_error, Code, Reason}. - -decode_stat_error_els(__TopXMLNS, __IgnoreEls, [], - Reason) -> - decode_stat_error_cdata(__TopXMLNS, Reason); -decode_stat_error_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Reason) -> - decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_stat_error_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Reason) -> - decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, - Reason). - -decode_stat_error_attrs(__TopXMLNS, - [{<<"code">>, _val} | _attrs], _Code) -> - decode_stat_error_attrs(__TopXMLNS, _attrs, _val); -decode_stat_error_attrs(__TopXMLNS, [_ | _attrs], - Code) -> - decode_stat_error_attrs(__TopXMLNS, _attrs, Code); -decode_stat_error_attrs(__TopXMLNS, [], Code) -> - decode_stat_error_attr_code(__TopXMLNS, Code). - -encode_stat_error({stat_error, Code, Reason}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/stats">>, - [], __TopXMLNS), - _els = encode_stat_error_cdata(Reason, []), - _attrs = encode_stat_error_attr_code(Code, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"error">>, _attrs, _els}. - -decode_stat_error_attr_code(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"code">>, <<"error">>, __TopXMLNS}}); -decode_stat_error_attr_code(__TopXMLNS, _val) -> - case catch dec_int(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"code">>, <<"error">>, __TopXMLNS}}); - _res -> _res - end. - -encode_stat_error_attr_code(_val, _acc) -> - [{<<"code">>, enc_int(_val)} | _acc]. - -decode_stat_error_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_stat_error_cdata(__TopXMLNS, _val) -> _val. - -encode_stat_error_cdata(<<>>, _acc) -> _acc; -encode_stat_error_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_bookmarks_storage(__TopXMLNS, __IgnoreEls, - {xmlel, <<"storage">>, _attrs, _els}) -> - {Conference, Url} = - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, [], []), - {bookmark_storage, Conference, Url}. - -decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - [], Conference, Url) -> - {lists:reverse(Conference), lists:reverse(Url)}; -decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"conference">>, _attrs, _} = _el - | _els], - Conference, Url) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_bookmark_conference(__TopXMLNS, - __IgnoreEls, - _el) - | Conference], - Url); - <<"storage:bookmarks">> -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, - [decode_bookmark_conference(<<"storage:bookmarks">>, - __IgnoreEls, - _el) - | Conference], - Url); - _ -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, Conference, Url) - end; -decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"url">>, _attrs, _} = _el | _els], - Conference, Url) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, Conference, - [decode_bookmark_url(__TopXMLNS, - __IgnoreEls, _el) - | Url]); - <<"storage:bookmarks">> -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, Conference, - [decode_bookmark_url(<<"storage:bookmarks">>, - __IgnoreEls, _el) - | Url]); - _ -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, Conference, Url) - end; -decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Conference, Url) -> - decode_bookmarks_storage_els(__TopXMLNS, __IgnoreEls, - _els, Conference, Url). - -encode_bookmarks_storage({bookmark_storage, Conference, - Url}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"storage:bookmarks">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_bookmarks_storage_$conference'(Conference, - __NewTopXMLNS, - 'encode_bookmarks_storage_$url'(Url, - __NewTopXMLNS, - []))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"storage">>, _attrs, _els}. - -'encode_bookmarks_storage_$conference'([], __TopXMLNS, - _acc) -> - _acc; -'encode_bookmarks_storage_$conference'([Conference - | _els], - __TopXMLNS, _acc) -> - 'encode_bookmarks_storage_$conference'(_els, __TopXMLNS, - [encode_bookmark_conference(Conference, - __TopXMLNS) - | _acc]). - -'encode_bookmarks_storage_$url'([], __TopXMLNS, _acc) -> - _acc; -'encode_bookmarks_storage_$url'([Url | _els], - __TopXMLNS, _acc) -> - 'encode_bookmarks_storage_$url'(_els, __TopXMLNS, - [encode_bookmark_url(Url, __TopXMLNS) - | _acc]). - -decode_bookmark_url(__TopXMLNS, __IgnoreEls, - {xmlel, <<"url">>, _attrs, _els}) -> - {Name, Url} = decode_bookmark_url_attrs(__TopXMLNS, - _attrs, undefined, undefined), - {bookmark_url, Name, Url}. - -decode_bookmark_url_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name, Url) -> - decode_bookmark_url_attrs(__TopXMLNS, _attrs, _val, - Url); -decode_bookmark_url_attrs(__TopXMLNS, - [{<<"url">>, _val} | _attrs], Name, _Url) -> - decode_bookmark_url_attrs(__TopXMLNS, _attrs, Name, - _val); -decode_bookmark_url_attrs(__TopXMLNS, [_ | _attrs], - Name, Url) -> - decode_bookmark_url_attrs(__TopXMLNS, _attrs, Name, - Url); -decode_bookmark_url_attrs(__TopXMLNS, [], Name, Url) -> - {decode_bookmark_url_attr_name(__TopXMLNS, Name), - decode_bookmark_url_attr_url(__TopXMLNS, Url)}. - -encode_bookmark_url({bookmark_url, Name, Url}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"storage:bookmarks">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_bookmark_url_attr_url(Url, - encode_bookmark_url_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))), - {xmlel, <<"url">>, _attrs, _els}. - -decode_bookmark_url_attr_name(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"url">>, __TopXMLNS}}); -decode_bookmark_url_attr_name(__TopXMLNS, _val) -> _val. - -encode_bookmark_url_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_bookmark_url_attr_url(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"url">>, <<"url">>, __TopXMLNS}}); -decode_bookmark_url_attr_url(__TopXMLNS, _val) -> _val. - -encode_bookmark_url_attr_url(_val, _acc) -> - [{<<"url">>, _val} | _acc]. - -decode_bookmark_conference(__TopXMLNS, __IgnoreEls, - {xmlel, <<"conference">>, _attrs, _els}) -> - {Password, Nick} = - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, undefined, undefined), - {Name, Jid, Autojoin} = - decode_bookmark_conference_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined), - {bookmark_conference, Name, Jid, Autojoin, Nick, - Password}. - -decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - [], Password, Nick) -> - {Password, Nick}; -decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"nick">>, _attrs, _} = _el | _els], - Password, Nick) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, Password, - decode_conference_nick(__TopXMLNS, - __IgnoreEls, - _el)); - <<"storage:bookmarks">> -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, Password, - decode_conference_nick(<<"storage:bookmarks">>, - __IgnoreEls, - _el)); - _ -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, Password, Nick) - end; -decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"password">>, _attrs, _} = _el - | _els], - Password, Nick) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"storage:bookmarks">> -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, - decode_conference_password(__TopXMLNS, - __IgnoreEls, - _el), - Nick); - <<"storage:bookmarks">> -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, - decode_conference_password(<<"storage:bookmarks">>, - __IgnoreEls, - _el), - Nick); - _ -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, Password, Nick) - end; -decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Password, Nick) -> - decode_bookmark_conference_els(__TopXMLNS, __IgnoreEls, - _els, Password, Nick). - -decode_bookmark_conference_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name, Jid, - Autojoin) -> - decode_bookmark_conference_attrs(__TopXMLNS, _attrs, - _val, Jid, Autojoin); -decode_bookmark_conference_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], Name, _Jid, - Autojoin) -> - decode_bookmark_conference_attrs(__TopXMLNS, _attrs, - Name, _val, Autojoin); -decode_bookmark_conference_attrs(__TopXMLNS, - [{<<"autojoin">>, _val} | _attrs], Name, Jid, - _Autojoin) -> - decode_bookmark_conference_attrs(__TopXMLNS, _attrs, - Name, Jid, _val); -decode_bookmark_conference_attrs(__TopXMLNS, - [_ | _attrs], Name, Jid, Autojoin) -> - decode_bookmark_conference_attrs(__TopXMLNS, _attrs, - Name, Jid, Autojoin); -decode_bookmark_conference_attrs(__TopXMLNS, [], Name, - Jid, Autojoin) -> - {decode_bookmark_conference_attr_name(__TopXMLNS, Name), - decode_bookmark_conference_attr_jid(__TopXMLNS, Jid), - decode_bookmark_conference_attr_autojoin(__TopXMLNS, - Autojoin)}. - -encode_bookmark_conference({bookmark_conference, Name, - Jid, Autojoin, Nick, Password}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"storage:bookmarks">>, [], - __TopXMLNS), - _els = - lists:reverse('encode_bookmark_conference_$password'(Password, - __NewTopXMLNS, - 'encode_bookmark_conference_$nick'(Nick, - __NewTopXMLNS, - []))), - _attrs = - encode_bookmark_conference_attr_autojoin(Autojoin, - encode_bookmark_conference_attr_jid(Jid, - encode_bookmark_conference_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"conference">>, _attrs, _els}. - -'encode_bookmark_conference_$password'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_bookmark_conference_$password'(Password, - __TopXMLNS, _acc) -> - [encode_conference_password(Password, __TopXMLNS) - | _acc]. - -'encode_bookmark_conference_$nick'(undefined, - __TopXMLNS, _acc) -> - _acc; -'encode_bookmark_conference_$nick'(Nick, __TopXMLNS, - _acc) -> - [encode_conference_nick(Nick, __TopXMLNS) | _acc]. - -decode_bookmark_conference_attr_name(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"conference">>, - __TopXMLNS}}); -decode_bookmark_conference_attr_name(__TopXMLNS, - _val) -> - _val. - -encode_bookmark_conference_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_bookmark_conference_attr_jid(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"conference">>, - __TopXMLNS}}); -decode_bookmark_conference_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"conference">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_bookmark_conference_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_bookmark_conference_attr_autojoin(__TopXMLNS, - undefined) -> - false; -decode_bookmark_conference_attr_autojoin(__TopXMLNS, - _val) -> - case catch dec_bool(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"autojoin">>, <<"conference">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_bookmark_conference_attr_autojoin(false, _acc) -> - _acc; -encode_bookmark_conference_attr_autojoin(_val, _acc) -> - [{<<"autojoin">>, enc_bool(_val)} | _acc]. - -decode_conference_password(__TopXMLNS, __IgnoreEls, - {xmlel, <<"password">>, _attrs, _els}) -> - Cdata = decode_conference_password_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_conference_password_els(__TopXMLNS, __IgnoreEls, - [], Cdata) -> - decode_conference_password_cdata(__TopXMLNS, Cdata); -decode_conference_password_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_conference_password_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_conference_password_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_conference_password_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_conference_password(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"storage:bookmarks">>, [], - __TopXMLNS), - _els = encode_conference_password_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"password">>, _attrs, _els}. - -decode_conference_password_cdata(__TopXMLNS, <<>>) -> - <<>>; -decode_conference_password_cdata(__TopXMLNS, _val) -> - _val. - -encode_conference_password_cdata(<<>>, _acc) -> _acc; -encode_conference_password_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_conference_nick(__TopXMLNS, __IgnoreEls, - {xmlel, <<"nick">>, _attrs, _els}) -> - Cdata = decode_conference_nick_els(__TopXMLNS, - __IgnoreEls, _els, <<>>), - Cdata. - -decode_conference_nick_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_conference_nick_cdata(__TopXMLNS, Cdata); -decode_conference_nick_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_conference_nick_els(__TopXMLNS, __IgnoreEls, - _els, <>); -decode_conference_nick_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_conference_nick_els(__TopXMLNS, __IgnoreEls, - _els, Cdata). - -encode_conference_nick(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"storage:bookmarks">>, [], - __TopXMLNS), - _els = encode_conference_nick_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"nick">>, _attrs, _els}. - -decode_conference_nick_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_conference_nick_cdata(__TopXMLNS, _val) -> _val. - -encode_conference_nick_cdata(<<>>, _acc) -> _acc; -encode_conference_nick_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_private(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - __Xmls = decode_private_els(__TopXMLNS, __IgnoreEls, - _els, []), - {private, __Xmls}. - -decode_private_els(__TopXMLNS, __IgnoreEls, [], - __Xmls) -> - lists:reverse(__Xmls); -decode_private_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], __Xmls) -> - decode_private_els(__TopXMLNS, __IgnoreEls, _els, - [_el | __Xmls]); -decode_private_els(__TopXMLNS, __IgnoreEls, [_ | _els], - __Xmls) -> - decode_private_els(__TopXMLNS, __IgnoreEls, _els, - __Xmls). - -encode_private({private, __Xmls}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:private">>, [], - __TopXMLNS), - _els = __Xmls, - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -decode_disco_items(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Items, Rsm} = decode_disco_items_els(__TopXMLNS, - __IgnoreEls, _els, [], undefined), - Node = decode_disco_items_attrs(__TopXMLNS, _attrs, - undefined), - {disco_items, Node, Items, Rsm}. - -decode_disco_items_els(__TopXMLNS, __IgnoreEls, [], - Items, Rsm) -> - {lists:reverse(Items), Rsm}; -decode_disco_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items, - Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/disco#items">> -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - [decode_disco_item(__TopXMLNS, __IgnoreEls, - _el) - | Items], - Rsm); - <<"http://jabber.org/protocol/disco#items">> -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - [decode_disco_item(<<"http://jabber.org/protocol/disco#items">>, - __IgnoreEls, _el) - | Items], - Rsm); - _ -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Rsm) - end; -decode_disco_items_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"set">>, _attrs, _} = _el | _els], Items, - Rsm) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"http://jabber.org/protocol/rsm">> -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, - decode_rsm_set(<<"http://jabber.org/protocol/rsm">>, - __IgnoreEls, _el)); - _ -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Rsm) - end; -decode_disco_items_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items, Rsm) -> - decode_disco_items_els(__TopXMLNS, __IgnoreEls, _els, - Items, Rsm). - -decode_disco_items_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_disco_items_attrs(__TopXMLNS, _attrs, _val); -decode_disco_items_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_disco_items_attrs(__TopXMLNS, _attrs, Node); -decode_disco_items_attrs(__TopXMLNS, [], Node) -> - decode_disco_items_attr_node(__TopXMLNS, Node). - -encode_disco_items({disco_items, Node, Items, Rsm}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/disco#items">>, - [], __TopXMLNS), - _els = lists:reverse('encode_disco_items_$items'(Items, - __NewTopXMLNS, - 'encode_disco_items_$rsm'(Rsm, - __NewTopXMLNS, - []))), - _attrs = encode_disco_items_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_disco_items_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_disco_items_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_disco_items_$items'(_els, __TopXMLNS, - [encode_disco_item(Items, __TopXMLNS) | _acc]). - -'encode_disco_items_$rsm'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_disco_items_$rsm'(Rsm, __TopXMLNS, _acc) -> - [encode_rsm_set(Rsm, __TopXMLNS) | _acc]. - -decode_disco_items_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_disco_items_attr_node(__TopXMLNS, _val) -> _val. - -encode_disco_items_attr_node(<<>>, _acc) -> _acc; -encode_disco_items_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_disco_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Jid, Name, Node} = decode_disco_item_attrs(__TopXMLNS, - _attrs, undefined, undefined, - undefined), - {disco_item, Jid, Name, Node}. - -decode_disco_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Name, Node) -> - decode_disco_item_attrs(__TopXMLNS, _attrs, _val, Name, - Node); -decode_disco_item_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], Jid, _Name, Node) -> - decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, _val, - Node); -decode_disco_item_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], Jid, Name, _Node) -> - decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, Name, - _val); -decode_disco_item_attrs(__TopXMLNS, [_ | _attrs], Jid, - Name, Node) -> - decode_disco_item_attrs(__TopXMLNS, _attrs, Jid, Name, - Node); -decode_disco_item_attrs(__TopXMLNS, [], Jid, Name, - Node) -> - {decode_disco_item_attr_jid(__TopXMLNS, Jid), - decode_disco_item_attr_name(__TopXMLNS, Name), - decode_disco_item_attr_node(__TopXMLNS, Node)}. - -encode_disco_item({disco_item, Jid, Name, Node}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/disco#items">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_disco_item_attr_node(Node, - encode_disco_item_attr_name(Name, - encode_disco_item_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)))), - {xmlel, <<"item">>, _attrs, _els}. - -decode_disco_item_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); -decode_disco_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_disco_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_disco_item_attr_name(__TopXMLNS, undefined) -> - <<>>; -decode_disco_item_attr_name(__TopXMLNS, _val) -> _val. - -encode_disco_item_attr_name(<<>>, _acc) -> _acc; -encode_disco_item_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_disco_item_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_disco_item_attr_node(__TopXMLNS, _val) -> _val. - -encode_disco_item_attr_node(<<>>, _acc) -> _acc; -encode_disco_item_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_disco_info(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Xdata, Features, Identities} = - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, [], - [], []), - Node = decode_disco_info_attrs(__TopXMLNS, _attrs, - undefined), - {disco_info, Node, Identities, Features, Xdata}. - -decode_disco_info_els(__TopXMLNS, __IgnoreEls, [], - Xdata, Features, Identities) -> - {lists:reverse(Xdata), lists:reverse(Features), - lists:reverse(Identities)}; -decode_disco_info_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"identity">>, _attrs, _} = _el | _els], - Xdata, Features, Identities) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/disco#info">> -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, - [decode_disco_identity(__TopXMLNS, __IgnoreEls, - _el) - | Identities]); - <<"http://jabber.org/protocol/disco#info">> -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, - [decode_disco_identity(<<"http://jabber.org/protocol/disco#info">>, - __IgnoreEls, _el) - | Identities]); - _ -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, Identities) - end; -decode_disco_info_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"feature">>, _attrs, _} = _el | _els], Xdata, - Features, Identities) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> - when __TopXMLNS == - <<"http://jabber.org/protocol/disco#info">> -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - [decode_disco_feature(__TopXMLNS, __IgnoreEls, - _el) - | Features], - Identities); - <<"http://jabber.org/protocol/disco#info">> -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, - [decode_disco_feature(<<"http://jabber.org/protocol/disco#info">>, - __IgnoreEls, _el) - | Features], - Identities); - _ -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, Identities) - end; -decode_disco_info_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, - Features, Identities) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"jabber:x:data">> -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - [decode_xdata(<<"jabber:x:data">>, __IgnoreEls, - _el) - | Xdata], - Features, Identities); - _ -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, Identities) - end; -decode_disco_info_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Xdata, Features, Identities) -> - decode_disco_info_els(__TopXMLNS, __IgnoreEls, _els, - Xdata, Features, Identities). - -decode_disco_info_attrs(__TopXMLNS, - [{<<"node">>, _val} | _attrs], _Node) -> - decode_disco_info_attrs(__TopXMLNS, _attrs, _val); -decode_disco_info_attrs(__TopXMLNS, [_ | _attrs], - Node) -> - decode_disco_info_attrs(__TopXMLNS, _attrs, Node); -decode_disco_info_attrs(__TopXMLNS, [], Node) -> - decode_disco_info_attr_node(__TopXMLNS, Node). - -encode_disco_info({disco_info, Node, Identities, - Features, Xdata}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, - [], __TopXMLNS), - _els = lists:reverse('encode_disco_info_$xdata'(Xdata, - __NewTopXMLNS, - 'encode_disco_info_$features'(Features, - __NewTopXMLNS, - 'encode_disco_info_$identities'(Identities, - __NewTopXMLNS, - [])))), - _attrs = encode_disco_info_attr_node(Node, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_disco_info_$xdata'([], __TopXMLNS, _acc) -> - _acc; -'encode_disco_info_$xdata'([Xdata | _els], __TopXMLNS, - _acc) -> - 'encode_disco_info_$xdata'(_els, __TopXMLNS, - [encode_xdata(Xdata, __TopXMLNS) | _acc]). - -'encode_disco_info_$features'([], __TopXMLNS, _acc) -> - _acc; -'encode_disco_info_$features'([Features | _els], - __TopXMLNS, _acc) -> - 'encode_disco_info_$features'(_els, __TopXMLNS, - [encode_disco_feature(Features, __TopXMLNS) - | _acc]). - -'encode_disco_info_$identities'([], __TopXMLNS, _acc) -> - _acc; -'encode_disco_info_$identities'([Identities | _els], - __TopXMLNS, _acc) -> - 'encode_disco_info_$identities'(_els, __TopXMLNS, - [encode_disco_identity(Identities, - __TopXMLNS) - | _acc]). - -decode_disco_info_attr_node(__TopXMLNS, undefined) -> - <<>>; -decode_disco_info_attr_node(__TopXMLNS, _val) -> _val. - -encode_disco_info_attr_node(<<>>, _acc) -> _acc; -encode_disco_info_attr_node(_val, _acc) -> - [{<<"node">>, _val} | _acc]. - -decode_disco_feature(__TopXMLNS, __IgnoreEls, - {xmlel, <<"feature">>, _attrs, _els}) -> - Var = decode_disco_feature_attrs(__TopXMLNS, _attrs, - undefined), - Var. - -decode_disco_feature_attrs(__TopXMLNS, - [{<<"var">>, _val} | _attrs], _Var) -> - decode_disco_feature_attrs(__TopXMLNS, _attrs, _val); -decode_disco_feature_attrs(__TopXMLNS, [_ | _attrs], - Var) -> - decode_disco_feature_attrs(__TopXMLNS, _attrs, Var); -decode_disco_feature_attrs(__TopXMLNS, [], Var) -> - decode_disco_feature_attr_var(__TopXMLNS, Var). - -encode_disco_feature(Var, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_disco_feature_attr_var(Var, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"feature">>, _attrs, _els}. - -decode_disco_feature_attr_var(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"var">>, <<"feature">>, __TopXMLNS}}); -decode_disco_feature_attr_var(__TopXMLNS, _val) -> _val. - -encode_disco_feature_attr_var(_val, _acc) -> - [{<<"var">>, _val} | _acc]. - -decode_disco_identity(__TopXMLNS, __IgnoreEls, - {xmlel, <<"identity">>, _attrs, _els}) -> - {Category, Type, Lang, Name} = - decode_disco_identity_attrs(__TopXMLNS, _attrs, - undefined, undefined, undefined, undefined), - {identity, Category, Type, Lang, Name}. - -decode_disco_identity_attrs(__TopXMLNS, - [{<<"category">>, _val} | _attrs], _Category, Type, - Lang, Name) -> - decode_disco_identity_attrs(__TopXMLNS, _attrs, _val, - Type, Lang, Name); -decode_disco_identity_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Category, _Type, - Lang, Name) -> - decode_disco_identity_attrs(__TopXMLNS, _attrs, - Category, _val, Lang, Name); -decode_disco_identity_attrs(__TopXMLNS, - [{<<"xml:lang">>, _val} | _attrs], Category, Type, - _Lang, Name) -> - decode_disco_identity_attrs(__TopXMLNS, _attrs, - Category, Type, _val, Name); -decode_disco_identity_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], Category, Type, Lang, - _Name) -> - decode_disco_identity_attrs(__TopXMLNS, _attrs, - Category, Type, Lang, _val); -decode_disco_identity_attrs(__TopXMLNS, [_ | _attrs], - Category, Type, Lang, Name) -> - decode_disco_identity_attrs(__TopXMLNS, _attrs, - Category, Type, Lang, Name); -decode_disco_identity_attrs(__TopXMLNS, [], Category, - Type, Lang, Name) -> - {decode_disco_identity_attr_category(__TopXMLNS, - Category), - decode_disco_identity_attr_type(__TopXMLNS, Type), - 'decode_disco_identity_attr_xml:lang'(__TopXMLNS, Lang), - decode_disco_identity_attr_name(__TopXMLNS, Name)}. - -encode_disco_identity({identity, Category, Type, Lang, - Name}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"http://jabber.org/protocol/disco#info">>, - [], __TopXMLNS), - _els = [], - _attrs = encode_disco_identity_attr_name(Name, - 'encode_disco_identity_attr_xml:lang'(Lang, - encode_disco_identity_attr_type(Type, - encode_disco_identity_attr_category(Category, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"identity">>, _attrs, _els}. - -decode_disco_identity_attr_category(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"category">>, <<"identity">>, - __TopXMLNS}}); -decode_disco_identity_attr_category(__TopXMLNS, _val) -> - _val. - -encode_disco_identity_attr_category(_val, _acc) -> - [{<<"category">>, _val} | _acc]. - -decode_disco_identity_attr_type(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"type">>, <<"identity">>, - __TopXMLNS}}); -decode_disco_identity_attr_type(__TopXMLNS, _val) -> - _val. - -encode_disco_identity_attr_type(_val, _acc) -> - [{<<"type">>, _val} | _acc]. - -'decode_disco_identity_attr_xml:lang'(__TopXMLNS, - undefined) -> - <<>>; -'decode_disco_identity_attr_xml:lang'(__TopXMLNS, - _val) -> - _val. - -'encode_disco_identity_attr_xml:lang'(<<>>, _acc) -> - _acc; -'encode_disco_identity_attr_xml:lang'(_val, _acc) -> - [{<<"xml:lang">>, _val} | _acc]. - -decode_disco_identity_attr_name(__TopXMLNS, - undefined) -> - <<>>; -decode_disco_identity_attr_name(__TopXMLNS, _val) -> - _val. - -encode_disco_identity_attr_name(<<>>, _acc) -> _acc; -encode_disco_identity_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_block_list(__TopXMLNS, __IgnoreEls, - {xmlel, <<"blocklist">>, _attrs, _els}) -> - Items = decode_block_list_els(__TopXMLNS, __IgnoreEls, - _els, []), - {block_list, Items}. - -decode_block_list_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_block_list_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> - decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(__TopXMLNS, __IgnoreEls, _el) - | Items]); - <<"urn:xmpp:blocking">> -> - decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(<<"urn:xmpp:blocking">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_block_list_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_block_list_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -encode_block_list({block_list, Items}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:blocking">>, [], - __TopXMLNS), - _els = lists:reverse('encode_block_list_$items'(Items, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"blocklist">>, _attrs, _els}. - -'encode_block_list_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_block_list_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_block_list_$items'(_els, __TopXMLNS, - [encode_block_item(Items, __TopXMLNS) | _acc]). - -decode_unblock(__TopXMLNS, __IgnoreEls, - {xmlel, <<"unblock">>, _attrs, _els}) -> - Items = decode_unblock_els(__TopXMLNS, __IgnoreEls, - _els, []), - {unblock, Items}. - -decode_unblock_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_unblock_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> - decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(__TopXMLNS, __IgnoreEls, _el) - | Items]); - <<"urn:xmpp:blocking">> -> - decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(<<"urn:xmpp:blocking">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, Items) - end; -decode_unblock_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Items) -> - decode_unblock_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -encode_unblock({unblock, Items}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:blocking">>, [], - __TopXMLNS), - _els = lists:reverse('encode_unblock_$items'(Items, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"unblock">>, _attrs, _els}. - -'encode_unblock_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_unblock_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_unblock_$items'(_els, __TopXMLNS, - [encode_block_item(Items, __TopXMLNS) | _acc]). - -decode_block(__TopXMLNS, __IgnoreEls, - {xmlel, <<"block">>, _attrs, _els}) -> - Items = decode_block_els(__TopXMLNS, __IgnoreEls, _els, - []), - {block, Items}. - -decode_block_els(__TopXMLNS, __IgnoreEls, [], Items) -> - lists:reverse(Items); -decode_block_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"urn:xmpp:blocking">> -> - decode_block_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(__TopXMLNS, __IgnoreEls, _el) - | Items]); - <<"urn:xmpp:blocking">> -> - decode_block_els(__TopXMLNS, __IgnoreEls, _els, - [decode_block_item(<<"urn:xmpp:blocking">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items) - end; -decode_block_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Items) -> - decode_block_els(__TopXMLNS, __IgnoreEls, _els, Items). - -encode_block({block, Items}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:blocking">>, [], - __TopXMLNS), - _els = lists:reverse('encode_block_$items'(Items, - __NewTopXMLNS, [])), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"block">>, _attrs, _els}. - -'encode_block_$items'([], __TopXMLNS, _acc) -> _acc; -'encode_block_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_block_$items'(_els, __TopXMLNS, - [encode_block_item(Items, __TopXMLNS) | _acc]). - -decode_block_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - Jid = decode_block_item_attrs(__TopXMLNS, _attrs, - undefined), - Jid. - -decode_block_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid) -> - decode_block_item_attrs(__TopXMLNS, _attrs, _val); -decode_block_item_attrs(__TopXMLNS, [_ | _attrs], - Jid) -> - decode_block_item_attrs(__TopXMLNS, _attrs, Jid); -decode_block_item_attrs(__TopXMLNS, [], Jid) -> - decode_block_item_attr_jid(__TopXMLNS, Jid). - -encode_block_item(Jid, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:blocking">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_block_item_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"item">>, _attrs, _els}. - -decode_block_item_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); -decode_block_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_block_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_privacy(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Lists, Default, Active} = - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, [], - undefined, undefined), - {privacy_query, Lists, Default, Active}. - -decode_privacy_els(__TopXMLNS, __IgnoreEls, [], Lists, - Default, Active) -> - {lists:reverse(Lists), Default, Active}; -decode_privacy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"list">>, _attrs, _} = _el | _els], Lists, - Default, Active) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privacy_list(__TopXMLNS, __IgnoreEls, _el) - | Lists], - Default, Active); - <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privacy_list(<<"jabber:iq:privacy">>, - __IgnoreEls, _el) - | Lists], - Default, Active); - _ -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, Active) - end; -decode_privacy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"default">>, _attrs, _} = _el | _els], Lists, - Default, Active) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - decode_privacy_default_list(__TopXMLNS, - __IgnoreEls, _el), - Active); - <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - decode_privacy_default_list(<<"jabber:iq:privacy">>, - __IgnoreEls, _el), - Active); - _ -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, Active) - end; -decode_privacy_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"active">>, _attrs, _} = _el | _els], Lists, - Default, Active) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, - decode_privacy_active_list(__TopXMLNS, __IgnoreEls, - _el)); - <<"jabber:iq:privacy">> -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, - decode_privacy_active_list(<<"jabber:iq:privacy">>, - __IgnoreEls, _el)); - _ -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, Active) - end; -decode_privacy_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Lists, Default, Active) -> - decode_privacy_els(__TopXMLNS, __IgnoreEls, _els, Lists, - Default, Active). - -encode_privacy({privacy_query, Lists, Default, Active}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = lists:reverse('encode_privacy_$lists'(Lists, - __NewTopXMLNS, - 'encode_privacy_$default'(Default, - __NewTopXMLNS, - 'encode_privacy_$active'(Active, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_privacy_$lists'([], __TopXMLNS, _acc) -> _acc; -'encode_privacy_$lists'([Lists | _els], __TopXMLNS, - _acc) -> - 'encode_privacy_$lists'(_els, __TopXMLNS, - [encode_privacy_list(Lists, __TopXMLNS) | _acc]). - -'encode_privacy_$default'(undefined, __TopXMLNS, - _acc) -> - _acc; -'encode_privacy_$default'(Default, __TopXMLNS, _acc) -> - [encode_privacy_default_list(Default, __TopXMLNS) - | _acc]. - -'encode_privacy_$active'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_privacy_$active'(Active, __TopXMLNS, _acc) -> - [encode_privacy_active_list(Active, __TopXMLNS) | _acc]. - -decode_privacy_active_list(__TopXMLNS, __IgnoreEls, - {xmlel, <<"active">>, _attrs, _els}) -> - Name = decode_privacy_active_list_attrs(__TopXMLNS, - _attrs, undefined), - Name. - -decode_privacy_active_list_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_privacy_active_list_attrs(__TopXMLNS, _attrs, - _val); -decode_privacy_active_list_attrs(__TopXMLNS, - [_ | _attrs], Name) -> - decode_privacy_active_list_attrs(__TopXMLNS, _attrs, - Name); -decode_privacy_active_list_attrs(__TopXMLNS, [], - Name) -> - decode_privacy_active_list_attr_name(__TopXMLNS, Name). - -encode_privacy_active_list(Name, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_privacy_active_list_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"active">>, _attrs, _els}. - -decode_privacy_active_list_attr_name(__TopXMLNS, - undefined) -> - none; -decode_privacy_active_list_attr_name(__TopXMLNS, - _val) -> - _val. - -encode_privacy_active_list_attr_name(none, _acc) -> - _acc; -encode_privacy_active_list_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_privacy_default_list(__TopXMLNS, __IgnoreEls, - {xmlel, <<"default">>, _attrs, _els}) -> - Name = decode_privacy_default_list_attrs(__TopXMLNS, - _attrs, undefined), - Name. - -decode_privacy_default_list_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_privacy_default_list_attrs(__TopXMLNS, _attrs, - _val); -decode_privacy_default_list_attrs(__TopXMLNS, - [_ | _attrs], Name) -> - decode_privacy_default_list_attrs(__TopXMLNS, _attrs, - Name); -decode_privacy_default_list_attrs(__TopXMLNS, [], - Name) -> - decode_privacy_default_list_attr_name(__TopXMLNS, Name). - -encode_privacy_default_list(Name, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = encode_privacy_default_list_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"default">>, _attrs, _els}. - -decode_privacy_default_list_attr_name(__TopXMLNS, - undefined) -> - none; -decode_privacy_default_list_attr_name(__TopXMLNS, - _val) -> - _val. - -encode_privacy_default_list_attr_name(none, _acc) -> - _acc; -encode_privacy_default_list_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_privacy_list(__TopXMLNS, __IgnoreEls, - {xmlel, <<"list">>, _attrs, _els}) -> - Items = decode_privacy_list_els(__TopXMLNS, __IgnoreEls, - _els, []), - Name = decode_privacy_list_attrs(__TopXMLNS, _attrs, - undefined), - {privacy_list, Name, Items}. - -decode_privacy_list_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_privacy_list_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privacy_item(__TopXMLNS, __IgnoreEls, - _el) - | Items]); - <<"jabber:iq:privacy">> -> - decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, - [decode_privacy_item(<<"jabber:iq:privacy">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_privacy_list_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_privacy_list_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -decode_privacy_list_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], _Name) -> - decode_privacy_list_attrs(__TopXMLNS, _attrs, _val); -decode_privacy_list_attrs(__TopXMLNS, [_ | _attrs], - Name) -> - decode_privacy_list_attrs(__TopXMLNS, _attrs, Name); -decode_privacy_list_attrs(__TopXMLNS, [], Name) -> - decode_privacy_list_attr_name(__TopXMLNS, Name). - -encode_privacy_list({privacy_list, Name, Items}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = lists:reverse('encode_privacy_list_$items'(Items, - __NewTopXMLNS, [])), - _attrs = encode_privacy_list_attr_name(Name, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"list">>, _attrs, _els}. - -'encode_privacy_list_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_privacy_list_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_privacy_list_$items'(_els, __TopXMLNS, - [encode_privacy_item(Items, __TopXMLNS) - | _acc]). - -decode_privacy_list_attr_name(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"name">>, <<"list">>, __TopXMLNS}}); -decode_privacy_list_attr_name(__TopXMLNS, _val) -> _val. - -encode_privacy_list_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_privacy_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - {Iq, Presence_out, Message, Presence_in} = - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - false, false, false, false), - {Action, Order, Type, Value} = - decode_privacy_item_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {privacy_item, Order, Action, Type, Value, Message, Iq, - Presence_in, Presence_out}. - -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, [], Iq, - Presence_out, Message, Presence_in) -> - {Iq, Presence_out, Message, Presence_in}; -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"message">>, _attrs, _} = _el | _els], Iq, - Presence_out, Message, Presence_in) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, - decode_privacy_message(__TopXMLNS, - __IgnoreEls, _el), - Presence_in); - <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, - decode_privacy_message(<<"jabber:iq:privacy">>, - __IgnoreEls, _el), - Presence_in); - _ -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, Presence_in) - end; -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"iq">>, _attrs, _} = _el | _els], Iq, - Presence_out, Message, Presence_in) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_privacy_iq(__TopXMLNS, __IgnoreEls, - _el), - Presence_out, Message, Presence_in); - <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - decode_privacy_iq(<<"jabber:iq:privacy">>, - __IgnoreEls, _el), - Presence_out, Message, Presence_in); - _ -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, Presence_in) - end; -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"presence-in">>, _attrs, _} = _el | _els], - Iq, Presence_out, Message, Presence_in) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, - decode_privacy_presence_in(__TopXMLNS, - __IgnoreEls, _el)); - <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, - decode_privacy_presence_in(<<"jabber:iq:privacy">>, - __IgnoreEls, _el)); - _ -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, Presence_in) - end; -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"presence-out">>, _attrs, _} = _el | _els], - Iq, Presence_out, Message, Presence_in) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, - decode_privacy_presence_out(__TopXMLNS, - __IgnoreEls, _el), - Message, Presence_in); - <<"jabber:iq:privacy">> -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, - decode_privacy_presence_out(<<"jabber:iq:privacy">>, - __IgnoreEls, _el), - Message, Presence_in); - _ -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, Presence_in) - end; -decode_privacy_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Iq, Presence_out, Message, Presence_in) -> - decode_privacy_item_els(__TopXMLNS, __IgnoreEls, _els, - Iq, Presence_out, Message, Presence_in). - -decode_privacy_item_attrs(__TopXMLNS, - [{<<"action">>, _val} | _attrs], _Action, Order, Type, - Value) -> - decode_privacy_item_attrs(__TopXMLNS, _attrs, _val, - Order, Type, Value); -decode_privacy_item_attrs(__TopXMLNS, - [{<<"order">>, _val} | _attrs], Action, _Order, Type, - Value) -> - decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, - _val, Type, Value); -decode_privacy_item_attrs(__TopXMLNS, - [{<<"type">>, _val} | _attrs], Action, Order, _Type, - Value) -> - decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, - Order, _val, Value); -decode_privacy_item_attrs(__TopXMLNS, - [{<<"value">>, _val} | _attrs], Action, Order, Type, - _Value) -> - decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, - Order, Type, _val); -decode_privacy_item_attrs(__TopXMLNS, [_ | _attrs], - Action, Order, Type, Value) -> - decode_privacy_item_attrs(__TopXMLNS, _attrs, Action, - Order, Type, Value); -decode_privacy_item_attrs(__TopXMLNS, [], Action, Order, - Type, Value) -> - {decode_privacy_item_attr_action(__TopXMLNS, Action), - decode_privacy_item_attr_order(__TopXMLNS, Order), - decode_privacy_item_attr_type(__TopXMLNS, Type), - decode_privacy_item_attr_value(__TopXMLNS, Value)}. - -encode_privacy_item({privacy_item, Order, Action, Type, - Value, Message, Iq, Presence_in, Presence_out}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = lists:reverse('encode_privacy_item_$iq'(Iq, - __NewTopXMLNS, - 'encode_privacy_item_$presence_out'(Presence_out, - __NewTopXMLNS, - 'encode_privacy_item_$message'(Message, - __NewTopXMLNS, - 'encode_privacy_item_$presence_in'(Presence_in, - __NewTopXMLNS, - []))))), - _attrs = encode_privacy_item_attr_value(Value, - encode_privacy_item_attr_type(Type, - encode_privacy_item_attr_order(Order, - encode_privacy_item_attr_action(Action, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_privacy_item_$iq'(false, __TopXMLNS, _acc) -> - _acc; -'encode_privacy_item_$iq'(Iq, __TopXMLNS, _acc) -> - [encode_privacy_iq(Iq, __TopXMLNS) | _acc]. - -'encode_privacy_item_$presence_out'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_privacy_item_$presence_out'(Presence_out, - __TopXMLNS, _acc) -> - [encode_privacy_presence_out(Presence_out, __TopXMLNS) - | _acc]. - -'encode_privacy_item_$message'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_privacy_item_$message'(Message, __TopXMLNS, - _acc) -> - [encode_privacy_message(Message, __TopXMLNS) | _acc]. - -'encode_privacy_item_$presence_in'(false, __TopXMLNS, - _acc) -> - _acc; -'encode_privacy_item_$presence_in'(Presence_in, - __TopXMLNS, _acc) -> - [encode_privacy_presence_in(Presence_in, __TopXMLNS) - | _acc]. - -decode_privacy_item_attr_action(__TopXMLNS, - undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"action">>, <<"item">>, __TopXMLNS}}); -decode_privacy_item_attr_action(__TopXMLNS, _val) -> - case catch dec_enum(_val, [allow, deny]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"action">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_privacy_item_attr_action(_val, _acc) -> - [{<<"action">>, enc_enum(_val)} | _acc]. - -decode_privacy_item_attr_order(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"order">>, <<"item">>, __TopXMLNS}}); -decode_privacy_item_attr_order(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"order">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_privacy_item_attr_order(_val, _acc) -> - [{<<"order">>, enc_int(_val)} | _acc]. - -decode_privacy_item_attr_type(__TopXMLNS, undefined) -> - undefined; -decode_privacy_item_attr_type(__TopXMLNS, _val) -> - case catch dec_enum(_val, [group, jid, subscription]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"type">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_privacy_item_attr_type(undefined, _acc) -> _acc; -encode_privacy_item_attr_type(_val, _acc) -> - [{<<"type">>, enc_enum(_val)} | _acc]. - -decode_privacy_item_attr_value(__TopXMLNS, undefined) -> - <<>>; -decode_privacy_item_attr_value(__TopXMLNS, _val) -> - _val. - -encode_privacy_item_attr_value(<<>>, _acc) -> _acc; -encode_privacy_item_attr_value(_val, _acc) -> - [{<<"value">>, _val} | _acc]. - -decode_privacy_presence_out(__TopXMLNS, __IgnoreEls, - {xmlel, <<"presence-out">>, _attrs, _els}) -> - true. - -encode_privacy_presence_out(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"presence-out">>, _attrs, _els}. - -decode_privacy_presence_in(__TopXMLNS, __IgnoreEls, - {xmlel, <<"presence-in">>, _attrs, _els}) -> - true. - -encode_privacy_presence_in(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"presence-in">>, _attrs, _els}. - -decode_privacy_iq(__TopXMLNS, __IgnoreEls, - {xmlel, <<"iq">>, _attrs, _els}) -> - true. - -encode_privacy_iq(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"iq">>, _attrs, _els}. - -decode_privacy_message(__TopXMLNS, __IgnoreEls, - {xmlel, <<"message">>, _attrs, _els}) -> - true. - -encode_privacy_message(true, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:privacy">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"message">>, _attrs, _els}. - -decode_rosterver_feature(__TopXMLNS, __IgnoreEls, - {xmlel, <<"ver">>, _attrs, _els}) -> - {rosterver_feature}. - -encode_rosterver_feature({rosterver_feature}, - __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"urn:xmpp:features:rosterver">>, [], - __TopXMLNS), - _els = [], - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"ver">>, _attrs, _els}. - -decode_roster_query(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - Items = decode_roster_query_els(__TopXMLNS, __IgnoreEls, - _els, []), - Ver = decode_roster_query_attrs(__TopXMLNS, _attrs, - undefined), - {roster_query, Items, Ver}. - -decode_roster_query_els(__TopXMLNS, __IgnoreEls, [], - Items) -> - lists:reverse(Items); -decode_roster_query_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"item">>, _attrs, _} = _el | _els], Items) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:roster">> -> - decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, - [decode_roster_item(__TopXMLNS, __IgnoreEls, - _el) - | Items]); - <<"jabber:iq:roster">> -> - decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, - [decode_roster_item(<<"jabber:iq:roster">>, - __IgnoreEls, _el) - | Items]); - _ -> - decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, - Items) - end; -decode_roster_query_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Items) -> - decode_roster_query_els(__TopXMLNS, __IgnoreEls, _els, - Items). - -decode_roster_query_attrs(__TopXMLNS, - [{<<"ver">>, _val} | _attrs], _Ver) -> - decode_roster_query_attrs(__TopXMLNS, _attrs, _val); -decode_roster_query_attrs(__TopXMLNS, [_ | _attrs], - Ver) -> - decode_roster_query_attrs(__TopXMLNS, _attrs, Ver); -decode_roster_query_attrs(__TopXMLNS, [], Ver) -> - decode_roster_query_attr_ver(__TopXMLNS, Ver). - -encode_roster_query({roster_query, Items, Ver}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, - [], __TopXMLNS), - _els = lists:reverse('encode_roster_query_$items'(Items, - __NewTopXMLNS, [])), - _attrs = encode_roster_query_attr_ver(Ver, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_roster_query_$items'([], __TopXMLNS, _acc) -> - _acc; -'encode_roster_query_$items'([Items | _els], __TopXMLNS, - _acc) -> - 'encode_roster_query_$items'(_els, __TopXMLNS, - [encode_roster_item(Items, __TopXMLNS) - | _acc]). - -decode_roster_query_attr_ver(__TopXMLNS, undefined) -> - undefined; -decode_roster_query_attr_ver(__TopXMLNS, _val) -> _val. - -encode_roster_query_attr_ver(undefined, _acc) -> _acc; -encode_roster_query_attr_ver(_val, _acc) -> - [{<<"ver">>, _val} | _acc]. - -decode_roster_item(__TopXMLNS, __IgnoreEls, - {xmlel, <<"item">>, _attrs, _els}) -> - Groups = decode_roster_item_els(__TopXMLNS, __IgnoreEls, - _els, []), - {Jid, Name, Subscription, Ask} = - decode_roster_item_attrs(__TopXMLNS, _attrs, undefined, - undefined, undefined, undefined), - {roster_item, Jid, Name, Groups, Subscription, Ask}. - -decode_roster_item_els(__TopXMLNS, __IgnoreEls, [], - Groups) -> - lists:reverse(Groups); -decode_roster_item_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"group">>, _attrs, _} = _el | _els], - Groups) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:roster">> -> - decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, - [decode_roster_group(__TopXMLNS, __IgnoreEls, - _el) - | Groups]); - <<"jabber:iq:roster">> -> - decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, - [decode_roster_group(<<"jabber:iq:roster">>, - __IgnoreEls, _el) - | Groups]); - _ -> - decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, - Groups) - end; -decode_roster_item_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Groups) -> - decode_roster_item_els(__TopXMLNS, __IgnoreEls, _els, - Groups). - -decode_roster_item_attrs(__TopXMLNS, - [{<<"jid">>, _val} | _attrs], _Jid, Name, Subscription, - Ask) -> - decode_roster_item_attrs(__TopXMLNS, _attrs, _val, Name, - Subscription, Ask); -decode_roster_item_attrs(__TopXMLNS, - [{<<"name">>, _val} | _attrs], Jid, _Name, - Subscription, Ask) -> - decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, _val, - Subscription, Ask); -decode_roster_item_attrs(__TopXMLNS, - [{<<"subscription">>, _val} | _attrs], Jid, Name, - _Subscription, Ask) -> - decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, - _val, Ask); -decode_roster_item_attrs(__TopXMLNS, - [{<<"ask">>, _val} | _attrs], Jid, Name, Subscription, - _Ask) -> - decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, - Subscription, _val); -decode_roster_item_attrs(__TopXMLNS, [_ | _attrs], Jid, - Name, Subscription, Ask) -> - decode_roster_item_attrs(__TopXMLNS, _attrs, Jid, Name, - Subscription, Ask); -decode_roster_item_attrs(__TopXMLNS, [], Jid, Name, - Subscription, Ask) -> - {decode_roster_item_attr_jid(__TopXMLNS, Jid), - decode_roster_item_attr_name(__TopXMLNS, Name), - decode_roster_item_attr_subscription(__TopXMLNS, - Subscription), - decode_roster_item_attr_ask(__TopXMLNS, Ask)}. - -encode_roster_item({roster_item, Jid, Name, Groups, - Subscription, Ask}, - __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, - [], __TopXMLNS), - _els = - lists:reverse('encode_roster_item_$groups'(Groups, - __NewTopXMLNS, [])), - _attrs = encode_roster_item_attr_ask(Ask, - encode_roster_item_attr_subscription(Subscription, - encode_roster_item_attr_name(Name, - encode_roster_item_attr_jid(Jid, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS))))), - {xmlel, <<"item">>, _attrs, _els}. - -'encode_roster_item_$groups'([], __TopXMLNS, _acc) -> - _acc; -'encode_roster_item_$groups'([Groups | _els], - __TopXMLNS, _acc) -> - 'encode_roster_item_$groups'(_els, __TopXMLNS, - [encode_roster_group(Groups, __TopXMLNS) - | _acc]). - -decode_roster_item_attr_jid(__TopXMLNS, undefined) -> - erlang:error({xmpp_codec, - {missing_attr, <<"jid">>, <<"item">>, __TopXMLNS}}); -decode_roster_item_attr_jid(__TopXMLNS, _val) -> - case catch dec_jid(_val) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"jid">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_roster_item_attr_jid(_val, _acc) -> - [{<<"jid">>, enc_jid(_val)} | _acc]. - -decode_roster_item_attr_name(__TopXMLNS, undefined) -> - <<>>; -decode_roster_item_attr_name(__TopXMLNS, _val) -> _val. - -encode_roster_item_attr_name(<<>>, _acc) -> _acc; -encode_roster_item_attr_name(_val, _acc) -> - [{<<"name">>, _val} | _acc]. - -decode_roster_item_attr_subscription(__TopXMLNS, - undefined) -> - none; -decode_roster_item_attr_subscription(__TopXMLNS, - _val) -> - case catch dec_enum(_val, - [none, to, from, both, remove]) - of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"subscription">>, <<"item">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_roster_item_attr_subscription(none, _acc) -> - _acc; -encode_roster_item_attr_subscription(_val, _acc) -> - [{<<"subscription">>, enc_enum(_val)} | _acc]. - -decode_roster_item_attr_ask(__TopXMLNS, undefined) -> - undefined; -decode_roster_item_attr_ask(__TopXMLNS, _val) -> - case catch dec_enum(_val, [subscribe]) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"ask">>, <<"item">>, __TopXMLNS}}); - _res -> _res - end. - -encode_roster_item_attr_ask(undefined, _acc) -> _acc; -encode_roster_item_attr_ask(_val, _acc) -> - [{<<"ask">>, enc_enum(_val)} | _acc]. - -decode_roster_group(__TopXMLNS, __IgnoreEls, - {xmlel, <<"group">>, _attrs, _els}) -> - Cdata = decode_roster_group_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_roster_group_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_roster_group_cdata(__TopXMLNS, Cdata); -decode_roster_group_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_roster_group_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_roster_group_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_roster_group_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_roster_group(Cdata, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:roster">>, - [], __TopXMLNS), - _els = encode_roster_group_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"group">>, _attrs, _els}. - -decode_roster_group_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"group">>, __TopXMLNS}}); -decode_roster_group_cdata(__TopXMLNS, _val) -> _val. - -encode_roster_group_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_version(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - {Ver, Os, Name} = decode_version_els(__TopXMLNS, - __IgnoreEls, _els, undefined, - undefined, undefined), - {version, Name, Ver, Os}. - -decode_version_els(__TopXMLNS, __IgnoreEls, [], Ver, Os, - Name) -> - {Ver, Os, Name}; -decode_version_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"name">>, _attrs, _} = _el | _els], Ver, Os, - Name) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, - decode_version_name(__TopXMLNS, __IgnoreEls, _el)); - <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, - decode_version_name(<<"jabber:iq:version">>, - __IgnoreEls, _el)); - _ -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, Name) - end; -decode_version_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"version">>, _attrs, _} = _el | _els], Ver, - Os, Name) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, - decode_version_ver(__TopXMLNS, __IgnoreEls, _el), - Os, Name); - <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, - decode_version_ver(<<"jabber:iq:version">>, - __IgnoreEls, _el), - Os, Name); - _ -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, Name) - end; -decode_version_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"os">>, _attrs, _} = _el | _els], Ver, Os, - Name) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - decode_version_os(__TopXMLNS, __IgnoreEls, _el), - Name); - <<"jabber:iq:version">> -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - decode_version_os(<<"jabber:iq:version">>, - __IgnoreEls, _el), - Name); - _ -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, Name) - end; -decode_version_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Ver, Os, Name) -> - decode_version_els(__TopXMLNS, __IgnoreEls, _els, Ver, - Os, Name). - -encode_version({version, Name, Ver, Os}, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:version">>, [], - __TopXMLNS), - _els = lists:reverse('encode_version_$ver'(Ver, - __NewTopXMLNS, - 'encode_version_$os'(Os, - __NewTopXMLNS, - 'encode_version_$name'(Name, - __NewTopXMLNS, - [])))), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"query">>, _attrs, _els}. - -'encode_version_$ver'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_version_$ver'(Ver, __TopXMLNS, _acc) -> - [encode_version_ver(Ver, __TopXMLNS) | _acc]. - -'encode_version_$os'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_version_$os'(Os, __TopXMLNS, _acc) -> - [encode_version_os(Os, __TopXMLNS) | _acc]. - -'encode_version_$name'(undefined, __TopXMLNS, _acc) -> - _acc; -'encode_version_$name'(Name, __TopXMLNS, _acc) -> - [encode_version_name(Name, __TopXMLNS) | _acc]. - -decode_version_os(__TopXMLNS, __IgnoreEls, - {xmlel, <<"os">>, _attrs, _els}) -> - Cdata = decode_version_os_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_version_os_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_version_os_cdata(__TopXMLNS, Cdata); -decode_version_os_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_version_os_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_version_os_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_version_os_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_version_os(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:version">>, [], - __TopXMLNS), - _els = encode_version_os_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"os">>, _attrs, _els}. - -decode_version_os_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"os">>, __TopXMLNS}}); -decode_version_os_cdata(__TopXMLNS, _val) -> _val. - -encode_version_os_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_version_ver(__TopXMLNS, __IgnoreEls, - {xmlel, <<"version">>, _attrs, _els}) -> - Cdata = decode_version_ver_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_version_ver_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_version_ver_cdata(__TopXMLNS, Cdata); -decode_version_ver_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_version_ver_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_version_ver_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_version_ver_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_version_ver(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:version">>, [], - __TopXMLNS), - _els = encode_version_ver_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"version">>, _attrs, _els}. - -decode_version_ver_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"version">>, __TopXMLNS}}); -decode_version_ver_cdata(__TopXMLNS, _val) -> _val. - -encode_version_ver_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_version_name(__TopXMLNS, __IgnoreEls, - {xmlel, <<"name">>, _attrs, _els}) -> - Cdata = decode_version_name_els(__TopXMLNS, __IgnoreEls, - _els, <<>>), - Cdata. - -decode_version_name_els(__TopXMLNS, __IgnoreEls, [], - Cdata) -> - decode_version_name_cdata(__TopXMLNS, Cdata); -decode_version_name_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Cdata) -> - decode_version_name_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_version_name_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Cdata) -> - decode_version_name_els(__TopXMLNS, __IgnoreEls, _els, - Cdata). - -encode_version_name(Cdata, __TopXMLNS) -> - __NewTopXMLNS = - choose_top_xmlns(<<"jabber:iq:version">>, [], - __TopXMLNS), - _els = encode_version_name_cdata(Cdata, []), - _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS), - {xmlel, <<"name">>, _attrs, _els}. - -decode_version_name_cdata(__TopXMLNS, <<>>) -> - erlang:error({xmpp_codec, - {missing_cdata, <<>>, <<"name">>, __TopXMLNS}}); -decode_version_name_cdata(__TopXMLNS, _val) -> _val. - -encode_version_name_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. - -decode_last(__TopXMLNS, __IgnoreEls, - {xmlel, <<"query">>, _attrs, _els}) -> - Status = decode_last_els(__TopXMLNS, __IgnoreEls, _els, - <<>>), - Seconds = decode_last_attrs(__TopXMLNS, _attrs, - undefined), - {last, Seconds, Status}. - -decode_last_els(__TopXMLNS, __IgnoreEls, [], Status) -> - decode_last_cdata(__TopXMLNS, Status); -decode_last_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Status) -> - decode_last_els(__TopXMLNS, __IgnoreEls, _els, - <>); -decode_last_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Status) -> - decode_last_els(__TopXMLNS, __IgnoreEls, _els, Status). - -decode_last_attrs(__TopXMLNS, - [{<<"seconds">>, _val} | _attrs], _Seconds) -> - decode_last_attrs(__TopXMLNS, _attrs, _val); -decode_last_attrs(__TopXMLNS, [_ | _attrs], Seconds) -> - decode_last_attrs(__TopXMLNS, _attrs, Seconds); -decode_last_attrs(__TopXMLNS, [], Seconds) -> - decode_last_attr_seconds(__TopXMLNS, Seconds). - -encode_last({last, Seconds, Status}, __TopXMLNS) -> - __NewTopXMLNS = choose_top_xmlns(<<"jabber:iq:last">>, - [], __TopXMLNS), - _els = encode_last_cdata(Status, []), - _attrs = encode_last_attr_seconds(Seconds, - enc_xmlns_attrs(__NewTopXMLNS, - __TopXMLNS)), - {xmlel, <<"query">>, _attrs, _els}. - -decode_last_attr_seconds(__TopXMLNS, undefined) -> - undefined; -decode_last_attr_seconds(__TopXMLNS, _val) -> - case catch dec_int(_val, 0, infinity) of - {'EXIT', _} -> - erlang:error({xmpp_codec, - {bad_attr_value, <<"seconds">>, <<"query">>, - __TopXMLNS}}); - _res -> _res - end. - -encode_last_attr_seconds(undefined, _acc) -> _acc; -encode_last_attr_seconds(_val, _acc) -> - [{<<"seconds">>, enc_int(_val)} | _acc]. - -decode_last_cdata(__TopXMLNS, <<>>) -> <<>>; -decode_last_cdata(__TopXMLNS, _val) -> _val. - -encode_last_cdata(<<>>, _acc) -> _acc; -encode_last_cdata(_val, _acc) -> - [{xmlcdata, _val} | _acc]. -- cgit v1.2.3 From de7a143a2c2d9e6b74e4270afda26458e72684ee Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 19 Nov 2016 13:05:13 +0300 Subject: Transform ejabberd_commands on the start --- src/ejabberd_commands.erl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 8d74ad5a2..6172b18ed 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -277,6 +277,10 @@ get_commands_spec() -> args_example = ["/home/me/docs/api.html", "mod_admin", "java,json"], result_example = ok}]. init() -> + try mnesia:transform_table(ejabberd_commands, ignore, + record_info(fields, ejabberd_commands)) + catch exit:{aborted, {no_exists, _}} -> ok + end, mnesia:create_table(ejabberd_commands, [{ram_copies, [node()]}, {local_content, true}, -- cgit v1.2.3 From 13c603970043c556e6e5f1a598c967c5db14f5f9 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 19 Nov 2016 13:57:25 +0300 Subject: Use xmpp_util.erl from XMPP library --- src/xmpp_util.erl | 169 ------------------------------------------------------ 1 file changed, 169 deletions(-) delete mode 100644 src/xmpp_util.erl (limited to 'src') diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl deleted file mode 100644 index 22b8ea597..000000000 --- a/src/xmpp_util.erl +++ /dev/null @@ -1,169 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc -%%% -%%% @end -%%% Created : 12 Jul 2016 by Evgeny Khramtsov -%%%------------------------------------------------------------------- --module(xmpp_util). - -%% API --export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1, - is_standalone_chat_state/1, get_xdata_values/2, - set_xdata_field/2, has_xdata_var/2, - make_adhoc_response/1, make_adhoc_response/2, - decode_timestamp/1, encode_timestamp/1]). - --include("xmpp.hrl"). - -%%%=================================================================== -%%% API -%%%=================================================================== --spec add_delay_info(stanza(), jid(), erlang:timestamp()) -> stanza(). -add_delay_info(Stz, From, Time) -> - add_delay_info(Stz, From, Time, <<"">>). - --spec add_delay_info(stanza(), jid(), - erlang:timestamp(), binary()) -> stanza(). - -add_delay_info(Stz, From, Time, Desc) -> - NewDelay = #delay{stamp = Time, from = From, desc = Desc}, - case xmpp:get_subtag(Stz, #delay{}) of - #delay{from = OldFrom} -> - case jid:tolower(From) == jid:tolower(OldFrom) of - false -> - xmpp:set_subtag(Stz, NewDelay); - true -> - xmpp:append_subtags(Stz, [NewDelay]) - end; - false -> - xmpp:append_subtags(Stz, [NewDelay]) - end. - --spec unwrap_carbon(stanza()) -> xmpp_element(). -unwrap_carbon(#message{} = Msg) -> - try - case xmpp:get_subtag(Msg, #carbons_sent{}) of - #carbons_sent{forwarded = #forwarded{xml_els = [El]}} -> - xmpp:decode(El, ?NS_CLIENT, [ignore_els]); - _ -> - case xmpp:get_subtag(Msg, #carbons_received{}) of - #carbons_received{forwarded = #forwarded{xml_els = [El]}} -> - xmpp:decode(El, ?NS_CLIENT, [ignore_els]); - _ -> - Msg - end - end - catch _:{xmpp_codec, _} -> - Msg - end; -unwrap_carbon(Stanza) -> Stanza. - --spec is_standalone_chat_state(stanza()) -> boolean(). -is_standalone_chat_state(Stanza) -> - case unwrap_carbon(Stanza) of - #message{body = [], subject = [], sub_els = Els} -> - IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY, ?NS_EVENT], - Stripped = [El || El <- Els, - not lists:member(xmpp:get_ns(El), IgnoreNS)], - Stripped == []; - _ -> - false - end. - --spec get_xdata_values(binary(), xdata()) -> [binary()]. -get_xdata_values(Var, #xdata{fields = Fields}) -> - case lists:keyfind(Var, #xdata_field.var, Fields) of - #xdata_field{values = Vals} -> Vals; - false -> [] - end. - --spec set_xdata_field(xdata_field(), xdata()) -> xdata(). -set_xdata_field(Field, #xdata{fields = Fields} = X) -> - NewFields = lists:keystore(Field#xdata_field.var, #xdata_field.var, - Fields, Field), - X#xdata{fields = NewFields}. - --spec has_xdata_var(binary(), xdata()) -> boolean(). -has_xdata_var(Var, #xdata{fields = Fields}) -> - lists:keymember(Var, #xdata_field.var, Fields). - --spec make_adhoc_response(adhoc_command(), adhoc_command()) -> adhoc_command(). -make_adhoc_response(#adhoc_command{lang = Lang, node = Node, sid = SID}, - Command) -> - make_adhoc_response( - Command#adhoc_command{lang = Lang, node = Node, sid = SID}). - --spec make_adhoc_response(adhoc_command()) -> adhoc_command(). -make_adhoc_response(#adhoc_command{sid = <<"">>, - status = Status, - actions = Actions} = Command) -> - SID = encode_timestamp(p1_time_compat:timestamp()), - NewActions = if Actions == undefined, Status /= completed -> - #adhoc_actions{execute = complete, complete = true}; - true -> - undefined - end, - Command#adhoc_command{sid = SID, actions = NewActions}; -make_adhoc_response(Command) -> - Command. - --spec decode_timestamp(binary()) -> erlang:timestamp(). -decode_timestamp(S) -> - try try_decode_timestamp(S) - catch _:_ -> erlang:error({bad_timestamp, S}) - end. - --spec encode_timestamp(erlang:timestamp()) -> binary(). -encode_timestamp({MegaSecs, Secs, MicroSecs}) -> - {{Year, Month, Day}, {Hour, Minute, Second}} = - calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}), - Fraction = if MicroSecs > 0 -> - io_lib:format(".~6..0B", [MicroSecs]); - true -> - "" - end, - list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT" - "~2..0B:~2..0B:~2..0B~sZ", - [Year, Month, Day, Hour, Minute, Second, - Fraction])). - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== -try_decode_timestamp(<>) -> - Date = {to_integer(Y, 1970, 9999), to_integer(Mo, 1, 12), to_integer(D, 1, 31)}, - Time = {to_integer(H, 0, 23), to_integer(Mi, 0, 59), to_integer(S, 0, 59)}, - {MS, {TZH, TZM}} = try_decode_fraction(T), - Seconds = calendar:datetime_to_gregorian_seconds({Date, Time}) - - calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}}) - - TZH * 60 * 60 - TZM * 60, - {Seconds div 1000000, Seconds rem 1000000, MS}; -try_decode_timestamp(<>) -> - try_decode_timestamp(<>). - -try_decode_fraction(<<$., T/binary>>) -> - {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], list}]), - Size = length(V), - <<_:Size/binary, TZD/binary>> = T, - {list_to_integer(string:left(V, 6, $0)), - try_decode_tzd(TZD)}; -try_decode_fraction(TZD) -> - {0, try_decode_tzd(TZD)}. - -try_decode_tzd(<<$Z>>) -> - {0, 0}; -try_decode_tzd(<<$-, H:2/binary, $:, M:2/binary>>) -> - {-1 * to_integer(H, 0, 12), to_integer(M, 0, 59)}; -try_decode_tzd(<<$+, H:2/binary, $:, M:2/binary>>) -> - {to_integer(H, 0, 12), to_integer(M, 0, 59)}. - -to_integer(S, Min, Max) -> - case binary_to_integer(S) of - I when I >= Min, I =< Max -> - I - end. -- cgit v1.2.3 From 049a6d97f1216b831e7cc3b1ebaf85564082a4d3 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 20 Nov 2016 18:08:49 +0300 Subject: Fix RSM for conference disco#items --- src/mod_muc.erl | 225 +++++++++++++++++++++++++++++++-------------------- src/mod_muc_room.erl | 3 +- 2 files changed, 139 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/mod_muc.erl b/src/mod_muc.erl index ea8bff5e3..9b475f69d 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -62,7 +62,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). - +-include_lib("stdlib/include/ms_transform.hrl"). -include("xmpp.hrl"). -include("mod_muc.hrl"). @@ -175,8 +175,10 @@ init([Host, Opts]) -> <<"conference.@HOST@">>), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, [{host, MyHost}|Opts]), + update_tables(), mnesia:create_table(muc_online_room, [{ram_copies, [node()]}, + {type, ordered_set}, {attributes, record_info(fields, muc_online_room)}]), mnesia:add_table_copy(muc_online_room, node(), ram_copies), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), @@ -497,8 +499,12 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang, ServerHost, ?MODULE, max_rooms_discoitems, fun(I) when is_integer(I), I>=0 -> I end, 100), - Items = iq_disco_items(Host, From, Lang, MaxRoomsDiscoItems, Node, RSM), - xmpp:make_iq_result(IQ, #disco_items{node = Node, items = Items}); + case iq_disco_items(Host, From, Lang, MaxRoomsDiscoItems, Node, RSM) of + {error, Err} -> + xmpp:make_error(IQ, Err); + {result, Result} -> + xmpp:make_iq_result(IQ, Result) + end; process_disco_items(#iq{lang = Lang} = IQ) -> Txt = <<"No module is handling this query">>, xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)). @@ -597,76 +603,112 @@ register_room(Host, Room, Pid) -> end, mnesia:transaction(F). -iq_disco_items(Host, From, Lang, MaxRoomsDiscoItems, <<"">>, undefined) -> - Rooms = get_vh_rooms(Host), - case erlang:length(Rooms) < MaxRoomsDiscoItems of - true -> - iq_disco_items_list(Host, Rooms, {get_disco_item, all, From, Lang}); - false -> - iq_disco_items(Host, From, Lang, MaxRoomsDiscoItems, <<"nonemptyrooms">>, undefined) - end; -iq_disco_items(Host, From, Lang, _MaxRoomsDiscoItems, <<"nonemptyrooms">>, undefined) -> - Empty = #disco_item{jid = jid:make(<<"conference.localhost">>), - node = <<"emptyrooms">>, - name = translate:translate(Lang, <<"Empty Rooms">>)}, - Query = {get_disco_item, only_non_empty, From, Lang}, - [Empty | iq_disco_items_list(Host, get_vh_rooms(Host), Query)]; -iq_disco_items(Host, From, Lang, _MaxRoomsDiscoItems, <<"emptyrooms">>, undefined) -> - iq_disco_items_list(Host, get_vh_rooms(Host), {get_disco_item, 0, From, Lang}); -iq_disco_items(Host, From, Lang, _MaxRoomsDiscoItems, _DiscoNode, Rsm) -> - {Rooms, RsmO} = get_vh_rooms(Host, Rsm), - RsmOut = jlib:rsm_encode(RsmO), - iq_disco_items_list(Host, Rooms, {get_disco_item, all, From, Lang}) ++ RsmOut. - -iq_disco_items_list(Host, Rooms, Query) -> - lists:zf( - fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> - case catch gen_fsm:sync_send_all_state_event(Pid, Query, 100) of - {item, Desc} -> - flush(), - {true, #disco_item{jid = jid:make(Name, Host), - name = Desc}}; - _ -> - false - end - end, Rooms). +-spec iq_disco_items(binary(), jid(), binary(), integer(), binary(), + rsm_set() | undefined) -> + {result, disco_items()} | {error, stanza_error()}. +iq_disco_items(Host, From, Lang, MaxRoomsDiscoItems, Node, RSM) + when Node == <<"">>; Node == <<"nonemptyrooms">>; Node == <<"emptyrooms">> -> + Count = get_vh_rooms_count(Host), + Query = if Node == <<"">>, RSM == undefined, Count > MaxRoomsDiscoItems -> + {get_disco_item, only_non_empty, From, Lang}; + Node == <<"nonemptyrooms">> -> + {get_disco_item, only_non_empty, From, Lang}; + Node == <<"emptyrooms">> -> + {get_disco_item, 0, From, Lang}; + true -> + {get_disco_item, all, From, Lang} + end, + Items = get_vh_rooms(Host, Query, RSM), + ResRSM = case Items of + [_|_] when RSM /= undefined -> + #disco_item{jid = #jid{luser = First}} = hd(Items), + #disco_item{jid = #jid{luser = Last}} = lists:last(Items), + #rsm_set{first = #rsm_first{data = First}, + last = Last, + count = Count}; + [] when RSM /= undefined -> + #rsm_set{count = Count}; + _ -> + undefined + end, + {result, #disco_items{node = Node, items = Items, rsm = ResRSM}}; +iq_disco_items(_Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM) -> + {error, xmpp:err_item_not_found(<<"Node not found">>, Lang)}. + +-spec get_vh_rooms(binary, term(), rsm_set() | undefined) -> [disco_item()]. +get_vh_rooms(Host, Query, + #rsm_set{max = Max, 'after' = After, before = undefined}) + when is_binary(After), After /= <<"">> -> + lists:reverse(get_vh_rooms(next, {After, Host}, Query, 0, Max, [])); +get_vh_rooms(Host, Query, + #rsm_set{max = Max, 'after' = undefined, before = Before}) + when is_binary(Before), Before /= <<"">> -> + get_vh_rooms(prev, {Before, Host}, Query, 0, Max, []); +get_vh_rooms(Host, Query, + #rsm_set{max = Max, 'after' = undefined, before = <<"">>}) -> + get_vh_rooms(last, {<<"">>, Host}, Query, 0, Max, []); +get_vh_rooms(Host, Query, #rsm_set{max = Max}) -> + lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Query, 0, Max, [])); +get_vh_rooms(Host, Query, undefined) -> + lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Query, 0, undefined, [])). + +-spec get_vh_rooms(prev | next | last | first, + {binary(), binary()}, term(), + non_neg_integer(), non_neg_integer() | undefined, + [disco_item()]) -> [disco_item()]. +get_vh_rooms(_Action, _Key, _Query, Count, Max, Items) when Count >= Max -> + Items; +get_vh_rooms(Action, {_, Host} = Key, Query, Count, Max, Items) -> + Call = fun() -> + case Action of + prev -> mnesia:dirty_prev(muc_online_room, Key); + next -> mnesia:dirty_next(muc_online_room, Key); + last -> mnesia:dirty_last(muc_online_room); + first -> mnesia:dirty_first(muc_online_room) + end + end, + NewAction = case Action of + last -> prev; + first -> next; + _ -> Action + end, + try Call() of + '$end_of_table' -> + Items; + {_, Host} = NewKey -> + case get_room_disco_item(NewKey, Query) of + {ok, Item} -> + get_vh_rooms(NewAction, NewKey, Query, + Count + 1, Max, [Item|Items]); + {error, _} -> + get_vh_rooms(NewAction, NewKey, Query, + Count, Max, Items) + end; + NewKey -> + get_vh_rooms(NewAction, NewKey, Query, Count, Max, Items) + catch _:{aborted, {badarg, _}} -> + Items + end. -get_vh_rooms(_, _) -> - todo. - %% AllRooms = lists:sort(get_vh_rooms(Host)), - %% Count = erlang:length(AllRooms), - %% Guard = case Direction of - %% _ when Index =/= undefined -> [{'==', {element, 2, '$1'}, Host}]; - %% aft -> [{'==', {element, 2, '$1'}, Host}, {'>=',{element, 1, '$1'} ,I}]; - %% before when I =/= []-> [{'==', {element, 2, '$1'}, Host}, {'=<',{element, 1, '$1'} ,I}]; - %% _ -> [{'==', {element, 2, '$1'}, Host}] - %% end, - %% L = lists:sort( - %% mnesia:dirty_select(muc_online_room, - %% [{#muc_online_room{name_host = '$1', _ = '_'}, - %% Guard, - %% ['$_']}])), - %% L2 = if - %% Index == undefined andalso Direction == before -> - %% lists:reverse(lists:sublist(lists:reverse(L), 1, M)); - %% Index == undefined -> - %% lists:sublist(L, 1, M); - %% Index > Count orelse Index < 0 -> - %% []; - %% true -> - %% lists:sublist(L, Index+1, M) - %% end, - %% if L2 == [] -> {L2, #rsm_out{count = Count}}; - %% true -> - %% H = hd(L2), - %% NewIndex = get_room_pos(H, AllRooms), - %% T = lists:last(L2), - %% {F, _} = H#muc_online_room.name_host, - %% {Last, _} = T#muc_online_room.name_host, - %% {L2, - %% #rsm_out{first = F, last = Last, count = Count, - %% index = NewIndex}} - %% end. +-spec get_room_disco_item({binary(), binary()}, term()) -> {ok, disco_item()} | + {error, timeout | notfound}. +get_room_disco_item({Name, Host}, Query) -> + case mnesia:dirty_read(muc_online_room, {Name, Host}) of + [#muc_online_room{pid = Pid}|_] -> + RoomJID = jid:make(Name, Host), + try gen_fsm:sync_send_all_state_event(Pid, Query, 100) of + {item, Desc} -> + {ok, #disco_item{jid = RoomJID, name = Desc}}; + false -> + {error, notfound} + catch _:{timeout, _} -> + {error, timeout}; + _:{noproc, _} -> + {error, notfound} + end; + _ -> + {error, notfound} + end. get_subscribed_rooms(_ServerHost, Host, From) -> Rooms = get_vh_rooms(Host), @@ -681,21 +723,6 @@ get_subscribed_rooms(_ServerHost, Host, From) -> [] end, Rooms). -%% @doc Return the position of desired room in the list of rooms. -%% The room must exist in the list. The count starts in 0. -%% @spec (Desired::muc_online_room(), Rooms::[muc_online_room()]) -> integer() -get_room_pos(Desired, Rooms) -> - get_room_pos(Desired, Rooms, 0). - -get_room_pos(Desired, [HeadRoom | _], HeadPosition) - when Desired#muc_online_room.name_host == - HeadRoom#muc_online_room.name_host -> - HeadPosition; -get_room_pos(Desired, [_ | Rooms], HeadPosition) -> - get_room_pos(Desired, Rooms, HeadPosition + 1). - -flush() -> receive _ -> flush() after 0 -> ok end. - get_nick(ServerHost, Host, From) -> LServer = jid:nameprep(ServerHost), Mod = gen_mod:db_mod(LServer, ?MODULE), @@ -782,6 +809,13 @@ get_vh_rooms(Host) -> [{'==', {element, 2, '$1'}, Host}], ['$_']}]). +-spec get_vh_rooms_count(binary()) -> non_neg_integer(). +get_vh_rooms_count(Host) -> + ets:select_count(muc_online_room, + ets:fun2ms( + fun(#muc_online_room{name_host = {_, H}}) -> + H == Host + end)). clean_table_from_bad_node(Node) -> F = fun() -> @@ -811,6 +845,23 @@ clean_table_from_bad_node(Node, Host) -> end, mnesia:async_dirty(F). +update_tables() -> + try + case mnesia:table_info(muc_online_room, type) of + ordered_set -> ok; + _ -> + case mnesia:delete_table(muc_online_room) of + {atomic, ok} -> ok; + Err -> erlang:error(Err) + end + end + catch _:{aborted, {no_exists, muc_online_room}} -> ok; + _:{aborted, {no_exists, muc_online_room, type}} -> ok; + E:R -> + ?ERROR_MSG("failed to update mnesia table '~s': ~p", + [muc_online_room, {E, R}]) + end. + opts_to_binary(Opts) -> lists:map( fun({title, Title}) -> diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 060ac2bcd..5b000548a 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -504,8 +504,7 @@ handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. handle_sync_event({get_disco_item, Filter, JID, Lang}, _From, StateName, StateData) -> - Len = ?DICT:fold(fun(_, _, Acc) -> Acc + 1 end, 0, - StateData#state.users), + Len = ?DICT:size(StateData#state.users), Reply = case (Filter == all) or (Filter == Len) or ((Filter /= 0) and (Len /= 0)) of true -> get_roomdesc_reply(JID, StateData, -- cgit v1.2.3 From c7ae916afc048e75f836344177f5411fccb5a00e Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 21 Nov 2016 10:23:09 +0300 Subject: Don't forget to start XMPP application --- src/ejabberd_app.erl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index 1791aa790..e4333c816 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -43,7 +43,6 @@ start(normal, _Args) -> ejabberd_logger:start(), write_pid_file(), - jid:start(), start_apps(), start_elixir_application(), ejabberd:check_app(ejabberd), @@ -223,8 +222,7 @@ start_apps() -> ejabberd:start_app(ssl), ejabberd:start_app(fast_yaml), ejabberd:start_app(fast_tls), - ejabberd:start_app(fast_xml), - ejabberd:start_app(stringprep), + ejabberd:start_app(xmpp), ejabberd:start_app(cache_tab). opt_type(net_ticktime) -> -- cgit v1.2.3 From 3f91668c46c0eca28333fd2a749c67b75dc105a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Mon, 21 Nov 2016 09:52:29 +0100 Subject: Log more data for failed s2s connection --- src/ejabberd_s2s_out.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 076ba2d3b..b9ce47830 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -231,10 +231,10 @@ open_socket(init, StateData) -> send_header(NewStateData, Version), {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; - {error, _Reason} -> + {error, Reason} -> ?INFO_MSG("s2s connection: ~s -> ~s (remote server " - "not found)", - [StateData#state.myname, StateData#state.server]), + "not found: ~p)", + [StateData#state.myname, StateData#state.server, Reason]), case ejabberd_hooks:run_fold(find_s2s_bridge, undefined, [StateData#state.myname, StateData#state.server]) -- cgit v1.2.3 From 274303f24829c347d91fa3f9e464b38cfa5b18c2 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 21 Nov 2016 12:14:24 +0300 Subject: Fix conference disco#items when running multiple virtual hosts --- src/mod_muc.erl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 9b475f69d..1f8b2479c 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -639,26 +639,26 @@ iq_disco_items(_Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM) -> get_vh_rooms(Host, Query, #rsm_set{max = Max, 'after' = After, before = undefined}) when is_binary(After), After /= <<"">> -> - lists:reverse(get_vh_rooms(next, {After, Host}, Query, 0, Max, [])); + lists:reverse(get_vh_rooms(next, {After, Host}, Host, Query, 0, Max, [])); get_vh_rooms(Host, Query, #rsm_set{max = Max, 'after' = undefined, before = Before}) when is_binary(Before), Before /= <<"">> -> - get_vh_rooms(prev, {Before, Host}, Query, 0, Max, []); + get_vh_rooms(prev, {Before, Host}, Host, Query, 0, Max, []); get_vh_rooms(Host, Query, #rsm_set{max = Max, 'after' = undefined, before = <<"">>}) -> - get_vh_rooms(last, {<<"">>, Host}, Query, 0, Max, []); + get_vh_rooms(last, {<<"">>, Host}, Host, Query, 0, Max, []); get_vh_rooms(Host, Query, #rsm_set{max = Max}) -> - lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Query, 0, Max, [])); + lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Host, Query, 0, Max, [])); get_vh_rooms(Host, Query, undefined) -> - lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Query, 0, undefined, [])). + lists:reverse(get_vh_rooms(first, {<<"">>, Host}, Host, Query, 0, undefined, [])). -spec get_vh_rooms(prev | next | last | first, - {binary(), binary()}, term(), + {binary(), binary()}, binary(), term(), non_neg_integer(), non_neg_integer() | undefined, [disco_item()]) -> [disco_item()]. -get_vh_rooms(_Action, _Key, _Query, Count, Max, Items) when Count >= Max -> +get_vh_rooms(_Action, _Key, _Host, _Query, Count, Max, Items) when Count >= Max -> Items; -get_vh_rooms(Action, {_, Host} = Key, Query, Count, Max, Items) -> +get_vh_rooms(Action, Key, Host, Query, Count, Max, Items) -> Call = fun() -> case Action of prev -> mnesia:dirty_prev(muc_online_room, Key); @@ -678,14 +678,14 @@ get_vh_rooms(Action, {_, Host} = Key, Query, Count, Max, Items) -> {_, Host} = NewKey -> case get_room_disco_item(NewKey, Query) of {ok, Item} -> - get_vh_rooms(NewAction, NewKey, Query, + get_vh_rooms(NewAction, NewKey, Host, Query, Count + 1, Max, [Item|Items]); {error, _} -> - get_vh_rooms(NewAction, NewKey, Query, + get_vh_rooms(NewAction, NewKey, Host, Query, Count, Max, Items) end; NewKey -> - get_vh_rooms(NewAction, NewKey, Query, Count, Max, Items) + get_vh_rooms(NewAction, NewKey, Host, Query, Count, Max, Items) catch _:{aborted, {badarg, _}} -> Items end. -- cgit v1.2.3 From c5e7b4738f6e2f2bf21da8530ebc4c9887cf1e44 Mon Sep 17 00:00:00 2001 From: Badlop Date: Mon, 21 Nov 2016 12:06:11 +0100 Subject: Fix handling mod_http_upload disco#info queries: need decoded elements As reported in https://www.ejabberd.im/forum/28605/ejabberd-modhttpupload-error-405-not-allowed --- src/mod_http_upload.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 6ad18531c..1abde4f5b 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -360,7 +360,8 @@ handle_cast(Request, State) -> -spec handle_info(timeout | _, state()) -> {noreply, state()}. -handle_info({route, From, To, #iq{} = IQ}, State) -> +handle_info({route, From, To, #iq{} = Packet}, State) -> + IQ = xmpp:decode_els(Packet), {Reply, NewState} = case process_iq(From, IQ, State) of R when is_record(R, iq) -> {R, State}; -- cgit v1.2.3 From 04fdf69737c8219f052a5a538c94b8e955058b2c Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 21 Nov 2016 14:21:34 +0300 Subject: Fix non-empty disco-nodes processing --- src/mod_delegation.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index 571817963..2cf9525fc 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -344,7 +344,9 @@ disco_identity(Acc, _From, To, <<"">>, _Lang, Type) -> empty when Identities /= [] -> {result, Identities}; {result, Ids} -> {result, Ids ++ Identities}; Acc -> Acc - end. + end; +disco_identity(Acc, _From, _To, _Node, _Lang, _Type) -> + Acc. my_features(ejabberd_local) -> [?NS_DELEGATION]; my_features(ejabberd_sm) -> []. -- cgit v1.2.3 From 3189bb3bb907335ac9288b1ef0e9738c6cfd56ea Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 21 Nov 2016 21:34:56 +0300 Subject: Set 'sql_pool_size' to 1 by default for sqlite --- src/ejabberd_sql_sup.erl | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ejabberd_sql_sup.erl b/src/ejabberd_sql_sup.erl index 682414557..29099fce3 100644 --- a/src/ejabberd_sql_sup.erl +++ b/src/ejabberd_sql_sup.erl @@ -61,10 +61,6 @@ start_link(Host) -> ?MODULE, [Host]). init([Host]) -> - PoolSize = ejabberd_config:get_option( - {sql_pool_size, Host}, - fun(I) when is_integer(I), I>0 -> I end, - ?DEFAULT_POOL_SIZE), StartInterval = ejabberd_config:get_option( {sql_start_interval, Host}, fun(I) when is_integer(I), I>0 -> I end, @@ -76,6 +72,7 @@ init([Host]) -> (mssql) -> mssql; (odbc) -> odbc end, odbc), + PoolSize = get_pool_size(Type, Host), case Type of sqlite -> check_sqlite_db(Host); @@ -117,6 +114,23 @@ remove_pid(Host, Pid) -> end, mnesia:ets(F). +-spec get_pool_size(atom(), binary()) -> pos_integer(). +get_pool_size(SQLType, Host) -> + PoolSize = ejabberd_config:get_option( + {sql_pool_size, Host}, + fun(I) when is_integer(I), I>0 -> I end, + case SQLType of + sqlite -> 1; + _ -> ?DEFAULT_POOL_SIZE + end), + if PoolSize > 1 andalso SQLType == sqlite -> + ?WARNING_MSG("it's not recommended to set sql_pool_size > 1 for " + "sqlite, because it may cause race conditions", []); + true -> + ok + end, + PoolSize. + transform_options(Opts) -> lists:foldl(fun transform_options/2, [], Opts). -- cgit v1.2.3 From fbfbb968727617ae9bbeedc9b3d4adb7636ad5da Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 14:48:01 +0100 Subject: Improve ODBC import --- src/ejabberd_auth.erl | 25 ++-- src/ejabberd_auth_mnesia.erl | 17 +-- src/ejabberd_auth_riak.erl | 16 ++- src/ejd2sql.erl | 294 ++++++++++++++++++++++----------------- src/mod_announce.erl | 22 +-- src/mod_announce_mnesia.erl | 11 +- src/mod_announce_riak.erl | 12 +- src/mod_announce_sql.erl | 19 +-- src/mod_caps.erl | 31 +---- src/mod_caps_mnesia.erl | 9 +- src/mod_caps_riak.erl | 11 +- src/mod_caps_sql.erl | 5 +- src/mod_last.erl | 30 ++-- src/mod_last_sql.erl | 19 +-- src/mod_muc.erl | 20 +-- src/mod_muc_mnesia.erl | 37 ++++- src/mod_muc_riak.erl | 36 ++++- src/mod_muc_sql.erl | 37 ++--- src/mod_offline.erl | 39 ++++-- src/mod_offline_mnesia.erl | 4 +- src/mod_offline_sql.erl | 28 +--- src/mod_privacy.erl | 112 +++++++++++++-- src/mod_privacy_sql.erl | 35 +---- src/mod_private.erl | 23 +-- src/mod_private_mnesia.erl | 7 +- src/mod_private_riak.erl | 7 +- src/mod_private_sql.erl | 14 +- src/mod_roster.erl | 38 +++-- src/mod_roster_mnesia.erl | 12 +- src/mod_roster_riak.erl | 21 ++- src/mod_roster_sql.erl | 25 +--- src/mod_shared_roster.erl | 19 +-- src/mod_shared_roster_mnesia.erl | 13 +- src/mod_shared_roster_riak.erl | 19 ++- src/mod_shared_roster_sql.erl | 20 +-- src/mod_vcard.erl | 35 +++-- src/mod_vcard_mnesia.erl | 31 ++++- src/mod_vcard_riak.erl | 12 +- src/mod_vcard_sql.erl | 39 +----- src/mod_vcard_xupdate.erl | 24 ++-- src/mod_vcard_xupdate_mnesia.erl | 7 +- src/mod_vcard_xupdate_riak.erl | 8 +- src/mod_vcard_xupdate_sql.erl | 14 +- 43 files changed, 718 insertions(+), 539 deletions(-) (limited to 'src') diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 6b7f537c0..74c8009c2 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -36,8 +36,8 @@ check_password/6, check_password_with_authmodule/4, check_password_with_authmodule/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, - get_vh_registered_users/2, export/1, import/1, - get_vh_registered_users_number/1, import/3, + get_vh_registered_users/2, export/1, import_info/0, + get_vh_registered_users_number/1, import/5, import_start/2, get_vh_registered_users_number/2, get_password/2, get_password_s/2, get_password_with_authmodule/2, is_user_exists/2, is_user_exists_in_other_modules/3, @@ -438,15 +438,20 @@ auth_modules(Server) -> export(Server) -> ejabberd_auth_mnesia:export(Server). -import(Server) -> - ejabberd_auth_mnesia:import(Server). +import_info() -> + [{<<"users">>, 3}]. -import(Server, mnesia, Passwd) -> - ejabberd_auth_mnesia:import(Server, mnesia, Passwd); -import(Server, riak, Passwd) -> - ejabberd_auth_riak:import(Server, riak, Passwd); -import(_, _, _) -> - pass. +import_start(_LServer, mnesia) -> + ejabberd_auth_mnesia:init_db(); +import_start(_LServer, _) -> + ok. + +import(Server, {sql, _}, mnesia, <<"users">>, Fields) -> + ejabberd_auth_mnesia:import(Server, Fields); +import(Server, {sql, _}, riak, <<"users">>, Fields) -> + ejabberd_auth_riak:import(Server, Fields); +import(_LServer, {sql, _}, sql, <<"users">>, _) -> + ok. opt_type(auth_method) -> fun (V) when is_list(V) -> diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index f36c9fbc7..2e9ef5c94 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -40,8 +40,8 @@ get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, - remove_user/3, store_type/0, export/1, import/1, - import/3, plain_password_required/0, opt_type/1]). + remove_user/3, store_type/0, export/1, import/2, + plain_password_required/0, opt_type/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -493,16 +493,9 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, password from users;">>, - fun([LUser, Password]) -> - #passwd{us = {LUser, LServer}, password = Password} - end}]. - -import(_LServer, mnesia, #passwd{} = P) -> - mnesia:dirty_write(P); -import(_, _, _) -> - pass. +import(LServer, [LUser, Password, _TimeStamp]) -> + mnesia:dirty_write( + #passwd{us = {LUser, LServer}, password = Password}). opt_type(auth_password_format) -> fun (V) -> V end; opt_type(_) -> [auth_password_format]. diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index 05add262e..51571c4e2 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -27,6 +27,8 @@ -compile([{parse_transform, ejabberd_sql_pt}]). +-behaviour(ejabberd_config). + -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -39,8 +41,8 @@ get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, - remove_user/3, store_type/0, export/1, import/3, - plain_password_required/0]). + remove_user/3, store_type/0, export/1, import/2, + plain_password_required/0, opt_type/1]). -export([passwd_schema/0]). -include("ejabberd.hrl"). @@ -301,7 +303,9 @@ export(_Server) -> [] end}]. -import(LServer, riak, #passwd{} = Passwd) -> - ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]); -import(_, _, _) -> - pass. +import(LServer, [LUser, Password, _TimeStamp]) -> + Passwd = #passwd{us = {LUser, LServer}, password = Password}, + ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]). + +opt_type(auth_password_format) -> fun (V) -> V end; +opt_type(_) -> [auth_password_format]. diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl index 7bace05dd..9b7fdbbef 100644 --- a/src/ejd2sql.erl +++ b/src/ejd2sql.erl @@ -30,12 +30,12 @@ -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). --export([export/2, export/3, import_file/2, import/2, - import/3, delete/1]). +-export([export/2, export/3, import/3, import/4, delete/1, import_info/1]). + -define(MAX_RECORDS_PER_TRANSACTION, 100). --record(dump, {fd, cont = start}). +-record(sql_dump, {fd, type}). %%%---------------------------------------------------------------------- %%% API @@ -50,13 +50,14 @@ modules() -> [ejabberd_auth, mod_announce, + mod_caps, mod_irc, mod_last, mod_muc, mod_offline, mod_privacy, mod_private, - %% mod_pubsub, + mod_pubsub, mod_roster, mod_shared_roster, mod_vcard, @@ -100,49 +101,44 @@ delete(Server, Module) -> delete(LServer, Table, ConvertFun) end, Module:export(Server)). -import_file(Server, FileName) when is_binary(FileName) -> - import(Server, binary_to_list(FileName)); -import_file(Server, FileName) -> - case disk_log:open([{name, make_ref()}, - {file, FileName}, - {mode, read_only}]) of - {ok, Fd} -> - LServer = jid:nameprep(Server), - Mods = [{Mod, gen_mod:db_type(LServer, Mod)} - || Mod <- modules(), gen_mod:is_loaded(LServer, Mod)], - AuthMods = case lists:member(ejabberd_auth_mnesia, - ejabberd_auth:auth_modules(LServer)) of - true -> - [{ejabberd_auth, mnesia}]; - false -> - [] - end, - import_dump(LServer, AuthMods ++ Mods, #dump{fd = Fd}); - Err -> - exit(Err) - end. - -import(Server, Output) -> - import(Server, Output, [{fast, true}]). - -import(Server, Output, Opts) -> - LServer = jid:nameprep(iolist_to_binary(Server)), - Modules = modules(), - IO = prepare_output(Output, disk_log), +import(Server, Dir, ToType) -> lists:foreach( - fun(Module) -> - import(LServer, IO, Opts, Module) - end, Modules), - close_output(Output, IO). + fun(Mod) -> + ?INFO_MSG("importing ~p...", [Mod]), + import(Mod, Server, Dir, ToType) + end, modules()). -import(Server, Output, Opts, Module) -> +import(Mod, Server, Dir, ToType) -> LServer = jid:nameprep(iolist_to_binary(Server)), - IO = prepare_output(Output, disk_log), + try Mod:import_start(LServer, ToType) + catch error:undef -> ok end, lists:foreach( - fun({SelectQuery, ConvertFun}) -> - import(LServer, SelectQuery, IO, ConvertFun, Opts) - end, Module:import(Server)), - close_output(Output, IO). + fun({File, Tab, _Mod, FieldsNumber}) -> + FileName = filename:join([Dir, File]), + case open_sql_dump(FileName) of + {ok, #sql_dump{type = FromType} = Dump} -> + import_rows(LServer, {sql, FromType}, ToType, + Tab, Mod, Dump, FieldsNumber), + close_sql_dump(Dump); + {error, enoent} -> + ok; + eof -> + ?INFO_MSG("It seems like SQL dump ~s is empty", [FileName]); + Err -> + ?ERROR_MSG("Failed to open SQL dump ~s: ~s", + [FileName, format_error(Err)]) + end + end, import_info(Mod)), + try Mod:import_stop(LServer, ToType) + catch error:undef -> ok end. + +import_info(Mod) -> + Info = Mod:import_info(), + lists:map( + fun({Tab, FieldsNum}) -> + FileName = <>, + {FileName, Tab, Mod, FieldsNum} + end, Info). %%%---------------------------------------------------------------------- %%% Internal functions @@ -200,79 +196,6 @@ delete(LServer, Table, ConvertFun) -> end, mnesia:transaction(F). -import(LServer, SelectQuery, IO, ConvertFun, Opts) -> - F = case proplists:get_bool(fast, Opts) of - true -> - fun() -> - case ejabberd_sql:sql_query_t(SelectQuery) of - {selected, _, Rows} -> - lists:foldl(fun process_sql_row/2, - {IO, ConvertFun, undefined}, Rows); - Err -> - erlang:error(Err) - end - end; - false -> - fun() -> - ejabberd_sql:sql_query_t( - [iolist_to_binary( - [<<"declare c cursor for ">>, SelectQuery])]), - fetch(IO, ConvertFun, undefined) - end - end, - ejabberd_sql:sql_transaction(LServer, F). - -fetch(IO, ConvertFun, PrevRow) -> - case ejabberd_sql:sql_query_t([<<"fetch c;">>]) of - {selected, _, [Row]} -> - process_sql_row(Row, {IO, ConvertFun, PrevRow}), - fetch(IO, ConvertFun, Row); - {selected, _, []} -> - ok; - Err -> - erlang:error(Err) - end. - -process_sql_row(Row, {IO, ConvertFun, PrevRow}) when Row == PrevRow -> - %% Avoid calling ConvertFun with the same input - {IO, ConvertFun, Row}; -process_sql_row(Row, {IO, ConvertFun, _PrevRow}) -> - case catch ConvertFun(Row) of - {'EXIT', _} = Err -> - ?ERROR_MSG("failed to convert ~p: ~p", [Row, Err]); - Term -> - ok = disk_log:log(IO#dump.fd, Term) - end, - {IO, ConvertFun, Row}. - -import_dump(LServer, Mods, #dump{fd = Fd, cont = Cont}) -> - case disk_log:chunk(Fd, Cont) of - {NewCont, Terms} -> - import_terms(LServer, Mods, Terms), - import_dump(LServer, Mods, #dump{fd = Fd, cont = NewCont}); - eof -> - ok; - Err -> - exit(Err) - end. - -import_terms(LServer, Mods, [Term|Terms]) -> - import_term(LServer, Mods, Term), - import_terms(LServer, Mods, Terms); -import_terms(_LServer, _Mods, []) -> - ok. - -import_term(LServer, [{Mod, DBType}|Mods], Term) -> - case catch Mod:import(LServer, DBType, Term) of - pass -> import_term(LServer, Mods, Term); - ok -> ok; - Err -> - ?ERROR_MSG("failed to import ~p for module ~p: ~p", - [Term, Mod, Err]) - end; -import_term(_LServer, [], _Term) -> - ok. - prepare_output(FileName) -> prepare_output(FileName, normal). @@ -285,25 +208,11 @@ prepare_output(FileName, normal) when is_list(FileName) -> Err -> exit(Err) end; -prepare_output(FileName, disk_log) when is_list(FileName) -> - case disk_log:open([{name, make_ref()}, - {repair, truncate}, - {file, FileName}]) of - {ok, Fd} -> - #dump{fd = Fd}; - Err -> - exit(Err) - end; prepare_output(Output, _Type) -> Output. close_output(FileName, Fd) when FileName /= Fd -> - case Fd of - #dump{} -> - disk_log:close(Fd#dump.fd); - _ -> - file:close(Fd) - end, + file:close(Fd), ok; close_output(_, _) -> ok. @@ -321,6 +230,129 @@ flatten1([H|T], Acc) -> flatten1([], Acc) -> Acc. +import_rows(LServer, FromType, ToType, Tab, Mod, Dump, FieldsNumber) -> + case read_row_from_sql_dump(Dump, FieldsNumber) of + {ok, Fields} -> + case catch Mod:import(LServer, FromType, ToType, Tab, Fields) of + ok -> + ok; + Err -> + ?ERROR_MSG("Failed to import fields ~p for tab ~p: ~p", + [Fields, Tab, Err]) + end, + import_rows(LServer, FromType, ToType, + Tab, Mod, Dump, FieldsNumber); + eof -> + ok; + Err -> + ?ERROR_MSG("Failed to read row from SQL dump: ~s", + [format_error(Err)]) + end. + +open_sql_dump(FileName) -> + case file:open(FileName, [raw, read, binary, read_ahead]) of + {ok, Fd} -> + case file:read(Fd, 11) of + {ok, <<"PGCOPY\n", 16#ff, "\r\n", 0>>} -> + case skip_pgcopy_header(Fd) of + ok -> + {ok, #sql_dump{fd = Fd, type = pgsql}}; + Err -> + Err + end; + {ok, _} -> + file:position(Fd, 0), + {ok, #sql_dump{fd = Fd, type = mysql}}; + Err -> + Err + end; + Err -> + Err + end. + +close_sql_dump(#sql_dump{fd = Fd}) -> + file:close(Fd). + +read_row_from_sql_dump(#sql_dump{fd = Fd, type = pgsql}, _) -> + case file:read(Fd, 2) of + {ok, <<(-1):16/signed>>} -> + eof; + {ok, <>} -> + read_fields(Fd, FieldsNum, []); + {ok, _} -> + {error, eof}; + eof -> + {error, eof}; + {error, _} = Err -> + Err + end; +read_row_from_sql_dump(#sql_dump{fd = Fd, type = mysql}, FieldsNum) -> + read_lines(Fd, FieldsNum, <<"">>, []). + +skip_pgcopy_header(Fd) -> + try + {ok, <<_:4/binary, ExtSize:32>>} = file:read(Fd, 8), + {ok, <<_:ExtSize/binary>>} = file:read(Fd, ExtSize), + ok + catch error:{badmatch, {error, _} = Err} -> + Err; + error:{badmatch, _} -> + {error, eof} + end. + +read_fields(_Fd, 0, Acc) -> + {ok, lists:reverse(Acc)}; +read_fields(Fd, N, Acc) -> + case file:read(Fd, 4) of + {ok, <<(-1):32/signed>>} -> + read_fields(Fd, N-1, [null|Acc]); + {ok, <>} -> + case file:read(Fd, ValSize) of + {ok, <>} -> + read_fields(Fd, N-1, [Val|Acc]); + {ok, _} -> + {error, eof}; + Err -> + Err + end; + {ok, _} -> + {error, eof}; + eof -> + {error, eof}; + {error, _} = Err -> + Err + end. + +read_lines(_Fd, 0, <<"">>, Acc) -> + {ok, lists:reverse(Acc)}; +read_lines(Fd, N, Buf, Acc) -> + case file:read_line(Fd) of + {ok, Data} when size(Data) >= 2 -> + Size = size(Data) - 2, + case Data of + <> -> + NewBuf = <>, + read_lines(Fd, N-1, <<"">>, [NewBuf|Acc]); + _ -> + NewBuf = <>, + read_lines(Fd, N, NewBuf, Acc) + end; + {ok, Data} -> + NewBuf = <>, + read_lines(Fd, N, NewBuf, Acc); + eof when Buf == <<"">>, Acc == [] -> + eof; + eof -> + {error, eof}; + {error, _} = Err -> + Err + end. + +format_error({error, eof}) -> + "unexpected end of file"; +format_error({error, Posix}) -> + file:format_error(Posix). + format_queries(SQLs) -> lists:map( fun(#sql_query{} = SQL) -> diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 1d93cbe65..a1c60f3c9 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -31,8 +31,8 @@ -behaviour(gen_mod). --export([start/2, init/0, stop/1, export/1, import/1, - import/3, announce/3, send_motd/1, disco_identity/5, +-export([start/2, init/0, stop/1, export/1, import_info/0, + import_start/2, import/5, announce/3, send_motd/1, disco_identity/5, disco_features/5, disco_items/5, depends/2, send_announcement_to_all/3, announce_commands/4, announce_items/4, mod_opt_type/1]). @@ -43,7 +43,7 @@ -include("mod_announce.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #motd{} | #motd_users{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback set_motd_users(binary(), [{binary(), binary(), binary()}]) -> {atomic, any()}. -callback set_motd(binary(), xmlel()) -> {atomic, any()}. -callback delete_motd(binary()) -> {atomic, any()}. @@ -832,15 +832,17 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"motd">>, 3}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, LA) -> +import(LServer, {sql, _}, DBType, Tab, List) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, LA). + Mod:import(LServer, Tab, List). -mod_opt_type(access) -> - fun acl:access_rules_validator/1; +mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [access, db_type]. diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl index b5a1f590e..23b2a5ba3 100644 --- a/src/mod_announce_mnesia.erl +++ b/src/mod_announce_mnesia.erl @@ -11,7 +11,7 @@ %% API -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, - get_motd/1, is_motd_user/2, set_motd_user/2, import/2]). + get_motd/1, is_motd_user/2, set_motd_user/2, import/3]). -include("xmpp.hrl"). -include("mod_announce.hrl"). @@ -81,10 +81,11 @@ set_motd_user(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #motd{} = Motd) -> - mnesia:dirty_write(Motd); -import(_LServer, #motd_users{} = Users) -> - mnesia:dirty_write(Users). +import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + mnesia:dirty_write(#motd{server = LServer, packet = El}); +import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) -> + mnesia:dirty_write(#motd_users{us = {LUser, LServer}}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_announce_riak.erl b/src/mod_announce_riak.erl index 879eb196d..242adee0c 100644 --- a/src/mod_announce_riak.erl +++ b/src/mod_announce_riak.erl @@ -11,7 +11,7 @@ %% API -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, - get_motd/1, is_motd_user/2, set_motd_user/2, import/2]). + get_motd/1, is_motd_user/2, set_motd_user/2, import/3]). -include("xmpp.hrl"). -include("mod_announce.hrl"). @@ -71,11 +71,13 @@ set_motd_user(LUser, LServer) -> #motd_users{us = {LUser, LServer}}, motd_users_schema(), [{'2i', [{<<"server">>, LServer}]}])}. -import(_LServer, #motd{} = Motd) -> - ejabberd_riak:put(Motd, motd_schema()); -import(_LServer, #motd_users{us = {_, S}} = Users) -> +import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + ejabberd_riak:put(#motd{server = LServer, packet = El}, motd_schema()); +import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) -> + Users = #motd_users{us = {LUser, LServer}}, ejabberd_riak:put(Users, motd_users_schema(), - [{'2i', [{<<"server">>, S}]}]). + [{'2i', [{<<"server">>, LServer}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl index 37b4412d3..90e3f9d75 100644 --- a/src/mod_announce_sql.erl +++ b/src/mod_announce_sql.erl @@ -13,8 +13,8 @@ %% API -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, - get_motd/1, is_motd_user/2, set_motd_user/2, import/1, - import/2, export/1]). + get_motd/1, is_motd_user/2, set_motd_user/2, import/3, + export/1]). -include("xmpp.hrl"). -include("mod_announce.hrl"). @@ -108,19 +108,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select xml from motd where username='';">>, - fun([XML]) -> - El = fxml_stream:parse_element(XML), - #motd{server = LServer, packet = El} - end}, - {<<"select username from motd where xml='';">>, - fun([LUser]) -> - #motd_users{us = {LUser, LServer}} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 65a745d2d..3a4492f5c 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -55,20 +55,16 @@ -include("logger.hrl"). -include("xmpp.hrl"). +-include("mod_caps.hrl"). -define(PROCNAME, ejabberd_mod_caps). -define(BAD_HASH_LIFETIME, 600). --record(caps_features, -{ - node_pair = {<<"">>, <<"">>} :: {binary(), binary()}, - features = [] :: [binary()] | pos_integer() -}). - -record(state, {host = <<"">> :: binary()}). -callback init(binary(), gen_mod:opts()) -> any(). +-callback import(binary(), {binary(), binary()}, [binary() | pos_integer()]) -> ok. -callback caps_read(binary(), {binary(), binary()}) -> {ok, non_neg_integer() | [binary()]} | error. -callback caps_write(binary(), {binary(), binary()}, @@ -525,9 +521,6 @@ is_valid_node(Node) -> false end. -caps_features_schema() -> - {record_info(fields, caps_features), #caps_features{}}. - export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). @@ -559,24 +552,8 @@ import_next(_LServer, _DBType, '$end_of_table') -> ok; import_next(LServer, DBType, NodePair) -> Features = [F || {_, F} <- ets:lookup(caps_features_tmp, NodePair)], - case Features of - [I] when is_integer(I), DBType == mnesia -> - mnesia:dirty_write( - #caps_features{node_pair = NodePair, features = I}); - [I] when is_integer(I), DBType == riak -> - ejabberd_riak:put( - #caps_features{node_pair = NodePair, features = I}, - caps_features_schema()); - _ when DBType == mnesia -> - mnesia:dirty_write( - #caps_features{node_pair = NodePair, features = Features}); - _ when DBType == riak -> - ejabberd_riak:put( - #caps_features{node_pair = NodePair, features = Features}, - caps_features_schema()); - _ when DBType == sql -> - ok - end, + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:import(LServer, NodePair, Features), import_next(LServer, DBType, ets:next(caps_features_tmp, NodePair)). mod_opt_type(cache_life_time) -> diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl index 0bf04b2c3..660fcb4ef 100644 --- a/src/mod_caps_mnesia.erl +++ b/src/mod_caps_mnesia.erl @@ -10,7 +10,7 @@ -behaviour(mod_caps). %% API --export([init/2, caps_read/2, caps_write/3]). +-export([init/2, caps_read/2, caps_write/3, import/3]). -include("mod_caps.hrl"). -include("logger.hrl"). @@ -46,6 +46,13 @@ caps_write(_LServer, Node, Features) -> mnesia:dirty_write(#caps_features{node_pair = Node, features = Features}). +import(_LServer, NodePair, [I]) when is_integer(I) -> + mnesia:dirty_write( + #caps_features{node_pair = NodePair, features = I}); +import(_LServer, NodePair, Features) -> + mnesia:dirty_write( + #caps_features{node_pair = NodePair, features = Features}). + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/mod_caps_riak.erl b/src/mod_caps_riak.erl index 6e59ba867..a504bb6ce 100644 --- a/src/mod_caps_riak.erl +++ b/src/mod_caps_riak.erl @@ -10,7 +10,7 @@ -behaviour(mod_caps). %% API --export([init/2, caps_read/2, caps_write/3]). +-export([init/2, caps_read/2, caps_write/3, import/3]). -include("mod_caps.hrl"). @@ -31,6 +31,15 @@ caps_write(_LServer, Node, Features) -> features = Features}, caps_features_schema()). +import(_LServer, NodePair, [I]) when is_integer(I) -> + ejabberd_riak:put( + #caps_features{node_pair = NodePair, features = I}, + caps_features_schema()); +import(_LServer, NodePair, Features) -> + ejabberd_riak:put( + #caps_features{node_pair = NodePair, features = Features}, + caps_features_schema()). + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl index dde301575..fee0f0960 100644 --- a/src/mod_caps_sql.erl +++ b/src/mod_caps_sql.erl @@ -12,7 +12,7 @@ -compile([{parse_transform, ejabberd_sql_pt}]). %% API --export([init/2, caps_read/2, caps_write/3, export/1]). +-export([init/2, caps_read/2, caps_write/3, export/1, import/3]). -include("mod_caps.hrl"). -include("ejabberd_sql_pt.hrl"). @@ -53,6 +53,9 @@ export(_Server) -> [] end}]. +import(_, _, _) -> + ok. + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/mod_last.erl b/src/mod_last.erl index 56e3b1c5e..47db0b6c6 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -34,8 +34,8 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/1, export/1, - process_sm_iq/1, on_presence_update/4, import/1, - import/3, store_last_info/4, get_last_info/2, + process_sm_iq/1, on_presence_update/4, import_info/0, + import/5, store_last_info/4, get_last_info/2, remove_user/2, transform_options/1, mod_opt_type/1, opt_type/1, register_user/2, depends/2]). @@ -207,18 +207,28 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:remove_user(LUser, LServer). -export(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:export(LServer). - -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"last">>, 3}]. -import(LServer, DBType, LA) -> +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). + +import(LServer, {sql, _}, DBType, <<"last">>, [LUser, TimeStamp, State]) -> + TS = case TimeStamp of + <<"">> -> 0; + _ -> jlib:binary_to_integer(TimeStamp) + end, + LA = #last_activity{us = {LUser, LServer}, + timestamp = TS, + status = State}, Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, LA). +export(LServer) -> + Mod = gen_mod:db_mod(LServer, ?MODULE), + Mod:export(LServer). + transform_options(Opts) -> lists:foldl(fun transform_options/2, [], Opts). diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl index 718f01dff..0351e668c 100644 --- a/src/mod_last_sql.erl +++ b/src/mod_last_sql.erl @@ -13,7 +13,7 @@ %% API -export([init/2, get_last/2, store_last_info/4, remove_user/2, - import/1, import/2, export/1]). + import/2, export/1]). -include("mod_last.hrl"). -include("logger.hrl"). @@ -43,9 +43,6 @@ store_last_info(LUser, LServer, TimeStamp, Status) -> remove_user(LUser, LServer) -> sql_queries:del_last(LServer, LUser). -import(_LServer, _LA) -> - pass. - export(_Server) -> [{last_activity, fun(Host, #last_activity{us = {LUser, LServer}, @@ -58,15 +55,5 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, seconds, state from last">>, - fun([LUser, TimeStamp, State]) -> - #last_activity{us = {LUser, LServer}, - timestamp = binary_to_integer( - TimeStamp), - status = State} - end}]. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== +import(_LServer, _LA) -> + pass. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 1f8b2479c..28008aaae 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -51,8 +51,9 @@ process_mucsub/1, broadcast_service_message/2, export/1, - import/1, - import/3, + import_info/0, + import/5, + import_start/2, opts_to_binary/1, can_use_nick/4]). @@ -79,7 +80,7 @@ -type muc_room_opts() :: [{atom(), any()}]. -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #muc_room{} | #muc_registered{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback store_room(binary(), binary(), binary(), list()) -> {atomic, any()}. -callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error. -callback forget_room(binary(), binary(), binary()) -> {atomic, any()}. @@ -904,13 +905,16 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"muc_room">>, 4}, {<<"muc_registered">>, 4}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, Data) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, Data). + Mod:import(LServer, Tab, L). mod_opt_type(access) -> fun acl:access_rules_validator/1; diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl index e3ae36978..072dddaae 100644 --- a/src/mod_muc_mnesia.erl +++ b/src/mod_muc_mnesia.erl @@ -9,11 +9,15 @@ -module(mod_muc_mnesia). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% API --export([init/2, import/2, store_room/4, restore_room/3, forget_room/3, +-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3, can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). +-include("jlib.hrl"). -include("mod_muc.hrl"). -include("logger.hrl"). @@ -113,10 +117,33 @@ set_nick(_LServer, Host, From, Nick) -> end, mnesia:transaction(F). -import(_LServer, #muc_room{} = R) -> - mnesia:dirty_write(R); -import(_LServer, #muc_registered{} = R) -> - mnesia:dirty_write(R). +set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) -> + {error, not_implemented}. + +set_affiliations(_ServerHost, _Room, _Host, _Affiliations) -> + {error, not_implemented}. + +get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) -> + {error, not_implemented}. + +get_affiliations(_ServerHost, _Room, _Host) -> + {error, not_implemented}. + +search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> + {error, not_implemented}. + +import(_LServer, <<"muc_room">>, + [Name, RoomHost, SOpts, _TimeStamp]) -> + Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)), + mnesia:dirty_write( + #muc_room{name_host = {Name, RoomHost}, + opts = Opts}); +import(_LServer, <<"muc_registered">>, + [J, RoomHost, Nick, _TimeStamp]) -> + #jid{user = U, server = S} = jid:from_string(J), + mnesia:dirty_write( + #muc_registered{us_host = {{U, S}, RoomHost}, + nick = Nick}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_muc_riak.erl b/src/mod_muc_riak.erl index bc6e5959a..ada08ace6 100644 --- a/src/mod_muc_riak.erl +++ b/src/mod_muc_riak.erl @@ -9,11 +9,15 @@ -module(mod_muc_riak). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% API --export([init/2, import/2, store_room/4, restore_room/3, forget_room/3, +-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3, can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). +-include("jlib.hrl"). -include("mod_muc.hrl"). %%%=================================================================== @@ -101,11 +105,33 @@ set_nick(LServer, Host, From, Nick) -> end end}. -import(_LServer, #muc_room{} = R) -> - ejabberd_riak:put(R, muc_room_schema()); -import(_LServer, #muc_registered{us_host = {_, Host}, nick = Nick} = R) -> +set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) -> + {error, not_implemented}. + +set_affiliations(_ServerHost, _Room, _Host, _Affiliations) -> + {error, not_implemented}. + +get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) -> + {error, not_implemented}. + +get_affiliations(_ServerHost, _Room, _Host) -> + {error, not_implemented}. + +search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> + {error, not_implemented}. + +import(_LServer, <<"muc_room">>, + [Name, RoomHost, SOpts, _TimeStamp]) -> + Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)), + ejabberd_riak:put( + #muc_room{name_host = {Name, RoomHost}, opts = Opts}, + muc_room_schema()); +import(_LServer, <<"muc_registered">>, + [J, RoomHost, Nick, _TimeStamp]) -> + #jid{user = U, server = S} = jid:from_string(J), + R = #muc_registered{us_host = {{U, S}, RoomHost}, nick = Nick}, ejabberd_riak:put(R, muc_registered_schema(), - [{'2i', [{<<"nick_host">>, {Nick, Host}}]}]). + [{'2i', [{<<"nick_host">>, {Nick, RoomHost}}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl index 3139b5316..4b6be7d06 100644 --- a/src/mod_muc_sql.erl +++ b/src/mod_muc_sql.erl @@ -11,11 +11,14 @@ -compile([{parse_transform, ejabberd_sql_pt}]). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% API -export([init/2, store_room/4, restore_room/3, forget_room/3, can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4, - import/1, import/2, export/1]). + import/3, export/1]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). -include("jid.hrl"). -include("mod_muc.hrl"). @@ -127,6 +130,21 @@ set_nick(LServer, Host, From, Nick) -> end, ejabberd_sql:sql_transaction(LServer, F). +set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) -> + {error, not_implemented}. + +set_affiliations(_ServerHost, _Room, _Host, _Affiliations) -> + {error, not_implemented}. + +get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) -> + {error, not_implemented}. + +get_affiliations(_ServerHost, _Room, _Host) -> + {error, not_implemented}. + +search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> + {error, not_implemented}. + export(_Server) -> [{muc_room, fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) -> @@ -158,21 +176,8 @@ export(_Server) -> end end}]. -import(_LServer) -> - [{<<"select name, host, opts from muc_room;">>, - fun([Name, RoomHost, SOpts]) -> - Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)), - #muc_room{name_host = {Name, RoomHost}, opts = Opts} - end}, - {<<"select jid, host, nick from muc_registered;">>, - fun([J, RoomHost, Nick]) -> - #jid{user = U, server = S} = jid:from_string(J), - #muc_registered{us_host = {{U, S}, RoomHost}, - nick = Nick} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_offline.erl b/src/mod_offline.erl index d007bf3c6..241677b2a 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -53,8 +53,9 @@ remove_expired_messages/1, remove_old_messages/2, remove_user/2, - import/1, - import/3, + import_info/0, + import_start/2, + import/5, export/1, get_queue_length/2, count_offline_messages/2, @@ -90,7 +91,7 @@ -type us() :: {binary(), binary()}. -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #offline_msg{}) -> ok | pass. +-callback import(#offline_msg{}) -> ok. -callback store_messages(binary(), us(), [#offline_msg{}], non_neg_integer(), non_neg_integer()) -> {atomic, any()}. @@ -851,13 +852,35 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"spool">>, 4}]. -import(LServer, DBType, Data) -> +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:import(LServer, []). + +import(LServer, {sql, _}, DBType, <<"spool">>, + [LUser, XML, _Seq, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + From = #jid{} = jid:from_string( + fxml:get_attr_s(<<"from">>, El#xmlel.attrs)), + To = #jid{} = jid:from_string( + fxml:get_attr_s(<<"to">>, El#xmlel.attrs)), + Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, + {attr, <<"stamp">>}]), + TS = case jlib:datetime_string_to_timestamp(Stamp) of + {MegaSecs, Secs, _} -> + {MegaSecs, Secs, 0}; + undefined -> + p1_time_compat:timestamp() + end, + US = {LUser, LServer}, + Expire = find_x_expire(TS, El#xmlel.children), + Msg = #offline_msg{us = US, packet = El, + from = From, to = To, + timestamp = TS, expire = Expire}, Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, Data). + Mod:import(Msg). mod_opt_type(access_max_user_messages) -> fun acl:shaper_rules_validator/1; diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index 9fec9c4d5..e84f7078a 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -13,7 +13,7 @@ -export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1, remove_old_messages/2, remove_user/2, read_message_headers/2, read_message/3, remove_message/3, read_all_messages/2, - remove_all_messages/2, count_messages/2, import/2]). + remove_all_messages/2, count_messages/2, import/1]). -include("xmpp.hrl"). -include("mod_offline.hrl"). @@ -164,7 +164,7 @@ count_messages(LUser, LServer) -> _ -> 0 end. -import(_LServer, #offline_msg{} = Msg) -> +import(#offline_msg{} = Msg) -> mnesia:dirty_write(Msg). %%%=================================================================== diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 025aa56f5..e626df425 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -15,8 +15,7 @@ -export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1, remove_old_messages/2, remove_user/2, read_message_headers/2, read_message/3, remove_message/3, read_all_messages/2, - remove_all_messages/2, count_messages/2, import/1, import/2, - export/1]). + remove_all_messages/2, count_messages/2, import/1, export/1]). -include("xmpp.hrl"). -include("mod_offline.hrl"). @@ -193,29 +192,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, xml from spool;">>, - fun([LUser, XML]) -> - El = #xmlel{} = fxml_stream:parse_element(XML), - #message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), - From = Pkt#message.from, - To = case Pkt#message.to of - undefined -> jid:make(LUser, LServer); - JID -> JID - end, - TS = case xmpp:get_subtag(Pkt, #delay{}) of - #delay{stamp = Stamp} -> Stamp; - false -> p1_time_compat:timestamp() - end, - Expire = mod_offline:find_x_expire(TS, Pkt), - #offline_msg{us = {LUser, LServer}, - from = From, to = To, - packet = El, - timestamp = TS, expire = Expire} - end}]. - -import(_, _) -> - pass. +import(_) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index d4c8464f1..97a8f1804 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -31,11 +31,11 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_iq/1, export/1, import/1, +-export([start/2, stop/1, process_iq/1, export/1, import_info/0, process_iq_set/3, process_iq_get/3, get_user_list/3, check_packet/6, remove_user/2, encode_list_item/1, is_list_needdb/1, updated_list/3, - item_to_xml/1, get_user_lists/2, import/3, + item_to_xml/1, get_user_lists/2, import/5, set_privacy_list/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). @@ -46,7 +46,7 @@ -include("mod_privacy.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #privacy{}) -> ok | pass. +-callback import(#privacy{}) -> ok. -callback process_lists_get(binary(), binary()) -> {none | binary(), [binary()]} | error. -callback process_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found. -callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}. @@ -544,18 +544,108 @@ updated_list(_, #userlist{name = OldName} = Old, true -> Old end. +numeric_to_binary(<<0, 0, _/binary>>) -> + <<"0">>; +numeric_to_binary(<<0, _, _:6/binary, T/binary>>) -> + Res = lists:foldl( + fun(X, Sum) -> + Sum*10000 + X + end, 0, [X || <> <= T]), + jlib:integer_to_binary(Res). + +bool_to_binary(<<0>>) -> <<"0">>; +bool_to_binary(<<1>>) -> <<"1">>. + +prepare_list_data(mysql, [ID|Row]) -> + [jlib:binary_to_integer(ID)|Row]; +prepare_list_data(pgsql, [<>, + SType, SValue, SAction, SOrder, SMatchAll, + SMatchIQ, SMatchMessage, SMatchPresenceIn, + SMatchPresenceOut]) -> + [ID, SType, SValue, SAction, + numeric_to_binary(SOrder), + bool_to_binary(SMatchAll), + bool_to_binary(SMatchIQ), + bool_to_binary(SMatchMessage), + bool_to_binary(SMatchPresenceIn), + bool_to_binary(SMatchPresenceOut)]. + +prepare_id(mysql, ID) -> + jlib:binary_to_integer(ID); +prepare_id(pgsql, <>) -> + ID. + +import_info() -> + [{<<"privacy_default_list">>, 2}, + {<<"privacy_list_data">>, 10}, + {<<"privacy_list">>, 4}]. + +import_start(LServer, DBType) -> + ets:new(privacy_default_list_tmp, [private, named_table]), + ets:new(privacy_list_data_tmp, [private, named_table, bag]), + ets:new(privacy_list_tmp, [private, named_table, bag, + {keypos, #privacy.us}]), + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). + +import(LServer, {sql, _}, _DBType, <<"privacy_default_list">>, [LUser, Name]) -> + US = {LUser, LServer}, + ets:insert(privacy_default_list_tmp, {US, Name}), + ok; +import(LServer, {sql, SQLType}, _DBType, <<"privacy_list_data">>, Row1) -> + [ID|Row] = prepare_list_data(SQLType, Row1), + case mod_privacy_sql:raw_to_item(Row) of + [Item] -> + IS = {ID, LServer}, + ets:insert(privacy_list_data_tmp, {IS, Item}), + ok; + [] -> + ok + end; +import(LServer, {sql, SQLType}, _DBType, <<"privacy_list">>, + [LUser, Name, ID, _TimeStamp]) -> + US = {LUser, LServer}, + IS = {prepare_id(SQLType, ID), LServer}, + Default = case ets:lookup(privacy_default_list_tmp, US) of + [{_, Name}] -> Name; + _ -> none + end, + case [Item || {_, Item} <- ets:lookup(privacy_list_data_tmp, IS)] of + [_|_] = Items -> + Privacy = #privacy{us = {LUser, LServer}, + default = Default, + lists = [{Name, Items}]}, + ets:insert(privacy_list_tmp, Privacy), + ets:delete(privacy_list_data_tmp, IS), + ok; + _ -> + ok + end. + +import_stop(_LServer, DBType) -> + import_next(DBType, ets:first(privacy_list_tmp)), + ets:delete(privacy_default_list_tmp), + ets:delete(privacy_list_data_tmp), + ets:delete(privacy_list_tmp), + ok. + +import_next(_DBType, '$end_of_table') -> + ok; +import_next(DBType, US) -> + [P|_] = Ps = ets:lookup(privacy_list_tmp, US), + Lists = lists:flatmap( + fun(#privacy{lists = Lists}) -> + Lists + end, Ps), + Privacy = P#privacy{lists = Lists}, + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:import(Privacy), + import_next(DBType, ets:next(privacy_list_tmp, US)). + export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). - -import(LServer, DBType, Data) -> - Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, Data). - depends(_Host, _Opts) -> []. diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index 10f3cddc8..a39e36766 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -17,7 +17,7 @@ process_default_set/3, process_active_set/3, remove_privacy_list/3, set_privacy_list/1, set_privacy_list/4, get_user_list/2, get_user_lists/2, - remove_user/2, import/1, import/2, export/1]). + remove_user/2, import/1, export/1]). -export([item_to_raw/1, raw_to_item/1, sql_add_privacy_list/2, @@ -249,37 +249,8 @@ get_id() -> put(id, ID + 1), ID + 1. -import(LServer) -> - [{<<"select username from privacy_list;">>, - fun([LUser]) -> - Default = case sql_get_default_privacy_list_t(LUser) of - {selected, [<<"name">>], []} -> - none; - {selected, [<<"name">>], [[DefName]]} -> - DefName; - _ -> - none - end, - {selected, [<<"name">>], Names} = - sql_get_privacy_list_names_t(LUser), - Lists = lists:flatmap( - fun([Name]) -> - case sql_get_privacy_list_data_t(LUser, Name) of - {selected, _, RItems} -> - [{Name, - lists:map(fun raw_to_item/1, - RItems)}]; - _ -> - [] - end - end, Names), - #privacy{default = Default, - us = {LUser, LServer}, - lists = Lists} - end}]. - -import(_, _) -> - pass. +import(_) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_private.erl b/src/mod_private.erl index 565500d4a..d11cad36f 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -31,9 +31,9 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_sm_iq/1, import/3, - remove_user/2, get_data/2, get_data/3, export/1, import/1, - mod_opt_type/1, set_data/3, depends/2]). +-export([start/2, stop/1, process_sm_iq/1, import_info/0, + remove_user/2, get_data/2, get_data/3, export/1, + import/5, import_start/2, mod_opt_type/1, set_data/3, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -42,7 +42,7 @@ -include("mod_private.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #private_storage{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}. -callback get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error. -callback get_all_data(binary(), binary()) -> [xmlel()]. @@ -124,17 +124,20 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(Server, ?MODULE), Mod:remove_user(LUser, LServer). +import_info() -> + [{<<"private_storage">>, 4}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). + export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). - -import(LServer, DBType, PD) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, PD). + Mod:import(LServer, Tab, L). depends(_Host, _Opts) -> []. diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index d1bf20c85..84871c1e7 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -11,7 +11,7 @@ %% API -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/2]). + import/3]). -include("xmpp.hrl"). -include("mod_private.hrl"). @@ -72,7 +72,10 @@ remove_user(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #private_storage{} = PS) -> +import(LServer, <<"private_storage">>, + [LUser, XMLNS, XML, _TimeStamp]) -> + El = #xmlel{} = fxml_stream:parse_element(XML), + PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El}, mnesia:dirty_write(PS). %%%=================================================================== diff --git a/src/mod_private_riak.erl b/src/mod_private_riak.erl index b05e7d725..7b091c4a6 100644 --- a/src/mod_private_riak.erl +++ b/src/mod_private_riak.erl @@ -12,7 +12,7 @@ %% API -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/2]). + import/3]). -include("xmpp.hrl"). -include("mod_private.hrl"). @@ -56,7 +56,10 @@ remove_user(LUser, LServer) -> {atomic, ejabberd_riak:delete_by_index(private_storage, <<"us">>, {LUser, LServer})}. -import(_LServer, #private_storage{usns = {LUser, LServer, _}} = PS) -> +import(LServer, <<"private_storage">>, + [LUser, XMLNS, XML, _TimeStamp]) -> + El = #xmlel{} = fxml_stream:parse_element(XML), + PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El}, ejabberd_riak:put(PS, private_storage_schema(), [{'2i', [{<<"us">>, {LUser, LServer}}]}]). diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl index eb113d923..b459916e4 100644 --- a/src/mod_private_sql.erl +++ b/src/mod_private_sql.erl @@ -12,7 +12,7 @@ %% API -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/1, import/2, export/1]). + import/3, export/1]). -include("xmpp.hrl"). -include("mod_private.hrl"). @@ -77,16 +77,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, namespace, data from private_storage;">>, - fun([LUser, XMLNS, XML]) -> - El = #xmlel{} = fxml_stream:parse_element(XML), - #private_storage{usns = {LUser, LServer, XMLNS}, - xml = El} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 2da09d317..89578571c 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -42,8 +42,9 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_iq/1, export/1, - import/1, process_local_iq/1, get_user_roster/2, - import/3, get_subscription_lists/3, get_roster/2, + import_info/0, process_local_iq/1, get_user_roster/2, + import/5, get_subscription_lists/3, get_roster/2, + import_start/2, import_stop/2, get_in_pending_subscriptions/3, in_subscription/6, out_subscription/4, set_items/3, remove_user/2, get_jid_info/4, encode_item/1, webadmin_page/3, @@ -65,7 +66,7 @@ -export_type([subscription/0]). -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #roster{} | #roster_version{}) -> ok | pass. +-callback import(binary(), binary(), #roster{} | [binary()]) -> ok. -callback read_roster_version(binary(), binary()) -> binary() | error. -callback write_roster_version(binary(), binary(), boolean(), binary()) -> any(). -callback get_roster(binary(), binary()) -> [#roster{}]. @@ -1022,13 +1023,34 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"roster_version">>, 2}, + {<<"rostergroups">>, 3}, + {<<"rosterusers">>, 10}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + ets:new(rostergroups_tmp, [private, named_table, bag]), + Mod:init(LServer, []), + ok. -import(LServer, DBType, R) -> +import_stop(_LServer, _DBType) -> + ets:delete(rostergroups_tmp), + ok. + +import(LServer, {sql, _}, _DBType, <<"rostergroups">>, [LUser, SJID, Group]) -> + LJID = jid:tolower(jid:from_string(SJID)), + ets:insert(rostergroups_tmp, {{LUser, LServer, LJID}, Group}), + ok; +import(LServer, {sql, _}, DBType, <<"rosterusers">>, Row) -> + I = mod_roster_sql:raw_to_record(LServer, lists:sublist(Row, 9)), + Groups = [G || {_, G} <- ets:lookup(rostergroups_tmp, I#roster.usj)], + RosterItem = I#roster{groups = Groups}, + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:import(LServer, <<"rosterusers">>, RosterItem); +import(LServer, {sql, _}, DBType, <<"roster_version">>, [LUser, Ver]) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, R). + Mod:import(LServer, <<"roster_version">>, [LUser, Ver]). mod_opt_type(access) -> fun acl:access_rules_validator/1; diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index 398f105d5..1a33407e1 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -15,7 +15,7 @@ get_roster/2, get_roster_by_jid/3, get_only_items/2, roster_subscribe/4, get_roster_by_jid_with_groups/3, remove_user/2, update_roster/4, del_roster/3, transaction/2, - read_subscription_and_groups/3, import/2]). + read_subscription_and_groups/3, import/3, create_roster/1]). -include("mod_roster.hrl"). -include("logger.hrl"). @@ -51,7 +51,7 @@ write_roster_version(LUser, LServer, InTransaction, Ver) -> end. get_roster(LUser, LServer) -> - mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us). + {ok, mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us)}. get_roster_by_jid(LUser, LServer, LJID) -> case mnesia:read({roster, {LUser, LServer, LJID}}) of @@ -103,9 +103,13 @@ read_subscription_and_groups(LUser, LServer, LJID) -> transaction(_LServer, F) -> mnesia:transaction(F). -import(_LServer, #roster{} = R) -> +create_roster(RItem) -> + mnesia:dirty_write(RItem). + +import(_LServer, <<"rosterusers">>, #roster{} = R) -> mnesia:dirty_write(R); -import(_LServer, #roster_version{} = RV) -> +import(LServer, <<"roster_version">>, [LUser, Ver]) -> + RV = #roster_version{us = {LUser, LServer}, version = Ver}, mnesia:dirty_write(RV). %%%=================================================================== diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl index 9ed5e7927..53f0e7fb4 100644 --- a/src/mod_roster_riak.erl +++ b/src/mod_roster_riak.erl @@ -13,10 +13,10 @@ %% API -export([init/2, read_roster_version/2, write_roster_version/4, - get_roster/2, get_roster_by_jid/3, + get_roster/2, get_roster_by_jid/3, create_roster/1, roster_subscribe/4, get_roster_by_jid_with_groups/3, remove_user/2, update_roster/4, del_roster/3, transaction/2, - read_subscription_and_groups/3, get_only_items/2, import/2]). + read_subscription_and_groups/3, get_only_items/2, import/3]). -include("mod_roster.hrl"). @@ -41,8 +41,8 @@ write_roster_version(LUser, LServer, _InTransaction, Ver) -> get_roster(LUser, LServer) -> case ejabberd_riak:get_by_index(roster, roster_schema(), <<"us">>, {LUser, LServer}) of - {ok, Items} -> Items; - _Err -> [] + {ok, Items} -> {ok, Items}; + _Err -> error end. get_roster_by_jid(LUser, LServer, LJID) -> @@ -96,10 +96,17 @@ read_subscription_and_groups(LUser, LServer, LJID) -> error end. -import(_LServer, #roster{us = {LUser, LServer}} = R) -> - ejabberd_riak:put(R, roster_schema(), +create_roster(#roster{us = {LUser, LServer}} = RItem) -> + ejabberd_riak:put( + RItem, roster_schema(), + [{'2i', [{<<"us">>, {LUser, LServer}}]}]). + +import(_LServer, <<"rosterusers">>, RosterItem) -> + {LUser, LServer} = RosterItem#roster.us, + ejabberd_riak:put(RosterItem, roster_schema(), [{'2i', [{<<"us">>, {LUser, LServer}}]}]); -import(_LServer, #roster_version{} = RV) -> +import(LServer, <<"roster_version">>, [LUser, Ver]) -> + RV = #roster_version{us = {LUser, LServer}, version = Ver}, ejabberd_riak:put(RV, roster_version_schema()). %%%=================================================================== diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl index 4d97aead0..708a20295 100644 --- a/src/mod_roster_sql.erl +++ b/src/mod_roster_sql.erl @@ -18,7 +18,7 @@ roster_subscribe/4, get_roster_by_jid_with_groups/3, remove_user/2, update_roster/4, del_roster/3, transaction/2, read_subscription_and_groups/3, get_only_items/2, - import/1, import/2, export/1]). + import/3, export/1]). -include("mod_roster.hrl"). -include("ejabberd_sql_pt.hrl"). @@ -185,27 +185,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, jid, nick, subscription, " - "ask, askmessage, server, subscribe, type from rosterusers;">>, - fun([LUser, JID|_] = Row) -> - Item = raw_to_record(LServer, Row), - Username = ejabberd_sql:escape(LUser), - SJID = ejabberd_sql:escape(JID), - {selected, _, Rows} = - ejabberd_sql:sql_query_t( - [<<"select grp from rostergroups where username='">>, - Username, <<"' and jid='">>, SJID, <<"'">>]), - Groups = [Grp || [Grp] <- Rows], - Item#roster{groups = Groups} - end}, - {<<"select username, version from roster_version;">>, - fun([LUser, Ver]) -> - #roster_version{us = {LUser, LServer}, version = Ver} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 45d91bccd..8ef0f41b5 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -30,9 +30,9 @@ -behaviour(gen_mod). -export([start/2, stop/1, export/1, - import/1, webadmin_menu/3, webadmin_page/3, + import_info/0, webadmin_menu/3, webadmin_page/3, get_user_roster/2, get_subscription_lists/3, - get_jid_info/4, import/3, process_item/2, + get_jid_info/4, import/5, process_item/2, import_start/2, in_subscription/6, out_subscription/4, user_available/1, unset_presence/4, register_user/2, remove_user/2, list_groups/1, create_group/2, create_group/3, @@ -56,7 +56,7 @@ -type group_options() :: [{atom(), any()}]. -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #sr_user{} | #sr_group{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback list_groups(binary()) -> [binary()]. -callback groups_with_opts(binary()) -> [{binary(), group_options()}]. -callback create_group(binary(), binary(), group_options()) -> {atomic, any()}. @@ -1072,13 +1072,16 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"sr_group">>, 3}, {<<"sr_user">>, 3}]. + +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, Data) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, Data). + Mod:import(LServer, Tab, L). mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type]. diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl index eb7c3c37d..0f9e93bf6 100644 --- a/src/mod_shared_roster_mnesia.erl +++ b/src/mod_shared_roster_mnesia.erl @@ -15,11 +15,12 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/2]). + add_user_to_group/3, remove_user_from_group/3, import/3]). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). -include("logger.hrl"). +-include("xmpp.hrl"). %%%=================================================================== %%% API @@ -118,10 +119,14 @@ remove_user_from_group(Host, US, Group) -> F = fun () -> mnesia:delete_object(R) end, mnesia:transaction(F). -import(_LServer, #sr_group{} = G) -> +import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) -> + G = #sr_group{group_host = {Group, LServer}, + opts = ejabberd_sql:decode_term(SOpts)}, mnesia:dirty_write(G); -import(_LServer, #sr_user{} = U) -> - mnesia:dirty_write(U). +import(LServer, <<"sr_user">>, [SJID, Group, _TimeStamp]) -> + #jid{luser = U, lserver = S} = jid:from_string(SJID), + User = #sr_user{us = {U, S}, group_host = {Group, LServer}}, + mnesia:dirty_write(User). %%%=================================================================== %%% Internal functions diff --git a/src/mod_shared_roster_riak.erl b/src/mod_shared_roster_riak.erl index 49d6edfcd..bdb750981 100644 --- a/src/mod_shared_roster_riak.erl +++ b/src/mod_shared_roster_riak.erl @@ -15,10 +15,11 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/2]). + add_user_to_group/3, remove_user_from_group/3, import/3]). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). +-include("xmpp.hrl"). %%%=================================================================== %%% API @@ -120,13 +121,17 @@ add_user_to_group(Host, US, Group) -> remove_user_from_group(Host, US, Group) -> {atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}. -import(_LServer, #sr_group{group_host = {_, Host}} = G) -> - ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]); -import(_LServer, #sr_user{us = US, group_host = {Group, Host}} = User) -> +import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) -> + G = #sr_group{group_host = {Group, LServer}, + opts = ejabberd_sql:decode_term(SOpts)}, + ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, LServer}]}]); +import(LServer, <<"sr_user">>, [SJID, Group|_]) -> + #jid{luser = U, lserver = S} = jid:from_string(SJID), + User = #sr_user{us = {U, S}, group_host = {Group, LServer}}, ejabberd_riak:put(User, sr_user_schema(), - [{i, {US, {Group, Host}}}, - {'2i', [{<<"us">>, US}, - {<<"group_host">>, {Group, Host}}]}]). + [{i, {{U, S}, {Group, LServer}}}, + {'2i', [{<<"us">>, {U, S}}, + {<<"group_host">>, {Group, LServer}}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl index 5cffffeb3..9f723f839 100644 --- a/src/mod_shared_roster_sql.erl +++ b/src/mod_shared_roster_sql.erl @@ -17,8 +17,8 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/1, - import/2, export/1]). + add_user_to_group/3, remove_user_from_group/3, import/3, + export/1]). -include("jid.hrl"). -include("mod_roster.hrl"). @@ -177,20 +177,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select name, opts from sr_group;">>, - fun([Group, SOpts]) -> - #sr_group{group_host = {Group, LServer}, - opts = ejabberd_sql:decode_term(SOpts)} - end}, - {<<"select jid, grp from sr_user;">>, - fun([SJID, Group]) -> - #jid{luser = U, lserver = S} = jid:from_string(SJID), - #sr_user{us = {U, S}, group_host = {Group, LServer}} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 35b907f95..dc9476206 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -34,8 +34,8 @@ -export([start/2, init/3, stop/1, get_sm_features/5, process_local_iq/1, process_sm_iq/1, string2lower/1, - remove_user/2, export/1, import/1, import/3, depends/2, - process_search/1, process_vcard/1, get_vcard/2, + remove_user/2, export/1, import_info/0, import/5, import_start/2, + depends/2, process_search/1, process_vcard/1, get_vcard/2, disco_items/5, disco_features/5, disco_identity/5, decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). @@ -50,7 +50,7 @@ -callback init(binary(), gen_mod:opts()) -> any(). -callback stop(binary()) -> any(). --callback import(binary(), #vcard{} | #vcard_search{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback get_vcard(binary(), binary()) -> [xmlel()] | error. -callback set_vcard(binary(), binary(), xmlel(), #vcard_search{}) -> {atomic, any()}. @@ -59,6 +59,7 @@ -callback search(binary(), [{binary(), [binary()]}], boolean(), infinity | pos_integer()) -> [{binary(), binary()}]. -callback remove_user(binary(), binary()) -> {atomic, any()}. +-callback is_search_supported(binary()) -> boolean(). start(Host, Opts) -> Mod = gen_mod:db_mod(Host, Opts, ?MODULE), @@ -105,6 +106,15 @@ init(Host, ServerHost, Search) -> false -> loop(Host, ServerHost); _ -> ejabberd_router:register_route(Host, ServerHost), + Mod = gen_mod:db_mod(ServerHost, ?MODULE), + case Mod:is_search_supported(ServerHost) of + false -> + ?WARNING_MSG("vcard search functionality is " + "not implemented for ~s backend", + [gen_mod:db_type(ServerHost, ?MODULE)]); + true -> + ejabberd_router:register_route(Host, ServerHost) + end, loop(Host, ServerHost) end. @@ -438,17 +448,20 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:remove_user(LUser, LServer). -export(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:export(LServer). +import_info() -> + [{<<"vcard">>, 3}, {<<"vcard_search">>, 24}]. -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, VCard) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, VCard). + Mod:import(LServer, Tab, L). + +export(LServer) -> + Mod = gen_mod:db_mod(LServer, ?MODULE), + Mod:export(LServer). depends(_Host, _Opts) -> []. diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index 3b64c29ef..a4a5f2562 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -11,8 +11,9 @@ -behaviour(mod_vcard). %% API --export([init/2, stop/1, import/2, get_vcard/2, set_vcard/4, search/4, +-export([init/2, stop/1, import/3, get_vcard/2, set_vcard/4, search/4, search_fields/1, search_reported/1, remove_user/2]). +-export([is_search_supported/1]). -include("ejabberd.hrl"). -include("xmpp.hrl"). @@ -47,6 +48,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_ServerHost) -> + true. + get_vcard(LUser, LServer) -> US = {LUser, LServer}, F = fun () -> mnesia:read({vcard, US}) end, @@ -121,10 +125,29 @@ remove_user(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #vcard{} = VCard) -> +import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) -> + #xmlel{} = El = fxml_stream:parse_element(XML), + VCard = #vcard{us = {LUser, LServer}, vcard = El}, mnesia:dirty_write(VCard); -import(_LServer, #vcard_search{} = S) -> - mnesia:dirty_write(S). +import(LServer, <<"vcard_search">>, + [User, LUser, FN, LFN, + Family, LFamily, Given, LGiven, + Middle, LMiddle, Nickname, LNickname, + BDay, LBDay, CTRY, LCTRY, Locality, LLocality, + EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) -> + mnesia:dirty_write( + #vcard_search{us = {LUser, LServer}, + user = {User, LServer}, luser = LUser, + fn = FN, lfn = LFN, family = Family, + lfamily = LFamily, given = Given, + lgiven = LGiven, middle = Middle, + lmiddle = LMiddle, nickname = Nickname, + lnickname = LNickname, bday = BDay, + lbday = LBDay, ctry = CTRY, lctry = LCTRY, + locality = Locality, llocality = LLocality, + email = EMail, lemail = LEMail, + orgname = OrgName, lorgname = LOrgName, + orgunit = OrgUnit, lorgunit = LOrgUnit}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl index 23f05f17d..411ec45fa 100644 --- a/src/mod_vcard_riak.erl +++ b/src/mod_vcard_riak.erl @@ -12,7 +12,8 @@ %% API -export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, - search_fields/1, search_reported/1, import/2, stop/1]). + search_fields/1, search_reported/1, import/3, stop/1]). +-export([is_search_supported/1]). -include("xmpp.hrl"). -include("mod_vcard.hrl"). @@ -26,6 +27,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_LServer) -> + false. + get_vcard(LUser, LServer) -> case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of {ok, R} -> @@ -101,7 +105,9 @@ search_reported(_LServer) -> remove_user(LUser, LServer) -> {atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}. -import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) -> +import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + VCard = #vcard{us = {LUser, LServer}, vcard = El}, #vcard_search{fn = FN, lfn = LFN, family = Family, @@ -150,7 +156,7 @@ import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) -> {<<"lorgname">>, LOrgName}, {<<"orgunit">>, OrgUnit}, {<<"lorgunit">>, LOrgUnit}]}]); -import(_LServer, #vcard_search{}) -> +import(_LServer, <<"vcard_search">>, _) -> ok. %%%=================================================================== diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index 129f76b5a..7fd64c44e 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -14,7 +14,8 @@ %% API -export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2, - search_fields/1, search_reported/1, import/1, import/2, export/1]). + search_fields/1, search_reported/1, import/3, export/1]). +-export([is_search_supported/1]). -include("xmpp.hrl"). -include("mod_vcard.hrl"). @@ -30,6 +31,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_LServer) -> + true. + get_vcard(LUser, LServer) -> case catch sql_queries:get_vcard(LServer, LUser) of {selected, [{SVCARD}]} -> @@ -188,37 +192,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, vcard from vcard;">>, - fun([LUser, SVCard]) -> - #xmlel{} = VCARD = fxml_stream:parse_element(SVCard), - #vcard{us = {LUser, LServer}, vcard = VCARD} - end}, - {<<"select username, lusername, fn, lfn, family, lfamily, " - "given, lgiven, middle, lmiddle, nickname, lnickname, " - "bday, lbday, ctry, lctry, locality, llocality, email, " - "lemail, orgname, lorgname, orgunit, lorgunit from vcard_search;">>, - fun([User, LUser, FN, LFN, - Family, LFamily, Given, LGiven, - Middle, LMiddle, Nickname, LNickname, - BDay, LBDay, CTRY, LCTRY, Locality, LLocality, - EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) -> - #vcard_search{us = {LUser, LServer}, - user = {User, LServer}, luser = LUser, - fn = FN, lfn = LFN, family = Family, - lfamily = LFamily, given = Given, - lgiven = LGiven, middle = Middle, - lmiddle = LMiddle, nickname = Nickname, - lnickname = LNickname, bday = BDay, - lbday = LBDay, ctry = CTRY, lctry = LCTRY, - locality = Locality, llocality = LLocality, - email = EMail, lemail = LEMail, - orgname = OrgName, lorgname = LOrgName, - orgunit = OrgUnit, lorgunit = LOrgUnit} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 27688e8fb..4d1dfa2fc 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -13,14 +13,15 @@ -export([start/2, stop/1]). -export([update_presence/3, vcard_set/3, export/1, - import/1, import/3, mod_opt_type/1, depends/2]). + import_info/0, import/5, import_start/2, + mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). -callback init(binary(), gen_mod:opts()) -> any(). --callback import(binary(), #vcard_xupdate{}) -> ok | pass. +-callback import(binary(), binary(), [binary()]) -> ok. -callback add_xupdate(binary(), binary(), binary()) -> {atomic, any()}. -callback get_xupdate(binary(), binary()) -> binary() | undefined. -callback remove_xupdate(binary(), binary()) -> {atomic, any()}. @@ -94,17 +95,20 @@ presence_with_xupdate(Presence, User, Host) -> Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}), xmpp:set_subtag(Presence1, #vcard_xupdate{hash = Hash}). -export(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:export(LServer). +import_info() -> + [{<<"vcard_xupdate">>, 3}]. -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_start(LServer, DBType) -> + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:init(LServer, []). -import(LServer, DBType, LA) -> +import(LServer, {sql, _}, DBType, Tab, [LUser, Hash, TimeStamp]) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, LA). + Mod:import(LServer, Tab, [LUser, Hash, TimeStamp]). + +export(LServer) -> + Mod = gen_mod:db_mod(LServer, ?MODULE), + Mod:export(LServer). mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type]. diff --git a/src/mod_vcard_xupdate_mnesia.erl b/src/mod_vcard_xupdate_mnesia.erl index f1b1693e4..3f8d6fcab 100644 --- a/src/mod_vcard_xupdate_mnesia.erl +++ b/src/mod_vcard_xupdate_mnesia.erl @@ -10,7 +10,7 @@ -behaviour(mod_vcard_xupdate). %% API --export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]). +-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]). -include("mod_vcard_xupdate.hrl"). -include("logger.hrl"). @@ -45,8 +45,9 @@ remove_xupdate(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #vcard_xupdate{} = R) -> - mnesia:dirty_write(R). +import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) -> + mnesia:dirty_write( + #vcard_xupdate{us = {LUser, LServer}, hash = Hash}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate_riak.erl b/src/mod_vcard_xupdate_riak.erl index 242485bf2..cff77f887 100644 --- a/src/mod_vcard_xupdate_riak.erl +++ b/src/mod_vcard_xupdate_riak.erl @@ -11,7 +11,7 @@ -behaviour(mod_vcard_xupdate). %% API --export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]). +-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]). -include("mod_vcard_xupdate.hrl"). @@ -36,8 +36,10 @@ get_xupdate(LUser, LServer) -> remove_xupdate(LUser, LServer) -> {atomic, ejabberd_riak:delete(vcard_xupdate, {LUser, LServer})}. -import(_LServer, #vcard_xupdate{} = R) -> - ejabberd_riak:put(R, vcard_xupdate_schema()). +import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) -> + ejabberd_riak:put( + #vcard_xupdate{us = {LUser, LServer}, hash = Hash}, + vcard_xupdate_schema()). %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate_sql.erl b/src/mod_vcard_xupdate_sql.erl index 938114b8f..fd2716c33 100644 --- a/src/mod_vcard_xupdate_sql.erl +++ b/src/mod_vcard_xupdate_sql.erl @@ -13,8 +13,8 @@ -behaviour(mod_vcard_xupdate). %% API --export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2, - import/1, export/1]). +-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2, + export/1]). -include("mod_vcard_xupdate.hrl"). -include("ejabberd_sql_pt.hrl"). @@ -62,14 +62,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, hash from vcard_xupdate;">>, - fun([LUser, Hash]) -> - #vcard_xupdate{us = {LUser, LServer}, hash = Hash} - end}]. - -import(_LServer, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions -- cgit v1.2.3 From ebadcf71c2e12e379afd31829c58717565d541c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Tue, 22 Nov 2016 13:17:05 +0100 Subject: New bosh module --- src/ejabberd_bosh.erl | 1095 +++++++++++++++++++++++++++++++++++++++++++++++ src/ejabberd_socket.erl | 6 +- src/mod_bosh.erl | 296 +++++++++++++ 3 files changed, 1395 insertions(+), 2 deletions(-) create mode 100644 src/ejabberd_bosh.erl create mode 100644 src/mod_bosh.erl (limited to 'src') diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl new file mode 100644 index 000000000..d4fc6809d --- /dev/null +++ b/src/ejabberd_bosh.erl @@ -0,0 +1,1095 @@ +%%%------------------------------------------------------------------- +%%% File : ejabberd_bosh.erl +%%% Author : Evgeniy Khramtsov +%%% Purpose : Manage BOSH sockets +%%% Created : 20 Jul 2011 by Evgeniy Khramtsov +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%------------------------------------------------------------------- +-module(ejabberd_bosh). + +-protocol({xep, 124, '1.11'}). +-protocol({xep, 206, '1.4'}). + +-define(GEN_FSM, p1_fsm). + +-behaviour(?GEN_FSM). + +%% API +-export([start/2, start/3, start_link/3]). + +-export([send_xml/2, setopts/2, controlling_process/2, + migrate/3, custom_receiver/1, become_controller/2, + reset_stream/1, change_shaper/2, monitor/1, close/1, + sockname/1, peername/1, process_request/3, send/2, + change_controller/2]). + +%% gen_fsm callbacks +-export([init/1, wait_for_session/2, wait_for_session/3, + active/2, active/3, handle_event/3, print_state/1, + handle_sync_event/4, handle_info/3, terminate/3, + code_change/4]). + +-include("ejabberd.hrl"). +-include("logger.hrl"). + +-include("jlib.hrl"). + +-include("ejabberd_http.hrl"). + +-include("bosh.hrl"). + +%%-define(DBGFSM, true). +-ifdef(DBGFSM). + +-define(FSMOPTS, [{debug, [trace]}]). + +-else. + +-define(FSMOPTS, []). + +-endif. + +-define(BOSH_VERSION, <<"1.11">>). + +-define(NS_BOSH, <<"urn:xmpp:xbosh">>). + +-define(NS_HTTP_BIND, + <<"http://jabber.org/protocol/httpbind">>). + +-define(DEFAULT_MAXPAUSE, 120). + +-define(DEFAULT_WAIT, 300). + +-define(DEFAULT_HOLD, 1). + +-define(DEFAULT_POLLING, 2). + +-define(DEFAULT_INACTIVITY, 30). + +-define(MAX_SHAPED_REQUESTS_QUEUE_LEN, 1000). + +-define(SEND_TIMEOUT, 15000). + +-type bosh_socket() :: {http_bind, pid(), + {inet:ip_address(), + inet:port_number()}}. + +-export_type([bosh_socket/0]). + +-record(state, + {host = <<"">> :: binary(), + sid = <<"">> :: binary(), + el_ibuf = buf_new() :: ?TQUEUE, + el_obuf = buf_new() :: ?TQUEUE, + shaper_state = none :: shaper:shaper(), + c2s_pid :: pid(), + xmpp_ver = <<"">> :: binary(), + inactivity_timer :: reference(), + wait_timer :: reference(), + wait_timeout = ?DEFAULT_WAIT :: timeout(), + inactivity_timeout = ?DEFAULT_INACTIVITY :: timeout(), + prev_rid = 0 :: non_neg_integer(), + prev_key = <<"">> :: binary(), + prev_poll :: erlang:timestamp(), + max_concat = unlimited :: unlimited | non_neg_integer(), + responses = gb_trees:empty() :: ?TGB_TREE, + receivers = gb_trees:empty() :: ?TGB_TREE, + shaped_receivers = queue:new() :: ?TQUEUE, + ip :: inet:ip_address(), + max_requests = 1 :: non_neg_integer()}). + +-record(body, + {http_reason = <<"">> :: binary(), + attrs = [] :: [{any(), any()}], + els = [] :: [fxml_stream:xml_stream_el()], + size = 0 :: non_neg_integer()}). + +start(#body{attrs = Attrs} = Body, IP, SID) -> + XMPPDomain = get_attr(to, Attrs), + SupervisorProc = gen_mod:get_module_proc(XMPPDomain, ?PROCNAME), + case catch supervisor:start_child(SupervisorProc, + [Body, IP, SID]) + of + {ok, Pid} -> {ok, Pid}; + {'EXIT', {noproc, _}} -> + check_bosh_module(XMPPDomain), + {error, module_not_loaded}; + Err -> + ?ERROR_MSG("Failed to start BOSH session: ~p", [Err]), + {error, Err} + end. + +start(StateName, State) -> + (?GEN_FSM):start_link(?MODULE, [StateName, State], + ?FSMOPTS). + +start_link(Body, IP, SID) -> + (?GEN_FSM):start_link(?MODULE, [Body, IP, SID], + ?FSMOPTS). + +send({http_bind, FsmRef, IP}, Packet) -> + send_xml({http_bind, FsmRef, IP}, Packet). + +send_xml({http_bind, FsmRef, _IP}, Packet) -> + case catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + {send_xml, Packet}, + ?SEND_TIMEOUT) + of + {'EXIT', {timeout, _}} -> {error, timeout}; + {'EXIT', _} -> {error, einval}; + Res -> Res + end. + +setopts({http_bind, FsmRef, _IP}, Opts) -> + case lists:member({active, once}, Opts) of + true -> + (?GEN_FSM):send_all_state_event(FsmRef, + {activate, self()}); + _ -> + case lists:member({active, false}, Opts) of + true -> + case catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + deactivate_socket) + of + {'EXIT', _} -> {error, einval}; + Res -> Res + end; + _ -> ok + end + end. + +controlling_process(_Socket, _Pid) -> ok. + +custom_receiver({http_bind, FsmRef, _IP}) -> + {receiver, ?MODULE, FsmRef}. + +become_controller(FsmRef, C2SPid) -> + (?GEN_FSM):send_all_state_event(FsmRef, + {become_controller, C2SPid}). + +change_controller({http_bind, FsmRef, _IP}, C2SPid) -> + become_controller(FsmRef, C2SPid). + +reset_stream({http_bind, _FsmRef, _IP}) -> ok. + +change_shaper({http_bind, FsmRef, _IP}, Shaper) -> + (?GEN_FSM):send_all_state_event(FsmRef, + {change_shaper, Shaper}). + +monitor({http_bind, FsmRef, _IP}) -> + erlang:monitor(process, FsmRef). + +close({http_bind, FsmRef, _IP}) -> + catch (?GEN_FSM):sync_send_all_state_event(FsmRef, + close). + +sockname(_Socket) -> {ok, {{0, 0, 0, 0}, 0}}. + +peername({http_bind, _FsmRef, IP}) -> {ok, IP}. + +migrate(FsmRef, Node, After) when node(FsmRef) == node() -> + catch erlang:send_after(After, FsmRef, {migrate, Node}); +migrate(_FsmRef, _Node, _After) -> + ok. + +process_request(Data, IP, Type) -> + Opts1 = ejabberd_c2s_config:get_c2s_limits(), + Opts = case Type of + xml -> + [{xml_socket, true} | Opts1]; + json -> + Opts1 + end, + MaxStanzaSize = case lists:keysearch(max_stanza_size, 1, + Opts) + of + {value, {_, Size}} -> Size; + _ -> infinity + end, + PayloadSize = iolist_size(Data), + if PayloadSize > MaxStanzaSize -> + http_error(403, <<"Request Too Large">>, Type); + true -> + case decode_body(Data, PayloadSize, Type) of + {ok, #body{attrs = Attrs} = Body} -> + SID = get_attr(sid, Attrs), + To = get_attr(to, Attrs), + if SID == <<"">>, To == <<"">> -> + bosh_response_with_msg(#body{http_reason = + <<"Missing 'to' attribute">>, + attrs = + [{type, <<"terminate">>}, + {condition, + <<"improper-addressing">>}]}, + Type, Body); + SID == <<"">> -> + case start(Body, IP, make_sid()) of + {ok, Pid} -> process_request(Pid, Body, IP, Type); + _Err -> + bosh_response_with_msg(#body{http_reason = + <<"Failed to start BOSH session">>, + attrs = + [{type, <<"terminate">>}, + {condition, + <<"internal-server-error">>}]}, + Type, Body) + end; + true -> + case mod_bosh:find_session(SID) of + {ok, Pid} -> process_request(Pid, Body, IP, Type); + error -> + bosh_response_with_msg(#body{http_reason = + <<"Session ID mismatch">>, + attrs = + [{type, <<"terminate">>}, + {condition, + <<"item-not-found">>}]}, + Type, Body) + end + end; + {error, Reason} -> http_error(400, Reason, Type) + end + end. + +process_request(Pid, Req, _IP, Type) -> + case catch (?GEN_FSM):sync_send_event(Pid, Req, + infinity) + of + #body{} = Resp -> bosh_response(Resp, Type); + {'EXIT', {Reason, _}} + when Reason == noproc; Reason == normal -> + bosh_response(#body{http_reason = + <<"BOSH session not found">>, + attrs = + [{type, <<"terminate">>}, + {condition, <<"item-not-found">>}]}, + Type); + {'EXIT', _} -> + bosh_response(#body{http_reason = + <<"Unexpected error">>, + attrs = + [{type, <<"terminate">>}, + {condition, <<"internal-server-error">>}]}, + Type) + end. + +init([#body{attrs = Attrs}, IP, SID]) -> + Opts1 = ejabberd_c2s_config:get_c2s_limits(), + Opts2 = [{xml_socket, true} | Opts1], + Shaper = none, + ShaperState = shaper:new(Shaper), + Socket = make_socket(self(), IP), + XMPPVer = get_attr('xmpp:version', Attrs), + XMPPDomain = get_attr(to, Attrs), + {InBuf, Opts} = case gen_mod:get_module_opt( + XMPPDomain, + mod_bosh, prebind, + fun(B) when is_boolean(B) -> B end, + false) of + true -> + JID = make_random_jid(XMPPDomain), + {buf_new(), [{jid, JID} | Opts2]}; + false -> + {buf_in([make_xmlstreamstart(XMPPDomain, XMPPVer)], + buf_new()), + Opts2} + end, + ejabberd_socket:start(ejabberd_c2s, ?MODULE, Socket, + Opts), + Inactivity = gen_mod:get_module_opt(XMPPDomain, + mod_bosh, max_inactivity, + fun(I) when is_integer(I), I>0 -> I end, + ?DEFAULT_INACTIVITY), + MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat, + fun(unlimited) -> unlimited; + (N) when is_integer(N), N>0 -> N + end, unlimited), + State = #state{host = XMPPDomain, sid = SID, ip = IP, + xmpp_ver = XMPPVer, el_ibuf = InBuf, + max_concat = MaxConcat, el_obuf = buf_new(), + inactivity_timeout = Inactivity, + shaper_state = ShaperState}, + NewState = restart_inactivity_timer(State), + mod_bosh:open_session(SID, self()), + {ok, wait_for_session, NewState}; +init([StateName, State]) -> + mod_bosh:open_session(State#state.sid, self()), + case State#state.c2s_pid of + C2SPid when is_pid(C2SPid) -> + NewSocket = make_socket(self(), State#state.ip), + C2SPid ! {change_socket, NewSocket}, + NewState = restart_inactivity_timer(State), + {ok, StateName, NewState}; + _ -> {stop, normal} + end. + +wait_for_session(_Event, State) -> + ?ERROR_MSG("unexpected event in 'wait_for_session': ~p", + [_Event]), + {next_state, wait_for_session, State}. + +wait_for_session(#body{attrs = Attrs} = Req, From, + State) -> + RID = get_attr(rid, Attrs), + ?DEBUG("got request:~n** RequestID: ~p~n** Request: " + "~p~n** From: ~p~n** State: ~p", + [RID, Req, From, State]), + Wait = min(get_attr(wait, Attrs, undefined), + ?DEFAULT_WAIT), + Hold = min(get_attr(hold, Attrs, undefined), + ?DEFAULT_HOLD), + NewKey = get_attr(newkey, Attrs), + Type = get_attr(type, Attrs), + Requests = Hold + 1, + {PollTime, Polling} = if Wait == 0, Hold == 0 -> + {p1_time_compat:timestamp(), [{polling, ?DEFAULT_POLLING}]}; + true -> {undefined, []} + end, + MaxPause = gen_mod:get_module_opt(State#state.host, + mod_bosh, max_pause, + fun(I) when is_integer(I), I>0 -> I end, + ?DEFAULT_MAXPAUSE), + Resp = #body{attrs = + [{sid, State#state.sid}, {wait, Wait}, + {ver, ?BOSH_VERSION}, {polling, ?DEFAULT_POLLING}, + {inactivity, State#state.inactivity_timeout}, + {hold, Hold}, {'xmpp:restartlogic', true}, + {requests, Requests}, {secure, true}, + {maxpause, MaxPause}, {'xmlns:xmpp', ?NS_BOSH}, + {'xmlns:stream', ?NS_STREAM}, {from, State#state.host} + | Polling]}, + {ShaperState, _} = + shaper:update(State#state.shaper_state, Req#body.size), + State1 = State#state{wait_timeout = Wait, + prev_rid = RID, prev_key = NewKey, + prev_poll = PollTime, shaper_state = ShaperState, + max_requests = Requests}, + Els = maybe_add_xmlstreamend(Req#body.els, Type), + State2 = route_els(State1, Els), + {State3, RespEls} = get_response_els(State2), + State4 = stop_inactivity_timer(State3), + case RespEls of + [] -> + State5 = restart_wait_timer(State4), + Receivers = gb_trees:insert(RID, {From, Resp}, + State5#state.receivers), + {next_state, active, + State5#state{receivers = Receivers}}; + _ -> + reply_next_state(State4, Resp#body{els = RespEls}, RID, + From) + end; +wait_for_session(_Event, _From, State) -> + ?ERROR_MSG("unexpected sync event in 'wait_for_session': ~p", + [_Event]), + {reply, {error, badarg}, wait_for_session, State}. + +active({#body{} = Body, From}, State) -> + active1(Body, From, State); +active(_Event, State) -> + ?ERROR_MSG("unexpected event in 'active': ~p", + [_Event]), + {next_state, active, State}. + +active(#body{attrs = Attrs, size = Size} = Req, From, + State) -> + ?DEBUG("got request:~n** Request: ~p~n** From: " + "~p~n** State: ~p", + [Req, From, State]), + {ShaperState, Pause} = + shaper:update(State#state.shaper_state, Size), + State1 = State#state{shaper_state = ShaperState}, + if Pause > 0 -> + QLen = queue:len(State1#state.shaped_receivers), + if QLen < (?MAX_SHAPED_REQUESTS_QUEUE_LEN) -> + TRef = start_shaper_timer(Pause), + Q = queue:in({TRef, From, Req}, + State1#state.shaped_receivers), + State2 = stop_inactivity_timer(State1), + {next_state, active, + State2#state{shaped_receivers = Q}}; + true -> + RID = get_attr(rid, Attrs), + reply_stop(State1, + #body{http_reason = <<"Too many requests">>, + attrs = + [{<<"type">>, <<"terminate">>}, + {<<"condition">>, + <<"policy-violation">>}]}, + From, RID) + end; + true -> active1(Req, From, State1) + end; +active(_Event, _From, State) -> + ?ERROR_MSG("unexpected sync event in 'active': ~p", + [_Event]), + {reply, {error, badarg}, active, State}. + +active1(#body{attrs = Attrs} = Req, From, State) -> + RID = get_attr(rid, Attrs), + Key = get_attr(key, Attrs), + IsValidKey = is_valid_key(State#state.prev_key, Key), + IsOveractivity = is_overactivity(State#state.prev_poll), + Type = get_attr(type, Attrs), + if RID > + State#state.prev_rid + State#state.max_requests -> + reply_stop(State, + #body{http_reason = <<"Request ID is out of range">>, + attrs = + [{<<"type">>, <<"terminate">>}, + {<<"condition">>, <<"item-not-found">>}]}, + From, RID); + RID > State#state.prev_rid + 1 -> + State1 = restart_inactivity_timer(State), + Receivers = gb_trees:insert(RID, {From, Req}, + State1#state.receivers), + {next_state, active, + State1#state{receivers = Receivers}}; + RID =< State#state.prev_rid -> + %% TODO: do we need to check 'key' here? It seems so... + case gb_trees:lookup(RID, State#state.responses) of + {value, PrevBody} -> + {next_state, active, + do_reply(State, From, PrevBody, RID)}; + none -> + State1 = drop_holding_receiver(State), + State2 = stop_inactivity_timer(State1), + State3 = restart_wait_timer(State2), + Receivers = gb_trees:insert(RID, {From, Req}, + State3#state.receivers), + {next_state, active, State3#state{receivers = Receivers}} + end; + not IsValidKey -> + reply_stop(State, + #body{http_reason = <<"Session key mismatch">>, + attrs = + [{<<"type">>, <<"terminate">>}, + {<<"condition">>, <<"item-not-found">>}]}, + From, RID); + IsOveractivity -> + reply_stop(State, + #body{http_reason = <<"Too many requests">>, + attrs = + [{<<"type">>, <<"terminate">>}, + {<<"condition">>, <<"policy-violation">>}]}, + From, RID); + true -> + State1 = stop_inactivity_timer(State), + State2 = stop_wait_timer(State1), + Els = case get_attr('xmpp:restart', Attrs, false) of + true -> + XMPPDomain = get_attr(to, Attrs, State#state.host), + XMPPVer = get_attr('xmpp:version', Attrs, + State#state.xmpp_ver), + [make_xmlstreamstart(XMPPDomain, XMPPVer)]; + false -> Req#body.els + end, + State3 = route_els(State2, + maybe_add_xmlstreamend(Els, Type)), + {State4, RespEls} = get_response_els(State3), + NewKey = get_attr(newkey, Attrs, Key), + Pause = get_attr(pause, Attrs, undefined), + NewPoll = case State#state.prev_poll of + undefined -> undefined; + _ -> p1_time_compat:timestamp() + end, + State5 = State4#state{prev_poll = NewPoll, + prev_key = NewKey}, + if Type == <<"terminate">> -> + reply_stop(State5, + #body{http_reason = <<"Session close">>, + attrs = [{<<"type">>, <<"terminate">>}], + els = RespEls}, + From, RID); + Pause /= undefined -> + State6 = drop_holding_receiver(State5), + State7 = restart_inactivity_timer(State6, Pause), + InBuf = buf_in(RespEls, State7#state.el_ibuf), + {next_state, active, + State7#state{prev_rid = RID, el_ibuf = InBuf}}; + RespEls == [] -> + State6 = drop_holding_receiver(State5), + State7 = stop_inactivity_timer(State6), + State8 = restart_wait_timer(State7), + Receivers = gb_trees:insert(RID, {From, #body{}}, + State8#state.receivers), + {next_state, active, + State8#state{prev_rid = RID, receivers = Receivers}}; + true -> + State6 = drop_holding_receiver(State5), + reply_next_state(State6#state{prev_rid = RID}, + #body{els = RespEls}, RID, From) + end + end. + +handle_event({become_controller, C2SPid}, StateName, + State) -> + State1 = route_els(State#state{c2s_pid = C2SPid}), + {next_state, StateName, State1}; +handle_event({change_shaper, Shaper}, StateName, + State) -> + NewShaperState = shaper:new(Shaper), + {next_state, StateName, + State#state{shaper_state = NewShaperState}}; +handle_event(_Event, StateName, State) -> + ?ERROR_MSG("unexpected event in '~s': ~p", + [StateName, _Event]), + {next_state, StateName, State}. + +handle_sync_event({send_xml, + {xmlstreamstart, _, _} = El}, + _From, StateName, State) + when State#state.xmpp_ver >= <<"1.0">> -> + OutBuf = buf_in([El], State#state.el_obuf), + {reply, ok, StateName, State#state{el_obuf = OutBuf}}; +handle_sync_event({send_xml, El}, _From, StateName, + State) -> + OutBuf = buf_in([El], State#state.el_obuf), + State1 = State#state{el_obuf = OutBuf}, + case gb_trees:lookup(State1#state.prev_rid, + State1#state.receivers) + of + {value, {From, Body}} -> + {State2, Els} = get_response_els(State1), + {reply, ok, StateName, + reply(State2, Body#body{els = Els}, + State2#state.prev_rid, From)}; + none -> + State2 = case queue:out(State1#state.shaped_receivers) + of + {{value, {TRef, From, Body}}, Q} -> + cancel_timer(TRef), + (?GEN_FSM):send_event(self(), {Body, From}), + State1#state{shaped_receivers = Q}; + _ -> State1 + end, + {reply, ok, StateName, State2} + end; +handle_sync_event(close, _From, _StateName, State) -> + {stop, normal, State}; +handle_sync_event(deactivate_socket, _From, StateName, + StateData) -> + {reply, ok, StateName, + StateData#state{c2s_pid = undefined}}; +handle_sync_event(_Event, _From, StateName, State) -> + ?ERROR_MSG("unexpected sync event in '~s': ~p", + [StateName, _Event]), + {reply, {error, badarg}, StateName, State}. + +handle_info({timeout, TRef, wait_timeout}, StateName, + #state{wait_timer = TRef} = State) -> + {next_state, StateName, drop_holding_receiver(State)}; +handle_info({timeout, TRef, inactive}, _StateName, + #state{inactivity_timer = TRef} = State) -> + {stop, normal, State}; +handle_info({timeout, TRef, shaper_timeout}, StateName, + State) -> + case queue:out(State#state.shaped_receivers) of + {{value, {TRef, From, Req}}, Q} -> + (?GEN_FSM):send_event(self(), {Req, From}), + {next_state, StateName, + State#state{shaped_receivers = Q}}; + {{value, _}, _} -> + ?ERROR_MSG("shaper_timeout mismatch:~n** TRef: ~p~n** " + "State: ~p", + [TRef, State]), + {stop, normal, State}; + _ -> {next_state, StateName, State} + end; +handle_info({migrate, Node}, StateName, State) -> + if Node /= node() -> + NewState = bounce_receivers(State, migrated), + {migrate, NewState, + {Node, ?MODULE, start, [StateName, NewState]}, 0}; + true -> {next_state, StateName, State} + end; +handle_info(_Info, StateName, State) -> + ?ERROR_MSG("unexpected info:~n** Msg: ~p~n** StateName: ~p", + [_Info, StateName]), + {next_state, StateName, State}. + +terminate({migrated, ClonePid}, _StateName, State) -> + ?INFO_MSG("Migrating session \"~s\" (c2s_pid = " + "~p) to ~p on node ~p", + [State#state.sid, State#state.c2s_pid, ClonePid, + node(ClonePid)]), + mod_bosh:close_session(State#state.sid); +terminate(_Reason, _StateName, State) -> + mod_bosh:close_session(State#state.sid), + case State#state.c2s_pid of + C2SPid when is_pid(C2SPid) -> + (?GEN_FSM):send_event(C2SPid, closed); + _ -> ok + end, + bounce_receivers(State, closed), + bounce_els_from_obuf(State). + +code_change(_OldVsn, StateName, State, _Extra) -> + {ok, StateName, State}. + +print_state(State) -> State. + +route_els(#state{el_ibuf = Buf} = State) -> + route_els(State#state{el_ibuf = buf_new()}, + buf_to_list(Buf)). + +route_els(State, Els) -> + case State#state.c2s_pid of + C2SPid when is_pid(C2SPid) -> + lists:foreach(fun (El) -> + (?GEN_FSM):send_event(C2SPid, El) + end, + Els), + State; + _ -> + InBuf = buf_in(Els, State#state.el_ibuf), + State#state{el_ibuf = InBuf} + end. + +get_response_els(#state{el_obuf = OutBuf, + max_concat = MaxConcat} = + State) -> + {Els, NewOutBuf} = buf_out(OutBuf, MaxConcat), + {State#state{el_obuf = NewOutBuf}, Els}. + +reply(State, Body, RID, From) -> + State1 = restart_inactivity_timer(State), + Receivers = gb_trees:delete_any(RID, + State1#state.receivers), + State2 = do_reply(State1, From, Body, RID), + case catch gb_trees:take_smallest(Receivers) of + {NextRID, {From1, Req}, Receivers1} + when NextRID == RID + 1 -> + (?GEN_FSM):send_event(self(), {Req, From1}), + State2#state{receivers = Receivers1}; + _ -> State2#state{receivers = Receivers} + end. + +reply_next_state(State, Body, RID, From) -> + State1 = restart_inactivity_timer(State), + Receivers = gb_trees:delete_any(RID, + State1#state.receivers), + State2 = do_reply(State1, From, Body, RID), + case catch gb_trees:take_smallest(Receivers) of + {NextRID, {From1, Req}, Receivers1} + when NextRID == RID + 1 -> + active(Req, From1, + State2#state{receivers = Receivers1}); + _ -> + {next_state, active, + State2#state{receivers = Receivers}} + end. + +reply_stop(State, Body, From, RID) -> + {stop, normal, do_reply(State, From, Body, RID)}. + +drop_holding_receiver(State) -> + RID = State#state.prev_rid, + case gb_trees:lookup(RID, State#state.receivers) of + {value, {From, Body}} -> + State1 = restart_inactivity_timer(State), + Receivers = gb_trees:delete_any(RID, + State1#state.receivers), + State2 = State1#state{receivers = Receivers}, + do_reply(State2, From, Body, RID); + none -> State + end. + +do_reply(State, From, Body, RID) -> + ?DEBUG("send reply:~n** RequestID: ~p~n** Reply: " + "~p~n** To: ~p~n** State: ~p", + [RID, Body, From, State]), + (?GEN_FSM):reply(From, Body), + Responses = gb_trees:delete_any(RID, + State#state.responses), + Responses1 = case gb_trees:size(Responses) of + N when N < State#state.max_requests; N == 0 -> + Responses; + _ -> element(3, gb_trees:take_smallest(Responses)) + end, + Responses2 = gb_trees:insert(RID, Body, Responses1), + State#state{responses = Responses2}. + +bounce_receivers(State, Reason) -> + Receivers = gb_trees:to_list(State#state.receivers), + ShapedReceivers = lists:map(fun ({_, From, + #body{attrs = Attrs} = Body}) -> + RID = get_attr(rid, Attrs), + {RID, {From, Body}} + end, + queue:to_list(State#state.shaped_receivers)), + lists:foldl(fun ({RID, {From, Body}}, AccState) -> + NewBody = if Reason == closed -> + #body{http_reason = + <<"Session closed">>, + attrs = + [{type, <<"terminate">>}, + {condition, + <<"other-request">>}]}; + Reason == migrated -> + Body#body{http_reason = + <<"Session migrated">>} + end, + do_reply(AccState, From, NewBody, RID) + end, + State, Receivers ++ ShapedReceivers). + +bounce_els_from_obuf(State) -> + lists:foreach(fun ({xmlstreamelement, El}) -> + case El of + #xmlel{name = Name, attrs = Attrs} + when Name == <<"presence">>; + Name == <<"message">>; + Name == <<"iq">> -> + FromS = fxml:get_attr_s(<<"from">>, Attrs), + ToS = fxml:get_attr_s(<<"to">>, Attrs), + case {jid:from_string(FromS), + jid:from_string(ToS)} + of + {#jid{} = From, #jid{} = To} -> + ejabberd_router:route(From, To, El); + _ -> ok + end; + _ -> ok + end; + (_) -> ok + end, + buf_to_list(State#state.el_obuf)). + +is_valid_key(<<"">>, <<"">>) -> true; +is_valid_key(PrevKey, Key) -> + p1_sha:sha(Key) == PrevKey. + +is_overactivity(undefined) -> false; +is_overactivity(PrevPoll) -> + PollPeriod = timer:now_diff(p1_time_compat:timestamp(), PrevPoll) div + 1000000, + if PollPeriod < (?DEFAULT_POLLING) -> true; + true -> false + end. + +make_xmlstreamstart(XMPPDomain, Version) -> + VersionEl = case Version of + <<"">> -> []; + _ -> [{<<"version">>, Version}] + end, + {xmlstreamstart, <<"stream:stream">>, + [{<<"to">>, XMPPDomain}, {<<"xmlns">>, ?NS_CLIENT}, + {<<"xmlns:xmpp">>, ?NS_BOSH}, + {<<"xmlns:stream">>, ?NS_STREAM} + | VersionEl]}. + +maybe_add_xmlstreamend(Els, <<"terminate">>) -> + Els ++ [{xmlstreamend, <<"stream:stream">>}]; +maybe_add_xmlstreamend(Els, _) -> Els. + +encode_body(#body{attrs = Attrs, els = Els}, Type) -> + Attrs1 = lists:map(fun ({K, V}) when is_atom(K) -> + AmK = iolist_to_binary(atom_to_list(K)), + case V of + true -> {AmK, <<"true">>}; + false -> {AmK, <<"false">>}; + I when is_integer(I), I >= 0 -> + {AmK, iolist_to_binary(integer_to_list(I))}; + _ -> {AmK, V} + end; + ({K, V}) -> {K, V} + end, + Attrs), + Attrs2 = [{<<"xmlns">>, ?NS_HTTP_BIND} | Attrs1], + {Attrs3, XMLs} = lists:foldr(fun ({xmlstreamraw, XML}, + {AttrsAcc, XMLBuf}) -> + {AttrsAcc, [XML | XMLBuf]}; + ({xmlstreamelement, + #xmlel{name = <<"stream:error">>} = El}, + {AttrsAcc, XMLBuf}) -> + {[{<<"type">>, <<"terminate">>}, + {<<"condition">>, + <<"remote-stream-error">>}, + {<<"xmlns:stream">>, ?NS_STREAM} + | AttrsAcc], + [encode_element(El, Type) | XMLBuf]}; + ({xmlstreamelement, + #xmlel{name = <<"stream:features">>} = + El}, + {AttrsAcc, XMLBuf}) -> + {lists:keystore(<<"xmlns:stream">>, 1, + AttrsAcc, + {<<"xmlns:stream">>, + ?NS_STREAM}), + [encode_element(El, Type) | XMLBuf]}; + ({xmlstreamelement, + #xmlel{name = Name, attrs = EAttrs} = El}, + {AttrsAcc, XMLBuf}) + when Name == <<"message">>; + Name == <<"presence">>; + Name == <<"iq">> -> + NewAttrs = lists:keystore( + <<"xmlns">>, 1, EAttrs, + {<<"xmlns">>, ?NS_CLIENT}), + NewEl = El#xmlel{attrs = NewAttrs}, + {AttrsAcc, + [encode_element(NewEl, Type) | XMLBuf]}; + ({xmlstreamelement, El}, + {AttrsAcc, XMLBuf}) -> + {AttrsAcc, + [encode_element(El, Type) | XMLBuf]}; + ({xmlstreamend, _}, {AttrsAcc, XMLBuf}) -> + {[{<<"type">>, <<"terminate">>}, + {<<"condition">>, + <<"remote-stream-error">>} + | AttrsAcc], + XMLBuf}; + ({xmlstreamstart, <<"stream:stream">>, + SAttrs}, + {AttrsAcc, XMLBuf}) -> + StreamID = fxml:get_attr_s(<<"id">>, + SAttrs), + NewAttrs = case + fxml:get_attr_s(<<"version">>, + SAttrs) + of + <<"">> -> + [{<<"authid">>, + StreamID} + | AttrsAcc]; + V -> + lists:keystore(<<"xmlns:xmpp">>, + 1, + [{<<"xmpp:version">>, + V}, + {<<"authid">>, + StreamID} + | AttrsAcc], + {<<"xmlns:xmpp">>, + ?NS_BOSH}) + end, + {NewAttrs, XMLBuf}; + ({xmlstreamerror, _}, + {AttrsAcc, XMLBuf}) -> + {[{<<"type">>, <<"terminate">>}, + {<<"condition">>, + <<"remote-stream-error">>} + | AttrsAcc], + XMLBuf}; + (_, Acc) -> Acc + end, + {Attrs2, []}, Els), + case XMLs of + [] when Type == xml -> + [<<">, attrs_to_list(Attrs3), <<"/>">>]; + _ when Type == xml -> + [<<">, attrs_to_list(Attrs3), $>, XMLs, + <<"">>] + end. + +encode_element(El, xml) -> + fxml:element_to_binary(El); +encode_element(El, json) -> + El. + +decode_body(Data, Size, Type) -> + case decode(Data, Type) of + #xmlel{name = <<"body">>, attrs = Attrs, + children = Els} -> + case attrs_to_body_attrs(Attrs) of + {error, _} = Err -> Err; + BodyAttrs -> + case get_attr(rid, BodyAttrs) of + <<"">> -> {error, <<"Missing \"rid\" attribute">>}; + _ -> + Els1 = lists:flatmap(fun (#xmlel{} = El) -> + [{xmlstreamelement, El}]; + (_) -> [] + end, + Els), + {ok, #body{attrs = BodyAttrs, size = Size, els = Els1}} + end + end; + #xmlel{} -> {error, <<"Unexpected payload">>}; + _ when Type == xml -> + {error, <<"XML is not well-formed">>}; + _ when Type == json -> + {error, <<"JSON is not well-formed">>} + end. + +decode(Data, xml) -> + fxml_stream:parse_element(Data). + +attrs_to_body_attrs(Attrs) -> + lists:foldl(fun (_, {error, Reason}) -> {error, Reason}; + ({Attr, Val}, Acc) -> + try case Attr of + <<"ver">> -> [{ver, Val} | Acc]; + <<"xmpp:version">> -> + [{'xmpp:version', Val} | Acc]; + <<"type">> -> [{type, Val} | Acc]; + <<"key">> -> [{key, Val} | Acc]; + <<"newkey">> -> [{newkey, Val} | Acc]; + <<"xmlns">> -> Val = (?NS_HTTP_BIND), Acc; + <<"secure">> -> [{secure, to_bool(Val)} | Acc]; + <<"xmpp:restart">> -> + [{'xmpp:restart', to_bool(Val)} | Acc]; + <<"to">> -> + [{to, jid:nameprep(Val)} | Acc]; + <<"wait">> -> [{wait, to_int(Val, 0)} | Acc]; + <<"ack">> -> [{ack, to_int(Val, 0)} | Acc]; + <<"sid">> -> [{sid, Val} | Acc]; + <<"hold">> -> [{hold, to_int(Val, 0)} | Acc]; + <<"rid">> -> [{rid, to_int(Val, 0)} | Acc]; + <<"pause">> -> [{pause, to_int(Val, 0)} | Acc]; + _ -> [{Attr, Val} | Acc] + end + catch + _:_ -> + {error, + <<"Invalid \"", Attr/binary, "\" attribute">>} + end + end, + [], Attrs). + +to_int(S, Min) -> + case jlib:binary_to_integer(S) of + I when I >= Min -> I; + _ -> erlang:error(badarg) + end. + +to_bool(<<"true">>) -> true; +to_bool(<<"1">>) -> true; +to_bool(<<"false">>) -> false; +to_bool(<<"0">>) -> false. + +attrs_to_list(Attrs) -> [attr_to_list(A) || A <- Attrs]. + +attr_to_list({Name, Value}) -> + [$\s, Name, $=, $', fxml:crypt(Value), $']. + +bosh_response(Body, Type) -> + CType = case Type of + xml -> ?CT_XML; + json -> ?CT_JSON + end, + {200, Body#body.http_reason, ?HEADER(CType), + encode_body(Body, Type)}. + +bosh_response_with_msg(Body, Type, RcvBody) -> + ?DEBUG("send error reply:~p~n** Receiced body: ~p", + [Body, RcvBody]), + bosh_response(Body, Type). + +http_error(Status, Reason, Type) -> + CType = case Type of + xml -> ?CT_XML; + json -> ?CT_JSON + end, + {Status, Reason, ?HEADER(CType), <<"">>}. + +make_sid() -> p1_sha:sha(randoms:get_string()). + +-compile({no_auto_import, [{min, 2}]}). + +min(undefined, B) -> B; +min(A, B) -> erlang:min(A, B). + +check_bosh_module(XmppDomain) -> + case gen_mod:is_loaded(XmppDomain, mod_bosh) of + true -> ok; + false -> + ?ERROR_MSG("You are trying to use BOSH (HTTP Bind) " + "in host ~p, but the module mod_bosh " + "is not started in that host. Configure " + "your BOSH client to connect to the correct " + "host, or add your desired host to the " + "configuration, or check your 'modules' " + "section in your ejabberd configuration " + "file.", + [XmppDomain]) + end. + +get_attr(Attr, Attrs) -> get_attr(Attr, Attrs, <<"">>). + +get_attr(Attr, Attrs, Default) -> + case lists:keysearch(Attr, 1, Attrs) of + {value, {_, Val}} -> Val; + _ -> Default + end. + +buf_new() -> queue:new(). + +buf_in(Xs, Buf) -> + lists:foldl(fun (X, Acc) -> queue:in(X, Acc) end, Buf, + Xs). + +buf_out(Buf, Num) when is_integer(Num), Num > 0 -> + buf_out(Buf, Num, []); +buf_out(Buf, _) -> {queue:to_list(Buf), buf_new()}. + +buf_out(Buf, 0, Els) -> {lists:reverse(Els), Buf}; +buf_out(Buf, I, Els) -> + case queue:out(Buf) of + {{value, El}, NewBuf} -> + buf_out(NewBuf, I - 1, [El | Els]); + {empty, _} -> buf_out(Buf, 0, Els) + end. + +buf_to_list(Buf) -> queue:to_list(Buf). + +cancel_timer(TRef) when is_reference(TRef) -> + (?GEN_FSM):cancel_timer(TRef); +cancel_timer(_) -> false. + +restart_timer(TRef, Timeout, Msg) -> + cancel_timer(TRef), + erlang:start_timer(timer:seconds(Timeout), self(), Msg). + +restart_inactivity_timer(#state{inactivity_timeout = + Timeout} = + State) -> + restart_inactivity_timer(State, Timeout). + +restart_inactivity_timer(#state{inactivity_timer = + TRef} = + State, + Timeout) -> + NewTRef = restart_timer(TRef, Timeout, inactive), + State#state{inactivity_timer = NewTRef}. + +stop_inactivity_timer(#state{inactivity_timer = TRef} = + State) -> + cancel_timer(TRef), + State#state{inactivity_timer = undefined}. + +restart_wait_timer(#state{wait_timer = TRef, + wait_timeout = Timeout} = + State) -> + NewTRef = restart_timer(TRef, Timeout, wait_timeout), + State#state{wait_timer = NewTRef}. + +stop_wait_timer(#state{wait_timer = TRef} = State) -> + cancel_timer(TRef), State#state{wait_timer = undefined}. + +start_shaper_timer(Timeout) -> + erlang:start_timer(Timeout, self(), shaper_timeout). + +make_random_jid(Host) -> + User = randoms:get_string(), + jid:make(User, Host, randoms:get_string()). + +make_socket(Pid, IP) -> {http_bind, Pid, IP}. diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index b5fa52ded..e26fc8652 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -52,12 +52,14 @@ -include("logger.hrl"). -type sockmod() :: ejabberd_http_bind | + ejabberd_bosh | ejabberd_http_ws | gen_tcp | fast_tls | ezlib. -type receiver() :: pid () | atom(). -type socket() :: pid() | inet:socket() | fast_tls:tls_socket() | - ezlib:zlib_socket() | + ezlib:zlib_socket() | + ejabberd_bosh:bind_socket() | ejabberd_http_bind:bind_socket(). -record(socket_state, {sockmod = gen_tcp :: sockmod(), @@ -228,6 +230,7 @@ get_transport(#socket_state{sockmod = SockMod, tcp -> tcp_zlib; tls -> tls_zlib end; + ejabberd_bosh -> http_bind; ejabberd_http_bind -> http_bind; ejabberd_http_ws -> websocket end. @@ -254,4 +257,3 @@ peername(#socket_state{sockmod = SockMod, gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end. - diff --git a/src/mod_bosh.erl b/src/mod_bosh.erl new file mode 100644 index 000000000..13d85b3cb --- /dev/null +++ b/src/mod_bosh.erl @@ -0,0 +1,296 @@ +%%%------------------------------------------------------------------- +%%% File : mod_bosh.erl +%%% Author : Evgeniy Khramtsov +%%% Purpose : This module acts as a bridge to ejabberd_bosh which implements +%%% the real stuff, this is to handle the new pluggable architecture +%%% for extending ejabberd's http service. +%%% Created : 20 Jul 2011 by Evgeniy Khramtsov +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%------------------------------------------------------------------- +-module(mod_bosh). + +-author('steve@zeank.in-berlin.de'). + +%%-define(ejabberd_debug, true). + +-behaviour(gen_server). +-behaviour(gen_mod). + +-export([start_link/0]). +-export([start/2, stop/1, process/2, open_session/2, + close_session/1, find_session/1]). + +-export([init/1, handle_call/3, handle_cast/2, + handle_info/2, terminate/2, code_change/3, + depends/2, mod_opt_type/1]). + +-include("ejabberd.hrl"). +-include("logger.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). +-include("jlib.hrl"). + +-include("ejabberd_http.hrl"). + +-include("bosh.hrl"). + +-record(bosh, {sid = <<"">> :: binary() | '_', + timestamp = p1_time_compat:timestamp() :: erlang:timestamp() | '_', + pid = self() :: pid() | '$1'}). + +-record(state, {}). + +%%%---------------------------------------------------------------------- +%%% API +%%%---------------------------------------------------------------------- +start_link() -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). + +process([], #request{method = 'POST', data = <<>>}) -> + ?DEBUG("Bad Request: no data", []), + {400, ?HEADER(?CT_XML), + #xmlel{name = <<"h1">>, attrs = [], + children = [{xmlcdata, <<"400 Bad Request">>}]}}; +process([], + #request{method = 'POST', data = Data, ip = IP, headers = Hdrs}) -> + ?DEBUG("Incoming data: ~p", [Data]), + Type = get_type(Hdrs), + ejabberd_bosh:process_request(Data, IP, Type); +process([], #request{method = 'GET', data = <<>>}) -> + {200, ?HEADER(?CT_XML), get_human_html_xmlel()}; +process([], #request{method = 'OPTIONS', data = <<>>}) -> + {200, ?OPTIONS_HEADER, []}; +process(_Path, _Request) -> + ?DEBUG("Bad Request: ~p", [_Request]), + {400, ?HEADER(?CT_XML), + #xmlel{name = <<"h1">>, attrs = [], + children = [{xmlcdata, <<"400 Bad Request">>}]}}. + +get_human_html_xmlel() -> + Heading = <<"ejabberd ", (jlib:atom_to_binary(?MODULE))/binary>>, + #xmlel{name = <<"html">>, + attrs = + [{<<"xmlns">>, <<"http://www.w3.org/1999/xhtml">>}], + children = + [#xmlel{name = <<"head">>, attrs = [], + children = + [#xmlel{name = <<"title">>, attrs = [], + children = [{xmlcdata, Heading}]}]}, + #xmlel{name = <<"body">>, attrs = [], + children = + [#xmlel{name = <<"h1">>, attrs = [], + children = [{xmlcdata, Heading}]}, + #xmlel{name = <<"p">>, attrs = [], + children = + [{xmlcdata, <<"An implementation of ">>}, + #xmlel{name = <<"a">>, + attrs = + [{<<"href">>, + <<"http://xmpp.org/extensions/xep-0206.html">>}], + children = + [{xmlcdata, + <<"XMPP over BOSH (XEP-0206)">>}]}]}, + #xmlel{name = <<"p">>, attrs = [], + children = + [{xmlcdata, + <<"This web page is only informative. To " + "use HTTP-Bind you need a Jabber/XMPP " + "client that supports it.">>}]}]}]}. + +open_session(SID, Pid) -> + Session = #bosh{sid = SID, timestamp = p1_time_compat:timestamp(), pid = Pid}, + lists:foreach( + fun(Node) when Node == node() -> + gen_server:call(?MODULE, {write, Session}); + (Node) -> + cluster_send({?MODULE, Node}, {write, Session}) + end, ejabberd_cluster:get_nodes()). + +close_session(SID) -> + case mnesia:dirty_read(bosh, SID) of + [Session] -> + lists:foreach( + fun(Node) when Node == node() -> + gen_server:call(?MODULE, {delete, Session}); + (Node) -> + cluster_send({?MODULE, Node}, {delete, Session}) + end, ejabberd_cluster:get_nodes()); + [] -> + ok + end. + +write_session(#bosh{pid = Pid1, sid = SID, timestamp = T1} = S1) -> + case mnesia:dirty_read(bosh, SID) of + [#bosh{pid = Pid2, timestamp = T2} = S2] -> + if Pid1 == Pid2 -> + mnesia:dirty_write(S1); + T1 < T2 -> + cluster_send(Pid2, replaced), + mnesia:dirty_write(S1); + true -> + cluster_send(Pid1, replaced), + mnesia:dirty_write(S2) + end; + [] -> + mnesia:dirty_write(S1) + end. + +delete_session(#bosh{sid = SID, pid = Pid1}) -> + case mnesia:dirty_read(bosh, SID) of + [#bosh{pid = Pid2}] -> + if Pid1 == Pid2 -> + mnesia:dirty_delete(bosh, SID); + true -> + ok + end; + [] -> + ok + end. + +find_session(SID) -> + case mnesia:dirty_read(bosh, SID) of + [#bosh{pid = Pid}] -> + {ok, Pid}; + [] -> + error + end. + +start(Host, Opts) -> + setup_database(), + start_jiffy(Opts), + TmpSup = gen_mod:get_module_proc(Host, ?PROCNAME), + TmpSupSpec = {TmpSup, + {ejabberd_tmp_sup, start_link, [TmpSup, ejabberd_bosh]}, + permanent, infinity, supervisor, [ejabberd_tmp_sup]}, + ProcSpec = {?MODULE, + {?MODULE, start_link, []}, + transient, 2000, worker, [?MODULE]}, + case supervisor:start_child(ejabberd_sup, ProcSpec) of + {ok, _} -> + supervisor:start_child(ejabberd_sup, TmpSupSpec); + {error, {already_started, _}} -> + supervisor:start_child(ejabberd_sup, TmpSupSpec); + Err -> + Err + end. + +stop(Host) -> + TmpSup = gen_mod:get_module_proc(Host, ?PROCNAME), + supervisor:terminate_child(ejabberd_sup, TmpSup), + supervisor:delete_child(ejabberd_sup, TmpSup). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== +init([]) -> + {ok, #state{}}. + +handle_call({write, Session}, _From, State) -> + Res = write_session(Session), + {reply, Res, State}; +handle_call({delete, Session}, _From, State) -> + Res = delete_session(Session), + {reply, Res, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info({write, Session}, State) -> + write_session(Session), + {noreply, State}; +handle_info({delete, Session}, State) -> + delete_session(Session), + {noreply, State}; +handle_info(_Info, State) -> + ?ERROR_MSG("got unexpected info: ~p", [_Info]), + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +setup_database() -> + case catch mnesia:table_info(bosh, attributes) of + [sid, pid] -> + mnesia:delete_table(bosh); + _ -> + ok + end, + mnesia:create_table(bosh, + [{ram_copies, [node()]}, {local_content, true}, + {attributes, record_info(fields, bosh)}]), + mnesia:add_table_copy(bosh, node(), ram_copies). + +start_jiffy(Opts) -> + case gen_mod:get_opt(json, Opts, + fun(false) -> false; + (true) -> true + end, false) of + false -> + ok; + true -> + case catch ejabberd:start_app(jiffy) of + ok -> + ok; + Err -> + ?WARNING_MSG("Failed to start JSON codec (jiffy): ~p. " + "JSON support will be disabled", [Err]) + end + end. + +get_type(Hdrs) -> + try + {_, S} = lists:keyfind('Content-Type', 1, Hdrs), + [T|_] = str:tokens(S, <<";">>), + [_, <<"json">>] = str:tokens(T, <<"/">>), + json + catch _:_ -> + xml + end. + +cluster_send(NodePid, Msg) -> + erlang:send(NodePid, Msg, [noconnect, nosuspend]). + +depends(_Host, _Opts) -> + []. + +mod_opt_type(json) -> + fun (false) -> false; + (true) -> true + end; +mod_opt_type(max_concat) -> + fun (unlimited) -> unlimited; + (N) when is_integer(N), N > 0 -> N + end; +mod_opt_type(max_inactivity) -> + fun (I) when is_integer(I), I > 0 -> I end; +mod_opt_type(max_pause) -> + fun (I) when is_integer(I), I > 0 -> I end; +mod_opt_type(prebind) -> + fun (B) when is_boolean(B) -> B end; +mod_opt_type(_) -> + [json, max_concat, max_inactivity, max_pause, prebind]. -- cgit v1.2.3 From cc63bcc997282da99e250dfc0d5dcd46ba2469c7 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 16:01:08 +0100 Subject: Fix issues on import improvements --- src/mod_offline_riak.erl | 4 ++-- src/mod_privacy.erl | 1 + src/mod_privacy_mnesia.erl | 4 ++-- src/mod_privacy_riak.erl | 4 ++-- src/mod_vcard_ldap.erl | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl index 24d565383..824abc89c 100644 --- a/src/mod_offline_riak.erl +++ b/src/mod_offline_riak.erl @@ -13,7 +13,7 @@ -export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1, remove_old_messages/2, remove_user/2, read_message_headers/2, read_message/3, remove_message/3, read_all_messages/2, - remove_all_messages/2, count_messages/2, import/2]). + remove_all_messages/2, count_messages/2, import/1]). -include("xmpp.hrl"). -include("mod_offline.hrl"). @@ -133,7 +133,7 @@ count_messages(LUser, LServer) -> 0 end. -import(_LServer, #offline_msg{us = US, timestamp = TS} = M) -> +import(#offline_msg{us = US, timestamp = TS} = M) -> ejabberd_riak:put(M, offline_msg_schema(), [{i, TS}, {'2i', [{<<"us">>, US}]}]). diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 97a8f1804..f1b8411d2 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -35,6 +35,7 @@ process_iq_set/3, process_iq_get/3, get_user_list/3, check_packet/6, remove_user/2, encode_list_item/1, is_list_needdb/1, updated_list/3, + import_start/2, import_stop/2, item_to_xml/1, get_user_lists/2, import/5, set_privacy_list/1, mod_opt_type/1, depends/2]). diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl index 4642ba58e..a93e92139 100644 --- a/src/mod_privacy_mnesia.erl +++ b/src/mod_privacy_mnesia.erl @@ -15,7 +15,7 @@ process_default_set/3, process_active_set/3, remove_privacy_list/3, set_privacy_list/1, set_privacy_list/4, get_user_list/2, get_user_lists/2, - remove_user/2, import/2]). + remove_user/2, import/1]). -include("xmpp.hrl"). -include("mod_privacy.hrl"). @@ -144,7 +144,7 @@ remove_user(LUser, LServer) -> F = fun () -> mnesia:delete({privacy, {LUser, LServer}}) end, mnesia:transaction(F). -import(_LServer, #privacy{} = P) -> +import(#privacy{} = P) -> mnesia:dirty_write(P). %%%=================================================================== diff --git a/src/mod_privacy_riak.erl b/src/mod_privacy_riak.erl index 509ff5ebb..b96a08cbc 100644 --- a/src/mod_privacy_riak.erl +++ b/src/mod_privacy_riak.erl @@ -15,7 +15,7 @@ process_default_set/3, process_active_set/3, remove_privacy_list/3, set_privacy_list/1, set_privacy_list/4, get_user_list/2, get_user_lists/2, - remove_user/2, import/2]). + remove_user/2, import/1]). -export([privacy_schema/0]). @@ -145,7 +145,7 @@ get_user_lists(LUser, LServer) -> remove_user(LUser, LServer) -> {atomic, ejabberd_riak:delete(privacy, {LUser, LServer})}. -import(_LServer, #privacy{} = P) -> +import(#privacy{} = P) -> ejabberd_riak:put(P, privacy_schema()). %%%=================================================================== diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index d8efe30f5..c9e19690f 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -14,7 +14,7 @@ %% API -export([start_link/2]). -export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, - remove_user/2, import/2, search_fields/1, search_reported/1, + remove_user/2, import/3, search_fields/1, search_reported/1, mod_opt_type/1, opt_type/1]). %% gen_server callbacks @@ -157,7 +157,7 @@ search_items(Entries, State) -> remove_user(_User, _Server) -> {atomic, not_implemented}. -import(_, _) -> +import(_, _, _) -> pass. %%%=================================================================== -- cgit v1.2.3 From c0e7b298db4bf045bfda196b029708cef3b9acc3 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 16:12:19 +0100 Subject: Add missing export --- src/mod_last.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mod_last.erl b/src/mod_last.erl index 47db0b6c6..895a8e215 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -35,7 +35,7 @@ -export([start/2, stop/1, process_local_iq/1, export/1, process_sm_iq/1, on_presence_update/4, import_info/0, - import/5, store_last_info/4, get_last_info/2, + import/5, import_start/2, store_last_info/4, get_last_info/2, remove_user/2, transform_options/1, mod_opt_type/1, opt_type/1, register_user/2, depends/2]). -- cgit v1.2.3 From 24ef90c5567c4bf6c60e2963dcdd59ab91a9570f Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 16:23:02 +0100 Subject: Fix vcard_ldap exports --- src/mod_vcard_ldap.erl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index c9e19690f..47504c39d 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_vcard_ldap). +-behaviour(ejabberd_config). + -behaviour(gen_server). -behaviour(mod_vcard). @@ -16,6 +18,7 @@ -export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2, import/3, search_fields/1, search_reported/1, mod_opt_type/1, opt_type/1]). +-export([is_search_supported/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -70,6 +73,9 @@ stop(Host) -> supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). +is_search_supported(_LServer) -> + true. + get_vcard(LUser, LServer) -> {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME), VCardMap = State#state.vcard_map, -- cgit v1.2.3 From 9ab169bc6366187d17e1137d0c26a67849ff4451 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 16:59:02 +0100 Subject: Fix get_roster issue injected by fbfbb96 --- src/mod_roster_mnesia.erl | 2 +- src/mod_roster_riak.erl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index 1a33407e1..e274ac5eb 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -51,7 +51,7 @@ write_roster_version(LUser, LServer, InTransaction, Ver) -> end. get_roster(LUser, LServer) -> - {ok, mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us)}. + mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us). get_roster_by_jid(LUser, LServer, LJID) -> case mnesia:read({roster, {LUser, LServer, LJID}}) of diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl index 53f0e7fb4..40992d77d 100644 --- a/src/mod_roster_riak.erl +++ b/src/mod_roster_riak.erl @@ -41,8 +41,8 @@ write_roster_version(LUser, LServer, _InTransaction, Ver) -> get_roster(LUser, LServer) -> case ejabberd_riak:get_by_index(roster, roster_schema(), <<"us">>, {LUser, LServer}) of - {ok, Items} -> {ok, Items}; - _Err -> error + {ok, Items} -> Items; + _Err -> [] end. get_roster_by_jid(LUser, LServer, LJID) -> -- cgit v1.2.3 From ee8cc1dac2a9cfcb3e845108c42d414764c0eb64 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 22 Nov 2016 17:51:21 +0100 Subject: Fix xref issue injected by fbfbb96 --- src/ejabberd_auth_mnesia.erl | 15 +++++++++------ src/mod_roster_sql.erl | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index 2e9ef5c94..dee3774db 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -36,7 +36,7 @@ -export([start/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, - get_vh_registered_users/2, + get_vh_registered_users/2, init_db/0, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, @@ -59,16 +59,19 @@ %%% API %%%---------------------------------------------------------------------- start(Host) -> + init_db(), + update_table(), + update_reg_users_counter_table(Host), + maybe_alert_password_scrammed_without_option(), + ok. + +init_db() -> mnesia:create_table(passwd, [{disc_copies, [node()]}, {attributes, record_info(fields, passwd)}]), mnesia:create_table(reg_users_counter, [{ram_copies, [node()]}, - {attributes, record_info(fields, reg_users_counter)}]), - update_table(), - update_reg_users_counter_table(Host), - maybe_alert_password_scrammed_without_option(), - ok. + {attributes, record_info(fields, reg_users_counter)}]). update_reg_users_counter_table(Server) -> Set = get_vh_registered_users(Server), diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl index 708a20295..2fc6b112e 100644 --- a/src/mod_roster_sql.erl +++ b/src/mod_roster_sql.erl @@ -18,7 +18,7 @@ roster_subscribe/4, get_roster_by_jid_with_groups/3, remove_user/2, update_roster/4, del_roster/3, transaction/2, read_subscription_and_groups/3, get_only_items/2, - import/3, export/1]). + import/3, export/1, raw_to_record/2]). -include("mod_roster.hrl"). -include("ejabberd_sql_pt.hrl"). -- cgit v1.2.3 From 114ca786ee051b68c6ddc88b012af2226b07601e Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 22 Nov 2016 19:25:20 +0100 Subject: Let ejabberd_sm mark copied messages When multiple resources have the same (highest) priority, ejabberd_sm dispatches messages addressed to the bare JID (or to an unavailable resource) to each of these resources. Such messages are now marked with an 'sm_copy' flag for all but one of the resources. This makes it easier for other modules to identify those duplicates. Resolves #1356. --- src/ejabberd_sm.erl | 23 +++++++++++++++++++---- src/mod_carboncopy.erl | 20 ++++++++++---------- src/mod_mam.erl | 39 ++++----------------------------------- 3 files changed, 33 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 18703dc9c..b3953ec49 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -570,9 +570,9 @@ route_message(From, To, Packet, Type) -> LServer = To#jid.lserver, PrioRes = get_user_present_resources(LUser, LServer), case catch lists:max(PrioRes) of - {Priority, _R} - when is_integer(Priority), Priority >= 0 -> - lists:foreach(fun ({P, R}) when P == Priority; + {MaxPrio, MaxRes} + when is_integer(MaxPrio), MaxPrio >= 0 -> + lists:foreach(fun ({P, R}) when P == MaxPrio; (P >= 0) and (Type == headline) -> LResource = jid:resourceprep(R), Mod = get_sm_backend(LServer), @@ -584,7 +584,12 @@ route_message(From, To, Packet, Type) -> Session = lists:max(Ss), Pid = element(2, Session#session.sid), ?DEBUG("sending to process ~p~n", [Pid]), - Pid ! {route, From, To, Packet} + LMaxRes = jid:resourceprep(MaxRes), + Packet1 = maybe_mark_as_copy(Packet, + LResource, + LMaxRes, + P, MaxPrio), + Pid ! {route, From, To, Packet1} end; %% Ignore other priority: ({_Prio, _Res}) -> ok @@ -603,6 +608,16 @@ route_message(From, To, Packet, Type) -> end end. +-spec maybe_mark_as_copy(message(), binary(), binary(), integer(), integer()) + -> message(). +maybe_mark_as_copy(Packet, R, R, P, P) -> + Packet; +maybe_mark_as_copy(Packet, _, _, P, P) -> + Meta = Packet#message.meta, + Packet#message{meta = Meta#{sm_copy => true}}; +maybe_mark_as_copy(Packet, _, _, _, _) -> + Packet. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec clean_session_list([#session{}]) -> [#session{}]. clean_session_list(Ss) -> diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 1c8ca1fdc..f1eb3e790 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -153,7 +153,7 @@ send_copies(JID, To, Packet, Direction)-> {U, S, R} = jid:tolower(JID), PrioRes = ejabberd_sm:get_user_present_resources(U, S), {_, AvailRs} = lists:unzip(PrioRes), - {MaxPrio, MaxRes} = case catch lists:max(PrioRes) of + {MaxPrio, _MaxRes} = case catch lists:max(PrioRes) of {Prio, Res} -> {Prio, Res}; _ -> {0, undefined} end, @@ -166,19 +166,19 @@ send_copies(JID, To, Packet, Direction)-> end, %% list of JIDs that should receive a carbon copy of this message (excluding the %% receiver(s) of the original message - TargetJIDs = case {IsBareTo, R} of - {true, MaxRes} -> - OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end, - [ {jid:make({U, S, CCRes}), CC_Version} - || {CCRes, CC_Version} <- list(U, S), - lists:member(CCRes, AvailRs), not OrigTo(CCRes) ]; - {true, _} -> + TargetJIDs = case {IsBareTo, Packet} of + {true, #message{meta = #{sm_copy := true}}} -> %% The message was sent to our bare JID, and we currently have %% multiple resources with the same highest priority, so the session %% manager routes the message to each of them. We create carbon - %% copies only from one of those resources (the one where R equals - %% MaxRes) in order to avoid duplicates. + %% copies only from one of those resources in order to avoid + %% duplicates. []; + {true, _} -> + OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end, + [ {jid:make({U, S, CCRes}), CC_Version} + || {CCRes, CC_Version} <- list(U, S), + lists:member(CCRes, AvailRs), not OrigTo(CCRes) ]; {false, _} -> [ {jid:make({U, S, CCRes}), CC_Version} || {CCRes, CC_Version} <- list(U, S), diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 61754ae59..0433dee79 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -200,12 +200,11 @@ set_room_option(Acc, _Property, _Lang) -> Acc. -spec user_receive_packet(stanza(), ejabberd_c2s:state(), jid(), jid(), jid()) -> stanza(). -user_receive_packet(Pkt, C2SState, JID, Peer, To) -> +user_receive_packet(Pkt, C2SState, JID, Peer, _To) -> LUser = JID#jid.luser, LServer = JID#jid.lserver, - IsBareCopy = is_bare_copy(JID, To), case should_archive(Pkt, LServer) of - true when not IsBareCopy -> + true -> NewPkt = strip_my_archived_tag(Pkt, LServer), case store_msg(C2SState, NewPkt, LUser, LServer, Peer, recv) of {ok, ID} -> @@ -454,6 +453,8 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang, should_archive(#message{type = error}, _LServer) -> false; +should_archive(#message{meta = #{sm_copy := true}}, _LServer) -> + false; should_archive(#message{body = Body, subject = Subject, type = Type} = Pkt, LServer) -> case is_resent(Pkt, LServer) of @@ -812,38 +813,6 @@ maybe_update_from_to(#message{sub_els = Els} = Pkt, JidRequestor, JidArchive, maybe_update_from_to(Pkt, _JidRequestor, _JidArchive, _Peer, chat, _Nick) -> Pkt. -is_bare_copy(#jid{luser = U, lserver = S, lresource = R}, To) -> - PrioRes = ejabberd_sm:get_user_present_resources(U, S), - MaxRes = case catch lists:max(PrioRes) of - {_Prio, Res} when is_binary(Res) -> - Res; - _ -> - undefined - end, - IsBareTo = case To of - #jid{lresource = <<"">>} -> - true; - #jid{lresource = LRes} -> - %% Unavailable resources are handled like bare JIDs. - lists:keyfind(LRes, 2, PrioRes) =:= false - end, - case {IsBareTo, R} of - {true, MaxRes} -> - ?DEBUG("Recipient of message to bare JID has top priority: ~s@~s/~s", - [U, S, R]), - false; - {true, _R} -> - %% The message was sent to our bare JID, and we currently have - %% multiple resources with the same highest priority, so the session - %% manager routes the message to each of them. We store the message - %% only from the resource where R equals MaxRes. - ?DEBUG("Additional recipient of message to bare JID: ~s@~s/~s", - [U, S, R]), - true; - {false, _R} -> - false - end. - -spec send([{binary(), integer(), xmlel()}], non_neg_integer(), boolean(), iq()) -> iq() | ignore. send(Msgs, Count, IsComplete, -- cgit v1.2.3 From 3325e69ae6d625968ce8ec09d9100b5eeca9fb28 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 22 Nov 2016 22:21:34 +0100 Subject: Let mod_carboncopy mark copied messages Carbon copies are now marked with a 'carbon_copy' flag. This makes it easier to identify them. --- src/ejabberd_c2s.erl | 44 +++++++++++++++----------------------------- src/mod_carboncopy.erl | 10 ++++++---- 2 files changed, 21 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 7ef708d31..6d84d8d93 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -2645,44 +2645,30 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData) Txt = <<"User session terminated">>, ejabberd_router:route_error( To, From, El, xmpp:err_service_unavailable(Txt, Lang)); + (From, _To, #message{meta = #{carbon_copy := true}}, _Time) -> + %% XEP-0280 says: "When a receiving server attempts to deliver a + %% forked message, and that message bounces with an error for + %% any reason, the receiving server MUST NOT forward that error + %% back to the original sender." Resending such a stanza could + %% easily lead to unexpected results as well. + ?DEBUG("Dropping forwarded message stanza from ~s", + [jid:to_string(From)]); (From, To, El, Time) -> - %% We'll drop the stanza if it was by some - %% encapsulating protocol as per XEP-0297. One such protocol is - %% XEP-0280, which says: "When a receiving server attempts to - %% deliver a forked message, and that message bounces with an - %% error for any reason, the receiving server MUST NOT forward - %% that error back to the original sender." Resending such a - %% stanza could easily lead to unexpected results as well. - case is_encapsulated_forward(El) of + case ejabberd_hooks:run_fold(message_is_archived, + StateData#state.server, false, + [StateData, From, + StateData#state.jid, El]) of true -> - ?DEBUG("Dropping forwarded message stanza from ~s", - [jid:to_string(From)]); + ?DEBUG("Dropping archived message stanza from ~p", + [jid:to_string(xmpp:get_from(El))]); false -> - case ejabberd_hooks:run_fold(message_is_archived, - StateData#state.server, - false, - [StateData, From, - StateData#state.jid, El]) of - true -> - ?DEBUG("Dropping archived message stanza from ~p", - [jid:to_string(xmpp:get_from(El))]); - false -> - ReRoute(From, To, El, Time) - end + ReRoute(From, To, El, Time) end end, handle_unacked_stanzas(StateData, F); handle_unacked_stanzas(_StateData) -> ok. --spec is_encapsulated_forward(stanza()) -> boolean(). -is_encapsulated_forward(#message{} = Msg) -> - xmpp:has_subtag(Msg, #forwarded{}) orelse - xmpp:has_subtag(Msg, #carbons_sent{}) orelse - xmpp:has_subtag(Msg, #carbons_received{}); -is_encapsulated_forward(_El) -> - false. - -spec inherit_session_state(state(), binary()) -> {ok, state()} | {error, binary()} | {error, binary(), non_neg_integer()}. diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index f1eb3e790..5839a65b2 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -52,9 +52,10 @@ -callback list(binary(), binary()) -> [{binary(), binary()}]. -spec is_carbon_copy(stanza()) -> boolean(). -is_carbon_copy(Packet) -> - xmpp:has_subtag(Packet, #carbons_sent{}) orelse - xmpp:has_subtag(Packet, #carbons_received{}). +is_carbon_copy(#message{meta = #{carbon_copy := true}}) -> + true; +is_carbon_copy(_) -> + false. start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts,fun gen_iq_handler:check_type/1, one_queue), @@ -203,7 +204,8 @@ build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) -> sent -> #carbons_sent{forwarded = Forwarded}; received -> #carbons_received{forwarded = Forwarded} end, - #message{from = Sender, to = Dest, type = T, sub_els = [Carbon]}. + #message{from = Sender, to = Dest, type = T, sub_els = [Carbon], + meta = #{carbon_copy => true}}. -spec enable(binary(), binary(), binary(), binary()) -> ok | {error, any()}. enable(Host, U, R, CC)-> -- cgit v1.2.3 From 6f2f1e87c950b7bc7396ae7f556f85b38c1e5fd4 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 23 Nov 2016 10:41:26 +0300 Subject: Don't use deprecated functions from jlib.erl --- src/ejabberd_bosh.erl | 2 +- src/mod_last.erl | 2 +- src/mod_offline.erl | 8 ++++---- src/mod_privacy.erl | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index d4fc6809d..1dc103aee 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -966,7 +966,7 @@ attrs_to_body_attrs(Attrs) -> [], Attrs). to_int(S, Min) -> - case jlib:binary_to_integer(S) of + case binary_to_integer(S) of I when I >= Min -> I; _ -> erlang:error(badarg) end. diff --git a/src/mod_last.erl b/src/mod_last.erl index 895a8e215..463eac051 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -217,7 +217,7 @@ import_start(LServer, DBType) -> import(LServer, {sql, _}, DBType, <<"last">>, [LUser, TimeStamp, State]) -> TS = case TimeStamp of <<"">> -> 0; - _ -> jlib:binary_to_integer(TimeStamp) + _ -> binary_to_integer(TimeStamp) end, LA = #last_activity{us = {LUser, LServer}, timestamp = TS, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 241677b2a..f620e73c5 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -868,10 +868,10 @@ import(LServer, {sql, _}, DBType, <<"spool">>, fxml:get_attr_s(<<"to">>, El#xmlel.attrs)), Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, {attr, <<"stamp">>}]), - TS = case jlib:datetime_string_to_timestamp(Stamp) of - {MegaSecs, Secs, _} -> - {MegaSecs, Secs, 0}; - undefined -> + TS = try xmpp_util:decode_timestamp(Stamp) of + {MegaSecs, Secs, _} -> + {MegaSecs, Secs, 0} + catch _:_ -> p1_time_compat:timestamp() end, US = {LUser, LServer}, diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index f1b8411d2..d6936e1b7 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -552,13 +552,13 @@ numeric_to_binary(<<0, _, _:6/binary, T/binary>>) -> fun(X, Sum) -> Sum*10000 + X end, 0, [X || <> <= T]), - jlib:integer_to_binary(Res). + integer_to_binary(Res). bool_to_binary(<<0>>) -> <<"0">>; bool_to_binary(<<1>>) -> <<"1">>. prepare_list_data(mysql, [ID|Row]) -> - [jlib:binary_to_integer(ID)|Row]; + [binary_to_integer(ID)|Row]; prepare_list_data(pgsql, [<>, SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ, SMatchMessage, SMatchPresenceIn, @@ -572,7 +572,7 @@ prepare_list_data(pgsql, [<>, bool_to_binary(SMatchPresenceOut)]. prepare_id(mysql, ID) -> - jlib:binary_to_integer(ID); + binary_to_integer(ID); prepare_id(pgsql, <>) -> ID. -- cgit v1.2.3 From 5d434c1aeac42323a9913c7261bf3f7ac6b6b1a8 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 23 Nov 2016 15:51:48 +0300 Subject: Move copyright definition to ejabberd.hrl --- src/mod_irc.erl | 3 +-- src/mod_muc.erl | 3 +-- src/mod_multicast.erl | 3 +-- src/mod_proxy65_service.erl | 3 +-- src/mod_pubsub.erl | 3 +-- src/mod_vcard.erl | 6 ++---- 6 files changed, 7 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 2fb35414d..3dd0e492d 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -420,10 +420,9 @@ iq_disco(ServerHost, Node, Lang) -> iq_get_vcard(Lang) -> Desc = translate:translate(Lang, <<"ejabberd IRC module">>), - Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, #vcard_temp{fn = <<"ejabberd/mod_irc">>, url = ?EJABBERD_URI, - desc = <>}. + desc = <>}. command_items(ServerHost, Host, Lang) -> lists:map(fun({Node, Name, _Function}) -> diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 28008aaae..554a21704 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -429,11 +429,10 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, -spec process_vcard(iq()) -> iq(). process_vcard(#iq{type = get, lang = Lang, sub_els = [#vcard_temp{}]} = IQ) -> Desc = translate:translate(Lang, <<"ejabberd MUC module">>), - Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, xmpp:make_iq_result( IQ, #vcard_temp{fn = <<"ejabberd/mod_muc">>, url = ?EJABBERD_URI, - desc = <>}); + desc = <>}); process_vcard(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>, xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index 72046491f..0aa2270ae 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -268,10 +268,9 @@ iq_disco_info(From, Lang, State) -> iq_vcard(Lang) -> Desc = translate:translate(Lang, <<"ejabberd Multicast service">>), - Copyright = <<"Copyright (c) 2002-2016 ProcessOne">>, #vcard_temp{fn = <<"ejabberd/mod_multicast">>, url = ?EJABBERD_URI, - desc = <>}. + desc = <>}. %%%------------------------- %%% Route diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index 789771d7d..0f69086e0 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -136,11 +136,10 @@ process_vcard(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_vcard(#iq{type = get, lang = Lang} = IQ) -> Desc = translate:translate(Lang, <<"ejabberd SOCKS5 Bytestreams module">>), - Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, xmpp:make_iq_result( IQ, #vcard_temp{fn = <<"ejabberd/mod_proxy65">>, url = ?EJABBERD_URI, - desc = <>}). + desc = <>}). -spec process_bytestreams(iq()) -> iq(). process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) -> diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index a138b1896..c379760ed 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -1186,10 +1186,9 @@ iq_sm(#iq{to = To, sub_els = [SubEl]} = IQ) -> -spec iq_get_vcard(binary()) -> vcard_temp(). iq_get_vcard(Lang) -> Desc = translate:translate(Lang, <<"ejabberd Publish-Subscribe module">>), - Copyright = <<"Copyright (c) 2004-2016 ProcessOne">>, #vcard_temp{fn = <<"ejabberd/mod_pubsub">>, url = ?EJABBERD_URI, - desc = <>}. + desc = <>}. -spec iq_pubsub(binary() | ljid(), atom(), iq()) -> {result, pubsub()} | {error, stanza_error()}. diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index dc9476206..843281ef8 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -191,11 +191,10 @@ process_local_iq(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_local_iq(#iq{type = get, lang = Lang} = IQ) -> Desc = translate:translate(Lang, <<"Erlang Jabber Server">>), - Copyright = <<"Copyright (c) 2002-2016 ProcessOne">>, xmpp:make_iq_result( IQ, #vcard_temp{fn = <<"ejabberd">>, url = ?EJABBERD_URI, - desc = <>, + desc = <>, bday = <<"2002-11-16">>}). -spec process_sm_iq(iq()) -> iq(). @@ -228,11 +227,10 @@ process_vcard(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_vcard(#iq{type = get, lang = Lang} = IQ) -> Desc = translate:translate(Lang, <<"ejabberd vCard module">>), - Copyright = <<"Copyright (c) 2003-2016 ProcessOne">>, xmpp:make_iq_result( IQ, #vcard_temp{fn = <<"ejabberd/mod_vcard">>, url = ?EJABBERD_URI, - desc = <>}). + desc = <>}). -spec process_search(iq()) -> iq(). process_search(#iq{type = get, to = To, lang = Lang} = IQ) -> -- cgit v1.2.3 From 12683b4aaff813b3fbc0e34029f412afdd19699f Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 23 Nov 2016 14:35:13 +0100 Subject: Fix typo in copyright date --- src/ejabberd_commands_doc.erl | 2 +- src/mod_admin_extra.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ejabberd_commands_doc.erl b/src/ejabberd_commands_doc.erl index 477e4f5d5..bb519a600 100644 --- a/src/ejabberd_commands_doc.erl +++ b/src/ejabberd_commands_doc.erl @@ -5,7 +5,7 @@ %%% Created : 20 May 2008 by Badlop %%% %%% -%%% ejabberd, Copyright (C) 2002-2015 ProcessOne +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 053ce8092..3c51e8c69 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -5,7 +5,7 @@ %%% Created : 10 Aug 2008 by Badlop %%% %%% -%%% ejabberd, Copyright (C) 2002-2008 ProcessOne +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as -- cgit v1.2.3 From 560038c808cafe08e0cc5c6abb431e1e82f02f88 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Thu, 24 Nov 2016 10:47:26 +0100 Subject: Use xmpp:put_meta/3 to update metadata --- src/ejabberd_sm.erl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index b3953ec49..d40db28cc 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -613,8 +613,7 @@ route_message(From, To, Packet, Type) -> maybe_mark_as_copy(Packet, R, R, P, P) -> Packet; maybe_mark_as_copy(Packet, _, _, P, P) -> - Meta = Packet#message.meta, - Packet#message{meta = Meta#{sm_copy => true}}; + xmpp:put_meta(Packet, sm_copy, true); maybe_mark_as_copy(Packet, _, _, _, _) -> Packet. -- cgit v1.2.3 From b14843d098dcfd8f9a7859132356caa396fd907c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Thu, 24 Nov 2016 12:44:09 +0100 Subject: Add missing -callbacks --- src/mod_muc_room.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 5b000548a..aa1c77aad 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -79,6 +79,16 @@ -export_type([state/0]). +-callback set_affiliation(binary(), binary(), binary(), jid(), affiliation(), + binary()) -> ok | {error, any()}. +-callback set_affiliations(binary(), binary(), binary(), + ?TDICT) -> ok | {error, any()}. +-callback get_affiliation(binary(), binary(), binary(), + binary(), binary()) -> {ok, affiliation()} | {error, any()}. +-callback get_affiliations(binary(), binary(), binary()) -> {ok, ?TDICT} | {error, any()}. +-callback search_affiliation(binary(), binary(), binary(), affiliation()) -> + {ok, [{ljid(), {affiliation(), binary()}}]} | {error, any()}. + %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -- cgit v1.2.3 From 49f1275e2005c8bce2fdcad8499f4fad94a9d768 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 24 Nov 2016 15:06:06 +0300 Subject: Get rid of excessive (io)list_to_binary/1 calls --- src/acl.erl | 2 +- src/ejabberd_access_permissions.erl | 4 +- src/ejabberd_admin.erl | 7 ++- src/ejabberd_bosh.erl | 2 +- src/ejabberd_captcha.erl | 2 +- src/ejabberd_http.erl | 6 +-- src/ejabberd_http_bind.erl | 18 +++----- src/ejabberd_piefxis.erl | 9 ++-- src/ejabberd_riak.erl | 6 +-- src/ejabberd_system_monitor.erl | 7 ++- src/ejabberd_web_admin.erl | 64 +++++++++++++-------------- src/jlib.erl | 8 ++-- src/mod_configure.erl | 50 +++++++++------------ src/mod_irc.erl | 87 +++++++++++++++++-------------------- src/mod_irc_connection.erl | 2 +- src/mod_muc_log.erl | 10 ++--- src/mod_offline.erl | 4 +- src/mod_pubsub.erl | 2 +- src/mod_register.erl | 2 +- src/mod_sip_proxy.erl | 4 +- src/mod_sip_registrar.erl | 2 +- src/mod_stats.erl | 26 +++++------ src/mod_version.erl | 2 +- src/pubsub_db_sql.erl | 2 +- src/pubsub_subscription.erl | 14 +++--- src/pubsub_subscription_sql.erl | 14 +++--- 26 files changed, 163 insertions(+), 193 deletions(-) (limited to 'src') diff --git a/src/acl.erl b/src/acl.erl index e3fdfcae1..595228ee9 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -342,7 +342,7 @@ acl_rule_verify({node_glob, {UR, SR}}) when is_binary(UR), is_binary(SR) -> acl_rule_verify(_Spec) -> false. invalid_syntax(Msg, Data) -> - throw({invalid_syntax, iolist_to_binary(io_lib:format(Msg, Data))}). + throw({invalid_syntax, (str:format(Msg, Data))}). acl_rules_verify([{acl, Name} | Rest], true) when is_atom(Name) -> acl_rules_verify(Rest, true); diff --git a/src/ejabberd_access_permissions.erl b/src/ejabberd_access_permissions.erl index 7ce75aa9c..60ad68a29 100644 --- a/src/ejabberd_access_permissions.erl +++ b/src/ejabberd_access_permissions.erl @@ -532,10 +532,10 @@ key_split([{Arg, Value} | Rest], Results, Order, Required, Duplicates) -> end. report_error(Format, Args) -> - throw({invalid_syntax, iolist_to_binary(io_lib:format(Format, Args))}). + throw({invalid_syntax, (str:format(Format, Args))}). parse_error(Format, Args) -> - {error, iolist_to_binary(io_lib:format(Format, Args))}. + {error, (str:format(Format, Args))}. opt_type(api_permissions) -> fun parse_api_permissions/1; diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index 8622ea8d0..99aa51794 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -302,8 +302,8 @@ set_loglevel(LogLevel) -> %%% stop_kindly(DelaySeconds, AnnouncementTextString) -> - Subject = list_to_binary(io_lib:format("Server stop in ~p seconds!", [DelaySeconds])), - WaitingDesc = list_to_binary(io_lib:format("Waiting ~p seconds", [DelaySeconds])), + Subject = (str:format("Server stop in ~p seconds!", [DelaySeconds])), + WaitingDesc = (str:format("Waiting ~p seconds", [DelaySeconds])), AnnouncementText = list_to_binary(AnnouncementTextString), Steps = [ {"Stopping ejabberd port listeners", @@ -337,8 +337,7 @@ stop_kindly(DelaySeconds, AnnouncementTextString) -> ok. send_service_message_all_mucs(Subject, AnnouncementText) -> - Message = list_to_binary( - io_lib:format("~s~n~s", [Subject, AnnouncementText])), + Message = str:format("~s~n~s", [Subject, AnnouncementText]), lists:foreach( fun(ServerHost) -> MUCHost = gen_mod:get_module_opt_host( diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index 1dc103aee..b94184167 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -807,7 +807,7 @@ encode_body(#body{attrs = Attrs, els = Els}, Type) -> true -> {AmK, <<"true">>}; false -> {AmK, <<"false">>}; I when is_integer(I), I >= 0 -> - {AmK, iolist_to_binary(integer_to_list(I))}; + {AmK, integer_to_binary(I)}; _ -> {AmK, V} end; ({K, V}) -> {K, V} diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index a122eda8e..f959d7f30 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -103,7 +103,7 @@ create_captcha(SID, From, To, Lang, Limiter, Args) -> BodyString1 = translate:translate(Lang, <<"Your messages to ~s are being blocked. " "To unblock them, visit ~s">>), - BodyString = iolist_to_binary(io_lib:format(BodyString1, + BodyString = (str:format(BodyString1, [JID, get_url(Id)])), Body = xmpp:mk_text(BodyString, Lang), OOB = #oob_x{url = get_url(Id)}, diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index c6c31a971..c0c7bbbd6 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -550,12 +550,12 @@ make_xhtml_output(State, Status, Headers, XHTML) -> of {value, _} -> [{<<"Content-Length">>, - iolist_to_binary(integer_to_list(byte_size(Data)))} + integer_to_binary(byte_size(Data))} | Headers]; _ -> [{<<"Content-Type">>, <<"text/html; charset=utf-8">>}, {<<"Content-Length">>, - iolist_to_binary(integer_to_list(byte_size(Data)))} + integer_to_binary(byte_size(Data))} | Headers] end, HeadersOut = case {State#state.request_version, @@ -577,7 +577,7 @@ make_xhtml_output(State, Status, Headers, XHTML) -> end, HeadersOut), SL = [Version, - iolist_to_binary(integer_to_list(Status)), <<" ">>, + integer_to_binary(Status), <<" ">>, code_to_phrase(Status), <<"\r\n">>], Data2 = case State#state.request_method of 'HEAD' -> <<"">>; diff --git a/src/ejabberd_http_bind.erl b/src/ejabberd_http_bind.erl index db529e69e..ea64b3cdf 100644 --- a/src/ejabberd_http_bind.erl +++ b/src/ejabberd_http_bind.erl @@ -972,21 +972,17 @@ prepare_outpacket_response(#http_bind{id = Sid, [{<<"xmlns">>, ?NS_HTTP_BIND}, {<<"sid">>, Sid}, {<<"wait">>, - iolist_to_binary(integer_to_list(Wait))}, + integer_to_binary(Wait)}, {<<"requests">>, - iolist_to_binary(integer_to_list(Hold - + - 1))}, + integer_to_binary(Hold + 1)}, {<<"inactivity">>, - iolist_to_binary(integer_to_list(trunc(MaxInactivity - / - 1000)))}, + integer_to_binary( + trunc(MaxInactivity / 1000))}, {<<"maxpause">>, - iolist_to_binary(integer_to_list(MaxPause))}, + integer_to_binary(MaxPause)}, {<<"polling">>, - iolist_to_binary(integer_to_list(trunc((?MIN_POLLING) - / - 1000000)))}, + integer_to_binary( + trunc((?MIN_POLLING) / 1000000))}, {<<"ver">>, ?BOSH_VERSION}, {<<"from">>, From}, {<<"secure">>, <<"true">>}] diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index 0e79c9913..b6f90ccf8 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -196,7 +196,7 @@ format_scram_password({StoredKey, ServerKey, Salt, IterationCount}) -> StoredKeyB64 = base64:encode(StoredKey), ServerKeyB64 = base64:encode(ServerKey), SaltB64 = base64:encode(Salt), - IterationCountBin = list_to_binary(integer_to_list(IterationCount)), + IterationCountBin = (integer_to_binary(IterationCount)), <<"scram:", StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>. parse_scram_password(PassData) -> @@ -206,7 +206,7 @@ parse_scram_password(PassData) -> storedkey = StoredKeyB64, serverkey = ServerKeyB64, salt = SaltB64, - iterationcount = list_to_integer(binary_to_list(IterationCountBin)) + iterationcount = (binary_to_integer(IterationCountBin)) }. -spec get_vcard(binary(), binary()) -> [xmlel()]. @@ -554,9 +554,8 @@ stop(Fmt, Args) -> make_filename_template() -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(), - list_to_binary( - io_lib:format("~4..0w~2..0w~2..0w-~2..0w~2..0w~2..0w", - [Year, Month, Day, Hour, Minute, Second])). + str:format("~4..0w~2..0w~2..0w-~2..0w~2..0w~2..0w", + [Year, Month, Day, Hour, Minute, Second]). make_main_basefilename(Dir, FnT) -> Filename2 = <>, diff --git a/src/ejabberd_riak.erl b/src/ejabberd_riak.erl index 575810acc..44628d1c2 100644 --- a/src/ejabberd_riak.erl +++ b/src/ejabberd_riak.erl @@ -428,7 +428,7 @@ map_key(Obj, _, _) -> <<"b_", B/binary>> -> B; <<"i_", B/binary>> -> - list_to_integer(binary_to_list(B)); + (binary_to_integer(B)); B -> erlang:binary_to_term(B) end]. @@ -483,7 +483,7 @@ encode_index_key(Idx, Key) -> encode_key(Bin) when is_binary(Bin) -> <<"b_", Bin/binary>>; encode_key(Int) when is_integer(Int) -> - <<"i_", (list_to_binary(integer_to_list(Int)))/binary>>; + <<"i_", ((integer_to_binary(Int)))/binary>>; encode_key(Term) -> erlang:term_to_binary(Term). @@ -519,7 +519,7 @@ log_error(_, _, _) -> ok. make_invalid_object(Val) -> - list_to_binary(io_lib:fwrite("Invalid object: ~p", [Val])). + (str:format("Invalid object: ~p", [Val])). get_random_pid() -> PoolPid = ejabberd_riak_sup:get_random_pid(), diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index df6af1c95..5d52a041d 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -180,10 +180,9 @@ process_large_heap(Pid, Info) -> Host = (?MYNAME), JIDs = get_admin_jids(), DetailedInfo = detailed_info(Pid), - Body = iolist_to_binary( - io_lib:format("(~w) The process ~w is consuming too " - "much memory:~n~p~n~s", - [node(), Pid, Info, DetailedInfo])), + Body = str:format("(~w) The process ~w is consuming too " + "much memory:~n~p~n~s", + [node(), Pid, Info, DetailedInfo]), From = jid:make(<<"">>, Host, <<"watchdog">>), Hint = [#hint{type = 'no-permanent-store'}], lists:foreach( diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index bf17c8ab1..3836beda7 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -763,8 +763,8 @@ process_admin(Host, [?XAE(<<"form">>, [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr), [?TEXTAREA(<<"acls">>, - (iolist_to_binary(integer_to_list(lists:max([16, - NumLines])))), + (integer_to_binary(lists:max([16, + NumLines]))), <<"80">>, <<(iolist_to_binary(ACLsP))/binary, ".">>), ?BR, ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])], @@ -865,8 +865,8 @@ process_admin(Host, [?XAE(<<"form">>, [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}]++direction(ltr), [?TEXTAREA(<<"access">>, - (iolist_to_binary(integer_to_list(lists:max([16, - NumLines])))), + (integer_to_binary(lists:max([16, + NumLines]))), <<"80">>, <<(iolist_to_binary(AccessP))/binary, ".">>), ?BR, ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])], @@ -926,7 +926,7 @@ process_admin(Host, Rs1 -> Rs1 end, make_xhtml([?XC(<<"h1">>, - list_to_binary(io_lib:format( + (str:format( ?T(<<"~s access rule configuration">>), [SName])))] ++ @@ -1141,7 +1141,7 @@ acl_spec_select(ID, Opt) -> %% @spec (T::any()) -> StringLine::string() term_to_string(T) -> StringParagraph = - iolist_to_binary(io_lib:format("~1000000p", [T])), + (str:format("~1000000p", [T])), ejabberd_regexp:greplace(StringParagraph, <<"\\n ">>, <<"">>). @@ -1506,7 +1506,7 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), - iolist_to_binary(io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + (str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, @@ -1683,14 +1683,14 @@ user_info(User, Server, Query, Lang) -> Shift rem 1000000, 0}, {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), - iolist_to_binary(io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + (str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])) end; _ -> ?T(<<"Online">>) end, - [?XC(<<"h1">>, list_to_binary(io_lib:format(?T(<<"User ~s">>), + [?XC(<<"h1">>, (str:format(?T(<<"User ~s">>), [us_to_list(US)])))] ++ case Res of @@ -1773,9 +1773,7 @@ list_last_activity(Host, Lang, Integral, Period) -> [?XAE(<<"li">>, [{<<"style">>, <<"width:", - (iolist_to_binary(integer_to_list(trunc(90 * V - / - Max))))/binary, + (integer_to_binary(trunc(90 * V / Max)))/binary, "%;">>}], [{xmlcdata, pretty_string_int(V)}]) || V <- Hist ++ Tail])] @@ -1850,7 +1848,7 @@ get_node(global, Node, [], Query, Lang) -> Base = get_base_path(global, Node), MenuItems2 = make_menu_items(global, Node, Base, Lang), [?XC(<<"h1">>, - list_to_binary(io_lib:format(?T(<<"Node ~p">>), [Node])))] + (str:format(?T(<<"Node ~p">>), [Node])))] ++ case Res of ok -> [?XREST(<<"Submitted">>)]; @@ -1875,7 +1873,7 @@ get_node(global, Node, [], Query, Lang) -> get_node(Host, Node, [], _Query, Lang) -> Base = get_base_path(Host, Node), MenuItems2 = make_menu_items(Host, Node, Base, Lang), - [?XC(<<"h1">>, list_to_binary(io_lib:format(?T(<<"Node ~p">>), [Node]))), + [?XC(<<"h1">>, (str:format(?T(<<"Node ~p">>), [Node]))), ?XE(<<"ul">>, ([?LI([?ACT(<>, <<"Modules">>)])] @@ -1934,7 +1932,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) -> end, STables), [?XC(<<"h1">>, - list_to_binary(io_lib:format(?T(<<"Database Tables at ~p">>), + (str:format(?T(<<"Database Tables at ~p">>), [Node])) )] ++ @@ -1970,9 +1968,9 @@ get_node(global, Node, [<<"backup">>], Query, Lang) -> ok -> [?XREST(<<"Submitted">>)]; {error, Error} -> [?XRES(<<(?T(<<"Error">>))/binary, ": ", - (list_to_binary(io_lib:format("~p", [Error])))/binary>>)] + ((str:format("~p", [Error])))/binary>>)] end, - [?XC(<<"h1">>, list_to_binary(io_lib:format(?T(<<"Backup of ~p">>), [Node])))] + [?XC(<<"h1">>, (str:format(?T(<<"Backup of ~p">>), [Node])))] ++ ResS ++ [?XCT(<<"p">>, @@ -2124,7 +2122,7 @@ get_node(global, Node, [<<"ports">>], Query, Lang) -> {'EXIT', _Reason} -> error; {is_added, ok} -> ok; {is_added, {error, Reason}} -> - {error, iolist_to_binary(io_lib:format("~p", [Reason]))}; + {error, (str:format("~p", [Reason]))}; _ -> nothing end, NewPorts = lists:sort(ejabberd_cluster:call(Node, ejabberd_config, @@ -2161,7 +2159,7 @@ get_node(Host, Node, [<<"modules">>], Query, Lang) end, NewModules = lists:sort(ejabberd_cluster:call(Node, gen_mod, loaded_modules_with_opts, [Host])), - H1String = list_to_binary(io_lib:format(?T(<<"Modules at ~p">>), [Node])), + H1String = (str:format(?T(<<"Modules at ~p">>), [Node])), (?H1GL(H1String, <<"modulesoverview">>, <<"Modules Overview">>)) ++ @@ -2177,10 +2175,10 @@ get_node(Host, Node, [<<"modules">>], Query, Lang) get_node(global, Node, [<<"stats">>], _Query, Lang) -> UpTime = ejabberd_cluster:call(Node, erlang, statistics, [wall_clock]), - UpTimeS = list_to_binary(io_lib:format("~.3f", + UpTimeS = (str:format("~.3f", [element(1, UpTime) / 1000])), CPUTime = ejabberd_cluster:call(Node, erlang, statistics, [runtime]), - CPUTimeS = list_to_binary(io_lib:format("~.3f", + CPUTimeS = (str:format("~.3f", [element(1, CPUTime) / 1000])), OnlineUsers = ejabberd_sm:connected_users_number(), TransactionsCommitted = ejabberd_cluster:call(Node, mnesia, @@ -2192,7 +2190,7 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) -> TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info, [transaction_log_writes]), [?XC(<<"h1">>, - list_to_binary(io_lib:format(?T(<<"Statistics of ~p">>), [Node]))), + (str:format(?T(<<"Statistics of ~p">>), [Node]))), ?XAE(<<"table">>, [], [?XE(<<"tbody">>, [?XE(<<"tr">>, @@ -2256,11 +2254,11 @@ get_node(global, Node, [<<"update">>], Query, Lang) -> (BeamsLis ++ SelectButtons)) end, FmtScript = (?XC(<<"pre">>, - list_to_binary(io_lib:format("~p", [Script])))), + (str:format("~p", [Script])))), FmtLowLevelScript = (?XC(<<"pre">>, - list_to_binary(io_lib:format("~p", [LowLevelScript])))), + (str:format("~p", [LowLevelScript])))), [?XC(<<"h1">>, - list_to_binary(io_lib:format(?T(<<"Update ~p">>), [Node])))] + (str:format(?T(<<"Update ~p">>), [Node])))] ++ case Res of ok -> [?XREST(<<"Submitted">>)]; @@ -2482,7 +2480,7 @@ node_ports_to_xhtml(Ports, Lang) -> SModule, <<"15">>)]), ?XAE(<<"td">>, direction(ltr), [?TEXTAREA(<<"opts", SSPort/binary>>, - (iolist_to_binary(integer_to_list(NumLines))), + (integer_to_binary(NumLines)), <<"35">>, SOptsClean)]), ?XE(<<"td">>, [?INPUTT(<<"submit">>, @@ -2625,7 +2623,7 @@ node_modules_to_xhtml(Modules, Lang) -> [?XC(<<"td">>, SModule), ?XAE(<<"td">>, direction(ltr), [?TEXTAREA(<<"opts", SModule/binary>>, - (iolist_to_binary(integer_to_list(NumLines))), + (integer_to_binary(NumLines)), <<"40">>, SOpts)]), ?XE(<<"td">>, [?INPUTT(<<"submit">>, @@ -2707,11 +2705,11 @@ node_update_parse_query(Node, Query) -> {ok, _} -> ok; {error, Error} -> ?ERROR_MSG("~p~n", [Error]), - {error, iolist_to_binary(io_lib:format("~p", [Error]))}; + {error, (str:format("~p", [Error]))}; {badrpc, Error} -> ?ERROR_MSG("Bad RPC: ~p~n", [Error]), {error, - <<"Bad RPC: ", (iolist_to_binary(io_lib:format("~p", [Error])))/binary>>} + <<"Bad RPC: ", ((str:format("~p", [Error])))/binary>>} end; _ -> nothing end. @@ -2776,7 +2774,7 @@ pretty_print_xml(#xmlel{name = Name, attrs = Attrs, element_to_list(X) when is_atom(X) -> iolist_to_binary(atom_to_list(X)); element_to_list(X) when is_integer(X) -> - iolist_to_binary(integer_to_list(X)). + integer_to_binary(X). list_to_element(Bin) -> {ok, Tokens, _} = erl_scan:string(binary_to_list(Bin)), @@ -2784,8 +2782,8 @@ list_to_element(Bin) -> Element. url_func({user_diapason, From, To}) -> - <<(iolist_to_binary(integer_to_list(From)))/binary, "-", - (iolist_to_binary(integer_to_list(To)))/binary, "/">>; + <<(integer_to_binary(From))/binary, "-", + (integer_to_binary(To))/binary, "/">>; url_func({users_queue, Prefix, User, _Server}) -> <>; url_func({user, Prefix, User, _Server}) -> @@ -2800,7 +2798,7 @@ cache_control_public() -> %% Transform 1234567890 into "1,234,567,890" pretty_string_int(Integer) when is_integer(Integer) -> - pretty_string_int(iolist_to_binary(integer_to_list(Integer))); + pretty_string_int(integer_to_binary(Integer)); pretty_string_int(String) when is_binary(String) -> {_, Result} = lists:foldl(fun (NewNumber, {3, Result}) -> {1, <>}; diff --git a/src/jlib.erl b/src/jlib.erl index f7dbebd86..096ef4012 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -677,14 +677,14 @@ timestamp_to_iso({{Year, Month, Day}, %% http://xmpp.org/extensions/xep-0091.html#time timestamp_to_legacy({{Year, Month, Day}, {Hour, Minute, Second}}) -> - iolist_to_binary(io_lib:format("~4..0B~2..0B~2..0BT~2..0B:~2..0B:~2..0B", + (str:format("~4..0B~2..0B~2..0BT~2..0B:~2..0B:~2..0B", [Year, Month, Day, Hour, Minute, Second])). -spec timestamp_to_iso_basic(calendar:datetime()) -> binary(). %% This is the ISO 8601 basic bormat timestamp_to_iso_basic({{Year, Month, Day}, {Hour, Minute, Second}}) -> - iolist_to_binary(io_lib:format("~4..0B~2..0B~2..0BT~2..0B~2..0B~2..0B", + (str:format("~4..0B~2..0B~2..0BT~2..0B~2..0B~2..0B", [Year, Month, Day, Hour, Minute, Second])). -spec now_to_utc_string(erlang:timestamp()) -> binary(). @@ -703,7 +703,7 @@ now_to_utc_string({MegaSecs, Secs, MicroSecs}, Precision) -> Max -> now_to_utc_string({MegaSecs, Secs + 1, 0}, Precision); FracOfSec -> - list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT" + (str:format("~4..0B-~2..0B-~2..0BT" "~2..0B:~2..0B:~2..0B.~*..0BZ", [Year, Month, Day, Hour, Minute, Second, Precision, FracOfSec])) @@ -725,7 +725,7 @@ now_to_local_string({MegaSecs, Secs, MicroSecs}) -> end, {{Year, Month, Day}, {Hour, Minute, Second}} = LocalTime, - list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B.~6." + (str:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B.~6." ".0B~s~2..0B:~2..0B", [Year, Month, Day, Hour, Minute, Second, MicroSecs, Sign, H, M])). diff --git a/src/mod_configure.erl b/src/mod_configure.erl index fc274dc03..436d736e6 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -680,9 +680,9 @@ get_all_vh_users(Host) -> lists:map(fun (K) -> L = K + M - 1, Node = <<"@", - (iolist_to_binary(integer_to_list(K)))/binary, + (integer_to_binary(K))/binary, "-", - (iolist_to_binary(integer_to_list(L)))/binary>>, + (integer_to_binary(L))/binary>>, {FS, FU} = lists:nth(K, SUsers), {LS, LU} = if L < N -> lists:nth(L, SUsers); true -> lists:last(SUsers) @@ -707,8 +707,7 @@ get_outgoing_s2s(Host, Lang) -> Host == FH orelse str:suffix(DotHost, FH)], lists:map( fun (T) -> - Name = iolist_to_binary( - io_lib:format(?T(Lang, <<"To ~s">>),[T])), + Name = str:format(?T(Lang, <<"To ~s">>),[T]), #disco_item{jid = jid:make(Host), node = <<"outgoing s2s/", T/binary>>, name = Name} @@ -722,8 +721,7 @@ get_outgoing_s2s(Host, Lang, To) -> lists:map( fun ({F, _T}) -> Node = <<"outgoing s2s/", To/binary, "/", F/binary>>, - Name = iolist_to_binary( - io_lib:format(?T(Lang, <<"From ~s">>), [F])), + Name = str:format(?T(Lang, <<"From ~s">>), [F]), #disco_item{jid = jid:make(Host), node = Node, name = Name} end, lists:keysort(1, @@ -1082,14 +1080,13 @@ get_form(_Host, label = ?T(Lang, <<"Message body">>)}]}}; get_form(Host, [<<"config">>, <<"acls">>], Lang) -> ACLs = str:tokens( - iolist_to_binary( - io_lib:format("~p.", - [mnesia:dirty_select( - acl, - ets:fun2ms( - fun({acl, {Name, H}, Spec}) when H == Host -> - {acl, Name, Spec} - end))])), + str:format("~p.", + [mnesia:dirty_select( + acl, + ets:fun2ms( + fun({acl, {Name, H}, Spec}) when H == Host -> + {acl, Name, Spec} + end))]), <<"\n">>), {result, #xdata{title = ?T(Lang, <<"Access Control List Configuration">>), @@ -1101,14 +1098,13 @@ get_form(Host, [<<"config">>, <<"acls">>], Lang) -> values = ACLs}]}}; get_form(Host, [<<"config">>, <<"access">>], Lang) -> Accs = str:tokens( - iolist_to_binary( - io_lib:format("~p.", - [mnesia:dirty_select( - access, - ets:fun2ms( - fun({access, {Name, H}, Acc}) when H == Host -> - {access, Name, Acc} - end))])), + str:format("~p.", + [mnesia:dirty_select( + access, + ets:fun2ms( + fun({access, {Name, H}, Acc}) when H == Host -> + {access, Name, Acc} + end))]), <<"\n">>), {result, #xdata{title = ?T(Lang, <<"Access Configuration">>), @@ -1199,9 +1195,7 @@ get_form(_Host, ?NS_ADMINL(<<"user-stats">>), Lang) -> required = true}]}}; get_form(Host, ?NS_ADMINL(<<"get-registered-users-num">>), Lang) -> - Num = list_to_binary( - io_lib:format("~p", - [ejabberd_auth:get_vh_registered_users_number(Host)])), + Num = integer_to_binary(ejabberd_auth:get_vh_registered_users_number(Host)), {result, completed, #xdata{type = form, fields = [?HFIELD(), @@ -1211,9 +1205,7 @@ get_form(Host, values = [Num]}]}}; get_form(Host, ?NS_ADMINL(<<"get-online-users-num">>), Lang) -> - Num = list_to_binary( - io_lib:format("~p", - [length(ejabberd_sm:get_vh_session_list(Host))])), + Num = integer_to_binary(ejabberd_sm:get_vh_session_number(Host)), {result, completed, #xdata{type = form, fields = [?HFIELD(), @@ -1641,7 +1633,7 @@ set_form(From, Host, TimeStamp = {Shift div 1000000, Shift rem 1000000, 0}, {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), - iolist_to_binary(io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + (str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])) end; diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 3dd0e492d..77bf34801 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -464,24 +464,23 @@ get_form(ServerHost, Host, From, Lang) -> var = <<"username">>, values = [Username]}, #xdata_field{type = fixed, - values = [iolist_to_binary( - io_lib:format( - translate:translate( - Lang, - <<"If you want to specify" - " different ports, " - "passwords, encodings " - "for IRC servers, " - "fill this list with " - "values in format " - "'{\"irc server\", " - "\"encoding\", port, " - "\"password\"}'. " - "By default this " - "service use \"~s\" " - "encoding, port ~p, " - "empty password.">>), - [DefaultEncoding, ?DEFAULT_IRC_PORT]))]}, + values = [str:format( + translate:translate( + Lang, + <<"If you want to specify" + " different ports, " + "passwords, encodings " + "for IRC servers, " + "fill this list with " + "values in format " + "'{\"irc server\", " + "\"encoding\", port, " + "\"password\"}'. " + "By default this " + "service use \"~s\" " + "encoding, port ~p, " + "empty password.">>), + [DefaultEncoding, ?DEFAULT_IRC_PORT])]}, #xdata_field{type = fixed, values = [translate:translate( Lang, @@ -493,11 +492,10 @@ get_form(ServerHost, Host, From, Lang) -> label = translate:translate( Lang, <<"Connections parameters">>), var = <<"connections_params">>, - values = str:tokens(list_to_binary( - io_lib:format( - "~p.", - [conn_params_to_list( - ConnectionsParams)])), + values = str:tokens(str:format( + "~p.", + [conn_params_to_list( + ConnectionsParams)]), <<"\n">>)}], X = #xdata{type = form, title = <<(translate:translate( @@ -657,11 +655,10 @@ adhoc_join(From, To, #adhoc_command{lang = Lang, xdata = X} = Request) -> RoomJID = jid:make(<>, To#jid.server), Reason = translate:translate(Lang, <<"Join the IRC channel here.">>), - Body = iolist_to_binary( - io_lib:format( - translate:translate( - Lang, <<"Join the IRC channel in this Jabber ID: ~s">>), - [jid:to_string(RoomJID)])), + Body = str:format( + translate:translate( + Lang, <<"Join the IRC channel in this Jabber ID: ~s">>), + [jid:to_string(RoomJID)]), Invite = #message{ body = xmpp:mk_text(Body, Lang), sub_els = [#muc_user{ @@ -782,43 +779,37 @@ generate_connection_params_field(Lang, Server, Encoding, Port; true -> ?DEFAULT_IRC_PORT end, - PortUsed = - iolist_to_binary(integer_to_list(PortUsedInt)), + PortUsed = integer_to_binary(PortUsedInt), PasswordUsed = case Password of <<>> -> <<>>; _ -> Password end, - NumberString = - iolist_to_binary(integer_to_list(Number)), + NumberString = integer_to_binary(Number), [#xdata_field{var = <<"password", NumberString/binary>>, type = 'text-single', - label = iolist_to_binary( - io_lib:format( - translate:translate(Lang, <<"Password ~b">>), - [Number])), + label = str:format( + translate:translate(Lang, <<"Password ~b">>), + [Number]), values = [PasswordUsed]}, #xdata_field{var = <<"port", NumberString/binary>>, type = 'text-single', - label = iolist_to_binary( - io_lib:format( - translate:translate(Lang, <<"Port ~b">>), - [Number])), + label = str:format( + translate:translate(Lang, <<"Port ~b">>), + [Number]), values = [PortUsed]}, #xdata_field{var = <<"encoding", NumberString/binary>>, type = 'list-single', - label = list_to_binary( - io_lib:format( - translate:translate(Lang, <<"Encoding for server ~b">>), - [Number])), + label = str:format( + translate:translate(Lang, <<"Encoding for server ~b">>), + [Number]), values = [EncodingUsed], options = [#xdata_option{label = E, value = E} || E <- ?POSSIBLE_ENCODINGS]}, #xdata_field{var = <<"server", NumberString/binary>>, type = 'text-single', - label = list_to_binary( - io_lib:format( - translate:translate(Lang, <<"Server ~b">>), - [Number])), + label = str:format( + translate:translate(Lang, <<"Server ~b">>), + [Number]), values = [Server]}]. parse_connections_params(#xdata{fields = Fields}) -> diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl index c9b460ad0..2e604203c 100644 --- a/src/mod_irc_connection.erl +++ b/src/mod_irc_connection.erl @@ -1213,5 +1213,5 @@ unixtime2string(Unixtime) -> {0, 0, 0}}), {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:universal_time_to_local_time(calendar:gregorian_seconds_to_datetime(Secs)), - iolist_to_binary(io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w", + (str:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second])). diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 5cf52e60f..2675db9b5 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -247,18 +247,18 @@ build_filename_string(TimeStamp, OutDir, RoomJID, {Dir, Filename, Rel} = case DirType of subdirs -> SYear = - iolist_to_binary(io_lib:format("~4..0w", + (str:format("~4..0w", [Year])), SMonth = - iolist_to_binary(io_lib:format("~2..0w", + (str:format("~2..0w", [Month])), - SDay = iolist_to_binary(io_lib:format("~2..0w", + SDay = (str:format("~2..0w", [Day])), {fjoin([SYear, SMonth]), SDay, <<"../..">>}; plain -> Date = - iolist_to_binary(io_lib:format("~4..0w-~2..0w-~2..0w", + (str:format("~4..0w-~2..0w-~2..0w", [Year, Month, Day])), @@ -727,7 +727,7 @@ fw(F, S, FileFormat) when is_atom(FileFormat) -> fw(F, S, [], FileFormat). fw(F, S, O, FileFormat) -> - S1 = list_to_binary(io_lib:format(binary_to_list(S) ++ "~n", O)), + S1 = (str:format(binary_to_list(S) ++ "~n", O)), S2 = case FileFormat of html -> S1; diff --git a/src/mod_offline.erl b/src/mod_offline.erl index f620e73c5..eedbcaeb1 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -717,7 +717,7 @@ user_queue(User, Server, Query, Lang) -> Hdrs = get_messages_subset(US, Server, HdrsAll), FMsgs = format_user_queue(Hdrs), [?XC(<<"h1">>, - list_to_binary(io_lib:format(?T(<<"~s's Offline Messages Queue">>), + (str:format(?T(<<"~s's Offline Messages Queue">>), [us_to_list(US)])))] ++ case Res of @@ -801,7 +801,7 @@ webadmin_user(Acc, User, Server, Lang) -> QueueLen = count_offline_messages(jid:nodeprep(User), jid:nameprep(Server)), FQueueLen = [?AC(<<"queue/">>, - (iolist_to_binary(integer_to_list(QueueLen))))], + (integer_to_binary(QueueLen)))], Acc ++ [?XCT(<<"h3">>, <<"Offline Messages:">>)] ++ FQueueLen ++ diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index c379760ed..ba79cf7bc 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -3776,7 +3776,7 @@ err_unsupported_access_model() -> -spec uniqid() -> mod_pubsub:itemId(). uniqid() -> {T1, T2, T3} = p1_time_compat:timestamp(), - iolist_to_binary(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). + (str:format("~.16B~.16B~.16B", [T1, T2, T3])). -spec itemsEls([#pubsub_item{}]) -> [ps_item()]. itemsEls(Items) -> diff --git a/src/mod_register.erl b/src/mod_register.erl index dc8ca995c..3cec0660b 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -392,7 +392,7 @@ send_registration_notifications(Mod, UJID, Source) -> [] -> ok; JIDs when is_list(JIDs) -> Body = - iolist_to_binary(io_lib:format("[~s] The account ~s was registered from " + (str:format("[~s] The account ~s was registered from " "IP address ~s on node ~w using ~p.", [get_time_string(), jid:to_string(UJID), diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index 04ae55ae7..06daf0810 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -299,7 +299,7 @@ add_record_route_and_set_uri(URI, LServer, #sip{hdrs = Hdrs} = Req) -> case need_record_route(LServer) of true -> RR_URI = get_configured_record_route(LServer), - TS = list_to_binary(integer_to_list(p1_time_compat:system_time(seconds))), + TS = (integer_to_binary(p1_time_compat:system_time(seconds))), Sign = make_sign(TS, Hdrs), User = <>, NewRR_URI = RR_URI#uri{user = User}, @@ -339,7 +339,7 @@ make_sign(TS, Hdrs) -> is_signed_by_me(TS_Sign, Hdrs) -> try [TSBin, Sign] = str:tokens(TS_Sign, <<"-">>), - TS = list_to_integer(binary_to_list(TSBin)), + TS = (binary_to_integer(TSBin)), NowTS = p1_time_compat:system_time(seconds), true = (NowTS - TS) =< ?SIGN_LIFETIME, Sign == make_sign(TSBin, Hdrs) diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index fcaa42365..e6532c934 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -355,7 +355,7 @@ min_expires() -> 60. to_integer(Bin, Min, Max) -> - case catch list_to_integer(binary_to_list(Bin)) of + case catch (binary_to_integer(Bin)) of N when N >= Min, N =< Max -> {ok, N}; _ -> diff --git a/src/mod_stats.erl b/src/mod_stats.erl index f146498c6..e43409e06 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -111,7 +111,7 @@ get_local_stat(Server, [], Name) {'EXIT', _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Users -> - ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), + ?STATVAL((integer_to_binary(length(Users))), <<"users">>) end; get_local_stat(Server, [], Name) @@ -122,13 +122,13 @@ get_local_stat(Server, [], Name) {'EXIT', _Reason} -> ?STATERR(500, <<"Internal Server Error">>); NUsers -> - ?STATVAL((iolist_to_binary(integer_to_list(NUsers))), + ?STATVAL((integer_to_binary(NUsers)), <<"users">>) end; get_local_stat(_Server, [], Name) when Name == <<"users/all-hosts/online">> -> Users = ejabberd_sm:connected_users_number(), - ?STATVAL((iolist_to_binary(integer_to_list(Users))), <<"users">>); + ?STATVAL((integer_to_binary(Users)), <<"users">>); get_local_stat(_Server, [], Name) when Name == <<"users/all-hosts/total">> -> NumUsers = lists:foldl(fun (Host, Total) -> @@ -136,7 +136,7 @@ get_local_stat(_Server, [], Name) + Total end, 0, ?MYHOSTS), - ?STATVAL((iolist_to_binary(integer_to_list(NumUsers))), + ?STATVAL((integer_to_binary(NumUsers)), <<"users">>); get_local_stat(_Server, _, Name) -> ?STATERR(404, <<"Not Found">>). @@ -149,9 +149,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); CPUTime -> - ?STATVAL(list_to_binary( - io_lib:format("~.3f", - [element(1, CPUTime) / 1000])), + ?STATVAL(str:format("~.3f", [element(1, CPUTime) / 1000]), <<"seconds">>) end; get_node_stat(Node, Name) @@ -161,9 +159,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); RunTime -> - ?STATVAL(list_to_binary( - io_lib:format("~.3f", - [element(1, RunTime) / 1000])), + ?STATVAL(str:format("~.3f", [element(1, RunTime) / 1000]), <<"seconds">>) end; get_node_stat(Node, Name) @@ -174,7 +170,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Users -> - ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), + ?STATVAL((integer_to_binary(length(Users))), <<"users">>) end; get_node_stat(Node, Name) @@ -185,7 +181,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -196,7 +192,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -207,7 +203,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -218,7 +214,7 @@ get_node_stat(Node, Name) {badrpc, _Reason} -> ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(_, Name) -> diff --git a/src/mod_version.erl b/src/mod_version.erl index 80b22554d..36bf796ee 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -70,7 +70,7 @@ get_os() -> OSType = list_to_binary([atom_to_list(Osfamily), $/, atom_to_list(Osname)]), OSVersion = case os:version() of {Major, Minor, Release} -> - iolist_to_binary(io_lib:format("~w.~w.~w", + (str:format("~w.~w.~w", [Major, Minor, Release])); VersionString -> VersionString end, diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index 713d33970..986a0b9b2 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -127,7 +127,7 @@ subscription_opt_to_sql({subscription_depth, Depth}) -> N -> integer_to_sql(N) end}. -integer_to_sql(N) -> iolist_to_binary(integer_to_list(N)). +integer_to_sql(N) -> integer_to_binary(N). boolean_to_sql(true) -> <<"1">>; boolean_to_sql(false) -> <<"0">>. diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index 297c6627c..b6986b69d 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -170,7 +170,7 @@ write_subscription(_JID, _NodeId, SubID, Options) -> -spec make_subid() -> SubId::mod_pubsub:subId(). make_subid() -> {T1, T2, T3} = p1_time_compat:timestamp(), - iolist_to_binary(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). + (str:format("~.16B~.16B~.16B", [T1, T2, T3])). %% %% Subscription XForm processing. @@ -207,14 +207,14 @@ val_xfield(digest_frequency = Opt, [Val]) -> N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> try xmpp_util:decode_timestamp(Val) catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); @@ -227,7 +227,7 @@ val_xfield(subscription_depth = Opt, [Depth]) -> N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end. @@ -238,7 +238,7 @@ xopt_to_bool(_, <<"false">>) -> false; xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])), + ErrTxt = (str:format(Txt, [Option])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if @@ -311,7 +311,7 @@ xfield_label(subscription_depth) -> ?SUBSCRIPTION_DEPTH_LABEL. xfield_val(deliver, Val) -> [bool_to_xopt(Val)]; %xfield_val(digest, Val) -> [bool_to_xopt(Val)]; %xfield_val(digest_frequency, Val) -> -% [iolist_to_binary(integer_to_list(Val))]; +% [integer_to_binary(Val))]; %xfield_val(expire, Val) -> % [jlib:now_to_utc_string(Val)]; %xfield_val(include_body, Val) -> [bool_to_xopt(Val)]; @@ -320,7 +320,7 @@ xfield_val(subscription_type, items) -> [<<"items">>]; xfield_val(subscription_type, nodes) -> [<<"nodes">>]; xfield_val(subscription_depth, all) -> [<<"all">>]; xfield_val(subscription_depth, N) -> - [iolist_to_binary(integer_to_list(N))]. + [integer_to_binary(N)]. bool_to_xopt(true) -> <<"true">>; diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index bb7b64112..da72cc96e 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -135,7 +135,7 @@ create_table() -> ok. -spec make_subid() -> mod_pubsub:subId(). make_subid() -> {T1, T2, T3} = p1_time_compat:timestamp(), - iolist_to_binary(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). + (str:format("~.16B~.16B~.16B", [T1, T2, T3])). %% %% Subscription XForm processing. @@ -172,14 +172,14 @@ val_xfield(digest_frequency = Opt, [Val]) -> N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> try xmpp_util:decode_timestamp(Val) catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); @@ -192,7 +192,7 @@ val_xfield(subscription_depth = Opt, [Depth]) -> N when is_integer(N) -> N; _ -> Txt = <<"Value of '~s' should be integer">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), + ErrTxt = (str:format(Txt, [Opt])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end. @@ -203,7 +203,7 @@ xopt_to_bool(_, <<"false">>) -> false; xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])), + ErrTxt = (str:format(Txt, [Option])), {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if @@ -276,7 +276,7 @@ xfield_label(subscription_depth) -> ?SUBSCRIPTION_DEPTH_LABEL. xfield_val(deliver, Val) -> [bool_to_xopt(Val)]; %xfield_val(digest, Val) -> [bool_to_xopt(Val)]; %xfield_val(digest_frequency, Val) -> -% [iolist_to_binary(integer_to_list(Val))]; +% [integer_to_binary(Val))]; %xfield_val(expire, Val) -> % [jlib:now_to_utc_string(Val)]; %xfield_val(include_body, Val) -> [bool_to_xopt(Val)]; @@ -285,7 +285,7 @@ xfield_val(subscription_type, items) -> [<<"items">>]; xfield_val(subscription_type, nodes) -> [<<"nodes">>]; xfield_val(subscription_depth, all) -> [<<"all">>]; xfield_val(subscription_depth, N) -> - [iolist_to_binary(integer_to_list(N))]. + [integer_to_binary(N)]. bool_to_xopt(false) -> <<"false">>; bool_to_xopt(true) -> <<"true">>. -- cgit v1.2.3 From 0f11b1be364e43189e06eeb577750e7d1b0e9fef Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 24 Nov 2016 18:40:20 +0300 Subject: Don't forget to erase cache on user removal --- src/mod_mam.erl | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 0433dee79..edb0d1485 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -176,6 +176,7 @@ remove_user(User, Server) -> LServer = jid:nameprep(Server), Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:remove_user(LUser, LServer), + cache_tab:dirty_delete(archive_prefs, {LUser, LServer}, fun() -> ok end), ok. -spec remove_room(binary(), binary(), binary()) -> ok. -- cgit v1.2.3 From e1539e57690b2ecb2203b1010e7ac5b042e955d2 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 25 Nov 2016 09:48:26 +0300 Subject: Get rid of compile warnings --- src/ejabberd_ctl.erl | 2 +- src/ejabberd_xmlrpc.erl | 8 ++++---- src/mod_http_api.erl | 4 ++-- src/mod_privacy_sql.erl | 3 --- 4 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index a96a28016..63adcdf69 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -311,7 +311,7 @@ try_call_command(Args, Auth, AccessCommands, Version) -> end. %% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType} -call_command([CmdString | Args], Auth, AccessCommands, Version) -> +call_command([CmdString | Args], Auth, _AccessCommands, Version) -> CmdStringU = ejabberd_regexp:greplace( list_to_binary(CmdString), <<"-">>, <<"_">>), Command = list_to_atom(binary_to_list(CmdStringU)), diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index 1b795d3fd..2792d08c1 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -216,10 +216,10 @@ process(_, #request{method = 'POST', data = Data, opts = Opts, ip = {IP, _}}) -> L), L end, all), - CommOpts = gen_mod:get_opt( - options, AcOpts, - fun(L) when is_list(L) -> L end, - []), + %% CommOpts = gen_mod:get_opt( + %% options, AcOpts, + %% fun(L) when is_list(L) -> L end, + %% []), [{<<"ejabberd_xmlrpc compatibility shim">>, {[?MODULE], [{access, Ac}], Commands}}]; (Wrong) -> ?WARNING_MSG("wrong options format for ~p: ~p", diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index a189777b1..3700060cb 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -503,8 +503,8 @@ unauthorized_response() -> invalid_token_response() -> json_error(401, 10, <<"Oauth Token is invalid or expired.">>). -outofscope_response() -> - json_error(401, 11, <<"Token does not grant usage to command required scope.">>). +%% outofscope_response() -> +%% json_error(401, 11, <<"Token does not grant usage to command required scope.">>). badrequest_response() -> badrequest_response(<<"400 Bad Request">>). diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index a39e36766..1984237c6 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -334,9 +334,6 @@ sql_get_privacy_list_id_t(LUser, Name) -> sql_get_privacy_list_data(LUser, LServer, Name) -> sql_queries:get_privacy_list_data(LServer, LUser, Name). -sql_get_privacy_list_data_t(LUser, Name) -> - sql_queries:get_privacy_list_data_t(LUser, Name). - sql_get_privacy_list_data_by_id(ID, LServer) -> sql_queries:get_privacy_list_data_by_id(LServer, ID). -- cgit v1.2.3 From ca1b22bdd4fbff9ee517d09b9d9c348189b073cf Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 25 Nov 2016 11:41:24 +0300 Subject: Use ejabberd_router:route_error/4 wherever possible --- src/ejabberd_local.erl | 15 ++++++-------- src/ejabberd_sm.erl | 20 ++++++++---------- src/gen_iq_handler.erl | 2 +- src/mod_announce.erl | 56 +++++++++++++++----------------------------------- src/mod_muc.erl | 10 ++++----- src/mod_muc_room.erl | 43 +++++++++++++++----------------------- src/mod_offline.erl | 5 ++--- 7 files changed, 54 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 74d86945d..3406192f7 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -87,14 +87,12 @@ process_iq(From, To, #iq{type = T, lang = Lang, sub_els = [El]} = Packet) From, To, Packet); [] -> Txt = <<"No module is handling this query">>, - Err = xmpp:make_error( - Packet, - xmpp:err_service_unavailable(Txt, Lang)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_service_unavailable(Txt, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end; process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> - Err = xmpp:make_error(Packet, xmpp:err_bad_request()), - ejabberd_router:route(To, From, Err); + Err = xmpp:err_bad_request(), + ejabberd_router:route_error(To, From, Packet, Err); process_iq(From, To, #iq{type = T} = Packet) when T == result; T == error -> process_iq_reply(From, To, Packet). @@ -186,9 +184,8 @@ bounce_resource_packet(_From, #jid{lresource = <<"">>}, bounce_resource_packet(From, To, Packet) -> Lang = xmpp:get_lang(Packet), Txt = <<"No available resource found">>, - Err = xmpp:make_error(Packet, - xmpp:err_item_not_found(Txt, Lang)), - ejabberd_router:route(To, From, Err), + Err = xmpp:err_item_not_found(Txt, Lang), + ejabberd_router:route_error(To, From, Packet, Err), stop. %%==================================================================== diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index d40db28cc..56dc3092e 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -173,9 +173,8 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) -> bounce_offline_message(From, To, Packet) -> Lang = xmpp:get_lang(Packet), Txt = <<"User session not found">>, - Err = xmpp:make_error( - Packet, xmpp:err_service_unavailable(Txt, Lang)), - ejabberd_router:route(To, From, Err), + Err = xmpp:err_service_unavailable(Txt, Lang), + ejabberd_router:route_error(To, From, Packet, Err), stop. -spec disconnect_removed_user(binary(), binary()) -> ok. @@ -602,9 +601,8 @@ route_message(From, To, Packet, Type) -> ejabberd_hooks:run(offline_message_hook, LServer, [From, To, Packet]); false -> - Err = xmpp:make_error(Packet, - xmpp:err_service_unavailable()), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_service_unavailable(), + ejabberd_router:route_error(To, From, Packet, Err) end end. @@ -724,14 +722,12 @@ process_iq(From, To, #iq{type = T, lang = Lang, sub_els = [El]} = Packet) From, To, Packet); [] -> Txt = <<"No module is handling this query">>, - Err = xmpp:make_error( - Packet, - xmpp:err_service_unavailable(Txt, Lang)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_service_unavailable(Txt, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end; process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> - Err = xmpp:make_error(Packet, xmpp:err_bad_request()), - ejabberd_router:route(To, From, Err), + Err = xmpp:err_bad_request(), + ejabberd_router:route_error(To, From, Packet, Err), ok; process_iq(_From, _To, #iq{}) -> ok. diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index bcbda1d1e..4a7a03c27 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -147,7 +147,7 @@ process_iq(_Host, Module, Function, From, To, IQ0) -> [xmpp:pp(IQ), {E, {R, erlang:get_stacktrace()}}]), Txt = <<"Module failed to handle the query">>, Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang), - ejabberd_router:route(To, From, xmpp:make_error(IQ, Err)) + ejabberd_router:route_error(To, From, IQ, Err) end. -spec process_iq(module(), atom(), iq()) -> ignore | iq(). diff --git a/src/mod_announce.erl b/src/mod_announce.erl index a1c60f3c9..2e182ed1e 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -601,10 +601,7 @@ announce_all(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> Local = jid:make(To#jid.server), lists:foreach( @@ -618,10 +615,7 @@ announce_all_hosts_all(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> Local = jid:make(To#jid.server), lists:foreach( @@ -636,10 +630,7 @@ announce_online(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> announce_online1(ejabberd_sm:get_vh_session_list(Host), To#jid.server, @@ -650,10 +641,7 @@ announce_all_hosts_online(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> announce_online1(ejabberd_sm:dirty_get_sessions_list(), To#jid.server, @@ -673,10 +661,7 @@ announce_motd(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> announce_motd(Host, Packet) end. @@ -685,10 +670,7 @@ announce_all_hosts_motd(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> Hosts = ?MYHOSTS, [announce_motd(Host, Packet) || Host <- Hosts] @@ -707,10 +689,7 @@ announce_motd_update(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> announce_motd_update(Host, Packet) end. @@ -719,10 +698,7 @@ announce_all_hosts_motd_update(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> Hosts = ?MYHOSTS, [announce_motd_update(Host, Packet) || Host <- Hosts] @@ -738,10 +714,7 @@ announce_motd_delete(From, To, Packet) -> Access = get_access(Host), case acl:match_rule(Host, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> announce_motd_delete(Host) end. @@ -750,10 +723,7 @@ announce_all_hosts_motd_delete(From, To, Packet) -> Access = get_access(global), case acl:match_rule(global, Access, From) of deny -> - Lang = xmpp:get_lang(Packet), - Txt = <<"Denied by ACL">>, - Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)), - ejabberd_router:route(To, From, Err); + route_forbidden_error(From, To, Packet); allow -> Hosts = ?MYHOSTS, [announce_motd_delete(Host) || Host <- Hosts] @@ -827,6 +797,12 @@ get_access(Host) -> add_store_hint(El) -> xmpp:set_subtag(El, #hint{type = store}). +-spec route_forbidden_error(jid(), jid(), stanza()) -> ok. +route_forbidden_error(From, To, Packet) -> + Lang = xmpp:get_lang(Packet), + Err = xmpp:err_forbidden(<<"Denied by ACL">>, Lang), + ejabberd_router:route_error(To, From, Packet, Err). + %%------------------------------------------------------------------------- export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 554a21704..ab358b957 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -378,9 +378,8 @@ do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper, deny -> ErrText = <<"Only service administrators are allowed " "to send service messages">>, - Err = xmpp:make_error( - Packet, xmpp:err_forbidden(ErrText, Lang)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end end; do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, @@ -409,9 +408,8 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, false -> Lang = xmpp:get_lang(Packet), ErrText = <<"Room creation is denied by service policy">>, - Err = xmpp:make_error( - Packet, xmpp:err_forbidden(ErrText, Lang)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_forbidden(ErrText, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end; false -> Lang = xmpp:get_lang(Packet), diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index aa1c77aad..2d21365d5 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -167,10 +167,8 @@ normal_state({route, From, <<"">>, shaper:update(Activity#activity.message_shaper, Size), if Activity#activity.message /= undefined -> ErrText = <<"Traffic rate limit is exceeded">>, - Err = xmpp:make_error( - Packet, - xmpp:err_resource_constraint(ErrText, Lang)), - ejabberd_router:route(StateData#state.jid, From, Err), + Err = xmpp:err_resource_constraint(ErrText, Lang), + ejabberd_router:route_error(StateData#state.jid, From, Packet, Err), {next_state, normal_state, StateData}; Now >= Activity#activity.message_time + MinMessageInterval, MessageShaperInterval == 0 -> @@ -328,8 +326,8 @@ normal_state({route, From, <<"">>, end catch _:{xmpp_codec, Why} -> ErrTxt = xmpp:format_error(Why), - Err = xmpp:make_error(IQ0, xmpp:err_bad_request(ErrTxt, Lang)), - ejabberd_router:route(StateData#state.jid, From, Err) + Err = xmpp:err_bad_request(ErrTxt, Lang), + ejabberd_router:route_error(StateData#state.jid, From, IQ0, Err) end; normal_state({route, From, <<"">>, #iq{} = IQ}, StateData) -> Err = xmpp:err_bad_request(), @@ -1821,9 +1819,8 @@ add_new_user(From, Nick, Packet, StateData) -> {false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers -> Txt = <<"Too many users in this conference">>, Err = xmpp:err_resource_constraint(Txt, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1831,18 +1828,16 @@ add_new_user(From, Nick, Packet, StateData) -> {false, _, _, _} when NConferences >= MaxConferences -> Txt = <<"You have joined too many conferences">>, Err = xmpp:err_resource_constraint(Txt, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} end; {false, _, _, _} -> Err = xmpp:err_service_unavailable(), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1856,9 +1851,8 @@ add_new_user(From, Nick, Packet, StateData) -> ErrText = <<"Membership is required to enter this room">>, xmpp:err_registration_required(ErrText, Lang) end, - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1866,9 +1860,8 @@ add_new_user(From, Nick, Packet, StateData) -> {_, true, _, _} -> ErrText = <<"That nickname is already in use by another occupant">>, Err = xmpp:err_conflict(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1876,9 +1869,8 @@ add_new_user(From, Nick, Packet, StateData) -> {_, _, false, _} -> ErrText = <<"That nickname is registered by another person">>, Err = xmpp:err_conflict(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1918,9 +1910,8 @@ add_new_user(From, Nick, Packet, StateData) -> nopass -> ErrText = <<"A password is required to enter this room">>, Err = xmpp:err_not_authorized(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error(UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1948,9 +1939,9 @@ add_new_user(From, Nick, Packet, StateData) -> {error, limit} -> ErrText = <<"Too many CAPTCHA requests">>, Err = xmpp:err_resource_constraint(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error( + UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1958,9 +1949,9 @@ add_new_user(From, Nick, Packet, StateData) -> _ -> ErrText = <<"Unable to generate a CAPTCHA">>, Err = xmpp:err_internal_server_error(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error( + UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} @@ -1969,9 +1960,9 @@ add_new_user(From, Nick, Packet, StateData) -> _ -> ErrText = <<"Incorrect password">>, Err = xmpp:err_not_authorized(ErrText, Lang), - ErrPacket = xmpp:make_error(Packet, Err), if not IsSubscribeRequest -> - ejabberd_router:route(UserRoomJID, From, ErrPacket), + ejabberd_router:route_error( + UserRoomJID, From, Packet, Err), StateData; true -> {error, Err} diff --git a/src/mod_offline.erl b/src/mod_offline.erl index eedbcaeb1..42bc46631 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -623,9 +623,8 @@ discard_warn_sender(Msgs) -> ErrText = <<"Your contact offline message queue is " "full. The message has been discarded.">>, Lang = xmpp:get_lang(Packet), - Err = xmpp:make_error( - Packet, xmpp:err_resource_constraint(ErrText, Lang)), - ejabberd_router:route(To, From, Err) + Err = xmpp:err_resource_constraint(ErrText, Lang), + ejabberd_router:route_error(To, From, Packet, Err) end, Msgs). webadmin_page(_, Host, -- cgit v1.2.3 From 56b30ab598ba76aa1a59041d67f743793ef877bb Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sat, 26 Nov 2016 10:05:22 +0300 Subject: Improve translation of some messages --- src/ejabberd_captcha.erl | 7 ++----- src/mod_http_upload.erl | 3 +-- src/mod_irc.erl | 8 +++----- src/mod_muc_room.erl | 9 +++------ src/mod_register.erl | 9 ++++----- src/pubsub_subscription.erl | 20 ++++++++------------ src/pubsub_subscription_sql.erl | 20 ++++++++------------ 7 files changed, 29 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index f959d7f30..85d7595a2 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -100,11 +100,8 @@ create_captcha(SID, From, To, Lang, Limiter, Args) -> mk_ocr_field(Lang, CID, Type)], X = #xdata{type = form, fields = Fs}, Captcha = #xcaptcha{xdata = X}, - BodyString1 = translate:translate(Lang, - <<"Your messages to ~s are being blocked. " - "To unblock them, visit ~s">>), - BodyString = (str:format(BodyString1, - [JID, get_url(Id)])), + BodyString = {<<"Your messages to ~s are being blocked. " + "To unblock them, visit ~s">>, [JID, get_url(Id)]}, Body = xmpp:mk_text(BodyString, Lang), OOB = #oob_x{url = get_url(Id)}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 1abde4f5b..37eaad27a 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -579,8 +579,7 @@ process_iq(_From, #iq{}, _State) -> create_slot(#state{service_url = undefined, max_size = MaxSize}, JID, File, Size, _ContentType, Lang) when MaxSize /= infinity, Size > MaxSize -> - Text = <<"File larger than ", (integer_to_binary(MaxSize))/binary, - " Bytes.">>, + Text = {<<"File larger than ~w bytes">>, [MaxSize]}, ?INFO_MSG("Rejecting file ~s from ~s (too large: ~B bytes)", [File, jid:to_string(JID), Size]), {error, xmpp:err_not_acceptable(Text, Lang)}; diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 77bf34801..f43a6653d 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -655,12 +655,10 @@ adhoc_join(From, To, #adhoc_command{lang = Lang, xdata = X} = Request) -> RoomJID = jid:make(<>, To#jid.server), Reason = translate:translate(Lang, <<"Join the IRC channel here.">>), - Body = str:format( - translate:translate( - Lang, <<"Join the IRC channel in this Jabber ID: ~s">>), - [jid:to_string(RoomJID)]), + BodyTxt = {<<"Join the IRC channel in this Jabber ID: ~s">>, + [jid:to_string(RoomJID)]}, Invite = #message{ - body = xmpp:mk_text(Body, Lang), + body = xmpp:mk_text(BodyTxt, Lang), sub_els = [#muc_user{ invites = [#muc_invite{from = From, reason = Reason}]}, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 2d21365d5..957220540 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -2723,11 +2723,8 @@ find_changed_items(UJID, UAffiliation, URole, Nick /= <<"">> -> case find_jids_by_nick(Nick, StateData) of [] -> - ErrText = str:format( - translate:translate( - Lang, - <<"Nickname ~s does not exist in the room">>), - [Nick]), + ErrText = {<<"Nickname ~s does not exist in the room">>, + [Nick]}, throw({error, xmpp:err_not_acceptable(ErrText, Lang)}); JIDList -> JIDList @@ -3299,7 +3296,7 @@ set_config(Opts, Config, ServerHost, Lang) -> {0, undefined} -> ?ERROR_MSG("set_room_option hook failed for " "option '~s' with value ~p", [O, V]), - Txt = <<"Failed to process option '", O/binary, "'">>, + Txt = {<<"Failed to process option '~s'">>, [O]}, {error, xmpp:err_internal_server_error(Txt, Lang)}; {Pos, Val} -> setelement(Pos, C, Val) diff --git a/src/mod_register.erl b/src/mod_register.erl index 3cec0660b..ba261e0f3 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -202,13 +202,13 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ, _ -> {false, <<"">>} end, + Instr = translate:translate( + Lang, <<"Choose a username and password to register " + "with this server">>), if IsCaptchaEnabled and not IsRegistered -> TopInstr = translate:translate( Lang, <<"You need a client that supports x:data " "and CAPTCHA to register">>), - Instr = translate:translate( - Lang, <<"Choose a username and password to register " - "with this server">>), UField = #xdata_field{type = 'text-single', label = translate:translate(Lang, <<"User">>), var = <<"username">>, @@ -234,10 +234,9 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ, IQ, xmpp:err_internal_server_error(ErrText, Lang)) end; true -> - Instr = <<"Choose a username and password to register with this server">>, xmpp:make_iq_result( IQ, - #register{instructions = translate:translate(Lang, Instr), + #register{instructions = Instr, username = Username, password = <<"">>, registered = IsRegistered}) diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index b6986b69d..077ac5ba9 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -206,16 +206,14 @@ val_xfield(digest_frequency = Opt, [Val]) -> case catch binary_to_integer(Val) of N when is_integer(N) -> N; _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be integer">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> try xmpp_util:decode_timestamp(Val) catch _:{bad_timestamp, _} -> - Txt = <<"Value of '~s' should be datetime string">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be datetime string">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; @@ -226,9 +224,8 @@ val_xfield(subscription_depth = Opt, [Depth]) -> case catch binary_to_integer(Depth) of N when is_integer(N) -> N; _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be integer">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end. %% Convert XForm booleans to Erlang booleans. @@ -237,9 +234,8 @@ xopt_to_bool(_, <<"1">>) -> true; xopt_to_bool(_, <<"false">>) -> false; xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> - Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = (str:format(Txt, [Option])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. + Txt = {<<"Value of '~s' should be boolean">>, [Option]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index da72cc96e..fddfe881e 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -171,16 +171,14 @@ val_xfield(digest_frequency = Opt, [Val]) -> case catch binary_to_integer(Val) of N when is_integer(N) -> N; _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be integer">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> try xmpp_util:decode_timestamp(Val) catch _:{bad_timestamp, _} -> - Txt = <<"Value of '~s' should be datetime string">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be datetime string">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; @@ -191,9 +189,8 @@ val_xfield(subscription_depth = Opt, [Depth]) -> case catch binary_to_integer(Depth) of N when is_integer(N) -> N; _ -> - Txt = <<"Value of '~s' should be integer">>, - ErrTxt = (str:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} + Txt = {<<"Value of '~s' should be integer">>, [Opt]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)} end. %% Convert XForm booleans to Erlang booleans. @@ -202,9 +199,8 @@ xopt_to_bool(_, <<"1">>) -> true; xopt_to_bool(_, <<"false">>) -> false; xopt_to_bool(_, <<"true">>) -> true; xopt_to_bool(Option, _) -> - Txt = <<"Value of '~s' should be boolean">>, - ErrTxt = (str:format(Txt, [Option])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}. + Txt = {<<"Value of '~s' should be boolean">>, [Option]}, + {error, xmpp:err_not_acceptable(Txt, ?MYLANG)}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. -- cgit v1.2.3 From fc7e52df71b0b02fb2a0f34fcb5db03e04cfac22 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Mon, 28 Nov 2016 17:15:57 +0100 Subject: Adds optional post_install and pre_uninstall hooks (thanks Igor Manturov Jr.)(#1300) --- src/ext_mod.erl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ext_mod.erl b/src/ext_mod.erl index 071fb827c..5b970623b 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -170,7 +170,10 @@ install(Package) when is_binary(Package) -> ok -> code:add_patha(module_ebin_dir(Module)), ejabberd_config:reload_file(), - ok; + case erlang:function_exported(Module, post_install, 0) of + true -> Module:post_install(); + _ -> ok + end; Error -> delete_path(module_lib_dir(Module)), Error @@ -183,6 +186,10 @@ uninstall(Package) when is_binary(Package) -> case installed(Package) of true -> Module = jlib:binary_to_atom(Package), + case erlang:function_exported(Module, pre_uninstall, 0) of + true -> Module:pre_uninstall(); + _ -> ok + end, [catch gen_mod:stop_module(Host, Module) || Host <- ejabberd_config:get_myhosts()], code:purge(Module), -- cgit v1.2.3 From 95a4b1b266355c19de0be4574803f486c0c94c05 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 30 Nov 2016 10:31:36 +0100 Subject: Cleanup admin_extra, add few functions --- src/mod_admin_extra.erl | 187 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 160 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 3c51e8c69..4b117d50a 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -30,24 +30,53 @@ -include("logger.hrl"). --export([start/2, stop/1, compile/1, get_cookie/0, - remove_node/1, set_password/3, check_password/3, - check_password_hash/4, delete_old_users/1, - delete_old_users_vhost/2, ban_account/3, +-export([start/2, stop/1, mod_opt_type/1, + get_commands_spec/0, depends/2]). + +% Commands API +-export([ + % Adminsys + compile/1, get_cookie/0, remove_node/1, export2sql/2, + restart_module/2, + + % Sessions num_active_users/2, num_resources/2, resource_num/3, kick_session/4, status_num/2, status_num/1, status_list/2, status_list/1, connected_users_info/0, connected_users_vhost/1, set_presence/7, - user_sessions_info/2, set_nickname/3, get_vcard/3, + get_presence/2, user_sessions_info/2, get_last/2, + + % Accounts + set_password/3, check_password_hash/4, delete_old_users/1, + delete_old_users_vhost/2, ban_account/3, check_password/3, + + % vCard + set_nickname/3, get_vcard/3, get_vcard/4, get_vcard_multi/4, set_vcard/4, - set_vcard/5, add_rosteritem/7, delete_rosteritem/4, + set_vcard/5, + + % Roster + add_rosteritem/7, delete_rosteritem/4, process_rosteritems/5, get_roster/2, push_roster/3, - push_roster_all/1, push_alltoall/2, get_last/2, - private_get/4, private_set/3, srg_create/5, + push_roster_all/1, push_alltoall/2, + + % Private storage + private_get/4, private_set/3, + + % Shared roster + srg_create/5, srg_delete/2, srg_list/1, srg_get_info/2, srg_get_members/2, srg_user_add/4, srg_user_del/4, - send_message/5, send_stanza/3, send_stanza_c2s/4, privacy_set/3, - stats/1, stats/2, mod_opt_type/1, get_commands_spec/0, depends/2]). + + % Send message + send_message/5, send_stanza/3, send_stanza_c2s/4, + + % Privacy list + privacy_set/3, + + % Stats + stats/1, stats/2 + ]). -include("ejabberd.hrl"). @@ -125,9 +154,30 @@ get_commands_spec() -> result = {res, rescode}, result_example = ok, result_desc = "Status code: 0 on success, 1 otherwise"}, + #ejabberd_commands{name = export2sql, tags = [mnesia], + desc = "Export Mnesia tables to files in directory", + module = ?MODULE, function = export2sql, + args = [{host, string}, {path, string}], + args_example = ["myserver.com","/tmp/export/sql"], + args_desc = ["Server name", "File to write sql export"], + result = {res, rescode}, + result_example = ok, + result_desc = "Status code: 0 on success, 1 otherwise"}, + #ejabberd_commands{name = restart_module, tags = [erlang], + desc = "Stop an ejabberd module, reload code and start", + module = ?MODULE, function = restart_module, + args = [{host, binary}, {module, binary}], + args_example = ["myserver.com","mod_admin_extra"], + args_desc = ["Server name", "Module to restart"], + result = {res, integer}, + result_example = 0, + result_desc = "Returns integer code:\n" + " - 0: code reloaded, module restarted\n" + " - 1: error: module not loaded\n" + " - 2: code not reloaded, but module restarted"}, #ejabberd_commands{name = num_active_users, tags = [accounts, stats], desc = "Get number of users active in the last days", - policy = admin, + policy = admin, module = ?MODULE, function = num_active_users, args = [{host, binary}, {days, integer}], args_example = [<<"myserver.com">>, 3], @@ -236,7 +286,7 @@ get_commands_spec() -> result_desc = "Status code: 0 on success, 1 otherwise"}, #ejabberd_commands{name = status_num_host, tags = [session, stats], desc = "Number of logged users with this status in host", - policy = admin, + policy = admin, module = ?MODULE, function = status_num, args = [{host, binary}, {status, binary}], args_example = [<<"myserver.com">>, <<"dnd">>], @@ -246,7 +296,7 @@ get_commands_spec() -> result_desc = "Number of connected sessions with given status type"}, #ejabberd_commands{name = status_num, tags = [session, stats], desc = "Number of logged users with this status", - policy = admin, + policy = admin, module = ?MODULE, function = status_num, args = [{status, binary}], args_example = [<<"dnd">>], @@ -298,11 +348,11 @@ get_commands_spec() -> ]}} }}}, #ejabberd_commands{name = connected_users_vhost, - tags = [session], - desc = "Get the list of established sessions in a vhost", - module = ?MODULE, function = connected_users_vhost, - args = [{host, binary}], - result = {connected_users_vhost, {list, {sessions, string}}}}, + tags = [session], + desc = "Get the list of established sessions in a vhost", + module = ?MODULE, function = connected_users_vhost, + args = [{host, binary}], + result = {connected_users_vhost, {list, {sessions, string}}}}, #ejabberd_commands{name = user_sessions_info, tags = [session], desc = "Get information about all sessions of a user", @@ -323,6 +373,28 @@ get_commands_spec() -> ]}} }}}, + #ejabberd_commands{name = get_presence, tags = [session], + desc = + "Retrieve the resource with highest priority, " + "and its presence (show and status message) " + "for a given user.", + longdesc = + "The 'jid' value contains the user jid " + "with resource.\nThe 'show' value contains " + "the user presence flag. It can take " + "limited values:\n - available\n - chat " + "(Free for chat)\n - away\n - dnd (Do " + "not disturb)\n - xa (Not available, " + "extended away)\n - unavailable (Not " + "connected)\n\n'status' is a free text " + "defined by the user client.", + module = ?MODULE, function = get_presence, + args = [{user, binary}, {server, binary}], + result = + {presence, + {tuple, + [{jid, string}, {show, string}, + {status, string}]}}}, #ejabberd_commands{name = set_presence, tags = [session], desc = "Set presence of a session", @@ -534,7 +606,7 @@ get_commands_spec() -> #ejabberd_commands{name = get_offline_count, tags = [offline], desc = "Get the number of unread offline messages", - policy = user, + policy = user, module = mod_offline, function = count_offline_messages, args = [], result = {value, integer}}, @@ -562,13 +634,13 @@ get_commands_spec() -> #ejabberd_commands{name = stats, tags = [stats], desc = "Get statistical value: registeredusers onlineusers onlineusersnode uptimeseconds processes", - policy = admin, + policy = admin, module = ?MODULE, function = stats, args = [{name, binary}], result = {stat, integer}}, #ejabberd_commands{name = stats_host, tags = [stats], desc = "Get statistical value for this host: registeredusers onlineusers", - policy = admin, + policy = admin, module = ?MODULE, function = stats, args = [{name, binary}, {host, binary}], result = {stat, integer}} @@ -589,6 +661,48 @@ remove_node(Node) -> mnesia:del_table_copy(schema, list_to_atom(Node)), ok. +restart_module(Host, Module) when is_binary(Module) -> + restart_module(Host, jlib:binary_to_atom(Module)); +restart_module(Host, Module) when is_atom(Module) -> + List = gen_mod:loaded_modules_with_opts(Host), + case proplists:get_value(Module, List) of + undefined -> + % not a running module, force code reload anyway + code:purge(Module), + code:delete(Module), + code:load_file(Module), + 1; + Opts -> + gen_mod:stop_module(Host, Module), + case code:soft_purge(Module) of + true -> + code:delete(Module), + code:load_file(Module), + gen_mod:start_module(Host, Module, Opts), + 0; + false -> + gen_mod:start_module(Host, Module, Opts), + 2 + end + end. + +export2sql(Host, Directory) -> + Tables = [{export_last, last}, + {export_offline, offline}, + {export_passwd, passwd}, + {export_private_storage, private_storage}, + {export_roster, roster}, + {export_vcard, vcard}, + {export_vcard_search, vcard_search}], + Export = fun({TableFun, Table}) -> + Filename = filename:join([Directory, atom_to_list(Table)++".txt"]), + io:format("Trying to export Mnesia table '~p' on Host '~s' to file '~s'~n", [Table, Host, Filename]), + Res = (catch ejd2sql:TableFun(Host, Filename)), + io:format(" Result: ~p~n", [Res]) + end, + lists:foreach(Export, Tables), + ok. + %%% %%% Accounts %%% @@ -607,10 +721,10 @@ check_password_hash(User, Host, PasswordHash, HashMethod) -> {A, _} when is_tuple(A) -> scrammed; {_, <<"md5">>} -> get_md5(AccountPass); {_, <<"sha">>} -> get_sha(AccountPass); - {_, Method} -> + {_, Method} -> ?ERROR_MSG("check_password_hash called " - "with hash method: ~p", [Method]), - undefined + "with hash method: ~p", [Method]), + undefined end, case AccountPassHash of scrammed -> @@ -628,10 +742,11 @@ get_sha(AccountPass) -> || X <- binary_to_list(p1_sha:sha1(AccountPass))]). num_active_users(Host, Days) -> - list_last_activity(Host, true, Days). + DB_Type = gen_mod:db_type(Host, mod_last), + list_last_activity(Host, true, Days, DB_Type). %% Code based on ejabberd/src/web/ejabberd_web_admin.erl -list_last_activity(Host, Integral, Days) -> +list_last_activity(Host, Integral, Days, mnesia) -> TimeStamp = p1_time_compat:system_time(seconds), TS = TimeStamp - Days * 86400, case catch mnesia:dirty_select( @@ -657,7 +772,11 @@ list_last_activity(Host, Integral, Days) -> end, lists:nth(Days, Hist ++ Tail) end - end. + end; +list_last_activity(_Host, _Integral, _Days, DB_Type) -> + throw({error, iolist_to_binary(io_lib:format("Unsupported backend: ~p", + [DB_Type]))}). + histogram(Values, Integral) -> histogram(lists:sort(Values), Integral, 0, 0, []). histogram([H | T], Integral, Current, Count, Hist) when Current == H -> @@ -882,6 +1001,20 @@ stringize(String) -> %% Replace newline characters with other code ejabberd_regexp:greplace(String, <<"\n">>, <<"\\n">>). +get_presence(U, S) -> + Pids = [ejabberd_sm:get_session_pid(U, S, R) + || R <- ejabberd_sm:get_user_resources(U, S)], + OnlinePids = [Pid || Pid <- Pids, Pid=/=none], + case OnlinePids of + [] -> + {jid:to_string({U, S, <<>>}), <<"unavailable">>, <<"">>}; + [SessionPid|_] -> + {_User, Resource, Show, Status} = + ejabberd_c2s:get_presence(SessionPid), + FullJID = jid:to_string({U, S, Resource}), + {FullJID, Show, Status} + end. + set_presence(User, Host, Resource, Type, Show, Status, Priority) when is_integer(Priority) -> BPriority = integer_to_binary(Priority), -- cgit v1.2.3 From 92db9ff10546e4a033621fbfd7d66d2aa3bf55e8 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 30 Nov 2016 11:09:17 +0100 Subject: Improve handling of mnesia schema --- src/acl.erl | 4 +- src/ejabberd_auth_anonymous.erl | 2 +- src/ejabberd_auth_mnesia.erl | 4 +- src/ejabberd_commands.erl | 2 +- src/ejabberd_config.erl | 4 +- src/ejabberd_local.erl | 2 +- src/ejabberd_mnesia.erl | 169 ++++++++++++++++++++++++++++++++++++++ src/ejabberd_oauth_mnesia.erl | 2 +- src/ejabberd_router.erl | 2 +- src/ejabberd_router_multicast.erl | 2 +- src/ejabberd_s2s.erl | 4 +- src/ejabberd_sm_mnesia.erl | 4 +- src/ejabberd_sql_sup.erl | 2 +- src/mod_announce_mnesia.erl | 4 +- src/mod_bosh.erl | 2 +- src/mod_caps_mnesia.erl | 2 +- src/mod_carboncopy_mnesia.erl | 2 +- src/mod_http_bind.erl | 2 +- src/mod_irc_mnesia.erl | 2 +- src/mod_last_mnesia.erl | 2 +- src/mod_mam_mnesia.erl | 4 +- src/mod_muc.erl | 2 +- src/mod_muc_mnesia.erl | 4 +- src/mod_multicast.erl | 2 +- src/mod_offline_mnesia.erl | 2 +- src/mod_privacy_mnesia.erl | 2 +- src/mod_private_mnesia.erl | 2 +- src/mod_proxy65_sm.erl | 2 +- src/mod_pubsub.erl | 2 +- src/mod_register.erl | 2 +- src/mod_roster_mnesia.erl | 4 +- src/mod_shared_roster_mnesia.erl | 4 +- src/mod_sip_registrar.erl | 2 +- src/mod_vcard_mnesia.erl | 4 +- src/mod_vcard_xupdate_mnesia.erl | 2 +- src/node_flat.erl | 4 +- src/nodetree_tree.erl | 2 +- src/pubsub_index.erl | 2 +- src/pubsub_migrate.erl | 4 +- src/pubsub_subscription.erl | 2 +- src/shaper.erl | 2 +- 41 files changed, 222 insertions(+), 53 deletions(-) create mode 100644 src/ejabberd_mnesia.erl (limited to 'src') diff --git a/src/acl.erl b/src/acl.erl index 595228ee9..e00aaa5d3 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -76,11 +76,11 @@ -export_type([acl/0]). start() -> - mnesia:create_table(acl, + ejabberd_mnesia:create(?MODULE, acl, [{ram_copies, [node()]}, {type, bag}, {local_content, true}, {attributes, record_info(fields, acl)}]), - mnesia:create_table(access, + ejabberd_mnesia:create(?MODULE, access, [{ram_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, access)}]), diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index c84321ad9..e0c4d471f 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -59,7 +59,7 @@ start(Host) -> %% TODO: Check cluster mode - mnesia:create_table(anonymous, [{ram_copies, [node()]}, + ejabberd_mnesia:create(?MODULE, anonymous, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, anonymous)}]), %% The hooks are needed to add / remove users from the anonymous tables diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index dee3774db..eac19f024 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -66,10 +66,10 @@ start(Host) -> ok. init_db() -> - mnesia:create_table(passwd, + ejabberd_mnesia:create(?MODULE, passwd, [{disc_copies, [node()]}, {attributes, record_info(fields, passwd)}]), - mnesia:create_table(reg_users_counter, + ejabberd_mnesia:create(?MODULE, reg_users_counter, [{ram_copies, [node()]}, {attributes, record_info(fields, reg_users_counter)}]). diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 6172b18ed..223163a2b 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -281,7 +281,7 @@ init() -> record_info(fields, ejabberd_commands)) catch exit:{aborted, {no_exists, _}} -> ok end, - mnesia:create_table(ejabberd_commands, + ejabberd_mnesia:create(?MODULE, ejabberd_commands, [{ram_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, ejabberd_commands)}, diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index af26767f8..e930e36b1 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -104,7 +104,7 @@ mnesia_init() -> _ -> ok end, - mnesia:create_table(local_config, + ejabberd_mnesia:create(?MODULE, local_config, [{ram_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, local_config)}]), @@ -1300,7 +1300,7 @@ convert_table_to_binary(Tab, Fields, Type, DetectFun, ConvertFun) -> ?INFO_MSG("Converting '~s' table from strings to binaries.", [Tab]), TmpTab = list_to_atom(atom_to_list(Tab) ++ "_tmp_table"), catch mnesia:delete_table(TmpTab), - case mnesia:create_table(TmpTab, + case ejabberd_mnesia:create(?MODULE, TmpTab, [{disc_only_copies, [node()]}, {type, Type}, {local_content, true}, diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 3406192f7..a5ee6a242 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -205,7 +205,7 @@ init([]) -> ?MYHOSTS), catch ets:new(?IQTABLE, [named_table, public]), update_table(), - mnesia:create_table(iq_response, + ejabberd_mnesia:create(?MODULE, iq_response, [{ram_copies, [node()]}, {attributes, record_info(fields, iq_response)}]), mnesia:add_table_copy(iq_response, node(), ram_copies), diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl new file mode 100644 index 000000000..f244d518f --- /dev/null +++ b/src/ejabberd_mnesia.erl @@ -0,0 +1,169 @@ +%%%---------------------------------------------------------------------- +%%% File : mnesia_mnesia.erl +%%% Author : Christophe Romain +%%% Purpose : Handle configurable mnesia schema +%%% Created : 17 Nov 2016 by Christophe Romain +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- + +%%% This module should be used everywhere ejabberd creates a mnesia table +%%% to make the schema customizable without code change +%%% Just apply this change in ejabberd modules +%%% s/ejabberd_mnesia:create(?MODULE, /ejabberd_mnesia:create(?MODULE, / + +-module(ejabberd_mnesia). +-author('christophe.romain@process-one.net'). +-export([create/3, reset/2, update/2]). + +-define(STORAGE_TYPES, [disc_copies, disc_only_copies, ram_copies]). +-define(NEED_RESET, [local_content, type]). + +create(Module, Name, TabDef) -> + Schema = schema(Module, Name, TabDef), + {attributes, Attrs} = lists:keyfind(attributes, 1, Schema), + case catch mnesia:table_info(Name, attributes) of + {'EXIT', _} -> + ejabberd_mnesia:create(?MODULE, Name, Schema); + Attrs -> + case need_reset(TabDef, Schema) of + true -> reset(Name, Schema); + false -> update(Name, Schema) + end; + OldAttrs -> + Fun = case lists:member({transform,1}, Module:module_info(exports)) of + true -> fun(Old) -> Module:transform(Old) end; + false -> fun(Old) -> transform(OldAttrs, Attrs, Old) end + end, + mnesia:transform_table(Name, Fun, Attrs) + end. + +reset(Name, TabDef) -> + mnesia:delete_table(Name), + ejabberd_mnesia:create(?MODULE, Name, TabDef). + +update(Name, TabDef) -> + Storage = mnesia:table_info(Name, storage_type), + NewStorage = lists:foldl( + fun({Key, _}, Acc) -> + case lists:member(Key, ?STORAGE_TYPES) of + true -> Key; + false -> Acc + end + end, Storage, TabDef), + R1 = if Storage=/=NewStorage -> + mnesia:change_table_copy_type(Name, node(), NewStorage); + true -> + {atomic, ok} + end, + Indexes = mnesia:table_info(Name, index), + NewIndexes = proplists:get_value(index, TabDef, []), + [mnesia:del_table_index(Name, Attr) + || Attr <- Indexes--NewIndexes], + R2 = [mnesia:add_table_index(Name, Attr) + || Attr <- NewIndexes--Indexes], + lists:foldl( + fun({atomic, ok}, Acc) -> Acc; + (Error, _Acc) -> Error + end, {atomic, ok}, [R1|R2]). + +% +% utilities +% + +schema(Module, Name, TabDef) -> + case parse(Module) of + {ok, CustomDefs} -> + case lists:keyfind(Name, 1, CustomDefs) of + {Name, CustomDef} -> merge(TabDef, CustomDef); + _ -> TabDef + end; + _ -> + TabDef + end. + +merge(TabDef, CustomDef) -> + {CustomKeys, _} = lists:unzip(CustomDef), + CleanDef = lists:foldl( + fun(Elem, Acc) -> + case lists:member(Elem, ?STORAGE_TYPES) of + true -> + lists:foldl( + fun(Key, CleanAcc) -> + lists:keydelete(Key, 1, CleanAcc) + end, Acc, ?STORAGE_TYPES); + false -> + Acc + end + end, TabDef, CustomKeys), + lists:ukeymerge(1, + lists:ukeysort(1, CustomDef), + lists:ukeysort(1, CleanDef)). + +parse(Module) -> + Path = case os:getenv("EJABBERD_SCHEMA_PATH") of + false -> + case code:priv_dir(ejabberd) of + {error, _} -> "schema"; % $SPOOL_DIR/schema + Priv -> filename:join(Priv, "schema") + end; + CustomDir -> + CustomDir + end, + File = filename:join(Path, atom_to_list(Module)++".mnesia"), + case file:consult(File) of + {ok, Terms} -> parse(Terms, []); + Error -> Error + end. + +parse([], Acc) -> + {ok, lists:reverse(Acc)}; +parse([{Name, Storage, TabDef}|Tail], Acc) + when is_atom(Name), + is_atom(Storage), + is_list(TabDef) -> + NewDef = case lists:member(Storage, ?STORAGE_TYPES) of + true -> [{Storage, [node()]} | TabDef]; + false -> TabDef + end, + parse(Tail, [{Name, NewDef} | Acc]); +parse([Other|_], _) -> + {error, {invalid, Other}}. + +need_reset(FromDef, ToDef) -> + ValuesF = [lists:keyfind(Key, 1, FromDef) || Key <- ?NEED_RESET], + ValuesT = [lists:keyfind(Key, 1, ToDef) || Key <- ?NEED_RESET], + lists:foldl( + fun({Val, Val}, Acc) -> Acc; + ({_, false}, Acc) -> Acc; + ({_, _}, _) -> true + end, false, lists:zip(ValuesF, ValuesT)). + +transform(OldAttrs, Attrs, Old) -> + [Name|OldValues] = tuple_to_list(Old), + Before = lists:zip(OldAttrs, OldValues), + After = lists:foldl( + fun(Attr, Acc) -> + case lists:keyfind(Attr, 1, Before) of + false -> [{Attr, undefined}|Acc]; + Value -> [Value|Acc] + end + end, [], lists:reverse(Attrs)), + {Attrs, NewRecord} = lists:unzip(After), + list_to_tuple([Name|NewRecord]). diff --git a/src/ejabberd_oauth_mnesia.erl b/src/ejabberd_oauth_mnesia.erl index a23f443ed..bdd2d0edd 100644 --- a/src/ejabberd_oauth_mnesia.erl +++ b/src/ejabberd_oauth_mnesia.erl @@ -34,7 +34,7 @@ -include("ejabberd_oauth.hrl"). init() -> - mnesia:create_table(oauth_token, + ejabberd_mnesia:create(?MODULE, oauth_token, [{disc_copies, [node()]}, {attributes, record_info(fields, oauth_token)}]), diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index c6d919097..33093abb0 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -280,7 +280,7 @@ process_iq(From, To, El) -> %%-------------------------------------------------------------------- init([]) -> update_tables(), - mnesia:create_table(route, + ejabberd_mnesia:create(?MODULE, route, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, route)}]), diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl index 283bcac25..c7a190670 100644 --- a/src/ejabberd_router_multicast.erl +++ b/src/ejabberd_router_multicast.erl @@ -115,7 +115,7 @@ unregister_route(Domain) -> %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> - mnesia:create_table(route_multicast, + ejabberd_mnesia:create(?MODULE, route_multicast, [{ram_copies, [node()]}, {type, bag}, {attributes, diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 97aef3cab..4df1761cb 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -236,14 +236,14 @@ make_key({From, To}, StreamID) -> init([]) -> update_tables(), - mnesia:create_table(s2s, + ejabberd_mnesia:create(?MODULE, s2s, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, s2s)}]), mnesia:add_table_copy(s2s, node(), ram_copies), mnesia:subscribe(system), ejabberd_commands:register_commands(get_commands_spec()), - mnesia:create_table(temporarily_blocked, + ejabberd_mnesia:create(?MODULE, temporarily_blocked, [{ram_copies, [node()]}, {attributes, record_info(fields, temporarily_blocked)}]), {ok, #state{}}. diff --git a/src/ejabberd_sm_mnesia.erl b/src/ejabberd_sm_mnesia.erl index 491872aee..ed38ceee9 100644 --- a/src/ejabberd_sm_mnesia.erl +++ b/src/ejabberd_sm_mnesia.erl @@ -80,10 +80,10 @@ get_sessions(LUser, LServer, LResource) -> %%%=================================================================== init([]) -> update_tables(), - mnesia:create_table(session, + ejabberd_mnesia:create(?MODULE, session, [{ram_copies, [node()]}, {attributes, record_info(fields, session)}]), - mnesia:create_table(session_counter, + ejabberd_mnesia:create(?MODULE, session_counter, [{ram_copies, [node()]}, {attributes, record_info(fields, session_counter)}]), mnesia:add_table_index(session, usr), diff --git a/src/ejabberd_sql_sup.erl b/src/ejabberd_sql_sup.erl index 29099fce3..93bc10ac5 100644 --- a/src/ejabberd_sql_sup.erl +++ b/src/ejabberd_sql_sup.erl @@ -49,7 +49,7 @@ -record(sql_pool, {host, pid}). start_link(Host) -> - mnesia:create_table(sql_pool, + ejabberd_mnesia:create(?MODULE, sql_pool, [{ram_copies, [node()]}, {type, bag}, {local_content, true}, {attributes, record_info(fields, sql_pool)}]), diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl index 23b2a5ba3..47753965d 100644 --- a/src/mod_announce_mnesia.erl +++ b/src/mod_announce_mnesia.erl @@ -21,11 +21,11 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(motd, + ejabberd_mnesia:create(?MODULE, motd, [{disc_copies, [node()]}, {attributes, record_info(fields, motd)}]), - mnesia:create_table(motd_users, + ejabberd_mnesia:create(?MODULE, motd_users, [{disc_copies, [node()]}, {attributes, record_info(fields, motd_users)}]), diff --git a/src/mod_bosh.erl b/src/mod_bosh.erl index 13d85b3cb..038218739 100644 --- a/src/mod_bosh.erl +++ b/src/mod_bosh.erl @@ -240,7 +240,7 @@ setup_database() -> _ -> ok end, - mnesia:create_table(bosh, + ejabberd_mnesia:create(?MODULE, bosh, [{ram_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, bosh)}]), mnesia:add_table_copy(bosh, node(), ram_copies). diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl index 660fcb4ef..ed22841e8 100644 --- a/src/mod_caps_mnesia.erl +++ b/src/mod_caps_mnesia.erl @@ -27,7 +27,7 @@ init(_Host, _Opts) -> _ -> mnesia:delete_table(caps_features) end, - mnesia:create_table(caps_features, + ejabberd_mnesia:create(?MODULE, caps_features, [{disc_only_copies, [node()]}, {local_content, true}, {attributes, diff --git a/src/mod_carboncopy_mnesia.erl b/src/mod_carboncopy_mnesia.erl index bf69bd21c..4cc7e6049 100644 --- a/src/mod_carboncopy_mnesia.erl +++ b/src/mod_carboncopy_mnesia.erl @@ -30,7 +30,7 @@ init(_Host, _Opts) -> %% probably table don't exist ok end, - mnesia:create_table(carboncopy, + ejabberd_mnesia:create(?MODULE, carboncopy, [{ram_copies, [node()]}, {attributes, record_info(fields, carboncopy)}, {type, bag}]), diff --git a/src/mod_http_bind.erl b/src/mod_http_bind.erl index 471b38c00..68500f2c4 100644 --- a/src/mod_http_bind.erl +++ b/src/mod_http_bind.erl @@ -89,7 +89,7 @@ stop(_Host) -> setup_database() -> migrate_database(), - mnesia:create_table(http_bind, + ejabberd_mnesia:create(?MODULE, http_bind, [{ram_copies, [node()]}, {attributes, record_info(fields, http_bind)}]). diff --git a/src/mod_irc_mnesia.erl b/src/mod_irc_mnesia.erl index 95cceb54c..e23f5a268 100644 --- a/src/mod_irc_mnesia.erl +++ b/src/mod_irc_mnesia.erl @@ -21,7 +21,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(irc_custom, + ejabberd_mnesia:create(?MODULE, irc_custom, [{disc_copies, [node()]}, {attributes, record_info(fields, irc_custom)}]), update_table(). diff --git a/src/mod_last_mnesia.erl b/src/mod_last_mnesia.erl index 7a1610abb..269ed4ba0 100644 --- a/src/mod_last_mnesia.erl +++ b/src/mod_last_mnesia.erl @@ -19,7 +19,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(last_activity, + ejabberd_mnesia:create(?MODULE, last_activity, [{disc_copies, [node()]}, {attributes, record_info(fields, last_activity)}]), diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl index 8b9c6676c..89ab92ff1 100644 --- a/src/mod_mam_mnesia.erl +++ b/src/mod_mam_mnesia.erl @@ -32,11 +32,11 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(archive_msg, + ejabberd_mnesia:create(?MODULE, archive_msg, [{disc_only_copies, [node()]}, {type, bag}, {attributes, record_info(fields, archive_msg)}]), - mnesia:create_table(archive_prefs, + ejabberd_mnesia:create(?MODULE, archive_prefs, [{disc_only_copies, [node()]}, {attributes, record_info(fields, archive_prefs)}]). diff --git a/src/mod_muc.erl b/src/mod_muc.erl index ab358b957..298749329 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -177,7 +177,7 @@ init([Host, Opts]) -> Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, [{host, MyHost}|Opts]), update_tables(), - mnesia:create_table(muc_online_room, + ejabberd_mnesia:create(?MODULE, muc_online_room, [{ram_copies, [node()]}, {type, ordered_set}, {attributes, record_info(fields, muc_online_room)}]), diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl index 072dddaae..8f570746c 100644 --- a/src/mod_muc_mnesia.erl +++ b/src/mod_muc_mnesia.erl @@ -26,11 +26,11 @@ %%%=================================================================== init(_Host, Opts) -> MyHost = proplists:get_value(host, Opts), - mnesia:create_table(muc_room, + ejabberd_mnesia:create(?MODULE, muc_room, [{disc_copies, [node()]}, {attributes, record_info(fields, muc_room)}]), - mnesia:create_table(muc_registered, + ejabberd_mnesia:create(?MODULE, muc_registered, [{disc_copies, [node()]}, {attributes, record_info(fields, muc_registered)}]), diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index 0aa2270ae..fbd2402ee 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -840,7 +840,7 @@ received_awaiter(JID, Waiter, LServiceS) -> %%%------------------------- create_cache() -> - mnesia:create_table(multicastc, + ejabberd_mnesia:create(?MODULE, multicastc, [{ram_copies, [node()]}, {attributes, record_info(fields, multicastc)}]). diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index e84f7078a..fb75f618e 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -25,7 +25,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(offline_msg, + ejabberd_mnesia:create(?MODULE, offline_msg, [{disc_only_copies, [node()]}, {type, bag}, {attributes, record_info(fields, offline_msg)}]), update_table(). diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl index a93e92139..eca6f8ecd 100644 --- a/src/mod_privacy_mnesia.erl +++ b/src/mod_privacy_mnesia.erl @@ -25,7 +25,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(privacy, + ejabberd_mnesia:create(?MODULE, privacy, [{disc_copies, [node()]}, {attributes, record_info(fields, privacy)}]), update_table(). diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index 84871c1e7..42e5ddfd8 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -21,7 +21,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(private_storage, + ejabberd_mnesia:create(?MODULE, private_storage, [{disc_only_copies, [node()]}, {attributes, record_info(fields, private_storage)}]), diff --git a/src/mod_proxy65_sm.erl b/src/mod_proxy65_sm.erl index 7ef4d390e..b1d33b5d9 100644 --- a/src/mod_proxy65_sm.erl +++ b/src/mod_proxy65_sm.erl @@ -62,7 +62,7 @@ start_link(Host, Opts) -> []). init([Opts]) -> - mnesia:create_table(bytestream, + ejabberd_mnesia:create(?MODULE, bytestream, [{ram_copies, [node()]}, {attributes, record_info(fields, bytestream)}]), mnesia:add_table_copy(bytestream, node(), ram_copies), diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index ba79cf7bc..717796fec 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -268,7 +268,7 @@ init([ServerHost, Opts]) -> BaseOptions = DefaultModule:options(), DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts, fun(A) when is_list(A) -> filter_node_options(A, BaseOptions) end, []), - mnesia:create_table(pubsub_last_item, + ejabberd_mnesia:create(?MODULE, pubsub_last_item, [{ram_copies, [node()]}, {attributes, record_info(fields, pubsub_last_item)}]), mod_disco:register_feature(ServerHost, ?NS_PUBSUB), diff --git a/src/mod_register.erl b/src/mod_register.erl index ba261e0f3..b96ebecbd 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -54,7 +54,7 @@ start(Host, Opts) -> stream_feature_register, 50), ejabberd_hooks:add(c2s_unauthenticated_iq, Host, ?MODULE, unauthenticated_iq_register, 50), - mnesia:create_table(mod_register_ip, + ejabberd_mnesia:create(?MODULE, mod_register_ip, [{ram_copies, [node()]}, {local_content, true}, {attributes, [key, value]}]), mnesia:add_table_copy(mod_register_ip, node(), diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index e274ac5eb..04bdf72e7 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -24,10 +24,10 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(roster, + ejabberd_mnesia:create(?MODULE, roster, [{disc_copies, [node()]}, {attributes, record_info(fields, roster)}]), - mnesia:create_table(roster_version, + ejabberd_mnesia:create(?MODULE, roster_version, [{disc_copies, [node()]}, {attributes, record_info(fields, roster_version)}]), diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl index 0f9e93bf6..ed4525041 100644 --- a/src/mod_shared_roster_mnesia.erl +++ b/src/mod_shared_roster_mnesia.erl @@ -26,10 +26,10 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(sr_group, + ejabberd_mnesia:create(?MODULE, sr_group, [{disc_copies, [node()]}, {attributes, record_info(fields, sr_group)}]), - mnesia:create_table(sr_user, + ejabberd_mnesia:create(?MODULE, sr_user, [{disc_copies, [node()]}, {type, bag}, {attributes, record_info(fields, sr_user)}]), update_tables(), diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index e6532c934..4ae8e077b 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -179,7 +179,7 @@ ping(SIPSocket) -> %%%=================================================================== init([]) -> update_table(), - mnesia:create_table(sip_session, + ejabberd_mnesia:create(?MODULE, sip_session, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, sip_session)}]), diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index a4a5f2562..40ea36381 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -24,10 +24,10 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(vcard, + ejabberd_mnesia:create(?MODULE, vcard, [{disc_only_copies, [node()]}, {attributes, record_info(fields, vcard)}]), - mnesia:create_table(vcard_search, + ejabberd_mnesia:create(?MODULE, vcard_search, [{disc_copies, [node()]}, {attributes, record_info(fields, vcard_search)}]), diff --git a/src/mod_vcard_xupdate_mnesia.erl b/src/mod_vcard_xupdate_mnesia.erl index 3f8d6fcab..454d97e25 100644 --- a/src/mod_vcard_xupdate_mnesia.erl +++ b/src/mod_vcard_xupdate_mnesia.erl @@ -19,7 +19,7 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(vcard_xupdate, + ejabberd_mnesia:create(?MODULE, vcard_xupdate, [{disc_copies, [node()]}, {attributes, record_info(fields, vcard_xupdate)}]), diff --git a/src/node_flat.erl b/src/node_flat.erl index 9c1bc9b98..55093b0e7 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -51,11 +51,11 @@ init(_Host, _ServerHost, _Opts) -> %pubsub_subscription:init(Host, ServerHost, Opts), - mnesia:create_table(pubsub_state, + ejabberd_mnesia:create(?MODULE, pubsub_state, [{disc_copies, [node()]}, {type, ordered_set}, {attributes, record_info(fields, pubsub_state)}]), - mnesia:create_table(pubsub_item, + ejabberd_mnesia:create(?MODULE, pubsub_item, [{disc_only_copies, [node()]}, {attributes, record_info(fields, pubsub_item)}]), ItemsFields = record_info(fields, pubsub_item), diff --git a/src/nodetree_tree.erl b/src/nodetree_tree.erl index 81972ca3c..eb28e3408 100644 --- a/src/nodetree_tree.erl +++ b/src/nodetree_tree.erl @@ -49,7 +49,7 @@ delete_node/2]). init(_Host, _ServerHost, _Options) -> - mnesia:create_table(pubsub_node, + ejabberd_mnesia:create(?MODULE, pubsub_node, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_node)}]), mnesia:add_table_index(pubsub_node, id), diff --git a/src/pubsub_index.erl b/src/pubsub_index.erl index 983356a18..45361e141 100644 --- a/src/pubsub_index.erl +++ b/src/pubsub_index.erl @@ -34,7 +34,7 @@ -export([init/3, new/1, free/2]). init(_Host, _ServerHost, _Opts) -> - mnesia:create_table(pubsub_index, + ejabberd_mnesia:create(?MODULE, pubsub_index, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_index)}]). diff --git a/src/pubsub_migrate.erl b/src/pubsub_migrate.erl index c493b58f9..a329f3c39 100644 --- a/src/pubsub_migrate.erl +++ b/src/pubsub_migrate.erl @@ -253,7 +253,7 @@ update_node_database(Host, ServerHost) -> end, {atomic, NewRecords} = mnesia:transaction(F), {atomic, ok} = mnesia:delete_table(pubsub_node), - {atomic, ok} = mnesia:create_table(pubsub_node, + {atomic, ok} = ejabberd_mnesia:create(?MODULE, pubsub_node, [{disc_copies, [node()]}, {attributes, record_info(fields, @@ -421,7 +421,7 @@ update_state_database(_Host, _ServerHost) -> {atomic, NewRecs} = mnesia:transaction(fun mnesia:foldl/3, [F, [], pubsub_state]), {atomic, ok} = mnesia:delete_table(pubsub_state), - {atomic, ok} = mnesia:create_table(pubsub_state, + {atomic, ok} = ejabberd_mnesia:create(?MODULE, pubsub_state, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_state)}]), FNew = fun () -> diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index 077ac5ba9..0ca066dae 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -126,7 +126,7 @@ parse_options_xform(XFields) -> %% Internal functions %%==================================================================== create_table() -> - case mnesia:create_table(pubsub_subscription, + case ejabberd_mnesia:create(?MODULE, pubsub_subscription, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_subscription)}, diff --git a/src/shaper.erl b/src/shaper.erl index eb82b8faa..19c9a049d 100644 --- a/src/shaper.erl +++ b/src/shaper.erl @@ -50,7 +50,7 @@ -spec start() -> ok. start() -> - mnesia:create_table(shaper, + ejabberd_mnesia:create(?MODULE, shaper, [{ram_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, shaper)}]), -- cgit v1.2.3 From 32f484a3497d9920a5d1e4ac5ad9a7d487e0dee2 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 30 Nov 2016 13:50:46 +0100 Subject: Fix typo introduced by 92db9ff changes --- src/ejabberd_mnesia.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl index f244d518f..0e067ad65 100644 --- a/src/ejabberd_mnesia.erl +++ b/src/ejabberd_mnesia.erl @@ -40,7 +40,7 @@ create(Module, Name, TabDef) -> {attributes, Attrs} = lists:keyfind(attributes, 1, Schema), case catch mnesia:table_info(Name, attributes) of {'EXIT', _} -> - ejabberd_mnesia:create(?MODULE, Name, Schema); + mnesia:create_table(Name, Schema); Attrs -> case need_reset(TabDef, Schema) of true -> reset(Name, Schema); -- cgit v1.2.3