Author: root Date: 2010-12-07 22:18:44 +0000 (Tue, 07 Dec 2010) New Revision: 2
Added: cpp/ cpp/framing/ cpp/framing/Makefile cpp/framing/amqp7.xml cpp/framing/amqp_framing.cpp cpp/framing/amqp_framing.h cpp/framing/amqp_methods.cpp.handwritten cpp/framing/amqp_methods.h.handwritten cpp/framing/amqp_protocol.h cpp/framing/amqp_protocol.h.handwritten cpp/framing/buffer.cpp cpp/framing/buffer.h cpp/framing/cpp.xsl cpp/framing/fieldtable.cpp cpp/framing/fieldtable.h cpp/framing/framing.xsl cpp/framing/framing_test.cpp cpp/framing/prepare1.xsl cpp/framing/prepare2.xsl cpp/framing/prepare3.xsl cpp/framing/registry.xsl cpp/framing/saxon8.jar cpp/framing/test.out cpp/framing/utils.xsl Log:
Added: cpp/framing/Makefile =================================================================== --- cpp/framing/Makefile (rev 0) +++ cpp/framing/Makefile 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,19 @@ +EXE = framing_test +OBJS = framing_test.o amqp_framing.o amqp_methods.o buffer.o fieldtable.o +HEADERS = amqp_framing.h amqp_protocol.h amqp_methods.h buffer.h fieldtable.h +SPEC = amqp7.xml +STYLESHEETS = framing.xsl prepare1.xsl prepare2.xsl prepare3.xsl cpp.xsl utils.xsl +GENERATED_SRC = amqp_methods.h amqp_methods.cpp +GENERATE = java -jar saxon8.jar ${SPEC} framing.xsl + +${EXE} : ${OBJS} + ${CXX} -o $@ ${OBJS} + +${OBJS}: ${HEADERS} + +${GENERATED_SRC}: ${STYLESHEETS} ${SPEC} + ${GENERATE} + +clean : + rm ${OBJS} ${GENERATED_SRC} ${EXE} +
Added: cpp/framing/amqp7.xml =================================================================== --- cpp/framing/amqp7.xml (rev 0) +++ cpp/framing/amqp7.xml 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,3837 @@ +<?xml version="1.0"?> + +<amqp major="7" minor="0" port="5672" comment="AMQ protocol 0.70"> + AMQ Protocol 0.70 +<!-- +Revision history: + 2006-05-11 (PH) - reset version to 0.70 so that putatitive standards + group can release 2-3 major new versions before hitting 1.0 (again). + + 2006-05-11 (PH) - TODO in documentation: cycle field in frame header + has been removed. + + 2006-05-11 (PH) - added nowait option to exchange.declare, delete, + queue.declare, delete, bind, purge, basic.consume, cancel, + file.consume, cancel, stream.consume and cancel methods. + + 2006-05-11 (PH) - removed notnull rule and added explanations on queue + name in queue.bind, purge, delete, basic.consume, cancel, file.consume, + cancel, stream.consume and cancel methods. + + 2006-05-11 (PH) - added basic.qos, file.qos, and stream.qos methods that + regroup all prefetch options from the consume methods. Also removed the + prefetch option from channel.open. + + 2006-05-11 (PH) - renumbered method indexes to show request-response + nature of methods; requests are 10, 20, 30 while responses are 11, 21, + etc. + + 2006-05-11 (PH) - removed OpenAMQ extension methods from this definition + since these are maintained seperately. + + 2006-05-15 (PH) - fixed comments on queue name in basic.get to clarify + use of current queue in this method. + + 2006-05-15 (PH) - fixed comments on routing key in queue.bind to clarify + how routing key is filled when empty (to allow asynch queue.declare). + + 2006-05-26 (RG) - added Basic.Recover method to allow replay of + unacknowledged messages on a channel. +--> + +<!-- +====================================================== +== AMQP = Advanced Message Queuing Protocol +== Protocol specification for use in protocol driver code. +== +== A General-Purpose Middleware Standard +== Published by The AMQP Working Group <group@amqprotocol.org> +== Copyright © 2004-2006 JPMorgan Chase +== All Rights Reserved +== +== *** CONFIDENTIAL *** +====================================================== +--> + <!-- +====================================================== +== CONSTANTS +====================================================== +--> + <constant name="frame method" value="1"/> + <constant name="frame header" value="2"/> + <constant name="frame body" value="3"/> + <constant name="frame oob method" value="4"/> + <constant name="frame oob header" value="5"/> + <constant name="frame oob body" value="6"/> + <constant name="frame trace" value="7"/> + <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"> + Indicates that the method completed successfully. This reply code is + reserved for future use - the current protocol design does not use + positive confirmation and reply codes are sent only in case of an + error. +</constant> + <constant name="not delivered" value="310" class="soft error"> + The client asked for a specific message that is no longer available. + The message was delivered to another client, or was purged from the + queue for some other reason. +</constant> + <constant name="content too large" value="311" class="soft error"> + The client attempted to transfer content larger than the server + could accept at the present time. The client may retry at a later + time. +</constant> + <constant name="connection forced" value="320" class="hard error"> + An operator intervened to close the connection for some reason. + The client may retry at some later date. +</constant> + <constant name="invalid path" value="402" class="hard error"> + The client tried to work with an unknown virtual host or cluster. +</constant> + <constant name="access refused" value="403" class="soft error"> + The client attempted to work with a server entity to which it has + no due to security settings. +</constant> + <constant name="not found" value="404" class="soft error"> + The client attempted to work with a server entity that does not exist. +</constant> + <constant name="resource locked" value="405" class="soft error"> + The client attempted to work with a server entity to which it has + no access because another client is working with it. +</constant> + <constant name="frame error" value="501" class="hard error"> + The client sent a malformed frame that the server could not decode. + This strongly implies a programming error in the client. +</constant> + <constant name="syntax error" value="502" class="hard error"> + The client sent a frame that contained illegal values for one or more + fields. This strongly implies a programming error in the client. +</constant> + <constant name="command invalid" value="503" class="hard error"> + The client sent an invalid sequence of frames, attempting to perform + an operation that was considered invalid by the server. This usually + implies a programming error in the client. +</constant> + <constant name="channel error" value="504" class="hard error"> + The client attempted to work with a channel that had not been + correctly opened. This most likely indicates a fault in the client + layer. +</constant> + <constant name="resource error" value="506" class="hard error"> + The server could not complete the method because it lacked sufficient + resources. This may be due to the client creating too many of some + type of entity. +</constant> + <constant name="not allowed" value="530" class="hard error"> + The client tried to work with some entity in a manner that is + prohibited by the server, due to security settings or by some other + criteria. +</constant> + <constant name="not implemented" value="540" class="hard error"> + The client tried to use functionality that is not implemented in the + server. +</constant> + <constant name="internal error" value="541" class="hard error"> + The server could not complete the method because of an internal error. + The server may require intervention by an operator in order to resume + normal operations. +</constant> + <!-- +====================================================== +== DOMAIN TYPES +====================================================== +--> + <domain name="access ticket" type="short"> + access ticket granted by server + <doc> + An access ticket granted by the server for a certain set of access + rights within a specific realm. Access tickets are valid within the + channel where they were created, and expire when the channel closes. + </doc> + <assert check="ne" value="0"/> + </domain> + <domain name="class id" type="short"/> + <domain name="consumer tag" type="shortstr"> + consumer tag + <doc> + Identifier for the consumer, valid within the current connection. + </doc> + <rule implement="MUST"> + The consumer tag is valid only within the channel from which the + consumer was created. I.e. a client MUST NOT create a consumer in + one channel and then use it in another. + </rule> + </domain> + <domain name="delivery tag" type="longlong"> + server-assigned delivery tag + <doc> + The server-assigned and channel-specific delivery tag + </doc> + <rule implement="MUST"> + The delivery tag is valid only within the channel from which the + message was received. I.e. a client MUST NOT receive a message on + one channel and then acknowledge it on another. + </rule> + <rule implement="MUST"> + The server MUST NOT use a zero value for delivery tags. Zero is + reserved for client use, meaning "all messages so far received". + </rule> + </domain> + <domain name="exchange name" type="shortstr"> + exchange name + <doc> + The exchange name is a client-selected string that identifies + the exchange for publish methods. Exchange names may consist + of any mixture of digits, letters, and underscores. Exchange + names are scoped by the virtual host. + </doc> + <assert check="length" value="127"/> + </domain> + <domain name="known hosts" type="shortstr"> +list of known hosts +<doc> +Specifies the list of equivalent or alternative hosts that the server +knows about, which will normally include the current server itself. +Clients can cache this information and use it when reconnecting to a +server after a failure. +</doc> + <rule implement="MAY"> +The server MAY leave this field empty if it knows of no other +hosts than itself. +</rule> + </domain> + <domain name="method id" type="short"/> + <domain name="no ack" type="bit"> + no acknowledgement needed + <doc> + If this field is set the server does not expect acknowledgments + for messages. That is, when a message is delivered to the client + the server automatically and silently acknowledges it on behalf + of the client. This functionality increases performance but at + the cost of reliability. Messages can get lost if a client dies + before it can deliver them to the application. + </doc> + </domain> + <domain name="no local" type="bit"> + do not deliver own messages + <doc> + If the no-local field is set the server will not send messages to + the client that published them. + </doc> + </domain> + <domain name="path" type="shortstr"> + <doc> + Must start with a slash "/" and continue with path names + separated by slashes. A path name consists of any combination + of at least one of [A-Za-z0-9] plus zero or more of [.-_+!=:]. +</doc> + <assert check="notnull"/> + <assert check="syntax" rule="path"/> + <assert check="length" value="127"/> + </domain> + <domain name="peer properties" type="table"> + <doc> +This string provides a set of peer properties, used for +identification, debugging, and general information. +</doc> + <rule implement="SHOULD"> +The properties SHOULD contain these fields: +"product", giving the name of the peer product, "version", giving +the name of the peer version, "platform", giving the name of the +operating system, "copyright", if appropriate, and "information", +giving other general information. +</rule> + </domain> + <domain name="queue name" type="shortstr"> + queue name + <doc> + The queue name identifies the queue within the vhost. Queue + names may consist of any mixture of digits, letters, and + underscores. + </doc> + <assert check="length" value="127"/> + </domain> + <domain name="redelivered" type="bit"> + message is being redelivered + <doc> + This indicates that the message has been previously delivered to + this or another client. + </doc> + <rule implement="SHOULD"> + The server SHOULD try to signal redelivered messages when it can. + When redelivering a message that was not successfully acknowledged, + the server SHOULD deliver it to the original client if possible. + </rule> + <rule implement="MUST"> + The client MUST NOT rely on the redelivered field but MUST take it + as a hint that the message may already have been processed. A + fully robust client must be able to track duplicate received messages + on non-transacted, and locally-transacted channels. + </rule> + </domain> + <domain name="reply code" type="short"> +reply code from server +<doc> + The reply code. The AMQ reply codes are defined in AMQ RFC 011. +</doc> + <assert check="notnull"/> + </domain> + <domain name="reply text" type="shortstr"> +localised reply text +<doc> + The localised reply text. This text can be logged as an aid to + resolving issues. +</doc> + <assert check="notnull"/> + </domain> + <class name="connection" handler="connection" index="10"> + <!-- +====================================================== +== CONNECTION +====================================================== +--> + work with socket connections +<doc> + The connection class provides methods for a client to establish a + network connection to a server, and for both peers to operate the + connection thereafter. +</doc> + <doc name="grammar"> + connection = open-connection *use-connection close-connection + open-connection = C:protocol-header + S:START C:START-OK + *challenge + S:TUNE C:TUNE-OK + C:OPEN S:OPEN-OK | S:REDIRECT + challenge = S:SECURE C:SECURE-OK + use-connection = *channel + close-connection = C:CLOSE S:CLOSE-OK + / S:CLOSE C:CLOSE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="start" synchronous="1" index="10"> + start connection negotiation + <doc> + This method starts the connection negotiation process by telling + the client the protocol version that the server proposes, along + with a list of security mechanisms which the client can use for + authentication. + </doc> + <rule implement="MUST"> + If the client cannot handle the protocol version suggested by the + server it MUST close the socket connection. + </rule> + <rule implement="MUST"> + The server MUST provide a protocol version that is lower than or + equal to that requested by the client in the protocol header. If + the server cannot support the specified protocol it MUST NOT send + this method, but MUST close the socket connection. + </rule> + <chassis name="client" implement="MUST"/> + <response name="start-ok"/> + <field name="version major" type="octet"> + protocol major version + <doc> + The protocol major version that the server agrees to use, which + cannot be higher than the client's major version. + </doc> + </field> + <field name="version minor" type="octet"> + protocol major version + <doc> + The protocol minor version that the server agrees to use, which + cannot be higher than the client's minor version. + </doc> + </field> + <field name="server properties" domain="peer properties"> + server properties + </field> + <field name="mechanisms" type="longstr"> + available security mechanisms + <doc> + A list of the security mechanisms that the server supports, delimited + by spaces. Currently ASL supports these mechanisms: PLAIN. + </doc> + <see name="security mechanisms"/> + <assert check="notnull"/> + </field> + <field name="locales" type="longstr"> + available message locales + <doc> + A list of the message locales that the server supports, delimited + by spaces. The locale defines the language in which the server + will send reply texts. + </doc> + <rule implement="MUST"> + All servers MUST support at least the en_US locale. + </rule> + <assert check="notnull"/> + </field> + </method> + <method name="start-ok" synchronous="1" index="11"> + select security mechanism and locale + <doc> + This method selects a SASL security mechanism. ASL uses SASL + (RFC2222) to negotiate authentication and encryption. + </doc> + <chassis name="server" implement="MUST"/> + <field name="client properties" domain="peer properties"> + client properties + </field> + <field name="mechanism" type="shortstr"> + selected security mechanism + <doc> + A single security mechanisms selected by the client, which must be + one of those specified by the server. + </doc> + <rule implement="SHOULD"> + The client SHOULD authenticate using the highest-level security + profile it can handle from the list provided by the server. + </rule> + <rule implement="MUST"> + The mechanism field MUST contain one of the security mechanisms + proposed by the server in the Start method. If it doesn't, the + server MUST close the socket. + </rule> + <assert check="notnull"/> + </field> + <field name="response" type="longstr"> + security response data + <doc> + A block of opaque data passed to the security mechanism. The contents + of this data are defined by the SASL security mechanism. For the + PLAIN security mechanism this is defined as a field table holding + two fields, LOGIN and PASSWORD. + </doc> + <assert check="notnull"/> + </field> + <field name="locale" type="shortstr"> + selected message locale + <doc> + A single message local selected by the client, which must be one + of those specified by the server. + </doc> + <assert check="notnull"/> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="secure" synchronous="1" index="20"> + security mechanism challenge + <doc> + The SASL protocol works by exchanging challenges and responses until + both peers have received sufficient information to authenticate each + other. This method challenges the client to provide more information. + </doc> + <chassis name="client" implement="MUST"/> + <response name="secure-ok"/> + <field name="challenge" type="longstr"> + security challenge data + <doc> + Challenge information, a block of opaque binary data passed to + the security mechanism. + </doc> + <see name="security mechanisms"/> + </field> + </method> + <method name="secure-ok" synchronous="1" index="21"> + security mechanism response + <doc> + This method attempts to authenticate, passing a block of SASL data + for the security mechanism at the server side. + </doc> + <chassis name="server" implement="MUST"/> + <field name="response" type="longstr"> + security response data + <doc> + A block of opaque data passed to the security mechanism. The contents + of this data are defined by the SASL security mechanism. + </doc> + <assert check="notnull"/> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="tune" synchronous="1" index="30"> + propose connection tuning parameters + <doc> + This method proposes a set of connection configuration values + to the client. The client can accept and/or adjust these. + </doc> + <chassis name="client" implement="MUST"/> + <response name="tune-ok"/> + <field name="channel max" type="short"> + proposed maximum channels + <doc> + The maximum total number of channels that the server allows + per connection. Zero means that the server does not impose a + fixed limit, but the number of allowed channels may be limited + by available server resources. + </doc> + </field> + <field name="frame max" type="long"> + proposed maximum frame size + <doc> + The largest frame size that the server proposes for the + connection. The client can negotiate a lower value. Zero means + that the server does not impose any specific limit but may reject + very large frames if it cannot allocate resources for them. + </doc> + <rule implement="MUST"> + Until the frame-max has been negotiated, both peers MUST accept + frames of up to 4096 octets large. The minimum non-zero value for + the frame-max field is 4096. + </rule> + </field> + <field name="heartbeat" type="short"> + desired heartbeat delay + <doc> + The delay, in seconds, of the connection heartbeat that the server + wants. Zero means the server does not want a heartbeat. + </doc> + </field> + </method> + <method name="tune-ok" synchronous="1" index="31"> + negotiate connection tuning parameters + <doc> + This method sends the client's connection tuning parameters to the + server. Certain fields are negotiated, others provide capability + information. + </doc> + <chassis name="server" implement="MUST"/> + <field name="channel max" type="short"> + negotiated maximum channels + <doc> + The maximum total number of channels that the client will use + per connection. May not be higher than the value specified by + the server. + </doc> + <rule implement="MAY"> + The server MAY ignore the channel-max value or MAY use it for + tuning its resource allocation. + </rule> + <assert check="notnull"/> + <assert check="le" method="tune" field="channel max"/> + </field> + <field name="frame max" type="long"> + negotiated maximum frame size + <doc> + The largest frame size that the client and server will use for + the connection. Zero means that the client does not impose any + specific limit but may reject very large frames if it cannot + allocate resources for them. Note that the frame-max limit + applies principally to content frames, where large contents + can be broken into frames of arbitrary size. + </doc> + <rule implement="MUST"> + Until the frame-max has been negotiated, both peers must accept + frames of up to 4096 octets large. The minimum non-zero value for + the frame-max field is 4096. + </rule> + </field> + <field name="heartbeat" type="short"> + desired heartbeat delay + <doc> + The delay, in seconds, of the connection heartbeat that the client + wants. Zero means the client does not want a heartbeat. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="open" synchronous="1" index="40"> + open connection to virtual host + <doc> + This method opens a connection to a virtual host, which is a + collection of resources, and acts to separate multiple application + domains within a server. + </doc> + <rule implement="MUST"> + The client MUST open the context before doing any work on the + connection. + </rule> + <chassis name="server" implement="MUST"/> + <response name="open-ok"/> + <response name="redirect"/> + <field name="virtual host" domain="path"> + virtual host name + <assert check="regexp" value="^[a-zA-Z0-9/-_]+$"/> + <doc> + The name of the virtual host to work with. + </doc> + <rule implement="MUST"> + If the server supports multiple virtual hosts, it MUST enforce a + full separation of exchanges, queues, and all associated entities + per virtual host. An application, connected to a specific virtual + host, MUST NOT be able to access resources of another virtual host. + </rule> + <rule implement="SHOULD"> + The server SHOULD verify that the client has permission to access + the specified virtual host. + </rule> + <rule implement="MAY"> + The server MAY configure arbitrary limits per virtual host, such + as the number of each type of entity that may be used, per + connection and/or in total. + </rule> + </field> + <field name="capabilities" type="shortstr"> + required capabilities + <doc> + The client may specify a number of capability names, delimited by + spaces. The server can use this string to how to process the + client's connection request. + </doc> + </field> + <field name="insist" type="bit"> + insist on connecting to server + <doc> + In a configuration with multiple load-sharing servers, the server + may respond to a Connection.Open method with a Connection.Redirect. + The insist option tells the server that the client is insisting on + a connection to the specified server. + </doc> + <rule implement="SHOULD"> + When the client uses the insist option, the server SHOULD accept + the client connection unless it is technically unable to do so. + </rule> + </field> + </method> + <method name="open-ok" synchronous="1" index="41"> + signal that the connection is ready + <doc> + This method signals to the client that the connection is ready for + use. + </doc> + <chassis name="client" implement="MUST"/> + <field name="known hosts" domain="known hosts"/> + </method> + <method name="redirect" synchronous="1" index="50"> + asks the client to use a different server + <doc> + This method redirects the client to another server, based on the + requested virtual host and/or capabilities. + </doc> + <rule implement="SHOULD"> + When getting the Connection.Redirect method, the client SHOULD + reconnect to the host specified, and if that host is not present, + to any of the hosts specified in the known-hosts list. + </rule> + <chassis name="client" implement="MAY"/> + <field name="host" type="shortstr"> + server to connect to + <doc> + Specifies the server to connect to. This is an IP address or a + DNS name, optionally followed by a colon and a port number. If + no port number is specified, the client should use the default + port number for the protocol. + </doc> + <assert check="notnull"/> + </field> + <field name="known hosts" domain="known hosts"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="close" synchronous="1" index="60"> + request a connection close + <doc> + This method indicates that the sender wants to close the connection. + This may be due to internal conditions (e.g. a forced shut-down) or + due to an error handling a specific method, i.e. an exception. When + a close is due to an exception, the sender provides the class and + method id of the method which caused the exception. + </doc> + <rule implement="MUST"> + After sending this method any received method except the Close-OK + method MUST be discarded. + </rule> + <rule implement="MAY"> + The peer sending this method MAY use a counter or timeout to + detect failure of the other peer to respond correctly with + the Close-OK method. + </rule> + <rule implement="MUST"> + When a server receives the Close method from a client it MUST + delete all server-side resources associated with the client's + context. A client CANNOT reconnect to a context after sending + or receiving a Close method. + </rule> + <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"> + failing method class + <doc> + When the close is provoked by a method exception, this is the + class of the method. + </doc> + </field> + <field name="method id" domain="class id"> + failing method ID + <doc> + When the close is provoked by a method exception, this is the + ID of the method. + </doc> + </field> + </method> + <method name="close-ok" synchronous="1" index="61"> + confirm a connection close + <doc> + This method confirms a Connection.Close method and tells the + recipient that it is safe to release resources for the connection + and close the socket. + </doc> + <rule implement="SHOULD"> + A peer that detects a socket closure without having received a + Close-Ok handshake method SHOULD log the error. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + </method> + </class> + <class name="channel" handler="channel" index="20"> + <!-- +====================================================== +== CHANNEL +====================================================== +--> + work with channels +<doc> + The channel class provides methods for a client to establish a virtual + connection - a channel - to a server and for both peers to operate the + virtual connection thereafter. +</doc> + <doc name="grammar"> + channel = open-channel *use-channel close-channel + open-channel = C:OPEN S:OPEN-OK + use-channel = C:FLOW S:FLOW-OK + / S:FLOW C:FLOW-OK + / S:ALERT + / functional-class + close-channel = C:CLOSE S:CLOSE-OK + / S:CLOSE C:CLOSE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="open" synchronous="1" index="10"> + open a channel for use + <doc> + This method opens a virtual connection (a channel). + </doc> + <rule implement="MUST"> + This method MUST NOT be called when the channel is already open. + </rule> + <chassis name="server" implement="MUST"/> + <response name="open-ok"/> + <field name="out of band" type="shortstr"> + out-of-band settings + <doc> + Configures out-of-band transfers on this channel. The syntax and + meaning of this field will be formally defined at a later date. + </doc> + <assert check="null"/> + </field> + </method> + <method name="open-ok" synchronous="1" index="11"> + signal that the channel is ready + <doc> + This method signals to the client that the channel is ready for use. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="flow" synchronous="1" index="20"> + enable/disable flow from peer + <doc> + This method asks the peer to pause or restart the flow of content + data. This is a simple flow-control mechanism that a peer can use + to avoid oveflowing its queues or otherwise finding itself receiving + more messages than it can process. Note that this method is not + intended for window control. The peer that receives a request to + stop sending content should finish sending the current content, if + any, and then wait until it receives a Flow restart method. + </doc> + <rule implement="MAY"> + When a new channel is opened, it is active. Some applications + assume that channels are inactive until started. To emulate this + behaviour a client MAY open the channel, then pause it. + </rule> + <rule implement="SHOULD"> + When sending content data in multiple frames, a peer SHOULD monitor + the channel for incoming methods and respond to a Channel.Flow as + rapidly as possible. + </rule> + <rule implement="MAY"> + A peer MAY use the Channel.Flow method to throttle incoming content + data for internal reasons, for example, when exchangeing data over a + slower connection. + </rule> + <rule implement="MAY"> + The peer that requests a Channel.Flow method MAY disconnect and/or + ban a peer that does not respect the request. + </rule> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <response name="flow-ok"/> + <field name="active" type="bit"> + start/stop content frames + <doc> + If 1, the peer starts sending content frames. If 0, the peer + stops sending content frames. + </doc> + </field> + </method> + <method name="flow-ok" index="21"> + confirm a flow method + <doc> + Confirms to the peer that a flow command was received and processed. + </doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <field name="active" type="bit"> + current flow setting + <doc> + Confirms the setting of the processed flow method: 1 means the + peer will start sending or continue to send content frames; 0 + means it will not. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="alert" index="30"> + send a non-fatal warning message + <doc> + This method allows the server to send a non-fatal warning to the + client. This is used for methods that are normally asynchronous + and thus do not have confirmations, and for which the server may + detect errors that need to be reported. Fatal errors are handled + as channel or connection exceptions; non-fatal errors are sent + through this method. + </doc> + <chassis name="client" implement="MUST"/> + <field name="reply code" domain="reply code"/> + <field name="reply text" domain="reply text"/> + <field name="details" type="table"> + detailed information for warning + <doc> + A set of fields that provide more information about the + problem. The meaning of these fields are defined on a + per-reply-code basis (TO BE DEFINED). + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="close" synchronous="1" index="40"> + request a channel close + <doc> + This method indicates that the sender wants to close the channel. + This may be due to internal conditions (e.g. a forced shut-down) or + due to an error handling a specific method, i.e. an exception. When + a close is due to an exception, the sender provides the class and + method id of the method which caused the exception. + </doc> + <rule implement="MUST"> + After sending this method any received method except + Channel.Close-OK MUST be discarded. + </rule> + <rule implement="MAY"> + The peer sending this method MAY use a counter or timeout to detect + failure of the other peer to respond correctly with Channel.Close-OK.. + </rule> + <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"> + failing method class + <doc> + When the close is provoked by a method exception, this is the + class of the method. + </doc> + </field> + <field name="method id" domain="method id"> + failing method ID + <doc> + When the close is provoked by a method exception, this is the + ID of the method. + </doc> + </field> + </method> + <method name="close-ok" synchronous="1" index="41"> + confirm a channel close + <doc> + This method confirms a Channel.Close method and tells the recipient + that it is safe to release resources for the channel and close the + socket. + </doc> + <rule implement="SHOULD"> + A peer that detects a socket closure without having received a + Channel.Close-Ok handshake method SHOULD log the error. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + </method> + </class> + <class name="access" handler="connection" index="30"> + <!-- +====================================================== +== ACCESS CONTROL +====================================================== +--> + work with access tickets +<doc> + The protocol control access to server resources using access tickets. + A client must explicitly request access tickets before doing work. + An access ticket grants a client the right to use a specific set of + resources - called a "realm" - in specific ways. +</doc> + <doc name="grammar"> + access = C:REQUEST S:REQUEST-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="request" synchronous="1" index="10"> + request an access ticket + <doc> + This method requests an access ticket for an access realm. + The server responds by granting the access ticket. If the + client does not have access rights to the requested realm + this causes a connection exception. Access tickets are a + per-channel resource. + </doc> + <rule implement="MUST"> + The realm name MUST start with either "/data" (for application + resources) or "/admin" (for server administration resources). + If the realm starts with any other path, the server MUST raise + a connection exception with reply code 403 (access refused). + </rule> + <rule implement="MUST"> + The server MUST implement the /data realm and MAY implement the + /admin realm. The mapping of resources to realms is not + defined in the protocol - this is a server-side configuration + issue. + </rule> + <chassis name="server" implement="MUST"/> + <response name="request-ok"/> + <field name="realm" domain="path"> + name of requested realm + <rule implement="MUST"> + If the specified realm is not known to the server, the server + must raise a channel exception with reply code 402 (invalid + path). + </rule> + </field> + <field name="exclusive" type="bit"> + request exclusive access + <doc> + Request exclusive access to the realm. If the server cannot grant + this - because there are other active tickets for the realm - it + raises a channel exception. + </doc> + </field> + <field name="passive" type="bit"> + request passive access + <doc> + Request message passive access to the specified access realm. + Passive access lets a client get information about resources in + the realm but not to make any changes to them. + </doc> + </field> + <field name="active" type="bit"> + request active access + <doc> + Request message active access to the specified access realm. + Acvtive access lets a client get create and delete resources in + the realm. + </doc> + </field> + <field name="write" type="bit"> + request write access + <doc> + Request write access to the specified access realm. Write access + lets a client publish messages to all exchanges in the realm. + </doc> + </field> + <field name="read" type="bit"> + request read access + <doc> + Request read access to the specified access realm. Read access + lets a client consume messages from queues in the realm. + </doc> + </field> + </method> + <method name="request-ok" synchronous="1" index="11"> + grant access to server resources + <doc> + This method provides the client with an access ticket. The access + ticket is valid within the current channel and for the lifespan of + the channel. + </doc> + <rule implement="MUST"> + The client MUST NOT use access tickets except within the same + channel as originally granted. + </rule> + <rule implement="MUST"> + The server MUST isolate access tickets per channel and treat an + attempt by a client to mix these as a connection exception. + </rule> + <chassis name="client" implement="MUST"/> + <field name="ticket" domain="access ticket"/> + </method> + </class> + <class name="exchange" handler="channel" index="40"> + <!-- +====================================================== +== EXCHANGES (or "routers", if you prefer) +== (Or matchers, plugins, extensions, agents,... Routing is just one of +== the many fun things an exchange can do.) +====================================================== +--> + work with exchanges +<doc> + Exchanges match and distribute messages across queues. Exchanges can be + configured in the server or created at runtime. +</doc> + <doc name="grammar"> + exchange = C:DECLARE S:DECLARE-OK + / C:DELETE S:DELETE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <rule implement="MUST"> + <test>amq_exchange_19</test> + The server MUST implement the direct and fanout exchange types, and + predeclare the corresponding exchanges named amq.direct and amq.fanout + in each virtual host. The server MUST also predeclare a direct + exchange to act as the default exchange for content Publish methods + and for default queue bindings. +</rule> + <rule implement="SHOULD"> + <test>amq_exchange_20</test> + The server SHOULD implement the topic exchange type, and predeclare + the corresponding exchange named amq.topic in each virtual host. +</rule> + <rule implement="MAY"> + <test>amq_exchange_21</test> + The server MAY implement the system exchange type, and predeclare the + corresponding exchanges named amq.system in each virtual host. If the + client attempts to bind a queue to the system exchange, the server + MUST raise a connection exception with reply code 507 (not allowed). +</rule> + <rule implement="MUST"> + <test>amq_exchange_22</test> + The default exchange MUST be defined as internal, and be inaccessible + to the client except by specifying an empty exchange name in a content + Publish method. That is, the server MUST NOT let clients make explicit + bindings to this exchange. +</rule> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="declare" synchronous="1" index="10"> + declare exchange, create if needed + <doc> + This method creates an exchange if it does not already exist, and if the + exchange exists, verifies that it is of the correct and expected class. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_23</test> + The server SHOULD support a minimum of 16 exchanges per virtual host + and ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="declare-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + When a client defines a new exchange, this belongs to the access realm + of the ticket used. All further work done with that exchange must be + done with an access ticket for the same realm. + </doc> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "active" access + to the realm in which the exchange exists or will be created, or + "passive" access if the if-exists flag is set. + </rule> + </field> + <field name="exchange" domain="exchange name"> + <rule implement="MUST"> + <test>amq_exchange_15</test> + Exchange names starting with "amq." are reserved for predeclared + and standardised exchanges. If the client attempts to create an + exchange starting with "amq.", the server MUST raise a channel + exception with reply code 403 (access refused). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/> + </field> + <field name="type" type="shortstr"> + exchange type + <doc> + Each exchange belongs to one of a set of exchange types implemented + by the server. The exchange types define the functionality of the + exchange - i.e. how messages are routed through it. It is not valid + or meaningful to attempt to change the type of an existing exchange. + </doc> + <rule implement="MUST"> + <test>amq_exchange_16</test> + If the exchange already exists with a different type, the server + MUST raise a connection exception with a reply code 507 (not allowed). + </rule> + <rule implement="MUST"> + <test>amq_exchange_18</test> + If the server does not support the requested exchange type it MUST + raise a connection exception with a reply code 503 (command invalid). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/> + </field> + <field name="passive" type="bit"> + do not create exchange + <doc> + If set, the server will not create the exchange. The client can use + this to check whether an exchange exists without modifying the server + state. + </doc> + <rule implement="MUST"> + <test>amq_exchange_05</test> + If set, and the exchange does not already exist, the server MUST + raise a channel exception with reply code 404 (not found). + </rule> + </field> + <field name="durable" type="bit"> + request a durable exchange + <doc> + If set when creating a new exchange, the exchange will be marked as + durable. Durable exchanges remain active when a server restarts. + Non-durable exchanges (transient exchanges) are purged if/when a + server restarts. + </doc> + <rule implement="MUST"> + <test>amq_exchange_24</test> + The server MUST support both durable and transient exchanges. + </rule> + <rule implement="MUST"> + The server MUST ignore the durable field if the exchange already + exists. + </rule> + </field> + <field name="auto delete" type="bit"> + auto-delete when unused + <doc> + If set, the exchange is deleted when all queues have finished + using it. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_02</test> + The server SHOULD allow for a reasonable delay between the point + when it determines that an exchange is not being used (or no longer + used), and the point when it deletes the exchange. At the least it + must allow a client to create an exchange and then bind a queue to + it, with a small but non-zero delay between these two actions. + </rule> + <rule implement="MUST"> + <test>amq_exchange_25</test> + The server MUST ignore the auto-delete field if the exchange already + exists. + </rule> + </field> + <field name="internal" type="bit"> + create internal exchange + <doc> + If set, the exchange may not be used directly by publishers, but + only when bound to other exchanges. Internal exchanges are used to + construct wiring that is not visible to applications. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for declaration + <doc> + A set of arguments for the declaration. The syntax and semantics + of these arguments depends on the server implementation. This + field is ignored if passive is 1. + </doc> + </field> + </method> + <method name="declare-ok" synchronous="1" index="11"> + confirms an exchange declaration + <doc> + This method confirms a Declare method and confirms the name of the + exchange, essential for automatically-named exchanges. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="delete" synchronous="1" index="20"> + delete an exchange + <doc> + This method deletes an exchange. When an exchange is deleted all queue + bindings on the exchange are cancelled. + </doc> + <chassis name="server" implement="MUST"/> + <response name="delete-ok"/> + <field name="ticket" domain="access ticket"> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "active" + access rights to the exchange's access realm. + </rule> + </field> + <field name="exchange" domain="exchange name"> + <rule implement="MUST"> + <test>amq_exchange_11</test> + The exchange MUST exist. Attempting to delete a non-existing exchange + causes a channel exception. + </rule> + <assert check="notnull"/> + </field> + <field name="if unused" type="bit"> + delete only if unused + <doc> + If set, the server will only delete the exchange if it has no queue + bindings. If the exchange has queue bindings the server does not + delete it but raises a channel exception instead. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_12</test> + If set, the server SHOULD delete the exchange but only if it has + no queue bindings. + </rule> + <rule implement="SHOULD"> + <test>amq_exchange_13</test> + If set, the server SHOULD raise a channel exception if the exchange is in + use. + </rule> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + </method> + <method name="delete-ok" synchronous="1" index="21"> + confirm deletion of an exchange + <doc> + This method confirms the deletion of an exchange. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="queue" handler="channel" index="50"> + <!-- +====================================================== +== QUEUES +====================================================== +--> + work with queues + +<doc> + Queues store and forward messages. Queues can be configured in the server + or created at runtime. Queues must be attached to at least one exchange + in order to receive messages from publishers. +</doc> + <doc name="grammar"> + queue = C:DECLARE S:DECLARE-OK + / C:BIND S:BIND-OK + / C:PURGE S:PURGE-OK + / C:DELETE S:DELETE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <rule implement="MUST"> + <test>amq_queue_33</test> + A server MUST allow any content class to be sent to any queue, in any + mix, and queue and delivery these content classes independently. Note + that all methods that fetch content off queues are specific to a given + content class. +</rule> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="declare" synchronous="1" index="10"> + declare queue, create if needed + <doc> + This method creates or checks a queue. When creating a new queue + the client can specify various properties that control the durability + of the queue and its contents, and the level of sharing for the queue. + </doc> + <rule implement="MUST"> + <test>amq_queue_34</test> + The server MUST create a default binding for a newly-created queue + to the default exchange, which is an exchange of type 'direct'. + </rule> + <rule implement="SHOULD"> + <test>amq_queue_35</test> + The server SHOULD support a minimum of 256 queues per virtual host + and ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="declare-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + When a client defines a new queue, this belongs to the access realm + of the ticket used. All further work done with that queue must be + done with an access ticket for the same realm. + </doc> + <doc> + The client provides a valid access ticket giving "active" access + to the realm in which the queue exists or will be created, or + "passive" access if the if-exists flag is set. + </doc> + </field> + <field name="queue" domain="queue name"> + <rule implement="MAY"> + <test>amq_queue_10</test> + The queue name MAY be empty, in which case the server MUST create + a new queue with a unique generated name and return this to the + client in the Declare-Ok method. + </rule> + <rule implement="MUST"> + <test>amq_queue_32</test> + Queue names starting with "amq." are reserved for predeclared and + standardised server queues. If the queue name starts with "amq." + and the passive option is zero, the server MUST raise a connection + exception with reply code 403 (access refused). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/> + </field> + <field name="passive" type="bit"> + do not create queue + <doc> + If set, the server will not create the queue. The client can use + this to check whether a queue exists without modifying the server + state. + </doc> + <rule implement="MUST"> + <test>amq_queue_05</test> + If set, and the queue does not already exist, the server MUST + respond with a reply code 404 (not found) and raise a channel + exception. + </rule> + </field> + <field name="durable" type="bit"> + request a durable queue + <doc> + If set when creating a new queue, the queue will be marked as + durable. Durable queues remain active when a server restarts. + Non-durable queues (transient queues) are purged if/when a + server restarts. Note that durable queues do not necessarily + hold persistent messages, although it does not make sense to + send persistent messages to a transient queue. + </doc> + <rule implement="MUST"> + <test>amq_queue_03</test> + The server MUST recreate the durable queue after a restart. + </rule> + <rule implement="MUST"> + <test>amq_queue_36</test> + The server MUST support both durable and transient queues. + </rule> + <rule implement="MUST"> + <test>amq_queue_37</test> + The server MUST ignore the durable field if the queue already + exists. + </rule> + </field> + <field name="exclusive" type="bit"> + request an exclusive queue + <doc> + Exclusive queues may only be consumed from by the current connection. + Setting the 'exclusive' flag always implies 'auto-delete'. + </doc> + <rule implement="MUST"> + <test>amq_queue_38</test> + The server MUST support both exclusive (private) and non-exclusive + (shared) queues. + </rule> + <rule implement="MUST"> + <test>amq_queue_04</test> + The server MUST raise a channel exception if 'exclusive' is specified + and the queue already exists and is owned by a different connection. + </rule> + </field> + <field name="auto delete" type="bit"> + auto-delete queue when unused + <doc> + If set, the queue is deleted when all consumers have finished + using it. Last consumer can be cancelled either explicitly or because + its channel is closed. If there was no consumer ever on the queue, it + won't be deleted. + </doc> + <rule implement="SHOULD"> + <test>amq_queue_02</test> + The server SHOULD allow for a reasonable delay between the point + when it determines that a queue is not being used (or no longer + used), and the point when it deletes the queue. At the least it + must allow a client to create a queue and then create a consumer + to read from it, with a small but non-zero delay between these + two actions. The server should equally allow for clients that may + be disconnected prematurely, and wish to re-consume from the same + queue without losing messages. We would recommend a configurable + timeout, with a suitable default value being one minute. + </rule> + <rule implement="MUST"> + <test>amq_queue_31</test> + The server MUST ignore the auto-delete field if the queue already + exists. + </rule> + </field> + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for declaration + <doc> + A set of arguments for the declaration. The syntax and semantics + of these arguments depends on the server implementation. This + field is ignored if passive is 1. + </doc> + </field> + </method> + <method name="declare-ok" synchronous="1" index="11"> + confirms a queue definition + <doc> + This method confirms a Declare method and confirms the name of the + queue, essential for automatically-named queues. + </doc> + <chassis name="client" implement="MUST"/> + <field name="queue" domain="queue name"> + <doc> + Reports the name of the queue. If the server generated a queue + name, this field contains that name. + </doc> + <assert check="notnull"/> + </field> + <field name="message count" type="long"> + number of messages in queue + <doc> + Reports the number of messages in the queue, which will be zero + for newly-created queues. + </doc> + </field> + <field name="consumer count" type="long"> + number of consumers + <doc> + Reports the number of active consumers for the queue. Note that + consumers can suspend activity (Channel.Flow) in which case they + do not appear in this count. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="bind" synchronous="1" index="20"> + bind queue to an exchange + <doc> + This method binds a queue to an exchange. Until a queue is + bound it will not receive any messages. In a classic messaging + model, store-and-forward queues are bound to a dest exchange + and subscription queues are bound to a dest_wild exchange. + </doc> + <rule implement="MUST"> + <test>amq_queue_25</test> + A server MUST allow ignore duplicate bindings - that is, two or + more bind methods for a specific queue, with identical arguments + - without treating these as an error. + </rule> + <rule implement="MUST"> + <test>amq_queue_39</test> + If a bind fails, the server MUST raise a connection exception. + </rule> + <rule implement="MUST"> + <test>amq_queue_12</test> + The server MUST NOT allow a durable queue to bind to a transient + exchange. If the client attempts this the server MUST raise a + channel exception. + </rule> + <rule implement="SHOULD"> + <test>amq_queue_13</test> + Bindings for durable queues are automatically durable and the + server SHOULD restore such bindings after a server restart. + </rule> + <rule implement="MUST"> + <test>amq_queue_17</test> + If the client attempts to an exchange that was declared as internal, + the server MUST raise a connection exception with reply code 530 + (not allowed). + </rule> + <rule implement="SHOULD"> + <test>amq_queue_40</test> + The server SHOULD support at least 4 bindings per queue, and + ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="bind-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The client provides a valid access ticket giving "active" + access rights to the queue's access realm. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to bind. If the queue name is + empty, refers to the current queue for the channel, which is + the last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_26"> + If the queue does not exist the server MUST raise a channel exception + with reply code 404 (not found). + </doc> + </field> + + <field name="exchange" domain="exchange name"> + The name of the exchange to bind to. + <rule implement="MUST"> + <test>amq_queue_14</test> + If the exchange does not exist the server MUST raise a channel + exception with reply code 404 (not found). + </rule> + </field> + <field name="routing key" type="shortstr"> + message routing key + <doc> + Specifies the routing key for the binding. The routing key is + used for routing messages depending on the exchange configuration. + Not all exchanges use a routing key - refer to the specific + exchange documentation. If the routing key is empty and the queue + name is empty, the routing key will be the current queue for the + channel, which is the last declared queue. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for binding + <doc> + A set of arguments for the binding. The syntax and semantics of + these arguments depends on the exchange class. + </doc> + </field> + </method> + <method name="bind-ok" synchronous="1" index="21"> + confirm bind successful + <doc> + This method confirms that the bind was successful. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="purge" synchronous="1" index="30"> + purge a queue + <doc> + This method removes all messages from a queue. It does not cancel + consumers. Purged messages are deleted without any formal "undo" + mechanism. + </doc> + <rule implement="MUST"> + <test>amq_queue_15</test> + A call to purge MUST result in an empty queue. + </rule> + <rule implement="MUST"> + <test>amq_queue_41</test> + On transacted channels the server MUST not purge messages that have + already been sent to a client but not yet acknowledged. + </rule> + <rule implement="MAY"> + <test>amq_queue_42</test> + The server MAY implement a purge queue or log that allows system + administrators to recover accidentally-purged messages. The server + SHOULD NOT keep purged messages in the same storage spaces as the + live messages since the volumes of purged messages may get very + large. + </rule> + <chassis name="server" implement="MUST"/> + <response name="purge-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The access ticket must be for the access realm that holds the + queue. + </doc> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "read" access + rights to the queue's access realm. Note that purging a queue is + equivalent to reading all messages and discarding them. + </rule> + </field> + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to purge. If the queue name is + empty, refers to the current queue for the channel, which is + the last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_16"> + The queue must exist. Attempting to purge a non-existing queue + causes a channel exception. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + </method> + <method name="purge-ok" synchronous="1" index="31"> + confirms a queue purge + <doc> + This method confirms the purge of a queue. + </doc> + <chassis name="client" implement="MUST"/> + <field name="message count" type="long"> + number of messages purged + <doc> + Reports the number of messages purged. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="delete" synchronous="1" index="40"> + delete a queue + <doc> + This method deletes a queue. When a queue is deleted any pending + messages are sent to a dead-letter queue if this is defined in the + server configuration, and all consumers on the queue are cancelled. + </doc> + <rule implement="SHOULD"> + <test>amq_queue_43</test> + The server SHOULD use a dead-letter queue to hold messages that + were pending on a deleted queue, and MAY provide facilities for + a system administrator to move these messages back to an active + queue. + </rule> + <chassis name="server" implement="MUST"/> + <response name="delete-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The client provides a valid access ticket giving "active" + access rights to the queue's access realm. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to delete. If the queue name is + empty, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_21"> + The queue must exist. Attempting to delete a non-existing queue + causes a channel exception. + </doc> + </field> + + <field name="if unused" type="bit"> + delete only if unused + <doc> + If set, the server will only delete the queue if it has no + consumers. If the queue has consumers the server does does not + delete it but raises a channel exception instead. + </doc> + <rule implement="MUST"> + <test>amq_queue_29</test> + <test>amq_queue_30</test> + The server MUST respect the if-unused flag when deleting a queue. + </rule> + </field> + <field name="if empty" type="bit"> + delete only if empty + <test>amq_queue_27</test> + <doc> + If set, the server will only delete the queue if it has no + messages. If the queue is not empty the server raises a channel + exception. + </doc> + </field> + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + </method> + + <method name="delete-ok" synchronous="1" index="41"> + confirm deletion of a queue + <doc> + This method confirms the deletion of a queue. + </doc> + <chassis name="client" implement="MUST"/> + <field name="message count" type="long"> + number of messages purged + <doc> + Reports the number of messages purged. + </doc> + </field> + </method> + </class> + <class name="basic" handler="channel" index="60"> + <!-- +====================================================== +== BASIC MIDDLEWARE +====================================================== +--> + work with basic content +<doc> + The Basic class provides methods that support an industry-standard + messaging model. +</doc> + +<doc name = "grammar"> + basic = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:PUBLISH content + / S:RETURN content + / S:DELIVER content + / C:GET ( S:GET-OK content / S:GET-EMPTY ) + / C:ACK + / C:REJECT +</doc> + +<chassis name = "server" implement = "MUST" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule" test = "amq_basic_08"> + The server SHOULD respect the persistent property of basic messages + and SHOULD make a best-effort to hold persistent basic messages on a + reliable storage mechanism. +</doc> +<doc name = "rule" test = "amq_basic_09"> + The server MUST NOT discard a persistent basic message in case of a + queue overflow. The server MAY use the Channel.Flow method to slow + or stop a basic message publisher when necessary. +</doc> +<doc name = "rule" test = "amq_basic_10"> + The server MAY overflow non-persistent basic messages to persistent + storage and MAY discard or dead-letter non-persistent basic messages + on a priority basis if the queue size exceeds some configured limit. +</doc> +<doc name = "rule" test = "amq_basic_11"> + The server MUST implement at least 2 priority levels for basic + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule" test = "amq_basic_12"> + The server MUST deliver messages of the same priority in order + irrespective of their individual persistence. +</doc> +<doc name = "rule" test = "amq_basic_13"> + The server MUST support both automatic and explicit acknowledgements + on Basic content. +</doc> + +<!-- These are the properties for a Basic content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "delivery mode" type = "octet"> + Non-persistent (1) or persistent (2) +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "correlation id" type = "shortstr"> + The application correlation identifier +</field> +<field name = "reply to" type = "shortstr"> + The destination to reply to +</field> +<field name = "expiration" type = "shortstr"> + Message expiration specification +</field> +<field name = "message id" type = "shortstr"> + The application message identifier +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> +<field name = "type" type = "shortstr"> + The message type name +</field> +<field name = "user id" type = "shortstr"> + The creating user id +</field> +<field name = "app id" type = "shortstr"> + The creating application id +</field> +<field name = "cluster id" type = "shortstr"> + Intra-cluster routing identifier +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. The + server will send a message in advance if it is equal to or + smaller in size than the available prefetch size (and also falls + into other prefetch limits). May be set to zero, meaning "no + specific limit", although other prefetch limits may still apply. + The prefetch-size is ignored if the no-ack option is set. + </doc> + <doc name = "rule" test = "amq_basic_17"> + The server MUST ignore this setting when the client is not + processing any messages - i.e. the prefetch size does not limit + the transfer of single messages to a client, only the sending in + advance of more messages while the client still has one or more + unacknowledged messages. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + field may be used in combination with the prefetch-size field; + a message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + The prefetch-count is ignored if the no-ack option is set. + </doc> + <doc name = "rule" test = "amq_basic_18"> + The server MAY send less data in advance than allowed by the + client's specified prefetch windows but it MUST NOT send more. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule" test = "amq_basic_01"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "no ack" domain = "no ack" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_basic_02"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 403 (access refused). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + The server provides the client with a consumer tag, which is used + by the client for methods called on the consumer at a later stage. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc test = "amq_basic_04"> + This method cancels a consumer. This does not affect already + delivered messages, but it does mean the server will not send any + more messages for that consumer. The client may receive an + abitrary number of messages in between sending the cancel method + and receiving the cancel-ok reply. + </doc> + <doc name = "rule" test = "todo"> + If the queue no longer exists when the client sends a cancel command, + or the consumer has been cancelled for other reasons, this command + has no effect. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" content = "1" index = "40"> + publish a message + <doc> + This method publishes a message to a specific exchange. The message + will be routed to queues as defined by the exchange configuration + and distributed to any active consumers when the transaction, if any, + is committed. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule" test = "amq_basic_06"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule" test = "amq_basic_14"> + If the exchange was declared as an internal exchange, the server + MUST raise a channel exception with a reply code 403 (access + refused). + </doc> + <doc name = "rule" test = "amq_basic_15"> + The exchange MAY refuse basic content in which case it MUST raise + a channel exception with reply code 540 (not implemented). + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_basic_07"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_basic_16"> + The server SHOULD implement the immediate flag. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "50"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <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"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" content = "1" index = "60"> + notify the client of a consumer message + <doc> + This method delivers a message to the client, via a consumer. In + the asynchronous message delivery model, the client starts a + consumer using the Consume method, then the server responds with + Deliver methods as and when messages arrive for that consumer. + </doc> + <doc name = "rule" test = "amq_basic_19"> + The server SHOULD track the number of times a message has been + delivered to clients and when a message is redelivered a certain + number of times - e.g. 5 times - without being acknowledged, the + server SHOULD consider the message to be unprocessable (possibly + causing client applications to abort), and move the message to a + dead letter queue. + </doc> + <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"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "get" synchronous = "1" index = "70"> + direct access to a queue + <doc> + This method provides a direct access to the messages in a queue + using a synchronous dialogue that is designed for specific types of + application where synchronous functionality is more important than + performance. + </doc> + <response name = "get-ok" /> + <response name = "get-empty" /> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" + access rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "no ack" domain = "no ack" /> +</method> + +<method name = "get-ok" synchronous = "1" content = "1" index = "71"> + provide client with a message + <doc> + This method delivers a message to the client following a get + method. A message delivered by 'get-ok' must be acknowledged + unless the no-ack option was set in the get method. + </doc> + <chassis name = "client" implement = "MAY" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "redelivered" domain = "redelivered" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was originally + published to. If empty, the message was published to the default + exchange. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> + + <field name = "message count" type = "long" > + number of messages pending + <doc> + This field reports the number of messages pending on the queue, + excluding the message being delivered. Note that this figure is + indicative, not reliable, and can change arbitrarily as messages + are added to the queue and removed by other clients. + </doc> + </field> +</method> + + +<method name = "get-empty" synchronous = "1" index = "72"> + indicate no messages available + <doc> + This method tells the client that the queue has no messages + available for the client. + </doc> + <chassis name = "client" implement = "MAY" /> + + <field name = "cluster id" type = "shortstr"> + Cluster id + <doc> + For use by cluster applications, should not be used by + client applications. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "ack" index = "80"> + acknowledge one or more messages + <doc> + This method acknowledges one or more messages delivered via the + Deliver or Get-Ok methods. The client can ask to confirm a + single message or a set of messages up to and including a specific + message. + </doc> + <chassis name = "server" implement = "MUST" /> + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "multiple" type = "bit"> + acknowledge multiple messages + <doc> + If set to 1, the delivery tag is treated as "up to and including", + so that the client can acknowledge multiple messages with a single + method. If set to zero, the delivery tag refers to a single + message. If the multiple field is 1, and the delivery tag is zero, + tells the server to acknowledge all outstanding mesages. + </doc> + <doc name = "rule" test = "amq_basic_20"> + The server MUST validate that a non-zero delivery-tag refers to an + delivered message, and raise a channel exception if this is not the + case. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "reject" index = "90"> + reject an incoming message + <doc> + This method allows a client to reject a message. It can be used to + interrupt and cancel large incoming messages, or return untreatable + messages to their original queue. + </doc> + <doc name = "rule" test = "amq_basic_21"> + The server SHOULD be capable of accepting and process the Reject + method while sending message content with a Deliver or Get-Ok + method. I.e. the server should read and process incoming methods + while sending output frames. To cancel a partially-send content, + the server sends a content body frame of size 1 (i.e. with no data + except the frame-end octet). + </doc> + <doc name = "rule" test = "amq_basic_22"> + The server SHOULD interpret this method as meaning that the client + is unable to process the message at this time. + </doc> + <doc name = "rule"> + A client MUST NOT use this method as a means of selecting messages + to process. A rejected message MAY be discarded or dead-lettered, + not necessarily passed to another client. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be discarded. If this bit + is 1, the server will attempt to requeue the message. + </doc> + <doc name = "rule" test = "amq_basic_23"> + The server MUST NOT deliver the message to the same client within + the context of the current channel. The recommended strategy is + to attempt to deliver the message to an alternative consumer, and + if that is not possible, to move the message to a dead-letter + queue. The server MAY use more sophisticated tracking to hold + the message on the queue and redeliver it to the same client at + a later stage. + </doc> + </field> +</method> + +<method name = "recover" index = "100"> + redeliver unacknowledged messages. This method is only allowed on non-transacted channels. + <doc> + This method asks the broker to redeliver all unacknowledged messages on a + specifieid channel. Zero or more messages may be redelivered. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be redelivered to the original recipient. If this bit + is 1, the server will attempt to requeue the message, potentially then delivering it to an + alternative subscriber. + </doc> + </field> + + <doc name="rule"> + The server MUST set the redelivered flag on all messages that are resent. + </doc> + <doc name="rule"> + The server MUST raise a channel exception if this is called on a transacted channel. + </doc> +</method> + + +</class> + + + <class name="file" handler="channel" index="70"> + <!-- +====================================================== +== FILE TRANSFER +====================================================== +--> + work with file content +<doc> + The file class provides methods that support reliable file transfer. + File messages have a specific set of properties that are required for + interoperability with file transfer applications. File messages and + acknowledgements are subject to channel transactions. Note that the + file class does not provide message browsing methods; these are not + compatible with the staging model. Applications that need browsable + file transfer should use Basic content and the Basic class. +</doc> + +<doc name = "grammar"> + file = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:OPEN S:OPEN-OK C:STAGE content + / S:OPEN C:OPEN-OK S:STAGE content + / C:PUBLISH + / S:DELIVER + / S:RETURN + / C:ACK + / C:REJECT +</doc> + +<chassis name = "server" implement = "MAY" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule"> + The server MUST make a best-effort to hold file messages on a + reliable storage mechanism. +</doc> +<doc name = "rule"> + The server MUST NOT discard a file message in case of a queue + overflow. The server MUST use the Channel.Flow method to slow or stop + a file message publisher when necessary. +</doc> +<doc name = "rule"> + The server MUST implement at least 2 priority levels for file + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule"> + The server MUST support both automatic and explicit acknowledgements + on file content. +</doc> + +<!-- These are the properties for a File content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "reply to" type = "shortstr"> + The destination to reply to +</field> +<field name = "message id" type = "shortstr"> + The application message identifier +</field> +<field name = "filename" type = "shortstr"> + The message filename +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> +<field name = "cluster id" type = "shortstr"> + Intra-cluster routing identifier +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. May be + set to zero, meaning "no specific limit". Note that other + prefetch limits may still apply. The prefetch-size is ignored + if the no-ack option is set. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + is compatible with some file API implementations. This field + may be used in combination with the prefetch-size field; a + message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + The prefetch-count is ignored if the no-ack option is set. + </doc> + <doc name = "rule"> + The server MAY send less data in advance than allowed by the + client's specified prefetch windows but it MUST NOT send more. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "no ack" domain = "no ack" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_file_00"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 405 (resource locked). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + This method provides the client with a consumer tag which it MUST + use in methods that work with the consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc> + This method cancels a consumer. This does not affect already + delivered messages, but it does mean the server will not send any + more messages for that consumer. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "open" synchronous = "1" index = "40"> + request to start staging + <doc> + This method requests permission to start staging a message. Staging + means sending the message into a temporary area at the recipient end + and then delivering the message by referring to this temporary area. + Staging is how the protocol handles partial file transfers - if a + message is partially staged and the connection breaks, the next time + the sender starts to stage it, it can restart from where it left off. + </doc> + <response name = "open-ok" /> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier. This is an arbitrary string chosen + by the sender. For staging to work correctly the sender must use + the same staging identifier when staging the same message a second + time after recovery from a failure. A good choice for the staging + identifier would be the SHA1 hash of the message properties data + (including the original filename, revised time, etc.). + </doc> + </field> + + <field name = "content size" type = "longlong"> + message content size + <doc> + The size of the content in octets. The recipient may use this + information to allocate or check available space in advance, to + avoid "disk full" errors during staging of very large messages. + </doc> + <doc name = "rule"> + The sender MUST accurately fill the content-size field. + Zero-length content is permitted. + </doc> + </field> +</method> + +<method name = "open-ok" synchronous = "1" index = "41"> + confirm staging ready + <doc> + This method confirms that the recipient is ready to accept staged + data. If the message was already partially-staged at a previous + time the recipient will report the number of octets already staged. + </doc> + <response name = "stage" /> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> + + <field name = "staged size" type = "longlong"> + already staged amount + <doc> + The amount of previously-staged content in octets. For a new + message this will be zero. + </doc> + <doc name = "rule"> + The sender MUST start sending data from this octet offset in the + message, counting from zero. + </doc> + <doc name = "rule"> + The recipient MAY decide how long to hold partially-staged content + and MAY implement staging by always discarding partially-staged + content. However if it uses the file content type it MUST support + the staging methods. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "stage" content = "1" index = "50"> + stage message content + <doc> + This method stages the message, sending the message content to the + recipient from the octet offset specified in the Open-Ok method. + </doc> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" index = "60"> + publish a message + <doc> + This method publishes a staged file message to a specific exchange. + The file message will be routed to queues as defined by the exchange + configuration and distributed to any active consumers when the + transaction, if any, is committed. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule"> + If the exchange was declared as an internal exchange, the server + MUST respond with a reply code 403 (access refused) and raise a + channel exception. + </doc> + <doc name = "rule"> + The exchange MAY refuse file content in which case it MUST respond + with a reply code 540 (not implemented) and raise a channel + exception. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_file_00"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_file_00"> + The server SHOULD implement the immediate flag. + </doc> + </field> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier of the message to publish. The + message must have been staged. Note that a client can send the + Publish method asynchronously without waiting for staging to + finish. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "70"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <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"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" index = "80"> + notify the client of a consumer message + <doc> + This method delivers a staged file message to the client, via a + consumer. In the asynchronous message delivery model, the client + starts a consumer using the Consume method, then the server + responds with Deliver methods as and when messages arrive for + that consumer. + </doc> + <doc name = "rule"> + The server SHOULD track the number of times a message has been + delivered to clients and when a message is redelivered a certain + number of times - e.g. 5 times - without being acknowledged, the + server SHOULD consider the message to be unprocessable (possibly + causing client applications to abort), and move the message to a + dead letter queue. + </doc> + <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"> + <doc> + Specifies the name of the exchange that the message was originally + published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier of the message to deliver. The + message must have been staged. Note that a server can send the + Deliver method asynchronously without waiting for staging to + finish. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "ack" index = "90"> + acknowledge one or more messages + <doc> + This method acknowledges one or more messages delivered via the + Deliver method. The client can ask to confirm a single message or + a set of messages up to and including a specific message. + </doc> + <chassis name = "server" implement = "MUST" /> + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "multiple" type = "bit"> + acknowledge multiple messages + <doc> + If set to 1, the delivery tag is treated as "up to and including", + so that the client can acknowledge multiple messages with a single + method. If set to zero, the delivery tag refers to a single + message. If the multiple field is 1, and the delivery tag is zero, + tells the server to acknowledge all outstanding mesages. + </doc> + <doc name = "rule"> + The server MUST validate that a non-zero delivery-tag refers to an + delivered message, and raise a channel exception if this is not the + case. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "reject" index = "100"> + reject an incoming message + <doc> + This method allows a client to reject a message. It can be used to + return untreatable messages to their original queue. Note that file + content is staged before delivery, so the client will not use this + method to interrupt delivery of a large message. + </doc> + <doc name = "rule"> + The server SHOULD interpret this method as meaning that the client + is unable to process the message at this time. + </doc> + <doc name = "rule"> + A client MUST NOT use this method as a means of selecting messages + to process. A rejected message MAY be discarded or dead-lettered, + not necessarily passed to another client. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be discarded. If this bit + is 1, the server will attempt to requeue the message. + </doc> + <doc name = "rule"> + The server MUST NOT deliver the message to the same client within + the context of the current channel. The recommended strategy is + to attempt to deliver the message to an alternative consumer, and + if that is not possible, to move the message to a dead-letter + queue. The server MAY use more sophisticated tracking to hold + the message on the queue and redeliver it to the same client at + a later stage. + </doc> + </field> +</method> + +</class> + + <class name="stream" handler="channel" index="80"> + <!-- +====================================================== +== STREAMING +====================================================== +--> + work with streaming content + +<doc> + The stream class provides methods that support multimedia streaming. + The stream class uses the following semantics: one message is one + packet of data; delivery is unacknowleged and unreliable; the consumer + can specify quality of service parameters that the server can try to + adhere to; lower-priority messages may be discarded in favour of high + priority messages. +</doc> + +<doc name = "grammar"> + stream = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:PUBLISH content + / S:RETURN + / S:DELIVER content +</doc> + +<chassis name = "server" implement = "MAY" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule"> + The server SHOULD discard stream messages on a priority basis if + the queue size exceeds some configured limit. +</doc> +<doc name = "rule"> + The server MUST implement at least 2 priority levels for stream + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule"> + The server MUST implement automatic acknowledgements on stream + content. That is, as soon as a message is delivered to a client + via a Deliver method, the server must remove it from the queue. +</doc> + + +<!-- These are the properties for a Stream content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. May be + set to zero, meaning "no specific limit". Note that other + prefetch limits may still apply. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + field may be used in combination with the prefetch-size field; + a message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + </doc> + </field> + + <field name = "consume rate" type = "long"> + transfer rate in octets/second + <doc> + Specifies a desired transfer rate in octets per second. This is + usually determined by the application that uses the streaming + data. A value of zero means "no limit", i.e. as rapidly as + possible. + </doc> + <doc name = "rule"> + The server MAY ignore the prefetch values and consume rates, + depending on the type of stream and the ability of the server + to queue and/or reply it. The server MAY drop low-priority + messages in favour of high-priority messages. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <doc name = "rule"> + Streaming applications SHOULD use different channels to select + different streaming resolutions. AMQP makes no provision for + filtering and/or transforming streams except on the basis of + priority-based selective delivery of individual messages. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_file_00"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 405 (resource locked). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + This method provides the client with a consumer tag which it may + use in methods that work with the consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc> + This method cancels a consumer. Since message delivery is + asynchronous the client may continue to receive messages for + a short while after canceling a consumer. It may process or + discard these as appropriate. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" content = "1" index = "40"> + publish a message + <doc> + This method publishes a message to a specific exchange. The message + will be routed to queues as defined by the exchange configuration + and distributed to any active consumers as appropriate. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule"> + If the exchange was declared as an internal exchange, the server + MUST respond with a reply code 403 (access refused) and raise a + channel exception. + </doc> + <doc name = "rule"> + The exchange MAY refuse stream content in which case it MUST + respond with a reply code 540 (not implemented) and raise a + channel exception. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_stream_00"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_stream_00"> + The server SHOULD implement the immediate flag. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "50"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <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"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" content = "1" index = "60"> + notify the client of a consumer message + <doc> + This method delivers a message to the client, via a consumer. In + the asynchronous message delivery model, the client starts a + consumer using the Consume method, then the server responds with + Deliver methods as and when messages arrive for that consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was originally + published to. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue that the message came from. Note + that a single channel can start many consumers on different + queues. + </doc> + <assert check = "notnull" /> + </field> +</method> + </class> + + <class name="tx" handler="channel" index="90"> + <!-- +====================================================== +== TRANSACTIONS +====================================================== +--> + work with standard transactions + +<doc> + Standard transactions provide so-called "1.5 phase commit". We can + ensure that work is never lost, but there is a chance of confirmations + being lost, so that messages may be resent. Applications that use + standard transactions must be able to detect and ignore duplicate + messages. +</doc> + <rule implement="SHOULD"> + An client using standard transactions SHOULD be able to track all + messages received within a reasonable period, and thus detect and + reject duplicates of the same message. It SHOULD NOT pass these to + the application layer. +</rule> + <doc name="grammar"> + tx = C:SELECT S:SELECT-OK + / C:COMMIT S:COMMIT-OK + / C:ROLLBACK S:ROLLBACK-OK +</doc> + <chassis name="server" implement="SHOULD"/> + <chassis name="client" implement="MAY"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="select" synchronous="1" index="10"> +select standard transaction mode + <doc> + This method sets the channel to use standard transactions. The + client must use this method at least once on a channel before + using the Commit or Rollback methods. + </doc> + <chassis name="server" implement="MUST"/> + <response name="select-ok"/> + </method> + <method name="select-ok" synchronous="1" index="11"> +confirm transaction mode + <doc> + This method confirms to the client that the channel was successfully + set to use standard transactions. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="commit" synchronous="1" index="20"> +commit the current transaction + <doc> + This method commits all messages published and acknowledged in + the current transaction. A new transaction starts immediately + after a commit. + </doc> + <chassis name="server" implement="MUST"/> + <response name="commit-ok"/> + </method> + <method name="commit-ok" synchronous="1" index="21"> +confirm a successful commit + <doc> + This method confirms to the client that the commit succeeded. + Note that if a commit fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="rollback" synchronous="1" index="30"> +abandon the current transaction + <doc> + This method abandons all messages published and acknowledged in + the current transaction. A new transaction starts immediately + after a rollback. + </doc> + <chassis name="server" implement="MUST"/> + <response name="rollback-ok"/> + </method> + <method name="rollback-ok" synchronous="1" index="31"> +confirm a successful rollback + <doc> + This method confirms to the client that the rollback succeeded. + Note that if an rollback fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="dtx" handler="channel" index="100"> + <!-- +====================================================== +== DISTRIBUTED TRANSACTIONS +====================================================== +--> + work with distributed transactions + +<doc> + Distributed transactions provide so-called "2-phase commit". The + AMQP distributed transaction model supports the X-Open XA + architecture and other distributed transaction implementations. + The Dtx class assumes that the server has a private communications + channel (not AMQP) to a distributed transaction coordinator. +</doc> + <doc name="grammar"> + dtx = C:SELECT S:SELECT-OK + C:START S:START-OK +</doc> + <chassis name="server" implement="MAY"/> + <chassis name="client" implement="MAY"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="select" synchronous="1" index="10"> +select standard transaction mode + <doc> + This method sets the channel to use distributed transactions. The + client must use this method at least once on a channel before + using the Start method. + </doc> + <chassis name="server" implement="MUST"/> + <response name="select-ok"/> + </method> + <method name="select-ok" synchronous="1" index="11"> +confirm transaction mode + <doc> + This method confirms to the client that the channel was successfully + set to use distributed transactions. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="start" synchronous="1" index="20"> + start a new distributed transaction + <doc> + This method starts a new distributed transaction. This must be + the first method on a new channel that uses the distributed + transaction mode, before any methods that publish or consume + messages. + </doc> + <chassis name="server" implement="MAY"/> + <response name="start-ok"/> + <field name="dtx identifier" type="shortstr"> + transaction identifier + <doc> + The distributed transaction key. This identifies the transaction + so that the AMQP server can coordinate with the distributed + transaction coordinator. + </doc> + <assert check="notnull"/> + </field> + </method> + <method name="start-ok" synchronous="1" index="21"> + confirm the start of a new distributed transaction + <doc> + This method confirms to the client that the transaction started. + Note that if a start fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="tunnel" handler="tunnel" index="110"> + <!-- +====================================================== +== TUNNEL +====================================================== +--> + methods for protocol tunneling. + +<doc> + The tunnel methods are used to send blocks of binary data - which + can be serialised AMQP methods or other protocol frames - between + AMQP peers. +</doc> + <doc name="grammar"> + tunnel = C:REQUEST + / S:REQUEST +</doc> + <chassis name="server" implement="MAY"/> + <chassis name="client" implement="MAY"/> + <field name="headers" type="table"> + Message header field table +</field> + <field name="proxy name" type="shortstr"> + The identity of the tunnelling proxy +</field> + <field name="data name" type="shortstr"> + The name or type of the message being tunnelled +</field> + <field name="durable" type="octet"> + The message durability indicator +</field> + <field name="broadcast" type="octet"> + The message broadcast mode +</field> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="request" content="1" index="10"> + sends a tunnelled method + <doc> + This method tunnels a block of binary data, which can be an + encoded AMQP method or other data. The binary data is sent + as the content for the Tunnel.Request method. + </doc> + <chassis name="server" implement="MUST"/> + <field name="meta data" type="table"> + meta data for the tunnelled block + <doc> + This field table holds arbitrary meta-data that the sender needs + to pass to the recipient. + </doc> + </field> + </method> + </class> + <class name="test" handler="channel" index="120"> + <!-- +====================================================== +== TEST - CHECK FUNCTIONAL CAPABILITIES OF AN IMPLEMENTATION +====================================================== +--> + test functional primitives of the implementation + +<doc> + The test class provides methods for a peer to test the basic + operational correctness of another peer. The test methods are + intended to ensure that all peers respect at least the basic + elements of the protocol, such as frame and content organisation + and field types. We assume that a specially-designed peer, a + "monitor client" would perform such tests. +</doc> + <doc name="grammar"> + test = C:INTEGER S:INTEGER-OK + / S:INTEGER C:INTEGER-OK + / C:STRING S:STRING-OK + / S:STRING C:STRING-OK + / C:TABLE S:TABLE-OK + / S:TABLE C:TABLE-OK + / C:CONTENT S:CONTENT-OK + / S:CONTENT C:CONTENT-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="SHOULD"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="integer" synchronous="1" index="10"> + test integer handling + <doc> + This method tests the peer's capability to correctly marshal integer + data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="integer-ok"/> + <field name="integer 1" type="octet"> + octet test value + <doc> + An octet integer test value. + </doc> + </field> + <field name="integer 2" type="short"> + short test value + <doc> + A short integer test value. + </doc> + </field> + <field name="integer 3" type="long"> + long test value + <doc> + A long integer test value. + </doc> + </field> + <field name="integer 4" type="longlong"> + long-long test value + <doc> + A long long integer test value. + </doc> + </field> + <field name="operation" type="octet"> + operation to test + <doc> + The client must execute this operation on the provided integer + test fields and return the result. + </doc> + <assert check="enum"> + <value name="add">return sum of test values</value> + <value name="min">return lowest of test values</value> + <value name="max">return highest of test values</value> + </assert> + </field> + </method> + <method name="integer-ok" synchronous="1" index="11"> + report integer test result + <doc> + This method reports the result of an Integer method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="result" type="longlong"> + result value + <doc> + The result of the tested operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="string" synchronous="1" index="20"> + test string handling + <doc> + This method tests the peer's capability to correctly marshal string + data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="string-ok"/> + <field name="string 1" type="shortstr"> + short string test value + <doc> + An short string test value. + </doc> + </field> + <field name="string 2" type="longstr"> + long string test value + <doc> + A long string test value. + </doc> + </field> + <field name="operation" type="octet"> + operation to test + <doc> + The client must execute this operation on the provided string + test fields and return the result. + </doc> + <assert check="enum"> + <value name="add">return concatentation of test strings</value> + <value name="min">return shortest of test strings</value> + <value name="max">return longest of test strings</value> + </assert> + </field> + </method> + <method name="string-ok" synchronous="1" index="21"> + report string test result + <doc> + This method reports the result of a String method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="result" type="longstr"> + result value + <doc> + The result of the tested operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="table" synchronous="1" index="30"> + test field table handling + <doc> + This method tests the peer's capability to correctly marshal field + table data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="table-ok"/> + <field name="table" type="table"> + field table of test values + <doc> + A field table of test values. + </doc> + </field> + <field name="integer op" type="octet"> + operation to test on integers + <doc> + The client must execute this operation on the provided field + table integer values and return the result. + </doc> + <assert check="enum"> + <value name="add">return sum of numeric field values</value> + <value name="min">return min of numeric field values</value> + <value name="max">return max of numeric field values</value> + </assert> + </field> + <field name="string op" type="octet"> + operation to test on strings + <doc> + The client must execute this operation on the provided field + table string values and return the result. + </doc> + <assert check="enum"> + <value name="add">return concatenation of string field values</value> + <value name="min">return shortest of string field values</value> + <value name="max">return longest of string field values</value> + </assert> + </field> + </method> + <method name="table-ok" synchronous="1" index="31"> + report table test result + <doc> + This method reports the result of a Table method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="integer result" type="longlong"> + integer result value + <doc> + The result of the tested integer operation. + </doc> + </field> + <field name="string result" type="longstr"> + string result value + <doc> + The result of the tested string operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="content" synchronous="1" content="1" index="40"> + test content handling + <doc> + This method tests the peer's capability to correctly marshal content. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="content-ok"/> + </method> + <method name="content-ok" synchronous="1" content="1" index="41"> + report content test result + <doc> + This method reports the result of a Content method. It contains the + content checksum and echoes the original content as provided. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="content checksum" type="long"> + content hash + <doc> + The 32-bit checksum of the content, calculated by adding the + content into a 32-bit accumulator. + </doc> + </field> + </method> + </class> +</amqp>
Added: cpp/framing/amqp_framing.cpp =================================================================== --- cpp/framing/amqp_framing.cpp (rev 0) +++ cpp/framing/amqp_framing.cpp 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,111 @@ +#include "amqp_framing.h" + +AMQFrame::AMQFrame(){} + +AMQFrame::AMQFrame(u_int16_t _channel, AMQBody* _body) : channel(_channel), body(_body){} + +AMQFrame::~AMQFrame(){ + if(body != 0) delete body; +} + +AMQBody* AMQFrame::getBody(){ + return body; +} + +u_int16_t AMQFrame::getChannel(){ + return channel; +} + +void AMQFrame::encode(Buffer& buffer) +{ + buffer.putOctet(body->type()); + buffer.putShort(channel); + buffer.putLong(body->size()); + body->encode(buffer); + buffer.putOctet(0xCE); +} + +AMQMethodBody* createAMQMethodBody(Buffer& buffer){ + u_int16_t classId = buffer.getShort(); + u_int16_t methodId = buffer.getShort(); + return createAMQMethodBody(classId, methodId); +} + +void AMQFrame::decode(Buffer& buffer) +{ + u_int8_t type = buffer.getOctet(); + channel = buffer.getShort(); + u_int32_t size = buffer.getLong(); + switch(type) + { + case 1: + body = createAMQMethodBody(buffer); + break; + case 2: + body = new AMQHeaderBody(); + break; + case 3: + body = new AMQContentBody(); + break; + case 8: + body = new AMQHeartbeatBody(); + break; + default: + throw "Unknown body type"; + } + body->decode(buffer, size); +} + +std::ostream& operator<<(std::ostream& out, const AMQFrame& t){ + out << "Frame[channel=" << t.channel << "; "; + if(t.body == 0){ + out << "empty"; + }else if(t.body->type() == 1){ + (dynamic_cast<AMQMethodBody*>(t.body))->print(out); + }else if(t.body->type() == 2){ + out << "header"; + }else if(t.body->type() == 3){ + out << "content"; + }else{ + out << "unknown type, " << t.body->type(); + } + out << "]"; + return out; +} + +void AMQMethodBody::encode(Buffer& buffer){ + buffer.putShort(amqpClassId()); + buffer.putShort(amqpMethodId()); + encodeContent(buffer); +} + +void AMQMethodBody::decode(Buffer& buffer, u_int32_t size){ + decodeContent(buffer); +} + +u_int32_t AMQHeaderBody::size(){ + //TODO + return 0; +} +void AMQHeaderBody::encode(Buffer& buffer){ + //TODO +} +void AMQHeaderBody::decode(Buffer& buffer, u_int32_t size){ + //TODO +} + +u_int32_t AMQContentBody::size(){ + //TODO + return 0; +} +void AMQContentBody::encode(Buffer& buffer){ + //TODO +} +void AMQContentBody::decode(Buffer& buffer, u_int32_t size){ + //TODO +} + +std::ostream& operator<<(std::ostream& out, AMQMethodBody& m){ + m.print(out); + return out; +}
Added: cpp/framing/amqp_framing.h =================================================================== --- cpp/framing/amqp_framing.h (rev 0) +++ cpp/framing/amqp_framing.h 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,75 @@ +#include <iostream> +#include "amqp_protocol.h" +#include "buffer.h" + +class AMQBody +{ +public: + virtual u_int32_t size() = 0; + virtual u_int8_t type() = 0; + virtual void encode(Buffer& buffer) = 0; + virtual void decode(Buffer& buffer, u_int32_t size) = 0; +}; + +class AMQMethodBody : public AMQBody +{ +public: + inline u_int8_t type(){ return 1; } + inline u_int32_t size(){ return 4 + bodySize(); } + virtual void print(std::ostream& out) = 0; + virtual u_int16_t amqpMethodId() = 0; + virtual u_int16_t amqpClassId() = 0; + virtual void invoke(AMQP& target, AMQP& peer) = 0; + virtual void encodeContent(Buffer& buffer) = 0; + virtual void decodeContent(Buffer& buffer) = 0; + virtual u_int32_t bodySize() = 0; + void encode(Buffer& buffer); + void decode(Buffer& buffer, u_int32_t size); + friend std::ostream& operator<<(std::ostream& out, AMQMethodBody& body); +}; + +class AMQHeaderBody : public AMQBody +{ + +public: + u_int32_t size(); + inline u_int8_t type(){ return 2; } + void encode(Buffer& buffer); + void decode(Buffer& buffer, u_int32_t size); +}; + +class AMQContentBody : public AMQBody +{ +public: + u_int32_t size(); + inline u_int8_t type(){ return 3; }; + void encode(Buffer& buffer); + void decode(Buffer& buffer, u_int32_t size); +}; + +class AMQHeartbeatBody : public AMQBody +{ +public: + inline u_int32_t size() { return 0; } + inline u_int8_t type() { return 8; } + inline void encode(Buffer& buffer) {} + inline void decode(Buffer& buffer, u_int32_t size) {} +}; + +class AMQFrame +{ + u_int16_t channel; + AMQBody* body; + +public: + AMQFrame(); + AMQFrame(u_int16_t channel, AMQBody* body); + ~AMQFrame(); + void encode(Buffer& buffer); + void decode(Buffer& buffer); + u_int16_t getChannel(); + AMQBody* getBody(); + friend std::ostream& operator<<(std::ostream& out, const AMQFrame& body); +}; + +AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId);
Added: cpp/framing/amqp_methods.cpp.handwritten =================================================================== --- cpp/framing/amqp_methods.cpp.handwritten (rev 0) +++ cpp/framing/amqp_methods.cpp.handwritten 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,15 @@ +#include "amqp_framing.h" + +AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId){ + switch(classId << 2 + methodId) + { + case 1001: return new BasicPublish(); + } + return 0; +} + +std::ostream& operator<<(std::ostream& out, const BasicPublish& body){ + out<< "basic.publish: a=" << body.a << ", b=" << body.b; + return out; +} +
Added: cpp/framing/amqp_methods.h.handwritten =================================================================== --- cpp/framing/amqp_methods.h.handwritten (rev 0) +++ cpp/framing/amqp_methods.h.handwritten 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,42 @@ +class BasicPublish : public AMQMethodBody +{ + u_int16_t a; + u_int32_t b; + +public: + + inline BasicPublish(){ + } + + inline BasicPublish(u_int16_t _a, u_int32_t _b) : a(_a), b(_b){ + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.basic_publish(peer, a, b); + } + + inline void encode(Buffer& buffer){ + buffer.putShort(a); + buffer.putLong(b); + } + + inline void decode(Buffer& buffer, u_int32_t size){ + a = buffer.getShort(); + b = buffer.getLong(); + } + + inline u_int32_t size(){ + return 10; + } + + inline u_int16_t classId(){ + return 1; + } + + inline u_int16_t methodId(){ + return 1; + } + + friend std::ostream& operator<<(std::ostream& out, const BasicPublish& body); + +};
Added: cpp/framing/amqp_protocol.h =================================================================== --- cpp/framing/amqp_protocol.h (rev 0) +++ cpp/framing/amqp_protocol.h 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,190 @@ + +#include "sys/types.h" +#include "fieldtable.h" + +class AMQP +{ + public: + + + virtual void connection_start(AMQP& peer, u_int8_t versionMajor, u_int8_t versionMinor, FieldTable& serverProperties, std::string& mechanisms, std::string& locales) = 0; + + virtual void connection_start_ok(AMQP& peer, FieldTable& clientProperties, std::string& mechanism, std::string& response, std::string& locale) = 0; + + virtual void connection_secure(AMQP& peer, std::string& challenge) = 0; + + virtual void connection_secure_ok(AMQP& peer, std::string& response) = 0; + + virtual void connection_tune(AMQP& peer, u_int16_t channelMax, u_int32_t frameMax, u_int16_t heartbeat) = 0; + + virtual void connection_tune_ok(AMQP& peer, u_int16_t channelMax, u_int32_t frameMax, u_int16_t heartbeat) = 0; + + virtual void connection_open(AMQP& peer, std::string& virtualHost, std::string& capabilities, bool insist) = 0; + + virtual void connection_open_ok(AMQP& peer, std::string& knownHosts) = 0; + + virtual void connection_redirect(AMQP& peer, std::string& host, std::string& knownHosts) = 0; + + virtual void connection_close(AMQP& peer, u_int16_t replyCode, std::string& replyText, u_int16_t classId, u_int16_t methodId) = 0; + + virtual void connection_close_ok(AMQP& peer) = 0; + + virtual void channel_open(AMQP& peer, std::string& outOfBand) = 0; + + virtual void channel_open_ok(AMQP& peer) = 0; + + virtual void channel_flow(AMQP& peer, bool active) = 0; + + virtual void channel_flow_ok(AMQP& peer, bool active) = 0; + + virtual void channel_alert(AMQP& peer, u_int16_t replyCode, std::string& replyText, FieldTable& details) = 0; + + virtual void channel_close(AMQP& peer, u_int16_t replyCode, std::string& replyText, u_int16_t classId, u_int16_t methodId) = 0; + + virtual void channel_close_ok(AMQP& peer) = 0; + + virtual void access_request(AMQP& peer, std::string& realm, bool exclusive, bool passive, bool active, bool write, bool read) = 0; + + virtual void access_request_ok(AMQP& peer, u_int16_t ticket) = 0; + + virtual void exchange_declare(AMQP& peer, u_int16_t ticket, std::string& exchange, std::string& type, bool passive, bool durable, bool autoDelete, bool internal, bool nowait, FieldTable& arguments) = 0; + + virtual void exchange_declare_ok(AMQP& peer) = 0; + + virtual void exchange_delete(AMQP& peer, u_int16_t ticket, std::string& exchange, bool ifUnused, bool nowait) = 0; + + virtual void exchange_delete_ok(AMQP& peer) = 0; + + virtual void queue_declare(AMQP& peer, u_int16_t ticket, std::string& queue, bool passive, bool durable, bool exclusive, bool autoDelete, bool nowait, FieldTable& arguments) = 0; + + virtual void queue_declare_ok(AMQP& peer, std::string& queue, u_int32_t messageCount, u_int32_t consumerCount) = 0; + + virtual void queue_bind(AMQP& peer, u_int16_t ticket, std::string& queue, std::string& exchange, std::string& routingKey, bool nowait, FieldTable& arguments) = 0; + + virtual void queue_bind_ok(AMQP& peer) = 0; + + virtual void queue_purge(AMQP& peer, u_int16_t ticket, std::string& queue, bool nowait) = 0; + + virtual void queue_purge_ok(AMQP& peer, u_int32_t messageCount) = 0; + + virtual void queue_delete(AMQP& peer, u_int16_t ticket, std::string& queue, bool ifUnused, bool ifEmpty, bool nowait) = 0; + + virtual void queue_delete_ok(AMQP& peer, u_int32_t messageCount) = 0; + + virtual void basic_qos(AMQP& peer, u_int32_t prefetchSize, u_int16_t prefetchCount, bool global) = 0; + + virtual void basic_qos_ok(AMQP& peer) = 0; + + virtual void basic_consume(AMQP& peer, u_int16_t ticket, std::string& queue, std::string& consumerTag, bool noLocal, bool noAck, bool exclusive, bool nowait) = 0; + + virtual void basic_consume_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void basic_cancel(AMQP& peer, std::string& consumerTag, bool nowait) = 0; + + virtual void basic_cancel_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void basic_publish(AMQP& peer, u_int16_t ticket, std::string& exchange, std::string& routingKey, bool mandatory, bool immediate) = 0; + + virtual void basic_return(AMQP& peer, u_int16_t replyCode, std::string& replyText, std::string& exchange, std::string& routingKey) = 0; + + virtual void basic_deliver(AMQP& peer, std::string& consumerTag, u_int64_t deliveryTag, bool redelivered, std::string& exchange, std::string& routingKey) = 0; + + virtual void basic_get(AMQP& peer, u_int16_t ticket, std::string& queue, bool noAck) = 0; + + virtual void basic_get_ok(AMQP& peer, u_int64_t deliveryTag, bool redelivered, std::string& exchange, std::string& routingKey, u_int32_t messageCount) = 0; + + virtual void basic_get_empty(AMQP& peer, std::string& clusterId) = 0; + + virtual void basic_ack(AMQP& peer, u_int64_t deliveryTag, bool multiple) = 0; + + virtual void basic_reject(AMQP& peer, u_int64_t deliveryTag, bool requeue) = 0; + + virtual void basic_recover(AMQP& peer, bool requeue) = 0; + + virtual void file_qos(AMQP& peer, u_int32_t prefetchSize, u_int16_t prefetchCount, bool global) = 0; + + virtual void file_qos_ok(AMQP& peer) = 0; + + virtual void file_consume(AMQP& peer, u_int16_t ticket, std::string& queue, std::string& consumerTag, bool noLocal, bool noAck, bool exclusive, bool nowait) = 0; + + virtual void file_consume_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void file_cancel(AMQP& peer, std::string& consumerTag, bool nowait) = 0; + + virtual void file_cancel_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void file_open(AMQP& peer, std::string& identifier, u_int64_t contentSize) = 0; + + virtual void file_open_ok(AMQP& peer, u_int64_t stagedSize) = 0; + + virtual void file_stage(AMQP& peer) = 0; + + virtual void file_publish(AMQP& peer, u_int16_t ticket, std::string& exchange, std::string& routingKey, bool mandatory, bool immediate, std::string& identifier) = 0; + + virtual void file_return(AMQP& peer, u_int16_t replyCode, std::string& replyText, std::string& exchange, std::string& routingKey) = 0; + + virtual void file_deliver(AMQP& peer, std::string& consumerTag, u_int64_t deliveryTag, bool redelivered, std::string& exchange, std::string& routingKey, std::string& identifier) = 0; + + virtual void file_ack(AMQP& peer, u_int64_t deliveryTag, bool multiple) = 0; + + virtual void file_reject(AMQP& peer, u_int64_t deliveryTag, bool requeue) = 0; + + virtual void stream_qos(AMQP& peer, u_int32_t prefetchSize, u_int16_t prefetchCount, u_int32_t consumeRate, bool global) = 0; + + virtual void stream_qos_ok(AMQP& peer) = 0; + + virtual void stream_consume(AMQP& peer, u_int16_t ticket, std::string& queue, std::string& consumerTag, bool noLocal, bool exclusive, bool nowait) = 0; + + virtual void stream_consume_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void stream_cancel(AMQP& peer, std::string& consumerTag, bool nowait) = 0; + + virtual void stream_cancel_ok(AMQP& peer, std::string& consumerTag) = 0; + + virtual void stream_publish(AMQP& peer, u_int16_t ticket, std::string& exchange, std::string& routingKey, bool mandatory, bool immediate) = 0; + + virtual void stream_return(AMQP& peer, u_int16_t replyCode, std::string& replyText, std::string& exchange, std::string& routingKey) = 0; + + virtual void stream_deliver(AMQP& peer, std::string& consumerTag, u_int64_t deliveryTag, std::string& exchange, std::string& queue) = 0; + + virtual void tx_select(AMQP& peer) = 0; + + virtual void tx_select_ok(AMQP& peer) = 0; + + virtual void tx_commit(AMQP& peer) = 0; + + virtual void tx_commit_ok(AMQP& peer) = 0; + + virtual void tx_rollback(AMQP& peer) = 0; + + virtual void tx_rollback_ok(AMQP& peer) = 0; + + virtual void dtx_select(AMQP& peer) = 0; + + virtual void dtx_select_ok(AMQP& peer) = 0; + + virtual void dtx_start(AMQP& peer, std::string& dtxIdentifier) = 0; + + virtual void dtx_start_ok(AMQP& peer) = 0; + + virtual void tunnel_request(AMQP& peer, FieldTable& metaData) = 0; + + virtual void test_integer(AMQP& peer, u_int8_t integer1, u_int16_t integer2, u_int32_t integer3, u_int64_t integer4, u_int8_t operation) = 0; + + virtual void test_integer_ok(AMQP& peer, u_int64_t result) = 0; + + virtual void test_string(AMQP& peer, std::string& string1, std::string& string2, u_int8_t operation) = 0; + + virtual void test_string_ok(AMQP& peer, std::string& result) = 0; + + virtual void test_table(AMQP& peer, FieldTable& table, u_int8_t integerOp, u_int8_t stringOp) = 0; + + virtual void test_table_ok(AMQP& peer, u_int64_t integerResult, std::string& stringResult) = 0; + + virtual void test_content(AMQP& peer) = 0; + + virtual void test_content_ok(AMQP& peer, u_int32_t contentChecksum) = 0; + + +}; +
Added: cpp/framing/amqp_protocol.h.handwritten =================================================================== --- cpp/framing/amqp_protocol.h.handwritten (rev 0) +++ cpp/framing/amqp_protocol.h.handwritten 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,9 @@ +#import "sys/types.h" + +class AMQP +{ + public: + + virtual void basic_publish(AMQP& peer, u_int16_t a, u_int32_t b) = 0; + +};
Added: cpp/framing/buffer.cpp =================================================================== --- cpp/framing/buffer.cpp (rev 0) +++ cpp/framing/buffer.cpp 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,114 @@ +#include "buffer.h" +#include "string.h" +#include "netinet/in.h" +#include <iostream> +#include "stdio.h" + +Buffer::Buffer(char *const _data, int _size) : data(_data), size(_size){ + position = 0; + limit = size; + reading = false; +} + +void Buffer::flip(){ + reading = !reading; + limit = position; + position = 0; +} + +void Buffer::putOctet(u_int8_t i){ + data[position++] = i; +} + +void Buffer::putShort(u_int16_t i){ + u_int16_t b = htons(i);//ensure value is bigendian + data[position++] = (u_int8_t) (0xFF & (b >> 8)); + data[position++] = (u_int8_t) (0xFF & b); +} + +void Buffer::putLong(u_int32_t i){ + u_int32_t b = htonl(i);//ensure value is bigendian + data[position++] = (u_int8_t) (0xFF & (b >> 24)); + data[position++] = (u_int8_t) (0xFF & (b >> 16)); + data[position++] = (u_int8_t) (0xFF & (b >> 8)); + data[position++] = (u_int8_t) (0xFF & b); +} + +void Buffer::putLongLong(u_int64_t i){ + u_int32_t hi = i >> 32; + u_int32_t lo = i; + //need to know whether this is in little or bigendian order + //putLong(hi);//bigendian + //putLong(lo); + + putLong(lo);//littleendian + putLong(hi); +} + +u_int8_t Buffer::getOctet(){ + return (u_int8_t) data[position++]; +} + +u_int16_t Buffer::getShort(){ + u_int16_t hi = (unsigned char) data[position++]; + hi = hi << 8; + hi |= (unsigned char) data[position++]; + return ntohs(hi); +} + +u_int32_t Buffer::getLong(){ + u_int32_t a = (unsigned char) data[position++]; + u_int32_t b = (unsigned char) data[position++]; + u_int32_t c = (unsigned char) data[position++]; + u_int32_t d = (unsigned char) data[position++]; + a = a << 24; + a |= b << 16; + a |= c << 8; + a |= d; + return ntohl(a); +} + +u_int64_t Buffer::getLongLong(){ + u_int64_t hi = getLong(); + u_int64_t lo = getLong(); + //need to know whether we should return as big- or little- endian + //hi = hi << 32; + //return hi & lo;//bigendian + lo = lo << 32; + return lo & hi;//littleendian +} + + +void Buffer::putShortString(std::string& s){ + u_int8_t size = s.length(); + putOctet(size); + s.copy(data + position, size); + position += size; +} + +void Buffer::putLongString(std::string& s){ + u_int32_t size = s.length(); + putLong(size); + s.copy(data + position, size); + position += size; +} + +void Buffer::getShortString(std::string& s){ + u_int8_t size = getOctet(); + s.assign(data + position, size); + position += size; +} + +void Buffer::getLongString(std::string& s){ + u_int32_t size = getLong(); + s.assign(data + position, size); + position += size; +} + +void Buffer::putFieldTable(FieldTable& t){ + +} + +void Buffer::getFieldTable(FieldTable& t){ + +}
Added: cpp/framing/buffer.h =================================================================== --- cpp/framing/buffer.h (rev 0) +++ cpp/framing/buffer.h 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,36 @@ +#include "fieldtable.h" +#include "sys/types.h" +#include <string> + +class Buffer +{ + char *const data; + const int size; + int position; + int limit; + bool reading; + +public: + + Buffer(char *const data, int size); + + void flip(); + + void putOctet(u_int8_t i); + void putShort(u_int16_t i); + void putLong(u_int32_t i); + void putLongLong(u_int64_t i); + + u_int8_t getOctet(); + u_int16_t getShort(); + u_int32_t getLong(); + u_int64_t getLongLong(); + + void putShortString(std::string& s); + void putLongString(std::string& s); + void getShortString(std::string& s); + void getLongString(std::string& s); + + void putFieldTable(FieldTable& t); + void getFieldTable(FieldTable& t); +};
Added: cpp/framing/cpp.xsl =================================================================== --- cpp/framing/cpp.xsl (rev 0) +++ cpp/framing/cpp.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,182 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<!-- this class contains the templates for generating C++ source code for a given framing model --> + +<xsl:import href="utils.xsl"/> +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="generate-single" select="frames"/> + <xsl:apply-templates mode="generate-registry" select="frames"/> +</xsl:template> + +<!-- processes all frames outputting the classes in a single stream --> +<xsl:template match="frames" mode="generate-single"> + <xsl:result-document href="amqp_methods.h" format="textFormat"> +#include "amqp_framing.h" + <xsl:for-each select="frame"> + <xsl:call-template name="generate-class"> + <xsl:with-param name="f" select="."/> + </xsl:call-template> + </xsl:for-each> + </xsl:result-document> +</xsl:template> + + +<!-- main class generation template --> +<xsl:template name="generate-class"> + <xsl:param name="f"/> +/** + * This class is autogenerated, do not modify. [From <xsl:value-of select="$f/parent::frames/@protocol"/>] + */ +class <xsl:value-of select="$f/@name"/> : public AMQMethodBody +{ + <xsl:for-each select="$f/field"> + <xsl:value-of select="@cpp-type"/> + xsl:text </xsl:text> + <xsl:value-of select="@name"/>; + </xsl:for-each> + +public: + + inline void print(std::ostream& out){ + std::cout << "<xsl:value-of select="$f/@invocation_name"/>" + <xsl:for-each select="$f/field"> + xsl:text << ", </xsl:text> + <xsl:value-of select="@name"/>="<< + <xsl:value-of select="@name"/> + </xsl:for-each> + ; + } + + inline u_int16_t amqpClassId(){ + return <xsl:value-of select="$f/@class-id"/>; + } + + inline u_int16_t amqpMethodId(){ + return <xsl:value-of select="$f/@method-id"/>; + } + + inline u_int32_t bodySize(){ + xsl:choose + <xsl:when test="$f/field"> + return + <xsl:for-each select="$f/field"> + <xsl:if test="position() != 1">+ + </xsl:if> + <xsl:value-of select="amq:field-length(.)"/> + </xsl:for-each> + ; + </xsl:when> + xsl:otherwisereturn 0;</xsl:otherwise> + </xsl:choose> + } + + inline void invoke(AMQP& target, AMQP& peer){ + <xsl:if test="field"> + <xsl:value-of select="concat('target.', $f/@invocation_name, '(peer, ')"/> + <xsl:value-of select="$f/field/@name" separator=", "/>); + </xsl:if> + <xsl:if test="not(field)"> + <xsl:value-of select="concat('target.', $f/@invocation_name, '(peer)')"/>; + </xsl:if> + } + + inline void encodeContent(Buffer& buffer) + { + <xsl:if test="$f/field[@type='bit']"> + u_int8_t flags = 0; + <xsl:for-each select="$f/field[@type='bit']"> + <xsl:value-of select="concat('flags |= ', @name,' << (8 - ', @boolean-index)"/>); + </xsl:for-each> + </xsl:if> + <xsl:for-each select="$f/field"> + <xsl:if test="@type != 'bit'"> + <xsl:value-of select="amq:encoder(.)"/>; + </xsl:if> + <xsl:if test="@type = 'bit' and @boolean-index = 1"> + xsl:textbuffer.putOctet(flags)</xsl:text>; + </xsl:if> + </xsl:for-each> + } + + inline void decodeContent(Buffer& buffer) + { + <xsl:if test="$f/field[@type='bit']"> + </xsl:if> + <xsl:for-each select="$f/field"> + xsl:choose + <xsl:when test="@type = 'bit' and @boolean-index = 1"> + xsl:textu_int8_t flags = buffer.getOctet()</xsl:text>; + <xsl:value-of select="amq:decoder(.)"/>; + </xsl:when> + xsl:otherwise + <xsl:value-of select="amq:decoder(.)"/>; + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + } + + <xsl:if test="$f/field"> + <!-- only generate overloaded constructor if there are fields in this method --> + inline <xsl:value-of select="$f/@name"/>(<xsl:value-of select="$f/field/concat(@cpp-arg-type, ' _', @name)" separator=", "/>) : <xsl:value-of select="$f/field/concat(@name, '(_', @name, ')')" separator=", "/> + { + } + </xsl:if> + + inline <xsl:value-of select="$f/@name"/>() + { + } +}; +</xsl:template> + +<xsl:template match="frames" mode="list-registry"> + <xsl:result-document href="amqp_methods.cpp" format="textFormat"> +#include "amqp_methods.h" + +/** + * This method is autogenerated, do not modify. + */ +AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId){ + switch(classId * 1000 + methodId) + { + <xsl:for-each select="frame"> + xsl:textcase </xsl:text> + <xsl:value-of select="@class-id"/> + xsl:text * 1000 + </xsl:text> + <xsl:value-of select="@method-id"/> + xsl:text: return new </xsl:text> + <xsl:value-of select="@name"/>(); + </xsl:for-each> + } + return 0; +} + +</xsl:result-document> +</xsl:template> + +<xsl:template match="frames" mode="generate-interface"> + <xsl:result-document href="amqp_protocol.h" format="textFormat"> +#include "sys/types.h" +#include "fieldtable.h" + +class AMQP +{ + public: + + <xsl:for-each select="frame"> + <xsl:if test="field"> + virtual void <xsl:value-of select="@invocation_name"/>(AMQP& peer, <xsl:value-of select="field/concat(@cpp-arg-type, ' ', @name)" separator=", "/>) = 0; + </xsl:if> + <xsl:if test="not(field)"> + virtual void <xsl:value-of select="@invocation_name"/>(AMQP& peer) = 0; + </xsl:if> + </xsl:for-each> + +}; + +</xsl:result-document> +</xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/fieldtable.cpp =================================================================== --- cpp/framing/fieldtable.cpp (rev 0) +++ cpp/framing/fieldtable.cpp 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,10 @@ +#import "fieldtable.h" + +u_int32_t FieldTable::size(){ + return 0; +} + +std::ostream& operator<<(std::ostream& out, const FieldTable& t){ + out << "field_table{}"; + return out; +}
Added: cpp/framing/fieldtable.h =================================================================== --- cpp/framing/fieldtable.h (rev 0) +++ cpp/framing/fieldtable.h 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,12 @@ +#include "sys/types.h" +#include <iostream> + +#ifndef AMQP_FIELD_TABLE +#define AMQP_FIELD_TABLE +class FieldTable +{ +public: + u_int32_t size(); + friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); +}; +#endif
Added: cpp/framing/framing.xsl =================================================================== --- cpp/framing/framing.xsl (rev 0) +++ cpp/framing/framing.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,45 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<xsl:import href="prepare1.xsl"/> +<xsl:import href="prepare2.xsl"/> +<xsl:import href="prepare3.xsl"/> +<xsl:import href="cpp.xsl"/> + +<xsl:output indent="yes"/> +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:template match="/"> + <xsl:variable name="prepare1"> + <xsl:apply-templates mode="prepare1" select="."/> + </xsl:variable> + + <xsl:variable name="prepare2"> + <xsl:apply-templates mode="prepare2" select="$prepare1"/> + </xsl:variable> + + <xsl:variable name="model"> + <xsl:apply-templates mode="prepare3" select="$prepare2"/> + </xsl:variable> + + <xsl:apply-templates mode="generate-single" select="$model"/> + <xsl:apply-templates mode="list-registry" select="$model"/> + <xsl:apply-templates mode="generate-interface" select="$model"/> + + <!-- dump out the intermediary files for debugging --> + <!-- + <xsl:result-document href="prepare1.out"> + <xsl:copy-of select="$prepare1"/> + </xsl:result-document> + + <xsl:result-document href="prepare2.out"> + <xsl:copy-of select="$prepare2"/> + </xsl:result-document> + + <xsl:result-document href="model.out"> + <xsl:copy-of select="$model"/> + </xsl:result-document> + --> +</xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/framing_test.cpp =================================================================== --- cpp/framing/framing_test.cpp (rev 0) +++ cpp/framing/framing_test.cpp 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,71 @@ +#include <iostream> +#include "stdio.h" +#include "amqp_methods.h" +#include "netinet/in.h" + +int main(char** argv, int argc) +{ + char data[100]; + for(int i = 0; i < 100; i++){ + data[i] = 0; + } + Buffer buffer(data, 100); + + { + BasicQosBody in(0xCAFEBABE, 0xABBA, true); + in.encodeContent(buffer); + std::cout << "Encoded " << in << "\n"; + buffer.flip(); + BasicQosBody out; + out.decodeContent(buffer); + std::cout << "Decoded " << out << "\n"; + } + buffer.flip(); + { + std::string s = "security credential"; + ConnectionSecureBody in(s); + in.encodeContent(buffer); + std::cout << "Encoded " << in << "\n"; + buffer.flip(); + ConnectionSecureBody out; + out.decodeContent(buffer); + std::cout << "Decoded " << out << "\n"; + } + buffer.flip(); + { + std::string a = "hostA"; + std::string b = "hostB"; + ConnectionRedirectBody in(a, b); + in.encodeContent(buffer); + std::cout << "Encoded " << in << "\n"; + buffer.flip(); + ConnectionRedirectBody out; + out.decodeContent(buffer); + std::cout << "Decoded " << out << "\n"; + } + buffer.flip(); + { + std::string s = "text"; + AccessRequestBody in(s, true, false, true, false, true); + in.encodeContent(buffer); + std::cout << "Encoded " << in << "\n"; + buffer.flip(); + AccessRequestBody out; + out.decodeContent(buffer); + std::cout << "Decoded " << out << "\n"; + } + + buffer.flip(); + { + std::string a = "hostA"; + std::string b = "hostB"; + AMQFrame in(999, new ConnectionRedirectBody(a, b)); + in.encode(buffer); + std::cout << "Encoded " << in << "\n"; + buffer.flip(); + AMQFrame out; + out.decode(buffer); + std::cout << "Decoded " << out << "\n"; + } + return 1; +}
Added: cpp/framing/prepare1.xsl =================================================================== --- cpp/framing/prepare1.xsl (rev 0) +++ cpp/framing/prepare1.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,90 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> +<xsl:param name="asl_base"/> + +<!-- pre-process, phase 1 --> + +<xsl:template match="/"> + <xsl:apply-templates select="protocol" mode="prepare1"/> +</xsl:template> + +<xsl:template match="amqp" mode="prepare1"> + <frames> + <xsl:attribute name="protocol"> + <xsl:value-of select="@comment"/> + xsl:text (</xsl:text> + xsl:textmajor=</xsl:text><xsl:value-of select="option[@name='protocol_major']/@value"/> + xsl:text, minor=</xsl:text><xsl:value-of select="option[@name='protocol_minor']/@value"/> + xsl:text)</xsl:text> + </xsl:attribute> + <xsl:apply-templates mode="prepare1" select="inherit"/> + <xsl:apply-templates mode="prepare1" select="include"/> + <xsl:apply-templates mode="prepare1" select="domain"/> + <xsl:apply-templates mode="prepare1" select="class"/> + </frames> +</xsl:template> + +<xsl:template match="include" mode="prepare1"> + <xsl:if test="@filename != 'asl_constants.asl'"> + <!-- skip asl_constants.asl, we don't need it and it is not well formed so causes error warnings --> + <xsl:apply-templates select="document(@filename)" mode="prepare1"/> + </xsl:if> +</xsl:template> + +<xsl:template match="inherit" mode="prepare1"> + <xsl:variable name="ibase" select="concat('file:///', $asl_base, '/', @name, '.asl')"/> + xsl:choose + <xsl:when test="document($ibase)"> + <xsl:apply-templates select="document($ibase)" mode="prepare1"/> + </xsl:when> + xsl:otherwise + xsl:message + Could not inherit from <xsl:value-of select="$ibase"/>; file not found. + </xsl:message> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<xsl:template match="class[@index]" mode="prepare1"> + <xsl:apply-templates select="method" mode="prepare1"/> +</xsl:template> + +<xsl:template match="method" mode="prepare1"> + <xsl:if test="parent::class[@index]"><!-- there is a template class that has no index, which we want to skip --> + <frame> + <xsl:attribute name="name"><xsl:value-of select="amq:class-name(parent::class/@name, @name)"/></xsl:attribute> + <xsl:attribute name="class-id"><xsl:value-of select="parent::class/@index"/></xsl:attribute> + <xsl:if test="@index"> + <xsl:attribute name="method-id"><xsl:value-of select="@index"/></xsl:attribute> + </xsl:if> + <xsl:if test="not(@index)"> + <xsl:attribute name="method-id"><xsl:number count="method"/></xsl:attribute> + </xsl:if> + <xsl:attribute name="invocation_name"> + <xsl:value-of select="amq:method-name(parent::class/@name, @name)"/> + </xsl:attribute> + <xsl:apply-templates select="field" mode="prepare1"/> + </frame> + </xsl:if> +</xsl:template> + +<xsl:template match="domain" mode="prepare1"> + <domain> + <name><xsl:value-of select="@name"/></name> + <type><xsl:value-of select="@type"/></type> + </domain> +</xsl:template> + +<xsl:template match="field" mode="prepare1"> + <field> + <xsl:copy-of select="@name"/> + <xsl:copy-of select="@type"/> + <xsl:copy-of select="@domain"/> + </field> +</xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/prepare2.xsl =================================================================== --- cpp/framing/prepare2.xsl (rev 0) +++ cpp/framing/prepare2.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,47 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> + +<!-- pre-process, phase 2 --> + +<xsl:key name="domain-lookup" match="domain" use="name"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="prepare2" select="frames"/> +</xsl:template> + +<xsl:template match="field[@domain]" mode="prepare2"> + <field> + <xsl:variable name="t1" select="key('domain-lookup', @domain)/type"/> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <xsl:attribute name="type"><xsl:value-of select="$t1"/></xsl:attribute> + </field> +</xsl:template> + +<xsl:template match="field[@type]" mode="prepare2"> + <field> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute> + </field> +</xsl:template> + +<xsl:template match="frames" mode="prepare2"> + <frames> + <xsl:copy-of select="@protocol"/> + <xsl:apply-templates mode="prepare2"/> + </frames> +</xsl:template> + +<xsl:template match="frame" mode="prepare2"> + <xsl:element name="{name()}"> + <xsl:copy-of select="@*"/> + <xsl:apply-templates mode="prepare2" select="field"/> + </xsl:element> +</xsl:template> + +<xsl:template match="domain" mode="prepare2"></xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/prepare3.xsl =================================================================== --- cpp/framing/prepare3.xsl (rev 0) +++ cpp/framing/prepare3.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,44 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> + +<!-- final preparation of the model --> + +<xsl:template match="/"> + <xsl:apply-templates mode="prepare3"/> +</xsl:template> + +<xsl:template match="frames" mode="prepare3"> + <frames> + <xsl:copy-of select="@protocol"/> + <xsl:apply-templates mode="prepare3"/> + </frames> +</xsl:template> + +<xsl:template match="frame" mode="prepare3"> + <xsl:element name="frame"> + <xsl:copy-of select="@*"/> + <xsl:if test="field[@type='bit']"><xsl:attribute name="has-bit-field">true</xsl:attribute></xsl:if> + <xsl:apply-templates mode="prepare3"/> + </xsl:element> +</xsl:template> + + +<xsl:template match="field" mode="prepare3"> + <field> + <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute> + <!-- ensure the field name is processed to be a valid java name --> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <!-- add some attributes to make code generation easier --> + <xsl:attribute name="cpp-type"><xsl:value-of select="amq:cpp-type(@type)"/></xsl:attribute> + <xsl:attribute name="cpp-arg-type"><xsl:value-of select="amq:cpp-arg-type(@type)"/></xsl:attribute> + <xsl:if test="@type='bit'"> + <xsl:attribute name="boolean-index"><xsl:number count="field[@type='bit']"/></xsl:attribute> + </xsl:if> + </field> +</xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/registry.xsl =================================================================== --- cpp/framing/registry.xsl (rev 0) +++ cpp/framing/registry.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,12 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<xsl:import href="java.xsl"/> + +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="generate-registry" select="registries"/> +</xsl:template> + +</xsl:stylesheet>
Added: cpp/framing/saxon8.jar =================================================================== (Binary files differ)
Property changes on: cpp/framing/saxon8.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream
Added: cpp/framing/test.out =================================================================== --- cpp/framing/test.out (rev 0) +++ cpp/framing/test.out 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,4929 @@ +<?xml version="1.0" encoding="UTF-8"?> +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionStartBody : public AMQMethodBody +{ + u_int8_t versionMajor; + u_int8_t versionMinor; + FieldTable serverProperties; + string mechanisms; + string locales; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 1 /*versionMajor*/+ + 1 /*versionMinor*/+ + EncodingUtils.encodedFieldTableLength(serverProperties)+ + 4 + (mechanisms == null ? 0 : mechanisms.length)+ + 4 + (locales == null ? 0 : locales.length) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionStartBody(peer, versionMajor, versionMinor, serverProperties, mechanisms, locales); + } + + inline void encode(Buffer& buffer) + { + buffer.putOctet(versionMajor); + buffer.putOctet(versionMinor); + buffer.putFieldTable(serverProperties); + buffer.putLongString(mechanisms); + buffer.putLongString(locales); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + versionMajor = buffer.getOctet(); + versionMinor = buffer.getOctet(); + serverProperties = buffer.getFieldTable(); + mechanisms = buffer.getLongString(); + locales = buffer.getLongString(); + + } + + inline ConnectionStartBody(u_int8_t _versionMajor, u_int8_t _versionMinor, FieldTable _serverProperties, string _mechanisms, string _locales) : versionMajor(_versionMajor), versionMinor(_versionMinor), serverProperties(_serverProperties), mechanisms(_mechanisms), locales(_locales) + { + } + + inline ConnectionStartBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionStartOkBody : public AMQMethodBody +{ + FieldTable clientProperties; + string mechanism; + string response; + string locale; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedFieldTableLength(clientProperties)+ + EncodingUtils.encodedShortStringLength(mechanism)+ + 4 + (response == null ? 0 : response.length)+ + EncodingUtils.encodedShortStringLength(locale) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionStartOkBody(peer, clientProperties, mechanism, response, locale); + } + + inline void encode(Buffer& buffer) + { + buffer.putFieldTable(clientProperties); + buffer.putShortString(mechanism); + buffer.putLongString(response); + buffer.putShortString(locale); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + clientProperties = buffer.getFieldTable(); + mechanism = buffer.getShortString(); + response = buffer.getLongString(); + locale = buffer.getShortString(); + + } + + inline ConnectionStartOkBody(FieldTable _clientProperties, string _mechanism, string _response, string _locale) : clientProperties(_clientProperties), mechanism(_mechanism), response(_response), locale(_locale) + { + } + + inline ConnectionStartOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionSecureBody : public AMQMethodBody +{ + string challenge; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 4 + (challenge == null ? 0 : challenge.length) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionSecureBody(peer, challenge); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongString(challenge); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + challenge = buffer.getLongString(); + + } + + inline ConnectionSecureBody(string _challenge) : challenge(_challenge) + { + } + + inline ConnectionSecureBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionSecureOkBody : public AMQMethodBody +{ + string response; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + 4 + (response == null ? 0 : response.length) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionSecureOkBody(peer, response); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongString(response); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + response = buffer.getLongString(); + + } + + inline ConnectionSecureOkBody(string _response) : response(_response) + { + } + + inline ConnectionSecureOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionTuneBody : public AMQMethodBody +{ + u_int16_t channelMax; + u_int32_t frameMax; + u_int16_t heartbeat; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + 2 /*channelMax*/+ + 4 /*frameMax*/+ + 2 /*heartbeat*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionTuneBody(peer, channelMax, frameMax, heartbeat); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(channelMax); + buffer.putLong(frameMax); + buffer.putShort(heartbeat); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + channelMax = buffer.getShort(); + frameMax = buffer.getLong(); + heartbeat = buffer.getShort(); + + } + + inline ConnectionTuneBody(u_int16_t _channelMax, u_int32_t _frameMax, u_int16_t _heartbeat) : channelMax(_channelMax), frameMax(_frameMax), heartbeat(_heartbeat) + { + } + + inline ConnectionTuneBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionTuneOkBody : public AMQMethodBody +{ + u_int16_t channelMax; + u_int32_t frameMax; + u_int16_t heartbeat; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + 2 /*channelMax*/+ + 4 /*frameMax*/+ + 2 /*heartbeat*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionTuneOkBody(peer, channelMax, frameMax, heartbeat); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(channelMax); + buffer.putLong(frameMax); + buffer.putShort(heartbeat); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + channelMax = buffer.getShort(); + frameMax = buffer.getLong(); + heartbeat = buffer.getShort(); + + } + + inline ConnectionTuneOkBody(u_int16_t _channelMax, u_int32_t _frameMax, u_int16_t _heartbeat) : channelMax(_channelMax), frameMax(_frameMax), heartbeat(_heartbeat) + { + } + + inline ConnectionTuneOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionOpenBody : public AMQMethodBody +{ + string virtualHost; + string capabilities; + boolean insist; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(virtualHost)+ + EncodingUtils.encodedShortStringLength(capabilities)+ + 1 /*insist*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionOpenBody(peer, virtualHost, capabilities, insist); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(virtualHost); + buffer.putShortString(capabilities); + EncodingUtils.writeBooleans(buffer, new boolean[]{insist}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + virtualHost = buffer.getShortString(); + capabilities = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);insist = bools[0]; + + } + + inline ConnectionOpenBody(string _virtualHost, string _capabilities, boolean _insist) : virtualHost(_virtualHost), capabilities(_capabilities), insist(_insist) + { + } + + inline ConnectionOpenBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionOpenOkBody : public AMQMethodBody +{ + string knownHosts; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 41; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(knownHosts) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionOpenOkBody(peer, knownHosts); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(knownHosts); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + knownHosts = buffer.getShortString(); + + } + + inline ConnectionOpenOkBody(string _knownHosts) : knownHosts(_knownHosts) + { + } + + inline ConnectionOpenOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionRedirectBody : public AMQMethodBody +{ + string host; + string knownHosts; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 50; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(host)+ + EncodingUtils.encodedShortStringLength(knownHosts) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionRedirectBody(peer, host, knownHosts); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(host); + buffer.putShortString(knownHosts); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + host = buffer.getShortString(); + knownHosts = buffer.getShortString(); + + } + + inline ConnectionRedirectBody(string _host, string _knownHosts) : host(_host), knownHosts(_knownHosts) + { + } + + inline ConnectionRedirectBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionCloseBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + u_int16_t classId; + u_int16_t methodId; + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 60; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + 2 /*classId*/+ + 2 /*methodId*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionCloseBody(peer, replyCode, replyText, classId, methodId); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putShort(classId); + buffer.putShort(methodId); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + classId = buffer.getShort(); + methodId = buffer.getShort(); + + } + + inline ConnectionCloseBody(u_int16_t _replyCode, string _replyText, u_int16_t _classId, u_int16_t _methodId) : replyCode(_replyCode), replyText(_replyText), classId(_classId), methodId(_methodId) + { + } + + inline ConnectionCloseBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ConnectionCloseOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 10; + } + + inline u_int16_t methodId(){ + return 61; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ConnectionCloseOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline ConnectionCloseOkBody() : + { + } + + inline ConnectionCloseOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelOpenBody : public AMQMethodBody +{ + string outOfBand; + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(outOfBand) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelOpenBody(peer, outOfBand); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(outOfBand); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + outOfBand = buffer.getShortString(); + + } + + inline ChannelOpenBody(string _outOfBand) : outOfBand(_outOfBand) + { + } + + inline ChannelOpenBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelOpenOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelOpenOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline ChannelOpenOkBody() : + { + } + + inline ChannelOpenOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelFlowBody : public AMQMethodBody +{ + boolean active; + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 1 /*active*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelFlowBody(peer, active); + } + + inline void encode(Buffer& buffer) + { + EncodingUtils.writeBooleans(buffer, new boolean[]{active}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + boolean[] bools = EncodingUtils.readBooleans(buffer);active = bools[0]; + + } + + inline ChannelFlowBody(boolean _active) : active(_active) + { + } + + inline ChannelFlowBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelFlowOkBody : public AMQMethodBody +{ + boolean active; + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + 1 /*active*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelFlowOkBody(peer, active); + } + + inline void encode(Buffer& buffer) + { + EncodingUtils.writeBooleans(buffer, new boolean[]{active}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + boolean[] bools = EncodingUtils.readBooleans(buffer);active = bools[0]; + + } + + inline ChannelFlowOkBody(boolean _active) : active(_active) + { + } + + inline ChannelFlowOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelAlertBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + FieldTable details; + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + EncodingUtils.encodedFieldTableLength(details) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelAlertBody(peer, replyCode, replyText, details); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putFieldTable(details); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + details = buffer.getFieldTable(); + + } + + inline ChannelAlertBody(u_int16_t _replyCode, string _replyText, FieldTable _details) : replyCode(_replyCode), replyText(_replyText), details(_details) + { + } + + inline ChannelAlertBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelCloseBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + u_int16_t classId; + u_int16_t methodId; + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + 2 /*classId*/+ + 2 /*methodId*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelCloseBody(peer, replyCode, replyText, classId, methodId); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putShort(classId); + buffer.putShort(methodId); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + classId = buffer.getShort(); + methodId = buffer.getShort(); + + } + + inline ChannelCloseBody(u_int16_t _replyCode, string _replyText, u_int16_t _classId, u_int16_t _methodId) : replyCode(_replyCode), replyText(_replyText), classId(_classId), methodId(_methodId) + { + } + + inline ChannelCloseBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ChannelCloseOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 20; + } + + inline u_int16_t methodId(){ + return 41; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ChannelCloseOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline ChannelCloseOkBody() : + { + } + + inline ChannelCloseOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class AccessRequestBody : public AMQMethodBody +{ + string realm; + boolean exclusive; + boolean passive; + boolean active; + boolean write; + boolean read; + + +public: + + inline u_int16_t classId(){ + return 30; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(realm)+ + 1 /*exclusive*/+ + 0 /*passive*/+ + 0 /*active*/+ + 0 /*write*/+ + 0 /*read*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.AccessRequestBody(peer, realm, exclusive, passive, active, write, read); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(realm); + EncodingUtils.writeBooleans(buffer, new boolean[]{exclusive, passive, active, write, read}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + realm = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);exclusive = bools[0]; + passive = bools[1]; + active = bools[2]; + write = bools[3]; + read = bools[4]; + + } + + inline AccessRequestBody(string _realm, boolean _exclusive, boolean _passive, boolean _active, boolean _write, boolean _read) : realm(_realm), exclusive(_exclusive), passive(_passive), active(_active), write(_write), read(_read) + { + } + + inline AccessRequestBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class AccessRequestOkBody : public AMQMethodBody +{ + u_int16_t ticket; + + +public: + + inline u_int16_t classId(){ + return 30; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.AccessRequestOkBody(peer, ticket); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + + } + + inline AccessRequestOkBody(u_int16_t _ticket) : ticket(_ticket) + { + } + + inline AccessRequestOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ExchangeDeclareBody : public AMQMethodBody +{ + u_int16_t ticket; + string exchange; + string type; + boolean passive; + boolean durable; + boolean autoDelete; + boolean internal; + boolean nowait; + FieldTable arguments; + + +public: + + inline u_int16_t classId(){ + return 40; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(type)+ + 1 /*passive*/+ + 0 /*durable*/+ + 0 /*autoDelete*/+ + 0 /*internal*/+ + 0 /*nowait*/+ + EncodingUtils.encodedFieldTableLength(arguments) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ExchangeDeclareBody(peer, ticket, exchange, type, passive, durable, autoDelete, internal, nowait, arguments); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(exchange); + buffer.putShortString(type); + EncodingUtils.writeBooleans(buffer, new boolean[]{passive, durable, autoDelete, internal, nowait}); + buffer.putFieldTable(arguments); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + exchange = buffer.getShortString(); + type = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);passive = bools[0]; + durable = bools[1]; + autoDelete = bools[2]; + internal = bools[3]; + nowait = bools[4]; + arguments = buffer.getFieldTable(); + + } + + inline ExchangeDeclareBody(u_int16_t _ticket, string _exchange, string _type, boolean _passive, boolean _durable, boolean _autoDelete, boolean _internal, boolean _nowait, FieldTable _arguments) : ticket(_ticket), exchange(_exchange), type(_type), passive(_passive), durable(_durable), autoDelete(_autoDelete), internal(_internal), nowait(_nowait), arguments(_arguments) + { + } + + inline ExchangeDeclareBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ExchangeDeclareOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 40; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ExchangeDeclareOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline ExchangeDeclareOkBody() : + { + } + + inline ExchangeDeclareOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ExchangeDeleteBody : public AMQMethodBody +{ + u_int16_t ticket; + string exchange; + boolean ifUnused; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 40; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + 1 /*ifUnused*/+ + 0 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ExchangeDeleteBody(peer, ticket, exchange, ifUnused, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(exchange); + EncodingUtils.writeBooleans(buffer, new boolean[]{ifUnused, nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + exchange = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);ifUnused = bools[0]; + nowait = bools[1]; + + } + + inline ExchangeDeleteBody(u_int16_t _ticket, string _exchange, boolean _ifUnused, boolean _nowait) : ticket(_ticket), exchange(_exchange), ifUnused(_ifUnused), nowait(_nowait) + { + } + + inline ExchangeDeleteBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class ExchangeDeleteOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 40; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.ExchangeDeleteOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline ExchangeDeleteOkBody() : + { + } + + inline ExchangeDeleteOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueDeclareBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + boolean passive; + boolean durable; + boolean exclusive; + boolean autoDelete; + boolean nowait; + FieldTable arguments; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + 1 /*passive*/+ + 0 /*durable*/+ + 0 /*exclusive*/+ + 0 /*autoDelete*/+ + 0 /*nowait*/+ + EncodingUtils.encodedFieldTableLength(arguments) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueDeclareBody(peer, ticket, queue, passive, durable, exclusive, autoDelete, nowait, arguments); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + EncodingUtils.writeBooleans(buffer, new boolean[]{passive, durable, exclusive, autoDelete, nowait}); + buffer.putFieldTable(arguments); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);passive = bools[0]; + durable = bools[1]; + exclusive = bools[2]; + autoDelete = bools[3]; + nowait = bools[4]; + arguments = buffer.getFieldTable(); + + } + + inline QueueDeclareBody(u_int16_t _ticket, string _queue, boolean _passive, boolean _durable, boolean _exclusive, boolean _autoDelete, boolean _nowait, FieldTable _arguments) : ticket(_ticket), queue(_queue), passive(_passive), durable(_durable), exclusive(_exclusive), autoDelete(_autoDelete), nowait(_nowait), arguments(_arguments) + { + } + + inline QueueDeclareBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueDeclareOkBody : public AMQMethodBody +{ + string queue; + u_int32_t messageCount; + u_int32_t consumerCount; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(queue)+ + 4 /*messageCount*/+ + 4 /*consumerCount*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueDeclareOkBody(peer, queue, messageCount, consumerCount); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(queue); + buffer.putLong(messageCount); + buffer.putLong(consumerCount); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + queue = buffer.getShortString(); + messageCount = buffer.getLong(); + consumerCount = buffer.getLong(); + + } + + inline QueueDeclareOkBody(string _queue, u_int32_t _messageCount, u_int32_t _consumerCount) : queue(_queue), messageCount(_messageCount), consumerCount(_consumerCount) + { + } + + inline QueueDeclareOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueBindBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + string exchange; + string routingKey; + boolean nowait; + FieldTable arguments; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + 1 /*nowait*/+ + EncodingUtils.encodedFieldTableLength(arguments) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueBindBody(peer, ticket, queue, exchange, routingKey, nowait, arguments); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + EncodingUtils.writeBooleans(buffer, new boolean[]{nowait}); + buffer.putFieldTable(arguments); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);nowait = bools[0]; + arguments = buffer.getFieldTable(); + + } + + inline QueueBindBody(u_int16_t _ticket, string _queue, string _exchange, string _routingKey, boolean _nowait, FieldTable _arguments) : ticket(_ticket), queue(_queue), exchange(_exchange), routingKey(_routingKey), nowait(_nowait), arguments(_arguments) + { + } + + inline QueueBindBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueBindOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueBindOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline QueueBindOkBody() : + { + } + + inline QueueBindOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueuePurgeBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + 1 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueuePurgeBody(peer, ticket, queue, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + EncodingUtils.writeBooleans(buffer, new boolean[]{nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);nowait = bools[0]; + + } + + inline QueuePurgeBody(u_int16_t _ticket, string _queue, boolean _nowait) : ticket(_ticket), queue(_queue), nowait(_nowait) + { + } + + inline QueuePurgeBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueuePurgeOkBody : public AMQMethodBody +{ + u_int32_t messageCount; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + 4 /*messageCount*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueuePurgeOkBody(peer, messageCount); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(messageCount); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + messageCount = buffer.getLong(); + + } + + inline QueuePurgeOkBody(u_int32_t _messageCount) : messageCount(_messageCount) + { + } + + inline QueuePurgeOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueDeleteBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + boolean ifUnused; + boolean ifEmpty; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + 1 /*ifUnused*/+ + 0 /*ifEmpty*/+ + 0 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueDeleteBody(peer, ticket, queue, ifUnused, ifEmpty, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + EncodingUtils.writeBooleans(buffer, new boolean[]{ifUnused, ifEmpty, nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);ifUnused = bools[0]; + ifEmpty = bools[1]; + nowait = bools[2]; + + } + + inline QueueDeleteBody(u_int16_t _ticket, string _queue, boolean _ifUnused, boolean _ifEmpty, boolean _nowait) : ticket(_ticket), queue(_queue), ifUnused(_ifUnused), ifEmpty(_ifEmpty), nowait(_nowait) + { + } + + inline QueueDeleteBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class QueueDeleteOkBody : public AMQMethodBody +{ + u_int32_t messageCount; + + +public: + + inline u_int16_t classId(){ + return 50; + } + + inline u_int16_t methodId(){ + return 41; + } + + inline u_int32_t size(){ + + return + 4 /*messageCount*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.QueueDeleteOkBody(peer, messageCount); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(messageCount); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + messageCount = buffer.getLong(); + + } + + inline QueueDeleteOkBody(u_int32_t _messageCount) : messageCount(_messageCount) + { + } + + inline QueueDeleteOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicQosBody : public AMQMethodBody +{ + u_int32_t prefetchSize; + u_int16_t prefetchCount; + boolean global; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 4 /*prefetchSize*/+ + 2 /*prefetchCount*/+ + 1 /*global*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicQosBody(peer, prefetchSize, prefetchCount, global); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(prefetchSize); + buffer.putShort(prefetchCount); + EncodingUtils.writeBooleans(buffer, new boolean[]{global}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + prefetchSize = buffer.getLong(); + prefetchCount = buffer.getShort(); + boolean[] bools = EncodingUtils.readBooleans(buffer);global = bools[0]; + + } + + inline BasicQosBody(u_int32_t _prefetchSize, u_int16_t _prefetchCount, boolean _global) : prefetchSize(_prefetchSize), prefetchCount(_prefetchCount), global(_global) + { + } + + inline BasicQosBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicQosOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicQosOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline BasicQosOkBody() : + { + } + + inline BasicQosOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicConsumeBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + string consumerTag; + boolean noLocal; + boolean noAck; + boolean exclusive; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*noLocal*/+ + 0 /*noAck*/+ + 0 /*exclusive*/+ + 0 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicConsumeBody(peer, ticket, queue, consumerTag, noLocal, noAck, exclusive, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{noLocal, noAck, exclusive, nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);noLocal = bools[0]; + noAck = bools[1]; + exclusive = bools[2]; + nowait = bools[3]; + + } + + inline BasicConsumeBody(u_int16_t _ticket, string _queue, string _consumerTag, boolean _noLocal, boolean _noAck, boolean _exclusive, boolean _nowait) : ticket(_ticket), queue(_queue), consumerTag(_consumerTag), noLocal(_noLocal), noAck(_noAck), exclusive(_exclusive), nowait(_nowait) + { + } + + inline BasicConsumeBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicConsumeOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicConsumeOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline BasicConsumeOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline BasicConsumeOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicCancelBody : public AMQMethodBody +{ + string consumerTag; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicCancelBody(peer, consumerTag, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);nowait = bools[0]; + + } + + inline BasicCancelBody(string _consumerTag, boolean _nowait) : consumerTag(_consumerTag), nowait(_nowait) + { + } + + inline BasicCancelBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicCancelOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicCancelOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline BasicCancelOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline BasicCancelOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicPublishBody : public AMQMethodBody +{ + u_int16_t ticket; + string exchange; + string routingKey; + boolean mandatory; + boolean immediate; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + 1 /*mandatory*/+ + 0 /*immediate*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicPublishBody(peer, ticket, exchange, routingKey, mandatory, immediate); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + EncodingUtils.writeBooleans(buffer, new boolean[]{mandatory, immediate}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);mandatory = bools[0]; + immediate = bools[1]; + + } + + inline BasicPublishBody(u_int16_t _ticket, string _exchange, string _routingKey, boolean _mandatory, boolean _immediate) : ticket(_ticket), exchange(_exchange), routingKey(_routingKey), mandatory(_mandatory), immediate(_immediate) + { + } + + inline BasicPublishBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicReturnBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + string exchange; + string routingKey; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 50; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicReturnBody(peer, replyCode, replyText, exchange, routingKey); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + + } + + inline BasicReturnBody(u_int16_t _replyCode, string _replyText, string _exchange, string _routingKey) : replyCode(_replyCode), replyText(_replyText), exchange(_exchange), routingKey(_routingKey) + { + } + + inline BasicReturnBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicDeliverBody : public AMQMethodBody +{ + string consumerTag; + long deliveryTag; + boolean redelivered; + string exchange; + string routingKey; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 60; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 8 /*deliveryTag*/+ + 1 /*redelivered*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicDeliverBody(peer, consumerTag, deliveryTag, redelivered, exchange, routingKey); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{redelivered}); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);redelivered = bools[0]; + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + + } + + inline BasicDeliverBody(string _consumerTag, long _deliveryTag, boolean _redelivered, string _exchange, string _routingKey) : consumerTag(_consumerTag), deliveryTag(_deliveryTag), redelivered(_redelivered), exchange(_exchange), routingKey(_routingKey) + { + } + + inline BasicDeliverBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicGetBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + boolean noAck; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 70; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + 1 /*noAck*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicGetBody(peer, ticket, queue, noAck); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + EncodingUtils.writeBooleans(buffer, new boolean[]{noAck}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);noAck = bools[0]; + + } + + inline BasicGetBody(u_int16_t _ticket, string _queue, boolean _noAck) : ticket(_ticket), queue(_queue), noAck(_noAck) + { + } + + inline BasicGetBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicGetOkBody : public AMQMethodBody +{ + long deliveryTag; + boolean redelivered; + string exchange; + string routingKey; + u_int32_t messageCount; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 71; + } + + inline u_int32_t size(){ + + return + 8 /*deliveryTag*/+ + 1 /*redelivered*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + 4 /*messageCount*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicGetOkBody(peer, deliveryTag, redelivered, exchange, routingKey, messageCount); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{redelivered}); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + buffer.putLong(messageCount); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);redelivered = bools[0]; + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + messageCount = buffer.getLong(); + + } + + inline BasicGetOkBody(long _deliveryTag, boolean _redelivered, string _exchange, string _routingKey, u_int32_t _messageCount) : deliveryTag(_deliveryTag), redelivered(_redelivered), exchange(_exchange), routingKey(_routingKey), messageCount(_messageCount) + { + } + + inline BasicGetOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicGetEmptyBody : public AMQMethodBody +{ + string clusterId; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 72; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(clusterId) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicGetEmptyBody(peer, clusterId); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(clusterId); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + clusterId = buffer.getShortString(); + + } + + inline BasicGetEmptyBody(string _clusterId) : clusterId(_clusterId) + { + } + + inline BasicGetEmptyBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicAckBody : public AMQMethodBody +{ + long deliveryTag; + boolean multiple; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 80; + } + + inline u_int32_t size(){ + + return + 8 /*deliveryTag*/+ + 1 /*multiple*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicAckBody(peer, deliveryTag, multiple); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{multiple}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);multiple = bools[0]; + + } + + inline BasicAckBody(long _deliveryTag, boolean _multiple) : deliveryTag(_deliveryTag), multiple(_multiple) + { + } + + inline BasicAckBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicRejectBody : public AMQMethodBody +{ + long deliveryTag; + boolean requeue; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 90; + } + + inline u_int32_t size(){ + + return + 8 /*deliveryTag*/+ + 1 /*requeue*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicRejectBody(peer, deliveryTag, requeue); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{requeue}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);requeue = bools[0]; + + } + + inline BasicRejectBody(long _deliveryTag, boolean _requeue) : deliveryTag(_deliveryTag), requeue(_requeue) + { + } + + inline BasicRejectBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class BasicRecoverBody : public AMQMethodBody +{ + boolean requeue; + + +public: + + inline u_int16_t classId(){ + return 60; + } + + inline u_int16_t methodId(){ + return 100; + } + + inline u_int32_t size(){ + + return + 1 /*requeue*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.BasicRecoverBody(peer, requeue); + } + + inline void encode(Buffer& buffer) + { + EncodingUtils.writeBooleans(buffer, new boolean[]{requeue}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + boolean[] bools = EncodingUtils.readBooleans(buffer);requeue = bools[0]; + + } + + inline BasicRecoverBody(boolean _requeue) : requeue(_requeue) + { + } + + inline BasicRecoverBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileQosBody : public AMQMethodBody +{ + u_int32_t prefetchSize; + u_int16_t prefetchCount; + boolean global; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 4 /*prefetchSize*/+ + 2 /*prefetchCount*/+ + 1 /*global*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileQosBody(peer, prefetchSize, prefetchCount, global); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(prefetchSize); + buffer.putShort(prefetchCount); + EncodingUtils.writeBooleans(buffer, new boolean[]{global}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + prefetchSize = buffer.getLong(); + prefetchCount = buffer.getShort(); + boolean[] bools = EncodingUtils.readBooleans(buffer);global = bools[0]; + + } + + inline FileQosBody(u_int32_t _prefetchSize, u_int16_t _prefetchCount, boolean _global) : prefetchSize(_prefetchSize), prefetchCount(_prefetchCount), global(_global) + { + } + + inline FileQosBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileQosOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileQosOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline FileQosOkBody() : + { + } + + inline FileQosOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileConsumeBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + string consumerTag; + boolean noLocal; + boolean noAck; + boolean exclusive; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*noLocal*/+ + 0 /*noAck*/+ + 0 /*exclusive*/+ + 0 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileConsumeBody(peer, ticket, queue, consumerTag, noLocal, noAck, exclusive, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{noLocal, noAck, exclusive, nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);noLocal = bools[0]; + noAck = bools[1]; + exclusive = bools[2]; + nowait = bools[3]; + + } + + inline FileConsumeBody(u_int16_t _ticket, string _queue, string _consumerTag, boolean _noLocal, boolean _noAck, boolean _exclusive, boolean _nowait) : ticket(_ticket), queue(_queue), consumerTag(_consumerTag), noLocal(_noLocal), noAck(_noAck), exclusive(_exclusive), nowait(_nowait) + { + } + + inline FileConsumeBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileConsumeOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileConsumeOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline FileConsumeOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline FileConsumeOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileCancelBody : public AMQMethodBody +{ + string consumerTag; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileCancelBody(peer, consumerTag, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);nowait = bools[0]; + + } + + inline FileCancelBody(string _consumerTag, boolean _nowait) : consumerTag(_consumerTag), nowait(_nowait) + { + } + + inline FileCancelBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileCancelOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileCancelOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline FileCancelOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline FileCancelOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileOpenBody : public AMQMethodBody +{ + string identifier; + long contentSize; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(identifier)+ + 8 /*contentSize*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileOpenBody(peer, identifier, contentSize); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(identifier); + buffer.putLongLong(contentSize); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + identifier = buffer.getShortString(); + contentSize = buffer.getLongLong(); + + } + + inline FileOpenBody(string _identifier, long _contentSize) : identifier(_identifier), contentSize(_contentSize) + { + } + + inline FileOpenBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileOpenOkBody : public AMQMethodBody +{ + long stagedSize; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 41; + } + + inline u_int32_t size(){ + + return + 8 /*stagedSize*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileOpenOkBody(peer, stagedSize); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(stagedSize); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + stagedSize = buffer.getLongLong(); + + } + + inline FileOpenOkBody(long _stagedSize) : stagedSize(_stagedSize) + { + } + + inline FileOpenOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileStageBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 50; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileStageBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline FileStageBody() : + { + } + + inline FileStageBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FilePublishBody : public AMQMethodBody +{ + u_int16_t ticket; + string exchange; + string routingKey; + boolean mandatory; + boolean immediate; + string identifier; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 60; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + 1 /*mandatory*/+ + 0 /*immediate*/+ + EncodingUtils.encodedShortStringLength(identifier) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FilePublishBody(peer, ticket, exchange, routingKey, mandatory, immediate, identifier); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + EncodingUtils.writeBooleans(buffer, new boolean[]{mandatory, immediate}); + buffer.putShortString(identifier); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);mandatory = bools[0]; + immediate = bools[1]; + identifier = buffer.getShortString(); + + } + + inline FilePublishBody(u_int16_t _ticket, string _exchange, string _routingKey, boolean _mandatory, boolean _immediate, string _identifier) : ticket(_ticket), exchange(_exchange), routingKey(_routingKey), mandatory(_mandatory), immediate(_immediate), identifier(_identifier) + { + } + + inline FilePublishBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileReturnBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + string exchange; + string routingKey; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 70; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileReturnBody(peer, replyCode, replyText, exchange, routingKey); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + + } + + inline FileReturnBody(u_int16_t _replyCode, string _replyText, string _exchange, string _routingKey) : replyCode(_replyCode), replyText(_replyText), exchange(_exchange), routingKey(_routingKey) + { + } + + inline FileReturnBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileDeliverBody : public AMQMethodBody +{ + string consumerTag; + long deliveryTag; + boolean redelivered; + string exchange; + string routingKey; + string identifier; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 80; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 8 /*deliveryTag*/+ + 1 /*redelivered*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + EncodingUtils.encodedShortStringLength(identifier) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileDeliverBody(peer, consumerTag, deliveryTag, redelivered, exchange, routingKey, identifier); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{redelivered}); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + buffer.putShortString(identifier); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);redelivered = bools[0]; + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + identifier = buffer.getShortString(); + + } + + inline FileDeliverBody(string _consumerTag, long _deliveryTag, boolean _redelivered, string _exchange, string _routingKey, string _identifier) : consumerTag(_consumerTag), deliveryTag(_deliveryTag), redelivered(_redelivered), exchange(_exchange), routingKey(_routingKey), identifier(_identifier) + { + } + + inline FileDeliverBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileAckBody : public AMQMethodBody +{ + long deliveryTag; + boolean multiple; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 90; + } + + inline u_int32_t size(){ + + return + 8 /*deliveryTag*/+ + 1 /*multiple*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileAckBody(peer, deliveryTag, multiple); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{multiple}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);multiple = bools[0]; + + } + + inline FileAckBody(long _deliveryTag, boolean _multiple) : deliveryTag(_deliveryTag), multiple(_multiple) + { + } + + inline FileAckBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class FileRejectBody : public AMQMethodBody +{ + long deliveryTag; + boolean requeue; + + +public: + + inline u_int16_t classId(){ + return 70; + } + + inline u_int16_t methodId(){ + return 100; + } + + inline u_int32_t size(){ + + return + 8 /*deliveryTag*/+ + 1 /*requeue*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.FileRejectBody(peer, deliveryTag, requeue); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(deliveryTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{requeue}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + deliveryTag = buffer.getLongLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);requeue = bools[0]; + + } + + inline FileRejectBody(long _deliveryTag, boolean _requeue) : deliveryTag(_deliveryTag), requeue(_requeue) + { + } + + inline FileRejectBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamQosBody : public AMQMethodBody +{ + u_int32_t prefetchSize; + u_int16_t prefetchCount; + u_int32_t consumeRate; + boolean global; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 4 /*prefetchSize*/+ + 2 /*prefetchCount*/+ + 4 /*consumeRate*/+ + 1 /*global*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamQosBody(peer, prefetchSize, prefetchCount, consumeRate, global); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(prefetchSize); + buffer.putShort(prefetchCount); + buffer.putLong(consumeRate); + EncodingUtils.writeBooleans(buffer, new boolean[]{global}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + prefetchSize = buffer.getLong(); + prefetchCount = buffer.getShort(); + consumeRate = buffer.getLong(); + boolean[] bools = EncodingUtils.readBooleans(buffer);global = bools[0]; + + } + + inline StreamQosBody(u_int32_t _prefetchSize, u_int16_t _prefetchCount, u_int32_t _consumeRate, boolean _global) : prefetchSize(_prefetchSize), prefetchCount(_prefetchCount), consumeRate(_consumeRate), global(_global) + { + } + + inline StreamQosBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamQosOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamQosOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline StreamQosOkBody() : + { + } + + inline StreamQosOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamConsumeBody : public AMQMethodBody +{ + u_int16_t ticket; + string queue; + string consumerTag; + boolean noLocal; + boolean exclusive; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(queue)+ + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*noLocal*/+ + 0 /*exclusive*/+ + 0 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamConsumeBody(peer, ticket, queue, consumerTag, noLocal, exclusive, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(queue); + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{noLocal, exclusive, nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + queue = buffer.getShortString(); + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);noLocal = bools[0]; + exclusive = bools[1]; + nowait = bools[2]; + + } + + inline StreamConsumeBody(u_int16_t _ticket, string _queue, string _consumerTag, boolean _noLocal, boolean _exclusive, boolean _nowait) : ticket(_ticket), queue(_queue), consumerTag(_consumerTag), noLocal(_noLocal), exclusive(_exclusive), nowait(_nowait) + { + } + + inline StreamConsumeBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamConsumeOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamConsumeOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline StreamConsumeOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline StreamConsumeOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamCancelBody : public AMQMethodBody +{ + string consumerTag; + boolean nowait; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 1 /*nowait*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamCancelBody(peer, consumerTag, nowait); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + EncodingUtils.writeBooleans(buffer, new boolean[]{nowait}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);nowait = bools[0]; + + } + + inline StreamCancelBody(string _consumerTag, boolean _nowait) : consumerTag(_consumerTag), nowait(_nowait) + { + } + + inline StreamCancelBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamCancelOkBody : public AMQMethodBody +{ + string consumerTag; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamCancelOkBody(peer, consumerTag); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + + } + + inline StreamCancelOkBody(string _consumerTag) : consumerTag(_consumerTag) + { + } + + inline StreamCancelOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamPublishBody : public AMQMethodBody +{ + u_int16_t ticket; + string exchange; + string routingKey; + boolean mandatory; + boolean immediate; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + + return + 2 /*ticket*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey)+ + 1 /*mandatory*/+ + 0 /*immediate*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamPublishBody(peer, ticket, exchange, routingKey, mandatory, immediate); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(ticket); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + EncodingUtils.writeBooleans(buffer, new boolean[]{mandatory, immediate}); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + ticket = buffer.getShort(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + boolean[] bools = EncodingUtils.readBooleans(buffer);mandatory = bools[0]; + immediate = bools[1]; + + } + + inline StreamPublishBody(u_int16_t _ticket, string _exchange, string _routingKey, boolean _mandatory, boolean _immediate) : ticket(_ticket), exchange(_exchange), routingKey(_routingKey), mandatory(_mandatory), immediate(_immediate) + { + } + + inline StreamPublishBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamReturnBody : public AMQMethodBody +{ + u_int16_t replyCode; + string replyText; + string exchange; + string routingKey; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 50; + } + + inline u_int32_t size(){ + + return + 2 /*replyCode*/+ + EncodingUtils.encodedShortStringLength(replyText)+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(routingKey) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamReturnBody(peer, replyCode, replyText, exchange, routingKey); + } + + inline void encode(Buffer& buffer) + { + buffer.putShort(replyCode); + buffer.putShortString(replyText); + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + replyCode = buffer.getShort(); + replyText = buffer.getShortString(); + exchange = buffer.getShortString(); + routingKey = buffer.getShortString(); + + } + + inline StreamReturnBody(u_int16_t _replyCode, string _replyText, string _exchange, string _routingKey) : replyCode(_replyCode), replyText(_replyText), exchange(_exchange), routingKey(_routingKey) + { + } + + inline StreamReturnBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class StreamDeliverBody : public AMQMethodBody +{ + string consumerTag; + long deliveryTag; + string exchange; + string queue; + + +public: + + inline u_int16_t classId(){ + return 80; + } + + inline u_int16_t methodId(){ + return 60; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(consumerTag)+ + 8 /*deliveryTag*/+ + EncodingUtils.encodedShortStringLength(exchange)+ + EncodingUtils.encodedShortStringLength(queue) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.StreamDeliverBody(peer, consumerTag, deliveryTag, exchange, queue); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(consumerTag); + buffer.putLongLong(deliveryTag); + buffer.putShortString(exchange); + buffer.putShortString(queue); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + consumerTag = buffer.getShortString(); + deliveryTag = buffer.getLongLong(); + exchange = buffer.getShortString(); + queue = buffer.getShortString(); + + } + + inline StreamDeliverBody(string _consumerTag, long _deliveryTag, string _exchange, string _queue) : consumerTag(_consumerTag), deliveryTag(_deliveryTag), exchange(_exchange), queue(_queue) + { + } + + inline StreamDeliverBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxSelectBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxSelectBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxSelectBody() : + { + } + + inline TxSelectBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxSelectOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxSelectOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxSelectOkBody() : + { + } + + inline TxSelectOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxCommitBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxCommitBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxCommitBody() : + { + } + + inline TxCommitBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxCommitOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxCommitOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxCommitOkBody() : + { + } + + inline TxCommitOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxRollbackBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxRollbackBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxRollbackBody() : + { + } + + inline TxRollbackBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TxRollbackOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 90; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TxRollbackOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TxRollbackOkBody() : + { + } + + inline TxRollbackOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class DtxSelectBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 100; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.DtxSelectBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline DtxSelectBody() : + { + } + + inline DtxSelectBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class DtxSelectOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 100; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.DtxSelectOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline DtxSelectOkBody() : + { + } + + inline DtxSelectOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class DtxStartBody : public AMQMethodBody +{ + string dtxIdentifier; + + +public: + + inline u_int16_t classId(){ + return 100; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(dtxIdentifier) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.DtxStartBody(peer, dtxIdentifier); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(dtxIdentifier); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + dtxIdentifier = buffer.getShortString(); + + } + + inline DtxStartBody(string _dtxIdentifier) : dtxIdentifier(_dtxIdentifier) + { + } + + inline DtxStartBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class DtxStartOkBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 100; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.DtxStartOkBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline DtxStartOkBody() : + { + } + + inline DtxStartOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TunnelRequestBody : public AMQMethodBody +{ + FieldTable metaData; + + +public: + + inline u_int16_t classId(){ + return 110; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedFieldTableLength(metaData) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TunnelRequestBody(peer, metaData); + } + + inline void encode(Buffer& buffer) + { + buffer.putFieldTable(metaData); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + metaData = buffer.getFieldTable(); + + } + + inline TunnelRequestBody(FieldTable _metaData) : metaData(_metaData) + { + } + + inline TunnelRequestBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestIntegerBody : public AMQMethodBody +{ + u_int8_t integer1; + u_int16_t integer2; + u_int32_t integer3; + long integer4; + u_int8_t operation; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 10; + } + + inline u_int32_t size(){ + + return + 1 /*integer1*/+ + 2 /*integer2*/+ + 4 /*integer3*/+ + 8 /*integer4*/+ + 1 /*operation*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestIntegerBody(peer, integer1, integer2, integer3, integer4, operation); + } + + inline void encode(Buffer& buffer) + { + buffer.putOctet(integer1); + buffer.putShort(integer2); + buffer.putLong(integer3); + buffer.putLongLong(integer4); + buffer.putOctet(operation); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + integer1 = buffer.getOctet(); + integer2 = buffer.getShort(); + integer3 = buffer.getLong(); + integer4 = buffer.getLongLong(); + operation = buffer.getOctet(); + + } + + inline TestIntegerBody(u_int8_t _integer1, u_int16_t _integer2, u_int32_t _integer3, long _integer4, u_int8_t _operation) : integer1(_integer1), integer2(_integer2), integer3(_integer3), integer4(_integer4), operation(_operation) + { + } + + inline TestIntegerBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestIntegerOkBody : public AMQMethodBody +{ + long result; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 11; + } + + inline u_int32_t size(){ + + return + 8 /*result*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestIntegerOkBody(peer, result); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(result); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + result = buffer.getLongLong(); + + } + + inline TestIntegerOkBody(long _result) : result(_result) + { + } + + inline TestIntegerOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestStringBody : public AMQMethodBody +{ + string string1; + string string2; + u_int8_t operation; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 20; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedShortStringLength(string1)+ + 4 + (string2 == null ? 0 : string2.length)+ + 1 /*operation*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestStringBody(peer, string1, string2, operation); + } + + inline void encode(Buffer& buffer) + { + buffer.putShortString(string1); + buffer.putLongString(string2); + buffer.putOctet(operation); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + string1 = buffer.getShortString(); + string2 = buffer.getLongString(); + operation = buffer.getOctet(); + + } + + inline TestStringBody(string _string1, string _string2, u_int8_t _operation) : string1(_string1), string2(_string2), operation(_operation) + { + } + + inline TestStringBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestStringOkBody : public AMQMethodBody +{ + string result; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 21; + } + + inline u_int32_t size(){ + + return + 4 + (result == null ? 0 : result.length) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestStringOkBody(peer, result); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongString(result); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + result = buffer.getLongString(); + + } + + inline TestStringOkBody(string _result) : result(_result) + { + } + + inline TestStringOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestTableBody : public AMQMethodBody +{ + FieldTable table; + u_int8_t integerOp; + u_int8_t stringOp; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 30; + } + + inline u_int32_t size(){ + + return + EncodingUtils.encodedFieldTableLength(table)+ + 1 /*integerOp*/+ + 1 /*stringOp*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestTableBody(peer, table, integerOp, stringOp); + } + + inline void encode(Buffer& buffer) + { + buffer.putFieldTable(table); + buffer.putOctet(integerOp); + buffer.putOctet(stringOp); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + table = buffer.getFieldTable(); + integerOp = buffer.getOctet(); + stringOp = buffer.getOctet(); + + } + + inline TestTableBody(FieldTable _table, u_int8_t _integerOp, u_int8_t _stringOp) : table(_table), integerOp(_integerOp), stringOp(_stringOp) + { + } + + inline TestTableBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestTableOkBody : public AMQMethodBody +{ + long integerResult; + string stringResult; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 31; + } + + inline u_int32_t size(){ + + return + 8 /*integerResult*/+ + 4 + (stringResult == null ? 0 : stringResult.length) + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestTableOkBody(peer, integerResult, stringResult); + } + + inline void encode(Buffer& buffer) + { + buffer.putLongLong(integerResult); + buffer.putLongString(stringResult); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + integerResult = buffer.getLongLong(); + stringResult = buffer.getLongString(); + + } + + inline TestTableOkBody(long _integerResult, string _stringResult) : integerResult(_integerResult), stringResult(_stringResult) + { + } + + inline TestTableOkBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestContentBody : public AMQMethodBody +{ + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 40; + } + + inline u_int32_t size(){ + return 0; + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestContentBody(peer, ); + } + + inline void encode(Buffer& buffer) + { + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + + } + + inline TestContentBody() : + { + } + + inline TestContentBody() + { + } +} + +/** + * This class is autogenerated, do not modify. [From AMQ protocol 0.70 (major=, minor=)] + */ +class TestContentOkBody : public AMQMethodBody +{ + u_int32_t contentChecksum; + + +public: + + inline u_int16_t classId(){ + return 120; + } + + inline u_int16_t methodId(){ + return 41; + } + + inline u_int32_t size(){ + + return + 4 /*contentChecksum*/ + ; + + } + + inline void invoke(AMQP& target, AMQP& peer){ + target.TestContentOkBody(peer, contentChecksum); + } + + inline void encode(Buffer& buffer) + { + buffer.putLong(contentChecksum); + + } + + inline void decode(Buffer& buffer, u_int32_t size) + { + contentChecksum = buffer.getLong(); + + } + + inline TestContentOkBody(u_int32_t _contentChecksum) : contentChecksum(_contentChecksum) + { + } + + inline TestContentOkBody() + { + } +}
Added: cpp/framing/utils.xsl =================================================================== --- cpp/framing/utils.xsl (rev 0) +++ cpp/framing/utils.xsl 2010-12-07 22:18:44 UTC (rev 2) @@ -0,0 +1,175 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org%22%3E + +<!-- This file contains functions that are used in the generation of the java classes for framing --> + +<!-- retrieve the java type of a given amq type --> +<xsl:function name="amq:cpp-type"> + <xsl:param name="t"/> + xsl:choose + <xsl:when test="$t='octet'">u_int8_t</xsl:when> + <xsl:when test="$t='short'">u_int16_t</xsl:when> + <xsl:when test="$t='shortstr'">std::string</xsl:when> + <xsl:when test="$t='longstr'">std::string</xsl:when> + <xsl:when test="$t='bit'">bool</xsl:when> + <xsl:when test="$t='long'">u_int32_t</xsl:when> + <xsl:when test="$t='longlong'">u_int64_t</xsl:when> + <xsl:when test="$t='table'">FieldTable</xsl:when> + xsl:otherwiseObject /*WARNING: undefined type*/</xsl:otherwise> + </xsl:choose> +</xsl:function> +<xsl:function name="amq:cpp-arg-type"> + <xsl:param name="t"/> + xsl:choose + <xsl:when test="$t='octet'">u_int8_t</xsl:when> + <xsl:when test="$t='short'">u_int16_t</xsl:when> + <xsl:when test="$t='shortstr'">std::string&</xsl:when> + <xsl:when test="$t='longstr'">std::string&</xsl:when> + <xsl:when test="$t='bit'">bool</xsl:when> + <xsl:when test="$t='long'">u_int32_t</xsl:when> + <xsl:when test="$t='longlong'">u_int64_t</xsl:when> + <xsl:when test="$t='table'">FieldTable&</xsl:when> + xsl:otherwiseObject /*WARNING: undefined type*/</xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to get the field size of a given amq type --> +<xsl:function name="amq:field-length"> + <xsl:param name="f"/> + xsl:choose + <xsl:when test="$f/@type='bit' and $f/@boolean-index=1"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='bit' and $f/@boolean-index > 1"> + <xsl:value-of select="concat('0 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='char'"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat('2 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat('4 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat('8 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat('1 + ', $f/@name, '.length()')"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat('4 + ', $f/@name, '.length()')"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat($f/@name, '.size()')"/> + </xsl:when> + xsl:otherwisexsl:text/* WARNING: COULD NOT DETERMINE FIELD SIZE */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to encode a field of a given amq type --> +<!-- Note: + This method will not provide an encoder for a bit field. + Bit fields should be encoded together separately. --> + +<xsl:function name="amq:encoder"> + <xsl:param name="f"/> + xsl:choose + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat('buffer.putOctet(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat('buffer.putShort(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat('buffer.putLong(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat('buffer.putLongLong(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat('buffer.putShortString(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat('buffer.putLongString(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat('buffer.putFieldTable(', $f/@name, ')')"/> + </xsl:when> + xsl:otherwisexsl:text/* WARNING: COULD NOT DETERMINE ENCODER */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to decode a field of a given amq type --> +<xsl:function name="amq:decoder"> + <xsl:param name="f"/> + xsl:choose + <xsl:when test="$f/@type='bit'"> + <xsl:value-of select="concat($f/@name, ' = (1 << (8 - ', $f/@boolean-index, ')) & flags;')"/> + </xsl:when> + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat($f/@name, ' = buffer.getOctet()')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat($f/@name, ' = buffer.getShort()')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat($f/@name, ' = buffer.getLong()')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat($f/@name, ' = buffer.getLongLong()')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat('buffer.getShortString(', $f/@name), ')'"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat('buffer.getLongString(', $f/@name), ')'"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat('buffer.getFieldTable(', $f/@name, ')')"/> + </xsl:when> + xsl:otherwisexsl:text/* WARNING: COULD NOT DETERMINE DECODER */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- create the class name for a frame, based on class and method (passed in) --> +<xsl:function name="amq:class-name"> + <xsl:param name="class"/> + <xsl:param name="method"/> + <xsl:value-of select="concat(amq:upper-first($class),amq:upper-first(amq:field-name($method)), 'Body')"/> +</xsl:function> + +<!-- create the class name for a frame, based on class and method (passed in) --> +<xsl:function name="amq:method-name"> + <xsl:param name="class"/> + <xsl:param name="method"/> + <xsl:value-of select="concat(translate($class, '- ', '__'), '_', translate($method, '- ', '__'))"/> +</xsl:function> + +<!-- get a valid field name, processing spaces and '-'s where appropriate --> +<xsl:function name="amq:field-name"> + <xsl:param name="name"/> + xsl:choose + <xsl:when test="contains($name, ' ')"> + <xsl:value-of select="concat(substring-before($name, ' '), amq:upper-first(substring-after($name, ' ')))"/> + </xsl:when> + <xsl:when test="contains($name, '-')"> + <xsl:value-of select="concat(substring-before($name, '-'), amq:upper-first(substring-after($name, '-')))"/> + </xsl:when> + xsl:otherwise + <xsl:value-of select="$name"/> + </xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- convert the first character of the input to upper-case --> +<xsl:function name="amq:upper-first"> + <xsl:param name="in"/> + <xsl:value-of select="concat(upper-case(substring($in, 1, 1)), substring($in, 2))"/> +</xsl:function> + +</xsl:stylesheet>
cumin-developers@lists.fedorahosted.org