diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-07-18 15:01:32 +0300 |
---|---|---|
committer | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-07-18 15:01:32 +0300 |
commit | 9a8e197d7e03298fce9cec030ae961ca7814419e (patch) | |
tree | fe78750783d006b27b66340b1bdff41a7c636ae9 /src | |
parent | Omit [info] message with number of queued stanzas (diff) |
Initial version based on XML generator
Diffstat (limited to 'src')
35 files changed, 26607 insertions, 3650 deletions
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, <<"</stream:stream>">>). --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 <forwarded/> 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">>, - <<Node/binary, "#", - SubNode/binary>>}], - children = []}]}, + IQ = #iq{type = get, + sub_els = [#disco_info{node = <<Node/binary, "#", + SubNode/binary>>}]}, 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 <enable/> or <disable/> 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 <received xmlns='urn:xmpp:carbons:1'/> +-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">>, - <<User/binary, "@", Server/binary, "/", - R/binary>>}, - {<<"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 <list/> 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: " + "<list/>, <active/> or <default/>">>, + {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, - <<UTC/binary, - UTC_diff/binary>>}]}]}]} - 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 = <<Desc/binary, $\n, Copyright/binary>>, + 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 = <<Desc/binary, $\n, Copyright/binary>>}). + +-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">>, - <<Username/binary, "@", LServer/binary>>), - ?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">>, <<Username/binary, "@", LServer/binary>>), + 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">>, <<User/binary, "@", Server/binary>>), - ?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">>, <<User/binary, "@", Server/binary>>), + 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 = <<OSType/binary, " ", OSVersion/binary>>, - #xmlel{name = <<"os">>, attrs = [], - children = [{xmlcdata, OS}]}. + <<OSType/binary, " ", OSVersion/binary>>. 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 <ekhramtsov@process-one.net> +%%% @copyright (C) 2015, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 9 Dec 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%%------------------------------------------------------------------- +-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) -> + <<H/binary, << <<Sep, X/binary>> || 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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +decode_mam_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_mam_jid_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_mam_jid(Cdata, _xmlns_attrs) -> + _els = encode_mam_jid_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"jid">>, _attrs, _els}. + +decode_mam_jid_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"jid">>, __TopXMLNS}}); +decode_mam_jid_cdata(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"jid">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mam_jid_cdata(_val, _acc) -> + [{xmlcdata, enc_jid(_val)} | _acc]. + +decode_mam_result(__TopXMLNS, __IgnoreEls, + {xmlel, <<"result">>, _attrs, _els}) -> + __Els = decode_mam_result_els(__TopXMLNS, __IgnoreEls, + _els, []), + {Queryid, Xmlns, Id} = + decode_mam_result_attrs(__TopXMLNS, _attrs, undefined, + undefined, undefined), + {mam_result, Xmlns, Queryid, Id, __Els}. + +decode_mam_result_els(__TopXMLNS, __IgnoreEls, [], + __Els) -> + lists:reverse(__Els); +decode_mam_result_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], __Els) -> + if __IgnoreEls -> + decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, + [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, + [decode(_el) | __Els]); + false -> + decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, + __Els) + end + end; +decode_mam_result_els(__TopXMLNS, __IgnoreEls, + [_ | _els], __Els) -> + decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els, + __Els). + +decode_mam_result_attrs(__TopXMLNS, + [{<<"queryid">>, _val} | _attrs], _Queryid, Xmlns, + Id) -> + decode_mam_result_attrs(__TopXMLNS, _attrs, _val, Xmlns, + Id); +decode_mam_result_attrs(__TopXMLNS, + [{<<"xmlns">>, _val} | _attrs], Queryid, _Xmlns, Id) -> + decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid, + _val, Id); +decode_mam_result_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], Queryid, Xmlns, _Id) -> + decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid, + Xmlns, _val); +decode_mam_result_attrs(__TopXMLNS, [_ | _attrs], + Queryid, Xmlns, Id) -> + decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid, + Xmlns, Id); +decode_mam_result_attrs(__TopXMLNS, [], Queryid, Xmlns, + Id) -> + {decode_mam_result_attr_queryid(__TopXMLNS, Queryid), + decode_mam_result_attr_xmlns(__TopXMLNS, Xmlns), + decode_mam_result_attr_id(__TopXMLNS, Id)}. + +encode_mam_result({mam_result, Xmlns, Queryid, Id, + __Els}, + _xmlns_attrs) -> + _els = [encode(_el) || _el <- __Els], + _attrs = encode_mam_result_attr_id(Id, + encode_mam_result_attr_xmlns(Xmlns, + encode_mam_result_attr_queryid(Queryid, + _xmlns_attrs))), + {xmlel, <<"result">>, _attrs, _els}. + +decode_mam_result_attr_queryid(__TopXMLNS, undefined) -> + undefined; +decode_mam_result_attr_queryid(__TopXMLNS, _val) -> + _val. + +encode_mam_result_attr_queryid(undefined, _acc) -> _acc; +encode_mam_result_attr_queryid(_val, _acc) -> + [{<<"queryid">>, _val} | _acc]. + +decode_mam_result_attr_xmlns(__TopXMLNS, undefined) -> + undefined; +decode_mam_result_attr_xmlns(__TopXMLNS, _val) -> _val. + +encode_mam_result_attr_xmlns(undefined, _acc) -> _acc; +encode_mam_result_attr_xmlns(_val, _acc) -> + [{<<"xmlns">>, _val} | _acc]. + +decode_mam_result_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_mam_result_attr_id(__TopXMLNS, _val) -> _val. + +encode_mam_result_attr_id(undefined, _acc) -> _acc; +encode_mam_result_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_mam_archived(__TopXMLNS, __IgnoreEls, + {xmlel, <<"archived">>, _attrs, _els}) -> + {Id, By} = decode_mam_archived_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {mam_archived, By, Id}. + +decode_mam_archived_attrs(__TopXMLNS, + [{<<"id">>, _val} | _attrs], _Id, By) -> + decode_mam_archived_attrs(__TopXMLNS, _attrs, _val, By); +decode_mam_archived_attrs(__TopXMLNS, + [{<<"by">>, _val} | _attrs], Id, _By) -> + decode_mam_archived_attrs(__TopXMLNS, _attrs, Id, _val); +decode_mam_archived_attrs(__TopXMLNS, [_ | _attrs], Id, + By) -> + decode_mam_archived_attrs(__TopXMLNS, _attrs, Id, By); +decode_mam_archived_attrs(__TopXMLNS, [], Id, By) -> + {decode_mam_archived_attr_id(__TopXMLNS, Id), + decode_mam_archived_attr_by(__TopXMLNS, By)}. + +encode_mam_archived({mam_archived, By, Id}, + _xmlns_attrs) -> + _els = [], + _attrs = encode_mam_archived_attr_by(By, + encode_mam_archived_attr_id(Id, + _xmlns_attrs)), + {xmlel, <<"archived">>, _attrs, _els}. + +decode_mam_archived_attr_id(__TopXMLNS, undefined) -> + undefined; +decode_mam_archived_attr_id(__TopXMLNS, _val) -> _val. + +encode_mam_archived_attr_id(undefined, _acc) -> _acc; +encode_mam_archived_attr_id(_val, _acc) -> + [{<<"id">>, _val} | _acc]. + +decode_mam_archived_attr_by(__TopXMLNS, undefined) -> + erlang:error({xmpp_codec, + {missing_attr, <<"by">>, <<"archived">>, __TopXMLNS}}); +decode_mam_archived_attr_by(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"by">>, <<"archived">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_mam_archived_attr_by(_val, _acc) -> + [{<<"by">>, enc_jid(_val)} | _acc]. + +decode_mam_query(__TopXMLNS, __IgnoreEls, + {xmlel, <<"query">>, _attrs, _els}) -> + {Xdata, End, Start, With, Rsm} = + decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined), + {Id, Xmlns} = decode_mam_query_attrs(__TopXMLNS, _attrs, + undefined, undefined), + {mam_query, Xmlns, Id, Start, End, With, Rsm, Xdata}. + +decode_mam_query_els(__TopXMLNS, __IgnoreEls, [], Xdata, + End, Start, With, Rsm) -> + {Xdata, End, Start, With, Rsm}; +decode_mam_query_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"start">>, _attrs, _} = _el | _els], Xdata, + End, Start, With, Rsm) -> + 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, + <<Cdata/binary, _data/binary>>); +decode_mam_with_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_mam_with_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_mam_with(Cdata, _xmlns_attrs) -> + _els = encode_mam_with_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"with">>, _attrs, _els}. + +decode_mam_with_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"with">>, __TopXMLNS}}); +decode_mam_with_cdata(__TopXMLNS, _val) -> + case catch dec_jid(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"with">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mam_with_cdata(_val, _acc) -> + [{xmlcdata, enc_jid(_val)} | _acc]. + +decode_mam_end(__TopXMLNS, __IgnoreEls, + {xmlel, <<"end">>, _attrs, _els}) -> + Cdata = decode_mam_end_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_mam_end_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_mam_end_cdata(__TopXMLNS, Cdata); +decode_mam_end_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_mam_end_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_mam_end(Cdata, _xmlns_attrs) -> + _els = encode_mam_end_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"end">>, _attrs, _els}. + +decode_mam_end_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"end">>, __TopXMLNS}}); +decode_mam_end_cdata(__TopXMLNS, _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"end">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mam_end_cdata(_val, _acc) -> + [{xmlcdata, enc_utc(_val)} | _acc]. + +decode_mam_start(__TopXMLNS, __IgnoreEls, + {xmlel, <<"start">>, _attrs, _els}) -> + Cdata = decode_mam_start_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_mam_start_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_mam_start_cdata(__TopXMLNS, Cdata); +decode_mam_start_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_mam_start_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_mam_start(Cdata, _xmlns_attrs) -> + _els = encode_mam_start_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"start">>, _attrs, _els}. + +decode_mam_start_cdata(__TopXMLNS, <<>>) -> + erlang:error({xmpp_codec, + {missing_cdata, <<>>, <<"start">>, __TopXMLNS}}); +decode_mam_start_cdata(__TopXMLNS, _val) -> + case catch dec_utc(_val) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"start">>, __TopXMLNS}}); + _res -> _res + end. + +encode_mam_start_cdata(_val, _acc) -> + [{xmlcdata, enc_utc(_val)} | _acc]. + +decode_rsm_set(__TopXMLNS, __IgnoreEls, + {xmlel, <<"set">>, _attrs, _els}) -> + {After, Last, First, Count, Before, Max, Index} = + decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined), + {rsm_set, After, Before, Count, First, Index, Last, + Max}. + +decode_rsm_set_els(__TopXMLNS, __IgnoreEls, [], After, + Last, First, Count, Before, Max, Index) -> + {After, Last, First, Count, Before, Max, Index}; +decode_rsm_set_els(__TopXMLNS, __IgnoreEls, + [{xmlel, <<"after">>, _attrs, _} = _el | _els], After, + Last, First, Count, Before, Max, Index) -> + 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, + <<Data/binary, _data/binary>>); +decode_rsm_first_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Data) -> + decode_rsm_first_els(__TopXMLNS, __IgnoreEls, _els, + Data). + +decode_rsm_first_attrs(__TopXMLNS, + [{<<"index">>, _val} | _attrs], _Index) -> + decode_rsm_first_attrs(__TopXMLNS, _attrs, _val); +decode_rsm_first_attrs(__TopXMLNS, [_ | _attrs], + Index) -> + decode_rsm_first_attrs(__TopXMLNS, _attrs, Index); +decode_rsm_first_attrs(__TopXMLNS, [], Index) -> + decode_rsm_first_attr_index(__TopXMLNS, Index). + +encode_rsm_first({rsm_first, Index, Data}, + _xmlns_attrs) -> + _els = encode_rsm_first_cdata(Data, []), + _attrs = encode_rsm_first_attr_index(Index, + _xmlns_attrs), + {xmlel, <<"first">>, _attrs, _els}. + +decode_rsm_first_attr_index(__TopXMLNS, undefined) -> + undefined; +decode_rsm_first_attr_index(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_attr_value, <<"index">>, <<"first">>, + __TopXMLNS}}); + _res -> _res + end. + +encode_rsm_first_attr_index(undefined, _acc) -> _acc; +encode_rsm_first_attr_index(_val, _acc) -> + [{<<"index">>, enc_int(_val)} | _acc]. + +decode_rsm_first_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_first_cdata(__TopXMLNS, _val) -> _val. + +encode_rsm_first_cdata(undefined, _acc) -> _acc; +encode_rsm_first_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_rsm_max(__TopXMLNS, __IgnoreEls, + {xmlel, <<"max">>, _attrs, _els}) -> + Cdata = decode_rsm_max_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_rsm_max_cdata(__TopXMLNS, Cdata); +decode_rsm_max_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_max(Cdata, _xmlns_attrs) -> + _els = encode_rsm_max_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"max">>, _attrs, _els}. + +decode_rsm_max_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_max_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"max">>, __TopXMLNS}}); + _res -> _res + end. + +encode_rsm_max_cdata(undefined, _acc) -> _acc; +encode_rsm_max_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_rsm_index(__TopXMLNS, __IgnoreEls, + {xmlel, <<"index">>, _attrs, _els}) -> + Cdata = decode_rsm_index_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_rsm_index_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_rsm_index_cdata(__TopXMLNS, Cdata); +decode_rsm_index_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_rsm_index_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_index(Cdata, _xmlns_attrs) -> + _els = encode_rsm_index_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"index">>, _attrs, _els}. + +decode_rsm_index_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_index_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"index">>, __TopXMLNS}}); + _res -> _res + end. + +encode_rsm_index_cdata(undefined, _acc) -> _acc; +encode_rsm_index_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_rsm_count(__TopXMLNS, __IgnoreEls, + {xmlel, <<"count">>, _attrs, _els}) -> + Cdata = decode_rsm_count_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_rsm_count_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_rsm_count_cdata(__TopXMLNS, Cdata); +decode_rsm_count_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_rsm_count_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_count(Cdata, _xmlns_attrs) -> + _els = encode_rsm_count_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"count">>, _attrs, _els}. + +decode_rsm_count_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_count_cdata(__TopXMLNS, _val) -> + case catch dec_int(_val, 0, infinity) of + {'EXIT', _} -> + erlang:error({xmpp_codec, + {bad_cdata_value, <<>>, <<"count">>, __TopXMLNS}}); + _res -> _res + end. + +encode_rsm_count_cdata(undefined, _acc) -> _acc; +encode_rsm_count_cdata(_val, _acc) -> + [{xmlcdata, enc_int(_val)} | _acc]. + +decode_rsm_last(__TopXMLNS, __IgnoreEls, + {xmlel, <<"last">>, _attrs, _els}) -> + Cdata = decode_rsm_last_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_rsm_last_cdata(__TopXMLNS, Cdata); +decode_rsm_last_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [_ | _els], + Cdata) -> + decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_last(Cdata, _xmlns_attrs) -> + _els = encode_rsm_last_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"last">>, _attrs, _els}. + +decode_rsm_last_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_last_cdata(__TopXMLNS, _val) -> _val. + +encode_rsm_last_cdata(undefined, _acc) -> _acc; +encode_rsm_last_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_rsm_before(__TopXMLNS, __IgnoreEls, + {xmlel, <<"before">>, _attrs, _els}) -> + Cdata = decode_rsm_before_els(__TopXMLNS, __IgnoreEls, + _els, <<>>), + Cdata. + +decode_rsm_before_els(__TopXMLNS, __IgnoreEls, [], + Cdata) -> + decode_rsm_before_cdata(__TopXMLNS, Cdata); +decode_rsm_before_els(__TopXMLNS, __IgnoreEls, + [{xmlcdata, _data} | _els], Cdata) -> + decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els, + <<Cdata/binary, _data/binary>>); +decode_rsm_before_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_before(Cdata, _xmlns_attrs) -> + _els = encode_rsm_before_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"before">>, _attrs, _els}. + +decode_rsm_before_cdata(__TopXMLNS, <<>>) -> 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, + <<Cdata/binary, _data/binary>>); +decode_rsm_after_els(__TopXMLNS, __IgnoreEls, + [_ | _els], Cdata) -> + decode_rsm_after_els(__TopXMLNS, __IgnoreEls, _els, + Cdata). + +encode_rsm_after(Cdata, _xmlns_attrs) -> + _els = encode_rsm_after_cdata(Cdata, []), + _attrs = _xmlns_attrs, + {xmlel, <<"after">>, _attrs, _els}. + +decode_rsm_after_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_after_cdata(__TopXMLNS, _val) -> _val. + +encode_rsm_after_cdata(undefined, _acc) -> _acc; +encode_rsm_after_cdata(_val, _acc) -> + [{xmlcdata, _val} | _acc]. + +decode_muc(__TopXMLNS, __IgnoreEls, + {xmlel, <<"x">>, _attrs, _els}) -> + History = decode_muc_els(__TopXMLNS, __IgnoreEls, _els, + 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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Desc/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Host/binary, _data/binary>>); +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, <<Data/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Data/binary, _data/binary>>); +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, + <<Text/binary, _data/binary>>); +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, + <<Text/binary, _data/binary>>); +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, + <<Text/binary, _data/binary>>); +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, + <<Text/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Data/binary, _data/binary>>); +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, + <<Uri/binary, _data/binary>>); +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, + <<Uri/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Data/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Data/binary, _data/binary>>); +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, <<Data/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Cdata/binary, _data/binary>>); +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, + <<Status/binary, _data/binary>>); +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 <ekhramtsov@process-one.net> +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 12 Jul 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%%------------------------------------------------------------------- +-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 = <<OldDesc/binary, ", ", Desc/binary>>, + 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 +%%%=================================================================== |