Initial work on an AMQP codec
This commit is contained in:
parent
074fd181c9
commit
717f933dff
|
@ -0,0 +1,459 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2009 AMQP Working Group.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
-->
|
||||||
|
<amqp major="0" minor="9" revision="1" port="5672">
|
||||||
|
<constant name="frame-method" value="1"/>
|
||||||
|
<constant name="frame-header" value="2"/>
|
||||||
|
<constant name="frame-body" value="3"/>
|
||||||
|
<constant name="frame-heartbeat" value="8"/>
|
||||||
|
<constant name="frame-min-size" value="4096"/>
|
||||||
|
<constant name="frame-end" value="206"/>
|
||||||
|
<constant name="reply-success" value="200"/>
|
||||||
|
<constant name="content-too-large" value="311" class="soft-error"/>
|
||||||
|
<constant name="no-consumers" value="313" class="soft-error"/>
|
||||||
|
<constant name="connection-forced" value="320" class="hard-error"/>
|
||||||
|
<constant name="invalid-path" value="402" class="hard-error"/>
|
||||||
|
<constant name="access-refused" value="403" class="soft-error"/>
|
||||||
|
<constant name="not-found" value="404" class="soft-error"/>
|
||||||
|
<constant name="resource-locked" value="405" class="soft-error"/>
|
||||||
|
<constant name="precondition-failed" value="406" class="soft-error"/>
|
||||||
|
<constant name="frame-error" value="501" class="hard-error"/>
|
||||||
|
<constant name="syntax-error" value="502" class="hard-error"/>
|
||||||
|
<constant name="command-invalid" value="503" class="hard-error"/>
|
||||||
|
<constant name="channel-error" value="504" class="hard-error"/>
|
||||||
|
<constant name="unexpected-frame" value="505" class="hard-error"/>
|
||||||
|
<constant name="resource-error" value="506" class="hard-error"/>
|
||||||
|
<constant name="not-allowed" value="530" class="hard-error"/>
|
||||||
|
<constant name="not-implemented" value="540" class="hard-error"/>
|
||||||
|
<constant name="internal-error" value="541" class="hard-error"/>
|
||||||
|
<domain name="class-id" type="short"/>
|
||||||
|
<domain name="consumer-tag" type="shortstr"/>
|
||||||
|
<domain name="delivery-tag" type="longlong"/>
|
||||||
|
<domain name="exchange-name" type="shortstr">
|
||||||
|
<assert check="length" value="127"/>
|
||||||
|
<assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
|
||||||
|
</domain>
|
||||||
|
<domain name="method-id" type="short"/>
|
||||||
|
<domain name="no-ack" type="bit"/>
|
||||||
|
<domain name="no-local" type="bit"/>
|
||||||
|
<domain name="no-wait" type="bit"/>
|
||||||
|
<domain name="path" type="shortstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
<assert check="length" value="127"/>
|
||||||
|
</domain>
|
||||||
|
<domain name="peer-properties" type="table"/>
|
||||||
|
<domain name="queue-name" type="shortstr">
|
||||||
|
<assert check="length" value="127"/>
|
||||||
|
<assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
|
||||||
|
</domain>
|
||||||
|
<domain name="redelivered" type="bit"/>
|
||||||
|
<domain name="message-count" type="long"/>
|
||||||
|
<domain name="reply-code" type="short">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</domain>
|
||||||
|
<domain name="reply-text" type="shortstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</domain>
|
||||||
|
<domain name="bit" type="bit"/>
|
||||||
|
<domain name="octet" type="octet"/>
|
||||||
|
<domain name="short" type="short"/>
|
||||||
|
<domain name="long" type="long"/>
|
||||||
|
<domain name="longlong" type="longlong"/>
|
||||||
|
<domain name="shortstr" type="shortstr"/>
|
||||||
|
<domain name="longstr" type="longstr"/>
|
||||||
|
<domain name="timestamp" type="timestamp"/>
|
||||||
|
<domain name="table" type="table"/>
|
||||||
|
<class name="connection" handler="connection" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<method name="start" synchronous="1" index="10">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<response name="start-ok"/>
|
||||||
|
<field name="version-major" domain="octet"/>
|
||||||
|
<field name="version-minor" domain="octet"/>
|
||||||
|
<field name="server-properties" domain="peer-properties"/>
|
||||||
|
<field name="mechanisms" domain="longstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="locales" domain="longstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
</method>
|
||||||
|
<method name="start-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="client-properties" domain="peer-properties"/>
|
||||||
|
<field name="mechanism" domain="shortstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="response" domain="longstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="locale" domain="shortstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
</method>
|
||||||
|
<method name="secure" synchronous="1" index="20">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<response name="secure-ok"/>
|
||||||
|
<field name="challenge" domain="longstr"/>
|
||||||
|
</method>
|
||||||
|
<method name="secure-ok" synchronous="1" index="21">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="response" domain="longstr">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
</method>
|
||||||
|
<method name="tune" synchronous="1" index="30">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<response name="tune-ok"/>
|
||||||
|
<field name="channel-max" domain="short"/>
|
||||||
|
<field name="frame-max" domain="long"/>
|
||||||
|
<field name="heartbeat" domain="short"/>
|
||||||
|
</method>
|
||||||
|
<method name="tune-ok" synchronous="1" index="31">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="channel-max" domain="short">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
<assert check="le" method="tune" field="channel-max"/>
|
||||||
|
</field>
|
||||||
|
<field name="frame-max" domain="long"/>
|
||||||
|
<field name="heartbeat" domain="short"/>
|
||||||
|
</method>
|
||||||
|
<method name="open" synchronous="1" index="40">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="open-ok"/>
|
||||||
|
<field name="virtual-host" domain="path"/>
|
||||||
|
<field name="reserved-1" type="shortstr" reserved="1"/>
|
||||||
|
<field name="reserved-2" type="bit" reserved="1"/>
|
||||||
|
</method>
|
||||||
|
<method name="open-ok" synchronous="1" index="41">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="reserved-1" type="shortstr" reserved="1"/>
|
||||||
|
</method>
|
||||||
|
<method name="close" synchronous="1" index="50">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="close-ok"/>
|
||||||
|
<field name="reply-code" domain="reply-code"/>
|
||||||
|
<field name="reply-text" domain="reply-text"/>
|
||||||
|
<field name="class-id" domain="class-id"/>
|
||||||
|
<field name="method-id" domain="method-id"/>
|
||||||
|
</method>
|
||||||
|
<method name="close-ok" synchronous="1" index="51">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
<class name="channel" handler="channel" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<method name="open" synchronous="1" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="open-ok"/>
|
||||||
|
<field name="reserved-1" type="shortstr" reserved="1"/>
|
||||||
|
</method>
|
||||||
|
<method name="open-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="reserved-1" type="longstr" reserved="1"/>
|
||||||
|
</method>
|
||||||
|
<method name="flow" synchronous="1" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<response name="flow-ok"/>
|
||||||
|
<field name="active" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="flow-ok" index="21">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="active" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="close" synchronous="1" index="40">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="close-ok"/>
|
||||||
|
<field name="reply-code" domain="reply-code"/>
|
||||||
|
<field name="reply-text" domain="reply-text"/>
|
||||||
|
<field name="class-id" domain="class-id"/>
|
||||||
|
<field name="method-id" domain="method-id"/>
|
||||||
|
</method>
|
||||||
|
<method name="close-ok" synchronous="1" index="41">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
<class name="exchange" handler="channel" index="40">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<method name="declare" synchronous="1" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="declare-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="exchange" domain="exchange-name">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="type" domain="shortstr"/>
|
||||||
|
<field name="passive" domain="bit"/>
|
||||||
|
<field name="durable" domain="bit"/>
|
||||||
|
<field name="reserved-2" type="bit" reserved="1"/>
|
||||||
|
<field name="reserved-3" type="bit" reserved="1"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
<field name="arguments" domain="table"/>
|
||||||
|
</method>
|
||||||
|
<method name="declare-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="delete" synchronous="1" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="delete-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="exchange" domain="exchange-name">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="if-unused" domain="bit"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
</method>
|
||||||
|
<method name="delete-ok" synchronous="1" index="21">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
<class name="queue" handler="channel" index="50">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<method name="declare" synchronous="1" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="declare-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="passive" domain="bit"/>
|
||||||
|
<field name="durable" domain="bit"/>
|
||||||
|
<field name="exclusive" domain="bit"/>
|
||||||
|
<field name="auto-delete" domain="bit"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
<field name="arguments" domain="table"/>
|
||||||
|
</method>
|
||||||
|
<method name="declare-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="queue" domain="queue-name">
|
||||||
|
<assert check="notnull"/>
|
||||||
|
</field>
|
||||||
|
<field name="message-count" domain="message-count"/>
|
||||||
|
<field name="consumer-count" domain="long"/>
|
||||||
|
</method>
|
||||||
|
<method name="bind" synchronous="1" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="bind-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
<field name="arguments" domain="table"/>
|
||||||
|
</method>
|
||||||
|
<method name="bind-ok" synchronous="1" index="21">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="unbind" synchronous="1" index="50">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="unbind-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
<field name="arguments" domain="table"/>
|
||||||
|
</method>
|
||||||
|
<method name="unbind-ok" synchronous="1" index="51">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="purge" synchronous="1" index="30">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="purge-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
</method>
|
||||||
|
<method name="purge-ok" synchronous="1" index="31">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="message-count" domain="message-count"/>
|
||||||
|
</method>
|
||||||
|
<method name="delete" synchronous="1" index="40">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="delete-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="if-unused" domain="bit"/>
|
||||||
|
<field name="if-empty" domain="bit"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
</method>
|
||||||
|
<method name="delete-ok" synchronous="1" index="41">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="message-count" domain="message-count"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
<class name="basic" handler="channel" index="60">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<chassis name="client" implement="MAY"/>
|
||||||
|
<field name="content-type" domain="shortstr"/>
|
||||||
|
<field name="content-encoding" domain="shortstr"/>
|
||||||
|
<field name="headers" domain="table"/>
|
||||||
|
<field name="delivery-mode" domain="octet"/>
|
||||||
|
<field name="priority" domain="octet"/>
|
||||||
|
<field name="correlation-id" domain="shortstr"/>
|
||||||
|
<field name="reply-to" domain="shortstr"/>
|
||||||
|
<field name="expiration" domain="shortstr"/>
|
||||||
|
<field name="message-id" domain="shortstr"/>
|
||||||
|
<field name="timestamp" domain="timestamp"/>
|
||||||
|
<field name="type" domain="shortstr"/>
|
||||||
|
<field name="user-id" domain="shortstr"/>
|
||||||
|
<field name="app-id" domain="shortstr"/>
|
||||||
|
<field name="reserved" domain="shortstr"/>
|
||||||
|
<method name="qos" synchronous="1" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="qos-ok"/>
|
||||||
|
<field name="prefetch-size" domain="long"/>
|
||||||
|
<field name="prefetch-count" domain="short"/>
|
||||||
|
<field name="global" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="qos-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="consume" synchronous="1" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="consume-ok"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="consumer-tag" domain="consumer-tag"/>
|
||||||
|
<field name="no-local" domain="no-local"/>
|
||||||
|
<field name="no-ack" domain="no-ack"/>
|
||||||
|
<field name="exclusive" domain="bit"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
<field name="arguments" domain="table"/>
|
||||||
|
</method>
|
||||||
|
<method name="consume-ok" synchronous="1" index="21">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="consumer-tag" domain="consumer-tag"/>
|
||||||
|
</method>
|
||||||
|
<method name="cancel" synchronous="1" index="30">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="cancel-ok"/>
|
||||||
|
<field name="consumer-tag" domain="consumer-tag"/>
|
||||||
|
<field name="no-wait" domain="no-wait"/>
|
||||||
|
</method>
|
||||||
|
<method name="cancel-ok" synchronous="1" index="31">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="consumer-tag" domain="consumer-tag"/>
|
||||||
|
</method>
|
||||||
|
<method name="publish" content="1" index="40">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
<field name="mandatory" domain="bit"/>
|
||||||
|
<field name="immediate" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="return" content="1" index="50">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="reply-code" domain="reply-code"/>
|
||||||
|
<field name="reply-text" domain="reply-text"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
</method>
|
||||||
|
<method name="deliver" content="1" index="60">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
<field name="consumer-tag" domain="consumer-tag"/>
|
||||||
|
<field name="delivery-tag" domain="delivery-tag"/>
|
||||||
|
<field name="redelivered" domain="redelivered"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
</method>
|
||||||
|
<method name="get" synchronous="1" index="70">
|
||||||
|
<response name="get-ok"/>
|
||||||
|
<response name="get-empty"/>
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="reserved-1" type="short" reserved="1"/>
|
||||||
|
<field name="queue" domain="queue-name"/>
|
||||||
|
<field name="no-ack" domain="no-ack"/>
|
||||||
|
</method>
|
||||||
|
<method name="get-ok" synchronous="1" content="1" index="71">
|
||||||
|
<chassis name="client" implement="MAY"/>
|
||||||
|
<field name="delivery-tag" domain="delivery-tag"/>
|
||||||
|
<field name="redelivered" domain="redelivered"/>
|
||||||
|
<field name="exchange" domain="exchange-name"/>
|
||||||
|
<field name="routing-key" domain="shortstr"/>
|
||||||
|
<field name="message-count" domain="message-count"/>
|
||||||
|
</method>
|
||||||
|
<method name="get-empty" synchronous="1" index="72">
|
||||||
|
<chassis name="client" implement="MAY"/>
|
||||||
|
<field name="reserved-1" type="shortstr" reserved="1"/>
|
||||||
|
</method>
|
||||||
|
<method name="ack" index="80">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="delivery-tag" domain="delivery-tag"/>
|
||||||
|
<field name="multiple" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="reject" index="90">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="delivery-tag" domain="delivery-tag"/>
|
||||||
|
<field name="requeue" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="recover-async" index="100" deprecated="1">
|
||||||
|
<chassis name="server" implement="MAY"/>
|
||||||
|
<field name="requeue" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="recover" index="110">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<field name="requeue" domain="bit"/>
|
||||||
|
</method>
|
||||||
|
<method name="recover-ok" synchronous="1" index="111">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
<class name="tx" handler="channel" index="90">
|
||||||
|
<chassis name="server" implement="SHOULD"/>
|
||||||
|
<chassis name="client" implement="MAY"/>
|
||||||
|
<method name="select" synchronous="1" index="10">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="select-ok"/>
|
||||||
|
</method>
|
||||||
|
<method name="select-ok" synchronous="1" index="11">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="commit" synchronous="1" index="20">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="commit-ok"/>
|
||||||
|
</method>
|
||||||
|
<method name="commit-ok" synchronous="1" index="21">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
<method name="rollback" synchronous="1" index="30">
|
||||||
|
<chassis name="server" implement="MUST"/>
|
||||||
|
<response name="rollback-ok"/>
|
||||||
|
</method>
|
||||||
|
<method name="rollback-ok" synchronous="1" index="31">
|
||||||
|
<chassis name="client" implement="MUST"/>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
</amqp>
|
|
@ -0,0 +1,229 @@
|
||||||
|
import xml.dom.minidom
|
||||||
|
|
||||||
|
def constify(s):
|
||||||
|
s = s.replace('-', '_')
|
||||||
|
s = s.replace(' ', '_')
|
||||||
|
s = s.upper()
|
||||||
|
return s
|
||||||
|
|
||||||
|
def cify(s):
|
||||||
|
s = constify(s)
|
||||||
|
s = s.lower()
|
||||||
|
return s
|
||||||
|
|
||||||
|
def camelify(s):
|
||||||
|
s = constify(s)
|
||||||
|
s = s.split('_')
|
||||||
|
s = [s[0].lower()] + [w.capitalize() for w in s[1:]]
|
||||||
|
s = ''.join(s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
ctypemap = {
|
||||||
|
'shortstr': 'cmsg_bytes_t',
|
||||||
|
'longstr': 'cmsg_bytes_t',
|
||||||
|
'table': 'cmsg_bytes_t', # TODO fix
|
||||||
|
'octet': 'uint8_t',
|
||||||
|
'short': 'uint16_t',
|
||||||
|
'long': 'uint32_t',
|
||||||
|
'longlong': 'uint64_t',
|
||||||
|
'bit': 'uint8_t',
|
||||||
|
'timestamp': 'uint64_t',
|
||||||
|
}
|
||||||
|
|
||||||
|
class Constant:
|
||||||
|
def __init__(self, e):
|
||||||
|
self.name = e.getAttribute('name')
|
||||||
|
self.value = e.getAttribute('value')
|
||||||
|
self.class_ = e.getAttribute('class') or None
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
if self.class_:
|
||||||
|
return 'CMSG_AMQP_ERROR_' + constify(self.name)
|
||||||
|
else:
|
||||||
|
return 'CMSG_AMQP_' + constify(self.name)
|
||||||
|
|
||||||
|
def getValue(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
class Field:
|
||||||
|
def __init__(self, e):
|
||||||
|
self.name = e.getAttribute('name')
|
||||||
|
self.domain = e.getAttribute('domain') or e.getAttribute('type')
|
||||||
|
# self.reserved = bool(e.getAttribute('reserved'))
|
||||||
|
self.type = resolveDomain(self.domain)
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return cify(self.name)
|
||||||
|
|
||||||
|
def ctype(self):
|
||||||
|
return ctypemap[str(self.type)]
|
||||||
|
|
||||||
|
class Entity:
|
||||||
|
def __init__(self, parent, e):
|
||||||
|
self.parent = parent
|
||||||
|
self.name = e.getAttribute('name')
|
||||||
|
self.index = int(e.getAttribute('index'))
|
||||||
|
self.fields = [Field(ee) \
|
||||||
|
for ee in e.getElementsByTagName('field') \
|
||||||
|
if ee.parentNode is e]
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
if self.parent:
|
||||||
|
return self.parent.getName() + '_' + cify(self.name)
|
||||||
|
else:
|
||||||
|
return cify(self.name)
|
||||||
|
|
||||||
|
def printStructDefExtras(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def printStructDef(self, suffix):
|
||||||
|
if self.fields:
|
||||||
|
print
|
||||||
|
print 'typedef struct cmsg_amqp_%s_%s_t_ {' % (self.getName(), suffix)
|
||||||
|
self.printStructDefExtras()
|
||||||
|
for f in self.fields:
|
||||||
|
print ' %s %s;' % (f.ctype(), f.getName())
|
||||||
|
print '} cmsg_amqp_%s_%s_t;' % (self.getName(), suffix)
|
||||||
|
|
||||||
|
class BitWriter:
|
||||||
|
def __init__(self):
|
||||||
|
self.bit_offset = 0
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
if self.bit_offset:
|
||||||
|
print ' write_amqp_octet(bit_buffer);'
|
||||||
|
self.bit_offset = 0
|
||||||
|
|
||||||
|
def emit(self, valueExpr):
|
||||||
|
if self.bit_offset == 0:
|
||||||
|
print ' bit_buffer = 0;'
|
||||||
|
print ' if (%s) bit_buffer |= 0x%02x;' % (valueExpr, 1 << self.bit_offset)
|
||||||
|
self.bit_offset += 1
|
||||||
|
if self.bit_offset == 8:
|
||||||
|
self.flush()
|
||||||
|
|
||||||
|
class Method(Entity):
|
||||||
|
def __init__(self, parent, e):
|
||||||
|
Entity.__init__(self, parent, e)
|
||||||
|
self.has_content = bool(e.getAttribute('content'))
|
||||||
|
self.synchronous = bool(e.getAttribute('synchronous'))
|
||||||
|
self.responses = [ee.getAttribute('name') for ee in e.getElementsByTagName('response')]
|
||||||
|
|
||||||
|
def methodId(self):
|
||||||
|
return self.parent.index << 16 | self.index
|
||||||
|
|
||||||
|
def printParseClause(self):
|
||||||
|
bit_offset = 0
|
||||||
|
print ' case 0x%08x: /* %s */ ' % (self.methodId(), self.getName())
|
||||||
|
for f in self.fields:
|
||||||
|
if f.type == 'bit':
|
||||||
|
if bit_offset == 0:
|
||||||
|
print ' if (!parse_amqp_octet(&bit_buffer, &input, &offset))'
|
||||||
|
print ' return -CMSG_AMQP_ERROR_FRAME_ERROR;'
|
||||||
|
print ' output->body.%s.%s = (bit_buffer & 0x%02x) != 0;' % \
|
||||||
|
(self.getName(), f.getName(), 1 << bit_offset)
|
||||||
|
bit_offset += 1
|
||||||
|
if bit_offset == 8: bit_offset = 0
|
||||||
|
else:
|
||||||
|
print ' if (!parse_amqp_%s(&output->body.%s.%s, &input, &offset))' % \
|
||||||
|
(f.type, self.getName(), f.getName())
|
||||||
|
print ' return -CMSG_AMQP_ERROR_FRAME_ERROR;'
|
||||||
|
print ' return 0;'
|
||||||
|
|
||||||
|
def printWriteClause(self):
|
||||||
|
bw = BitWriter()
|
||||||
|
print ' case 0x%08x: /* %s */ ' % (self.methodId(), self.getName())
|
||||||
|
for f in self.fields:
|
||||||
|
if f.type == 'bit':
|
||||||
|
bw.emit('output->body.%s.%s' % (self.getName(), f.getName()))
|
||||||
|
else:
|
||||||
|
bw.flush()
|
||||||
|
print ' write_amqp_%s(output->body.%s.%s);' % \
|
||||||
|
(f.type, self.getName(), f.getName())
|
||||||
|
bw.flush()
|
||||||
|
print ' break;'
|
||||||
|
|
||||||
|
class Class(Entity):
|
||||||
|
def __init__(self, e):
|
||||||
|
Entity.__init__(self, None, e)
|
||||||
|
self.methods = [Method(self, ee) for ee in e.getElementsByTagName('method')]
|
||||||
|
|
||||||
|
def printStructDefExtras(self):
|
||||||
|
print ' uint32_t _flags;'
|
||||||
|
|
||||||
|
def resolveDomain(n):
|
||||||
|
while n in domainmap and domainmap[n] != n:
|
||||||
|
n = domainmap[n]
|
||||||
|
return n
|
||||||
|
|
||||||
|
specxml = xml.dom.minidom.parse("amqp0-9-1.stripped.xml")
|
||||||
|
constants = [Constant(e) for e in specxml.getElementsByTagName('constant')]
|
||||||
|
domainmap = dict((e.getAttribute('name'), e.getAttribute('type')) \
|
||||||
|
for e in specxml.getElementsByTagName('domain'))
|
||||||
|
|
||||||
|
classes = [Class(e) for e in specxml.getElementsByTagName('class')]
|
||||||
|
classmap = dict((c.name, c) for c in classes)
|
||||||
|
|
||||||
|
def header():
|
||||||
|
print '/* TODO: put copyright etc */'
|
||||||
|
print '/* Generated from AMQP spec version %s.%s.%s */' % \
|
||||||
|
(specxml.documentElement.getAttribute('major'),
|
||||||
|
specxml.documentElement.getAttribute('minor'),
|
||||||
|
specxml.documentElement.getAttribute('revision'))
|
||||||
|
|
||||||
|
print
|
||||||
|
for c in constants:
|
||||||
|
print '#define %s %s' % (c.getName(), c.getValue())
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
c.printStructDef('properties')
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
for m in c.methods:
|
||||||
|
m.printStructDef('method')
|
||||||
|
|
||||||
|
print
|
||||||
|
print 'typedef struct cmsg_amqp_method_t_ {'
|
||||||
|
print ' uint32_t id;'
|
||||||
|
print ' union {'
|
||||||
|
for c in classes:
|
||||||
|
for m in c.methods:
|
||||||
|
if m.fields:
|
||||||
|
print ' cmsg_amqp_%s_method_t %s;' % (m.getName(), m.getName())
|
||||||
|
print ' } body;'
|
||||||
|
print '} cmsg_amqp_method_t;'
|
||||||
|
|
||||||
|
print
|
||||||
|
print 'int parse_amqp_method('
|
||||||
|
print ' cmsg_bytes_t input,'
|
||||||
|
print ' cmsg_amqp_method_t *output) {'
|
||||||
|
print ' size_t offset = 0;'
|
||||||
|
print ' uint8_t bit_buffer = 0;'
|
||||||
|
print ' if (!parse_amqp_long(&output->id, &input, &offset))'
|
||||||
|
print ' return -CMSG_AMQP_ERROR_FRAME_ERROR;'
|
||||||
|
print ' switch (output->id) {'
|
||||||
|
for c in classes:
|
||||||
|
for m in c.methods:
|
||||||
|
m.printParseClause()
|
||||||
|
print ' default:'
|
||||||
|
print ' warn("Invalid AMQP method number 0x%%08x", output->id);'
|
||||||
|
print ' return -CMSG_AMQP_ERROR_NOT_IMPLEMENTED;'
|
||||||
|
print ' }'
|
||||||
|
print '}'
|
||||||
|
|
||||||
|
print
|
||||||
|
print 'void write_amqp_method('
|
||||||
|
print ' IOHandle *h,'
|
||||||
|
print ' cmsg_amqp_method_t *m) {'
|
||||||
|
print ' uint8_t bit_buffer = 0;'
|
||||||
|
print ' write_amqp_long(&m->id);'
|
||||||
|
print ' switch (m->id) {'
|
||||||
|
for c in classes:
|
||||||
|
for m in c.methods:
|
||||||
|
m.printWriteClause()
|
||||||
|
print ' default:'
|
||||||
|
print ' die("Invalid AMQP method number 0x%%08x", m->id);'
|
||||||
|
print ' }'
|
||||||
|
print '}'
|
||||||
|
|
||||||
|
header()
|
Loading…
Reference in New Issue