summaryrefslogtreecommitdiff
path: root/tools/xmpp_codec.spec
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xmpp_codec.spec')
-rw-r--r--tools/xmpp_codec.spec1244
1 files changed, 1244 insertions, 0 deletions
diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec
new file mode 100644
index 00000000..ebcb77e9
--- /dev/null
+++ b/tools/xmpp_codec.spec
@@ -0,0 +1,1244 @@
+{spec, last,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"jabber:iq:last">>,
+ result = {last, '$seconds', '$text'},
+ attrs = [#attr{name = <<"seconds">>,
+ default = undefined,
+ enc = {enc_int, []},
+ dec = {dec_int, [0, infinity]}}],
+ cdata = #cdata{label = '$text'}}}.
+
+{spec, version,
+ #spec{name = <<"query">>,
+ xmlns = <<"jabber:iq:version">>,
+ min = 0, max = 1,
+ result = {version, '$name', '$version', '$os'},
+ els = [#spec{name = <<"name">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{label = '$cdata', required = true}},
+ #spec{name = <<"version">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{label = '$cdata', required = true}},
+ #spec{name = <<"os">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{label = '$cdata', required = true}}]}}.
+
+{spec, roster,
+ #spec{name = <<"query">>,
+ xmlns = <<"jabber:iq:roster">>,
+ result = {roster, '$item', '$ver'},
+ min = 0, max = 1,
+ attrs = [#attr{name = <<"ver">>}],
+ els = [#spec{name = <<"item">>,
+ result = {roster_item, '$jid', '$name',
+ '$groups', '$subscription', '$ask'},
+ attrs = [#attr{name = <<"jid">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"name">>},
+ #attr{name = <<"subscription">>,
+ default = none,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [[none,to,from,both,remove]]}},
+ #attr{name = <<"ask">>,
+ default = undefined,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [[subscribe]]}}],
+ els = [#spec{name = <<"group">>,
+ label = '$groups',
+ result = '$cdata',
+ cdata = #cdata{required = true,
+ label = '$cdata'}}]}]}}.
+
+{spec, privacy_item,
+ #spec{name = <<"item">>,
+ result = {privacy_item, '$order', '$action', '$type',
+ '$value', '$stanza'},
+ label = '$privacy_item',
+ attrs = [#attr{name = <<"action">>,
+ required = true,
+ dec = {dec_enum, [[allow, deny]]},
+ enc = {enc_enum, []}},
+ #attr{name = <<"order">>,
+ required = true,
+ dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}},
+ #attr{name = <<"type">>,
+ dec = {dec_enum, [[group, jid, subscription]]},
+ enc = {enc_enum, []}},
+ #attr{name = <<"value">>}],
+ els = [#spec{name = <<"message">>,
+ min = 0, max = 1,
+ label = '$stanza',
+ result = message},
+ #spec{name = <<"iq">>,
+ min = 0, max = 1,
+ label = '$stanza',
+ result = iq},
+ #spec{name = <<"presence-in">>,
+ min = 0, max = 1,
+ label = '$stanza',
+ result = 'presence-in'},
+ #spec{name = <<"presence-out">>,
+ min = 0, max = 1,
+ label = '$stanza',
+ result = 'presence-out'}]}}.
+
+{spec, privacy,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"jabber:iq:privacy">>,
+ result = {privacy, '$list', '$default', '$active'},
+ els = [#spec{name = <<"list">>,
+ result = {privacy_list, '$name', '$privacy_item'},
+ attrs = [#attr{name = <<"name">>,
+ required = true}],
+ els = [privacy_item]},
+ #spec{name = <<"default">>,
+ min = 0, max = 1,
+ result = '$name',
+ attrs = [#attr{name = <<"name">>,
+ default = none}]},
+ #spec{name = <<"active">>,
+ min = 0, max = 1,
+ result = '$name',
+ attrs = [#attr{name = <<"name">>,
+ default = none}]}]}}.
+
+{spec, block_item,
+ #spec{name = <<"item">>,
+ label = '$block_item',
+ result = '$jid',
+ attrs = [#attr{name = <<"jid">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}]}}.
+
+{spec, block,
+ #spec{name = <<"block">>,
+ xmlns = <<"urn:xmpp:blocking">>,
+ min = 0, max = 1,
+ result = {block, '$block_item'},
+ els = [block_item]}}.
+
+{spec, unblock,
+ #spec{name = <<"unblock">>,
+ xmlns = <<"urn:xmpp:blocking">>,
+ min = 0, max = 1,
+ result = {unblock, '$block_item'},
+ els = [block_item]}}.
+
+{spec, block_list,
+ #spec{name = <<"blocklist">>,
+ xmlns = <<"urn:xmpp:blocking">>,
+ result = {block_list},
+ min = 0, max = 1}}.
+
+{spec, disco_info,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/protocol/disco#info">>,
+ result = {disco_info, '$node', '$identity', '$feature', '$xdata'},
+ attrs = [#attr{name = <<"node">>}],
+ els = [#spec{name = <<"identity">>,
+ result = {'$category', '$type', '$name'},
+ attrs = [#attr{name = <<"category">>,
+ required = true},
+ #attr{name = <<"type">>,
+ required = true},
+ #attr{name = <<"name">>}]},
+ #spec{name = <<"feature">>,
+ result = '$var',
+ attrs = [#attr{name = <<"var">>,
+ required = true}]},
+ xdata]}}.
+
+{spec, disco_items,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/protocol/disco#items">>,
+ result = {disco_items, '$node', '$items'},
+ attrs = [#attr{name = <<"node">>}],
+ els = [#spec{name = <<"item">>,
+ label = '$items',
+ result = {disco_item, '$jid', '$name', '$node'},
+ cdata = #cdata{label = '$cdata'},
+ attrs = [#attr{name = <<"jid">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []},
+ required = true},
+ #attr{name = <<"name">>},
+ #attr{name = <<"node">>}]}]}}.
+
+{spec, private,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"jabber:iq:private">>,
+ result = {private, '$_els'}}}.
+
+{spec, bookmark_conference,
+ #spec{name = <<"conference">>,
+ result = {bookmark_conference, '$name', '$jid',
+ '$autojoin', '$nick', '$password'},
+ attrs = [#attr{name = <<"name">>,
+ required = true},
+ #attr{name = <<"jid">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"autojoin">>,
+ default = false,
+ dec = {dec_bool, []},
+ enc = {enc_bool, []}}],
+ els = [#spec{name = <<"nick">>,
+ min = 0, max = 1,
+ result = '$cdata'},
+ #spec{name = <<"password">>,
+ min = 0, max = 1,
+ result = '$cdata'}]}}.
+
+{spec, storage_bookmarks,
+ #spec{name = <<"storage">>,
+ xmlns = <<"storage:bookmarks">>,
+ min = 0, max = 1,
+ result = {bookmark_storage, '$conference', '$url'},
+ els = [bookmark_conference,
+ #spec{name = <<"url">>,
+ result = {bookmark_url, '$name', '$url'},
+ attrs = [#attr{name = <<"name">>,
+ required = true},
+ #attr{name = <<"url">>,
+ required = true}]}]}}.
+
+{spec, stats,
+ #spec{name = <<"query">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/protocol/stats">>,
+ result = {stats, '$stat'},
+ els = [#spec{name = <<"stat">>,
+ result = {stat, '$name', '$units', '$value', '$error'},
+ attrs = [#attr{name = <<"name">>,
+ required = true},
+ #attr{name = <<"units">>},
+ #attr{name = <<"value">>}],
+ els = [#spec{name = <<"error">>,
+ result = {'$code', '$cdata'},
+ attrs = [#attr{name = <<"code">>,
+ required = true,
+ enc = {enc_int, []},
+ dec = {dec_int, []}}]}]}]}}.
+
+{spec, iq,
+ #spec{name = <<"iq">>,
+ min = 0, max = 1,
+ result = {iq, '$id', '$type', '$lang', '$from', '$to',
+ '$error', '$_els'},
+ attrs = [#attr{name = <<"id">>,
+ required = true},
+ #attr{name = <<"type">>,
+ required = true,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [[get, set, result, error]]}},
+ #attr{name = <<"from">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"to">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"xml:lang">>,
+ label = '$lang'}],
+ els = [error]}}.
+
+{spec, message,
+ #spec{name = <<"message">>,
+ min = 0, max = 1,
+ result = {message, '$id', '$type', '$lang', '$from', '$to',
+ '$subject', '$body', '$thread', '$error', '$_els'},
+ attrs = [#attr{name = <<"id">>},
+ #attr{name = <<"type">>,
+ default = normal,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [[chat, normal, groupchat,
+ headline, error]]}},
+ #attr{name = <<"from">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"to">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"xml:lang">>,
+ label = '$lang'}],
+ els = [error,
+ #spec{name = <<"subject">>,
+ result = {'$subject_lang', '$cdata'},
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$subject_lang'}]},
+ #spec{name = <<"body">>,
+ result = {'$body_lang', '$cdata'},
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$body_lang'}]},
+ #spec{name = <<"thread">>,
+ min = 0, max = 1,
+ result = '$cdata'}]}}.
+
+{spec, presence,
+ #spec{name = <<"presence">>,
+ min = 0, max = 1,
+ result = {presence, '$id', '$type', '$lang', '$from', '$to',
+ '$show', '$status', '$priority', '$error', '$_els'},
+ attrs = [#attr{name = <<"id">>},
+ #attr{name = <<"type">>,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [[unavailable, subscribe, subscribed,
+ unsubscribe, unsubscribed,
+ probe, error]]}},
+ #attr{name = <<"from">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"to">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"xml:lang">>,
+ label = '$lang'}],
+ els = [error,
+ #spec{name = <<"show">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{enc = {enc_enum, []},
+ dec = {dec_enum, [[away, chat, dnd, xa]]}}},
+ #spec{name = <<"status">>,
+ result = {'$status_lang', '$cdata'},
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$status_lang'}]},
+ #spec{name = <<"priority">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{enc = {enc_int, []},
+ dec = {dec_int, [-128, 127]}}}]}}.
+
+{spec, error,
+ #spec{name = <<"error">>,
+ min = 0, max = 1,
+ result = {error, '$error_type', '$by', '$reason', '$text'},
+ attrs = [#attr{name = <<"type">>,
+ label = '$error_type',
+ required = true,
+ dec = {dec_enum, [[auth, cancel, continue,
+ modify, wait]]},
+ enc = {enc_enum, []}},
+ #attr{name = <<"by">>}],
+ els = [#spec{name = <<"text">>,
+ min = 0, max = 1,
+ result = {'$text_lang', '$cdata'},
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$text_lang'}]},
+ #spec{name = <<"bad-request">>,
+ result = 'bad-request',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"conflict">>,
+ result = 'conflict',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"feature-not-implemented">>,
+ result = 'feature-not-implemented',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"forbidden">>,
+ result = 'forbidden',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"gone">>,
+ result = {'gone', '$cdata'},
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"internal-server-error">>,
+ result = 'internal-server-error',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"item-not-found">>,
+ result = 'item-not-found',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"jid-malformed">>,
+ result = 'jid-malformed',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-acceptable">>,
+ result = 'not-acceptable',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-allowed">>,
+ result = 'not-allowed',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-authorized">>,
+ result = 'not-authorized',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"policy-violation">>,
+ result = 'policy-violation',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"recipient-unavailable">>,
+ result = 'recipient-unavailable',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"redirect">>,
+ result = {'redirect', '$cdata'},
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"registration-required">>,
+ result = 'registration-required',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"remote-server-not-found">>,
+ result = 'remote-server-not-found',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"remote-server-timeout">>,
+ result = 'remote-server-timeout',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"resource-constraint">>,
+ result = 'resource-constraint',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"service-unavailable">>,
+ result = 'service-unavailable',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"subscription-required">>,
+ result = 'subscription-required',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"undefined-condition">>,
+ result = 'undefined-condition',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"unexpected-request">>,
+ result = 'unexpected-request',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+ min = 0, max = 1, label = '$reason'}]}}.
+
+{spec, bind,
+ #spec{name = <<"bind">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-bind">>,
+ min = 0, max = 1,
+ result = {bind, '$jid', '$resource'},
+ els = [#spec{name = <<"jid">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{dec = {dec_jid, []},
+ enc = {enc_jid, []}}},
+ #spec{name = <<"resource">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{dec = {resourceprep, []},
+ enc = {resourceprep, []}}}]}}.
+
+{spec, sasl_auth,
+ #spec{name = <<"auth">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ cdata = #cdata{dec = {base64, decode, []},
+ enc = {base64, encode, []}},
+ result = {sasl_auth, '$mechanism', '$cdata'},
+ attrs = [#attr{name = <<"mechanism">>,
+ required = true}]}}.
+
+{spec, sasl_abort,
+ #spec{name = <<"abort">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ result = {sasl_abort}}}.
+
+{spec, sasl_challenge,
+ #spec{name = <<"challenge">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ cdata = #cdata{dec = {base64, decode, []},
+ enc = {base64, encode, []}},
+ result = {sasl_challenge, '$cdata'}}}.
+
+{spec, sasl_response,
+ #spec{name = <<"response">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ cdata = #cdata{dec = {base64, decode, []},
+ enc = {base64, encode, []}},
+ result = {sasl_response, '$cdata'}}}.
+
+{spec, sasl_success,
+ #spec{name = <<"success">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ cdata = #cdata{dec = {base64, decode, []},
+ enc = {base64, encode, []}},
+ result = {sasl_success, '$cdata'}}}.
+
+{spec, sasl_failure,
+ #spec{name = <<"failure">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ min = 0, max = 1,
+ result = {sasl_failure, '$reason', '$text'},
+ els = [#spec{name = <<"text">>,
+ min = 0, max = 1,
+ result = {'$text_lang', '$cdata'},
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$text_lang'}]},
+ #spec{name = <<"aborted">>,
+ result = 'aborted',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"account-disabled">>,
+ result = 'account-disabled',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"credentials-expired">>,
+ result = 'credentials-expired',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"encryption-required">>,
+ result = 'encryption-required',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"incorrect-encoding">>,
+ result = 'incorrect-encoding',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-authzid">>,
+ result = 'invalid-authzid',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-mechanism">>,
+ result = 'invalid-mechanism',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"malformed-request">>,
+ result = 'malformed-request',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"mechanism-too-weak">>,
+ result = 'mechanism-too-weak',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-authorized">>,
+ result = 'not-authorized',
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"temporary-auth-failure">>,
+ result = 'temporary-auth-failure',
+ min = 0, max = 1, label = '$reason'}]}}.
+
+{spec, sasl_mechanism,
+ #spec{name = <<"mechanism">>,
+ result = '$cdata',
+ min = 1,
+ cdata = #cdata{}}}.
+
+{spec, sasl_mechanisms,
+ #spec{name = <<"mechanisms">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+ result = {sasl_mechanisms, '$mechanism'},
+ min = 0, max = 1,
+ els = [sasl_mechanism]}}.
+
+{spec, starttls,
+ #spec{name = <<"starttls">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+ min = 0, max = 1,
+ result = {starttls, '$required'},
+ els = [#spec{name = <<"required">>,
+ min = 0, max = 1,
+ default = false,
+ result = true}]}}.
+
+{spec, starttls_proceed,
+ #spec{name = <<"proceed">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+ min = 0, max = 1,
+ result = {starttls_proceed}}}.
+
+{spec, starttls_failure,
+ #spec{name = <<"failure">>,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+ min = 0, max = 1,
+ result = {starttls_failure}}}.
+
+{spec, stream_features,
+ #spec{name = <<"stream:features">>,
+ min = 0, max = 1,
+ result = {stream_features, '$_els'}}}.
+
+{spec, p1_push,
+ #spec{name = <<"push">>,
+ min = 0, max = 1,
+ result = {p1_push},
+ xmlns = <<"p1:push">>}}.
+
+{spec, p1_rebind,
+ #spec{name = <<"rebind">>,
+ min = 0, max = 1,
+ result = {p1_rebind},
+ xmlns = <<"p1:rebind">>}}.
+
+{spec, p1_ack,
+ #spec{name = <<"ack">>,
+ min = 0, max = 1,
+ result = {p1_ack},
+ xmlns = <<"p1:ack">>}}.
+
+{spec, caps,
+ #spec{name = <<"c">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/protocol/caps">>,
+ result = {caps, '$hash', '$node', '$ver'},
+ attrs = [#attr{name = <<"hash">>},
+ #attr{name = <<"node">>},
+ #attr{name = <<"ver">>,
+ enc = {base64, encode, []},
+ dec = {base64, decode, []}}]}}.
+
+{spec, register,
+ #spec{name = <<"register">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/features/iq-register">>,
+ result = {register}}}.
+
+{spec, session,
+ #spec{name = <<"session">>,
+ min = 0, max = 1,
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-session">>,
+ result = {session}}}.
+
+{spec, ping,
+ #spec{name = <<"ping">>,
+ min = 0, max = 1,
+ xmlns = <<"urn:xmpp:ping">>,
+ result = {ping}}}.
+
+{spec, time,
+ #spec{name = <<"time">>,
+ min = 0, max = 1,
+ xmlns = <<"urn:xmpp:time">>,
+ result = {time, '$tzo', '$utc'},
+ els = [#spec{name = <<"tzo">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{dec = {dec_tzo, []},
+ enc = {enc_tzo, []}}},
+ #spec{name = <<"utc">>,
+ min = 0, max = 1,
+ result = '$cdata',
+ cdata = #cdata{dec = {dec_utc, []},
+ enc = {enc_utc, []}}}]}}.
+
+{spec, stream_error,
+ #spec{name = <<"stream:error">>,
+ min = 0, max = 1,
+ result = {stream_error, '$reason', '$text'},
+ els = [#spec{name = <<"text">>,
+ min = 0, max = 1,
+ result = {'$text_lang', '$cdata'},
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ attrs = [#attr{name = <<"xml:lang">>,
+ label = '$text_lang'}]},
+ #spec{name = <<"bad-format">>,
+ result = 'bad-format',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"bad-namespace-prefix">>,
+ result = 'bad-namespace-prefix',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"conflict">>,
+ result = 'conflict',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"connection-timeout">>,
+ result = 'connection-timeout',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"host-gone">>,
+ result = 'host-gone',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"host-unknown">>,
+ result = 'host-unknown',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"improper-addressing">>,
+ result = 'improper-addressing',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"internal-server-error">>,
+ result = 'internal-server-error',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-from">>,
+ result = 'invalid-from',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-id">>,
+ result = 'invalid-id',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-namespace">>,
+ result = 'invalid-namespace',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"invalid-xml">>,
+ result = 'invalid-xml',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-authorized">>,
+ result = 'not-authorized',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"not-well-formed">>,
+ result = 'not-well-formed',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"policy-violation">>,
+ result = 'policy-violation',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"remote-connection-failed">>,
+ result = 'remote-connection-failed',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"reset">>,
+ result = 'reset',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"resource-constraint">>,
+ result = 'resource-constraint',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"restricted-xml">>,
+ result = 'restricted-xml',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"see-other-host">>,
+ result = {'see-other-host', '$cdata'},
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"system-shutdown">>,
+ result = 'system-shutdown',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"undefined-condition">>,
+ result = 'undefined-condition',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"unsupported-encoding">>,
+ result = 'unsupported-encoding',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"unsupported-stanza-type">>,
+ result = 'unsupported-stanza-type',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'},
+ #spec{name = <<"unsupported-version">>,
+ result = 'unsupported-version',
+ xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+ min = 0, max = 1, label = '$reason'}
+ ]}}.
+
+{spec, vcard_name,
+ #spec{name = <<"N">>, label = '$n',
+ min = 0, max = 1,
+ result = {vcard_name, '$family', '$given', '$middle',
+ '$prefix', '$suffix'},
+ els = [#spec{name = <<"FAMILY">>, label = '$family',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"GIVEN">>, label = '$given',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"MIDDLE">>, label = '$middle',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"PREFIX">>, label = '$prefix',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"SUFFIX">>, label = '$suffix',
+ min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_adr,
+ #spec{name = <<"ADR">>, label = '$adr',
+ result = {vcard_adr, '$home', '$work', '$postal', '$parcel',
+ '$dom', '$intl', '$pref', '$pobox', '$extadd', '$street',
+ '$locality', '$region', '$pcode', '$ctry'},
+ els = [#spec{name = <<"HOME">>, label = '$home',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"WORK">>, label = '$work',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"POSTAL">>, label = '$postal',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PARCEL">>, label = '$parcel',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"DOM">>, label = '$dom',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"INTL">>, label = '$intl',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PREF">>, label = '$pref',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"POBOX">>, label = '$pobox',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"EXTADD">>, label = '$extadd',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"STREET">>, label = '$street',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"LOCALITY">>, label = '$locality',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"REGION">>, label = '$region',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"PCODE">>, label = '$pcode',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"CTRY">>, label = '$ctry',
+ min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_label,
+ #spec{name = <<"LABEL">>, label = '$label',
+ result = {vcard_label, '$home', '$work', '$postal', '$parcel',
+ '$dom', '$intl', '$pref', '$line'},
+ els = [#spec{name = <<"HOME">>, label = '$home',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"WORK">>, label = '$work',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"POSTAL">>, label = '$postal',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PARCEL">>, label = '$parcel',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"DOM">>, label = '$dom',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"INTL">>, label = '$intl',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PREF">>, label = '$pref',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"LINE">>, label = '$line',
+ result = '$cdata'}]}}.
+
+{spec, vcard_tel,
+ #spec{name = <<"TEL">>, label = '$tel',
+ result = {vcard_tel, '$home', '$work', '$voice', '$fax',
+ '$pager', '$msg', '$cell', '$video', '$bbs',
+ '$modem', '$isdn', '$pcs', '$pref', '$number'},
+ els = [#spec{name = <<"HOME">>, label = '$home',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"WORK">>, label = '$work',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"VOICE">>, label = '$voice',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"FAX">>, label = '$fax',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PAGER">>, label = '$pager',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"MSG">>, label = '$msg',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"CELL">>, label = '$cell',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"VIDEO">>, label = '$video',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"BBS">>, label = '$bbs',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"MODEM">>, label = '$modem',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"ISDN">>, label = '$isdn',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PCS">>, label = '$pcs',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PREF">>, label = '$pref',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"NUMBER">>, label = '$number',
+ min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_email,
+ #spec{name = <<"EMAIL">>, label = '$email',
+ result = {vcard_email, '$home', '$work',
+ '$internet', '$pref', '$x400', '$userid'},
+ els = [#spec{name = <<"HOME">>, label = '$home',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"WORK">>, label = '$work',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"INTERNET">>, label = '$internet',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"PREF">>, label = '$pref',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"X400">>, label = '$x400',
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"USERID">>, label = '$userid',
+ min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_geo,
+ #spec{name = <<"GEO">>, label = '$geo',
+ min = 0, max = 1,
+ result = {vcard_geo, '$lat', '$lon'},
+ els = [#spec{name = <<"LAT">>, label = '$lat',
+ min = 1, max = 1, result = '$cdata'},
+ #spec{name = <<"LON">>, label = '$lon',
+ min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_type,
+ #spec{name = <<"TYPE">>, label = '$type',
+ min = 0, max = 1,
+ result = '$cdata'}}.
+
+{spec, vcard_binval,
+ #spec{name = <<"BINVAL">>, label = '$binval',
+ min = 0, max = 1,
+ cdata = #cdata{dec = {base64, decode, []},
+ enc = {base64, encode, []}},
+ result = '$cdata'}}.
+
+{spec, vcard_extval,
+ #spec{name = <<"EXTVAL">>, label = '$extval',
+ min = 0, max = 1,
+ result = '$cdata'}}.
+
+{spec, vcard_logo,
+ #spec{name = <<"LOGO">>, label = '$logo',
+ min = 0, max = 1,
+ result = {vcard_logo, '$type', '$binval', '$extval'},
+ els = [vcard_type, vcard_binval, vcard_extval]}}.
+
+{spec, vcard_photo,
+ #spec{name = <<"PHOTO">>, label = '$photo',
+ min = 0, max = 1,
+ result = {vcard_photo, '$type', '$binval', '$extval'},
+ els = [vcard_type, vcard_binval, vcard_extval]}}.
+
+{spec, vcard_org,
+ #spec{name = <<"ORG">>, label = '$org',
+ min = 0, max = 1,
+ result = {vcard_org, '$name', '$units'},
+ els = [#spec{name = <<"ORGNAME">>,
+ label = '$name',
+ min = 1, max = 1,
+ result = '$cdata'},
+ #spec{name = <<"ORGUNIT">>,
+ label = '$units',
+ result = '$cdata'}]}}.
+
+{spec, vcard_sound,
+ #spec{name = <<"SOUND">>, label = '$sound',
+ min = 0, max = 1,
+ result = {vcard_sound, '$phonetic', '$binval', '$extval'},
+ els = [vcard_binval, vcard_extval,
+ #spec{name = <<"PHONETIC">>,
+ min = 0, max = 1,
+ result = '$cdata'}]}}.
+
+{spec, vcard_key,
+ #spec{name = <<"KEY">>, label = '$key',
+ min = 0, max = 1,
+ result = {vcard_key, '$type', '$cred'},
+ els = [vcard_type,
+ #spec{name = <<"CRED">>,
+ min = 1, max = 1,
+ result = '$cdata'}]}}.
+
+{spec, vcard,
+ #spec{name = <<"vCard">>,
+ xmlns = <<"vcard-temp">>,
+ min = 0, max = 1,
+ result = {vcard, '$version', '$fn', '$n', '$nickname', '$photo',
+ '$bday', '$adr', '$label', '$tel', '$email', '$jabberid',
+ '$mailer', '$tz', '$geo', '$title', '$role', '$logo',
+ %% '$agent' XXX: recursive specs are to be implemented
+ '$org', '$categories', '$note', '$prodid',
+ '$rev', '$sort-string', '$sound', '$uid', '$url', '$class',
+ '$key', '$desc'},
+ els = [vcard_name, vcard_adr, vcard_label, vcard_tel,
+ vcard_email, vcard_geo, vcard_logo, vcard_photo,
+ vcard_org, vcard_sound, vcard_key,
+ #spec{name = <<"VERSION">>, label = '$version',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"FN">>, label = '$fn',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"NICKNAME">>, label = '$nickname',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"BDAY">>, label = '$bday',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"JABBERID">>, label = '$jabberid',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"MAILER">>, label = '$mailer',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"TZ">>, label = '$tz',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"TITLE">>, label = '$title',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"ROLE">>, label = '$role',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"CATEGORIES">>, label = '$categories',
+ default = [],
+ min = 0, max = 1,
+ result = '$keywords',
+ els = [#spec{name = <<"KEYWORD">>,
+ label = '$keywords',
+ result = '$cdata'}]},
+ #spec{name = <<"NOTE">>, label = '$note',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"PRODID">>, label = '$prodid',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"REV">>, label = '$rev',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"SORT-STRING">>, label = '$sort-string',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"UID">>, label = '$uid',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"URL">>, label = '$url',
+ min = 0, max = 1, result = '$cdata'},
+ #spec{name = <<"CLASS">>, label = '$class',
+ min = 0, max = 1,
+ result = '$value',
+ els = [#spec{name = <<"PUBLIC">>,
+ min = 0, max = 1,
+ label = '$value',
+ result = public},
+ #spec{name = <<"PRIVATE">>,
+ label = '$value',
+ min = 0, max = 1,
+ result = private},
+ #spec{name = <<"CONFIDENTIAL">>,
+ label = '$value',
+ min = 0, max = 1,
+ result = confidential}]},
+ #spec{name = <<"DESC">>, label = '$desc',
+ min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, xfield,
+ #spec{name = <<"field">>,
+ label = '$fields',
+ result = {xfield, '$label', '$type', '$var',
+ '$required', '$desc', '$values', '$options'},
+ attrs = [#attr{name = <<"label">>},
+ #attr{name = <<"type">>,
+ enc = {enc_enum, []},
+ dec = {dec_enum, [['boolean',
+ 'fixed',
+ 'hidden',
+ 'jid-multi',
+ 'jid-single',
+ 'list-multi',
+ 'list-single',
+ 'text-multi',
+ 'text-private',
+ 'text-single']]}},
+ #attr{name = <<"var">>}],
+ els = [#spec{name = <<"required">>,
+ default = false, result = true,
+ min = 0, max = 1},
+ #spec{name = <<"desc">>,
+ min = 0, max = 1,
+ result = '$cdata'},
+ #spec{name = <<"value">>,
+ label = '$values',
+ result = '$cdata'},
+ #spec{name = <<"option">>,
+ label = '$options',
+ result = '$value',
+ els = [#spec{name = <<"value">>,
+ min = 1, max = 1,
+ result = '$cdata'}]}]}}.
+
+{spec, xdata,
+ #spec{name = <<"x">>,
+ label = '$xdata',
+ xmlns = <<"jabber:x:data">>,
+ result = {xdata, '$type', '$instructions', '$title',
+ '$reported', '$items', '$fields'},
+ attrs = [#attr{name = <<"type">>,
+ required = true,
+ dec = {dec_enum, [[cancel, form, result, submit]]},
+ enc = {enc_enum, []}}],
+ els = [#spec{name = <<"instructions">>,
+ result = '$cdata'},
+ #spec{name = <<"title">>,
+ min = 0, max = 1,
+ result = '$cdata'},
+ #spec{name = <<"reported">>,
+ min = 0, max = 1,
+ result = '$fields',
+ els = [xfield]},
+ #spec{name = <<"item">>,
+ label = '$items',
+ result = '$fields',
+ els = [xfield]},
+ xfield]}}.
+
+{spec, pubsub_subscription,
+ #spec{name = <<"subscription">>,
+ label = '$pubsub_subscriptions',
+ result = {pubsub_subscription, '$jid', '$node', '$subid',
+ '$type'},
+ attrs = [#attr{name = <<"jid">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}},
+ #attr{name = <<"node">>},
+ #attr{name = <<"subid">>},
+ #attr{name = <<"subscription">>,
+ label = '$type',
+ dec = {dec_enum, [[none, pending, subscribed,
+ unconfigured]]},
+ enc = {enc_enum, []}}]}}.
+
+{spec, pubsub_affiliation,
+ #spec{name = <<"affiliation">>,
+ label = '$pubsub_affiliations',
+ result = {pubsub_affiliation, '$node', '$type'},
+ attrs = [#attr{name = <<"node">>,
+ required = true},
+ #attr{name = <<"affiliation">>,
+ label = '$type',
+ required = true,
+ dec = {dec_enum, [[member, none, outcast, owner,
+ publisher, 'publish-only']]},
+ enc = {enc_enum, []}}]}}.
+
+{spec, pubsub_item,
+ #spec{name = <<"item">>,
+ result = {pubsub_item, '$id', '$_els'},
+ attrs = [#attr{name = <<"id">>}]}}.
+
+{spec, pubsub_items,
+ #spec{name = <<"items">>,
+ result = {pubsub_items, '$node', '$max_items',
+ '$subid', '$item'},
+ attrs = [#attr{name = <<"max_items">>,
+ dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}},
+ #attr{name = <<"node">>,
+ required = true},
+ #attr{name = <<"subid">>}],
+ els = [pubsub_item]}}.
+
+{spec, pubsub_event,
+ #spec{name = <<"event">>,
+ min = 0, max = 1,
+ xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
+ result = {pubsub_event, '$items'},
+ els = [pubsub_items]}}.
+
+{spec, pubsub,
+ #spec{name = <<"pubsub">>,
+ xmlns = <<"http://jabber.org/protocol/pubsub">>,
+ result = {pubsub, '$subscriptions', '$affiliations', '$publish',
+ '$subscribe'},
+ min = 0, max = 1,
+ els = [#spec{name = <<"subscriptions">>,
+ min = 0, max = 1,
+ result = {'$node', '$pubsub_subscriptions'},
+ attrs = [#attr{name = <<"node">>,
+ default = none}],
+ els = [pubsub_subscription]},
+ #spec{name = <<"affiliations">>,
+ min = 0, max = 1,
+ result = '$pubsub_affiliations',
+ els = [pubsub_affiliation]},
+ #spec{name = <<"subscribe">>,
+ min = 0, max = 1,
+ result = {'$node', '$jid'},
+ attrs = [#attr{name = <<"node">>},
+ #attr{name = <<"jid">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}]},
+ #spec{name = <<"publish">>,
+ min = 0, max = 1,
+ result = {'$node', '$item'},
+ attrs = [#attr{name = <<"node">>,
+ required = true}],
+ els = [pubsub_item]}]}}.
+
+{spec, delay,
+ #spec{name = <<"delay">>,
+ min = 0, max = 1,
+ xmlns = <<"urn:xmpp:delay">>,
+ result = {delay, '$stamp', '$from'},
+ attrs = [#attr{name = <<"stamp">>,
+ required = true,
+ dec = {dec_utc, []},
+ enc = {enc_utc, []}},
+ #attr{name = <<"from">>,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}]}}.
+
+dec_tzo(Val) ->
+ [H1, M1] = str:tokens(Val, <<":">>),
+ H = erlang:binary_to_integer(H1),
+ M = erlang:binary_to_integer(M1),
+ if H >= -12, H =< 12, M >= 0, M < 60 ->
+ {H, M}
+ end.
+
+enc_tzo({H, M}) ->
+ Sign = if H >= 0 ->
+ <<>>;
+ true ->
+ <<"-">>
+ end,
+ list_to_binary([Sign, io_lib:format("~2..0w:~2..0w", [H, M])]).
+
+dec_utc(Val) ->
+ {_, _, _} = jlib:datetime_string_to_timestamp(Val).
+
+enc_utc(Val) ->
+ jlib:now_to_utc_string(Val).
+
+dec_jid(Val) ->
+ case jlib:string_to_jid(Val) of
+ error ->
+ erlang:error(badarg);
+ J ->
+ J
+ end.
+
+enc_jid(J) ->
+ jlib:jid_to_string(J).
+
+resourceprep(R) ->
+ case jlib:resourceprep(R) of
+ error ->
+ erlang:error(badarg);
+ R1 ->
+ R1
+ end.
+
+dec_bool(<<"false">>) -> false;
+dec_bool(<<"true">>) -> true.
+
+enc_bool(false) -> <<"false">>;
+enc_bool(true) -> <<"true">>.
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8: