<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="amqp.xsl"?>

<!--
  Copyright Notice
  ================
  (c) Copyright Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche
  Boerse, Envoy Technologies Inc., Goldman Sachs, HCL Technologies Ltd, IIT Software GmbH, iMatix
  Corporation, INETCO Systems Limited, Informatica Corporation, JPMorgan Chase & Co., Kaazing
  Corporation, N.A, Microsoft Corporation, my-Channels, Novell, Progress Software, Red Hat Inc.,
  Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., TWIST Process Innovations Ltd,
  VMware, Inc., and WS02 Inc.
  2006-2011. All rights reserved.

  License
  =======

  Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche Boerse, Goldman
  Sachs, HCL Technologies Ltd, IIT Software GmbH, INETCO Systems Limited, Informatica Corporation,
  JPMorgan Chase & Co., Kaazing Corporation, N.A, Microsoft Corporation, my-Channels, Novell,
  Progress Software, Red Hat Inc., Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc.,
  TWIST Process Innovations Ltd, VMware, Inc., and WS02 Inc. (collectively, the "Authors") each
  hereby grants to you a worldwide, perpetual, royalty-free, nontransferable, nonexclusive license
  to (i) copy, display, distribute and implement the Advanced Message Queuing Protocol ("AMQP")
  Specification and (ii) the Licensed Claims that are held by the Authors, all for the purpose of
  implementing the Advanced Message Queuing Protocol Specification. Your license and any rights
  under this Agreement will terminate immediately without notice from any Author if you bring any
  claim, suit, demand, or action related to the Advanced Message Queuing Protocol Specification
  against any Author. Upon termination, you shall destroy all copies of the Advanced Message Queuing
  Protocol Specification in your possession or control.

  As used hereunder, "Licensed Claims" means those claims of a patent or patent application,
  throughout the world, excluding design patents and design registrations, owned or controlled, or
  that can be sublicensed without fee and in compliance with the requirements of this Agreement, by
  an Author or its affiliates now or at any future time and which would necessarily be infringed by
  implementation of the Advanced Message Queuing Protocol Specification. A claim is necessarily
  infringed hereunder only when it is not possible to avoid infringing it because there is no
  plausible non-infringing alternative for implementing the required portions of the Advanced
  Message Queuing Protocol Specification. Notwithstanding the foregoing, Licensed Claims shall not
  include any claims other than as set forth above even if contained in the same patent as Licensed
  Claims; or that read solely on any implementations of any portion of the Advanced Message Queuing
  Protocol Specification that are not required by the Advanced Message Queuing Protocol
  Specification, or that, if licensed, would require a payment of royalties by the licensor to
  unaffiliated third parties. Moreover, Licensed Claims shall not include (i) any enabling
  technologies that may be necessary to make or use any Licensed Product but are not themselves
  expressly set forth in the Advanced Message Queuing Protocol Specification (e.g., semiconductor
  manufacturing technology, compiler technology, object oriented technology, networking technology,
  operating system technology, and the like); or (ii) the implementation of other published
  standards developed elsewhere and merely referred to in the body of the Advanced Message Queuing
  Protocol Specification, or (iii) any Licensed Product and any combinations thereof the purpose or
  function of which is not required for compliance with the Advanced Message Queuing Protocol
  Specification. For purposes of this definition, the Advanced Message Queuing Protocol
  Specification shall be deemed to include both architectural and interconnection requirements
  essential for interoperability and may also include supporting source code artifacts where such
  architectural, interconnection requirements and source code artifacts are expressly identified as
  being required or documentation to achieve compliance with the Advanced Message Queuing Protocol
  Specification.

  As used hereunder, "Licensed Products" means only those specific portions of products (hardware,
  software or combinations thereof) that implement and are compliant with all relevant portions of
  the Advanced Message Queuing Protocol Specification.

  The following disclaimers, which you hereby also acknowledge as to any use you may make of the
  Advanced Message Queuing Protocol Specification:

  THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
  REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS
  OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
  IMPLEMENTATION OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD
  PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

  THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
  DAMAGES ARISING OUT OF OR RELATING TO ANY USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED
  MESSAGE QUEUING PROTOCOL SPECIFICATION.

  The name and trademarks of the Authors may NOT be used in any manner, including advertising or
  publicity pertaining to the Advanced Message Queuing Protocol Specification or its contents
  without specific, written prior permission. Title to copyright in the Advanced Message Queuing
  Protocol Specification will at all times remain with the Authors.

  No other rights are granted by implication, estoppel or otherwise.

  Upon termination of your license or rights under this Agreement, you shall destroy all copies of
  the Advanced Message Queuing Protocol Specification in your possession or control.

  Trademarks
  ==========
  "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the Octagon Symbol are
  trademarks of JPMorgan Chase & Co.

  RED HAT is a registered trademarks of Red Hat, Inc. in the US and other countries.

  Other company, product, or service names may be trademarks or service marks of others.

  Link to full AMQP specification:
  =================================
  http://www.amqp.org/confluence/display/AMQP/AMQP+Specification
-->

<!DOCTYPE amqp SYSTEM "amqp.dtd">

<amqp xmlns="http://www.amqp.org/schema/amqp.xsd"
      name="types" label="working version">

  <!-- == Section: types ======================================================================= -->

  <section name="types" title="Type System" label="AMQP Type System">
    <doc>
      <p>
        The AMQP type system defines a set of commonly used primitive types used for interoperable
        data representation. AMQP values may be annotated with additional semantic information
        beyond that associated with the primitive type. This allows for the association of an AMQP
        value with an external type that is not present as an AMQP primitive. For example, a URL is
        commonly represented as a string, however not all strings are valid URLs, and many
        programming languages and/or applications define a specific type to represent URLs. The AMQP
        type system would allow for the definition of a code with which to annotate strings when the
        value is intended to represent a URL.
      </p>
    </doc>

    <doc title="Primitive Types">
      <p>
        The following primitive types are defined:
      </p>

      <!--TypeListTable-->
    </doc>

    <doc title="Described Types">
      <p>
        The primitive types defined by AMQP can directly represent many of the basic types present
        in most popular programming languages, and therefore may be trivially used to exchange basic
        data. In practice, however, even the simplest applications have their own set of custom
        types used to model concepts within the application's domain, and, for messaging
        applications, these custom types need to be externalized for transmission.
      </p>

      <p>
        AMQP provides a means to do this by allowing any AMQP type to be annotated with
        a <i>descriptor</i>. A <i>descriptor</i> forms an association between a custom type, and an
        AMQP type. This association indicates that the AMQP type is actually a <i>representation</i>
        of the custom type. The resulting combination of the AMQP type and its descriptor is
        referred to as a <i>described type</i>.
      </p>

      <p>
        A described type contains two distinct kinds of type information. It identifies both an AMQP
        type and a custom type (as well as the relationship between them), and so can be understood
        at two different levels. An application with intimate knowledge of a given domain can
        understand described types as the custom types they represent, thereby decoding and
        processing them according to the complete semantics of the domain. An application with no
        intimate knowledge can still understand the described types as AMQP types, decoding and
        processing them as such.
      </p>
    </doc>

    <doc title="Descriptor Values">
      <p>
        Descriptor values other than symbolic (<xref name="symbol"/>) or numeric
        (<xref name="ulong"/>) are, while not syntactically invalid, reserved - this includes
        numeric types other than <xref name="ulong"/>. To allow for users of the type system to
        define their own descriptors without collision of descriptor values, an assignment policy
        for symbolic and numeric descriptors is given below.
       </p>

       <p>
        The namespace for both symbolic and numeric descriptors is divided into distinct domains.
        Each domain has a defined symbol and/or 4 byte numeric id assigned by the AMQP working
        group. For numeric ids the assigned domain-id will be equal to the IANA Private Enterprise
        Number (PEN) of the requesting organisation (<xref type="extern"
        name="http://www.iana.org/assignments/enterprise-numbers"/>) with domain-id 0 reserved for
        descriptors defined in the AMQP Specification.
      </p>

      <p>
        Descriptors are then assigned within each domain according to the following rules:
      </p>

      <dl>
        <dt>symbolic descriptors</dt>
        <dd>
          <p><i>&lt;domain&gt;</i><b>:</b><i>&lt;name&gt;</i></p>
        </dd>

        <dt>numeric descriptors</dt>
        <dd>
          <p>
            (<i>domain-id</i> &lt;&lt; 32) | <i>descriptor-id</i>
          </p>
        </dd>
      </dl>
    </doc>
  </section>

  <section name="encodings" title="Type Encodings" label="standard type encodings">
    <doc>
      <p>
        An AMQP encoded data stream consists of untyped bytes with embedded constructors. The
        embedded constructor indicates how to interpret the untyped bytes that follow. Constructors
        can be thought of as functions that consume untyped bytes from an open ended byte stream and
        construct a typed value. An AMQP encoded data stream always begins with a constructor.
      </p>

      <picture title="Primitive Format Code (String)"><![CDATA[
       constructor            untyped bytes
            |                      |
          +--+   +-----------------+-----------------+
          |  |   |                                   |
     ...  0xA1   0x1E "Hello Glorious Messaging World"  ...
           |     |  |              |                 |
           |     |  |         utf8 bytes             |
           |     |  |                                |
           |     | # of data octets                  |
           |     |                                   |
           |     +-----------------+-----------------+
           |                       |
           |        string value encoded according
           |          to the str8-utf8 encoding
           |
  primitive format code
for the str8-utf8 encoding
]]>
      </picture>

      <p>
        An AMQP constructor consists of either a primitive format code, or a described format code.
        A primitive format code is a constructor for an AMQP primitive type. A described format code
        consists of a descriptor and a primitive format-code. A descriptor defines how to produce a
        domain specific type from an AMQP primitive value.
      </p>

      <picture title="Described Format Code (URL)"><![CDATA[
            constructor                       untyped bytes
                 |                                 |
     +-----------+-----------+   +-----------------+-----------------+
     |                       |   |                                   |
...  0x00 0xA1 0x03 "URL" 0xA1   0x1E "http://example.org/hello-world"  ...
          |             |  |     |                                   |
          +------+------+  |     |                                   |
                 |         |     |                                   |
            descriptor     |     +------------------+----------------+
                           |                        |
                           |         string value encoded according
                           |           to the str8-utf8 encoding
                           |
                  primitive format code
                for the str8-utf8 encoding

     (Note: this example shows a string-typed descriptor, which should be
      considered reserved)
]]>
      </picture>

      <p>
        The descriptor portion of a described format code is itself any valid AMQP encoded value,
        including other described values. The formal BNF for constructors is given below.
      </p>

      <picture title="Constructor BNF"><![CDATA[
  constructor = format-code
              / %x00 descriptor constructor

  format-code = fixed / variable / compound / array
        fixed = empty / fixed-one / fixed-two / fixed-four
              / fixed-eight / fixed-sixteen
     variable = variable-one / variable-four
     compound = compound-one / compound-four
        array = array-one / array-four

   descriptor = value
        value = constructor untyped-bytes
untyped-bytes = *OCTET ; this is not actually *OCTET, the
                       ; valid byte sequences are restricted
                       ; by the constructor

; fixed width format codes
        empty = %x40-4E / %x4F %x00-FF
    fixed-one = %x50-5E / %x5F %x00-FF
    fixed-two = %x60-6E / %x6F %x00-FF
   fixed-four = %x70-7E / %x7F %x00-FF
  fixed-eight = %x80-8E / %x8F %x00-FF
fixed-sixteen = %x90-9E / %x9F %x00-FF

; variable width format codes
 variable-one = %xA0-AE / %xAF %x00-FF
variable-four = %xB0-BE / %xBF %x00-FF

; compound format codes
 compound-one = %xC0-CE / %xCF %x00-FF
compound-four = %xD0-DE / %xDF %x00-FF

; array format codes
    array-one = %xE0-EE / %xEF %x00-FF
   array-four = %xF0-FE / %xFF %x00-FF
]]>
      </picture>

      <p>
        Format codes map to one of four different categories: fixed width, variable width, compound
        and array. Values encoded within each category share the same basic structure parameterized
        by width. The subcategory within a format-code identifies both the category and width.
      </p>

      <dl>
        <dt>Fixed Width</dt>
        <dd>
          <p>
            The size of fixed-width data is determined based solely on the subcategory of the format
            code for the fixed width value.
          </p>
        </dd>
      </dl>

      <dl>
        <dt>Variable Width</dt>
        <dd>
          <p>
            The size of variable-width data is determined based on an encoded size that prefixes the
            data. The width of the encoded size is determined by the subcategory of the format code
            for the variable width value.
          </p>
        </dd>

        <dt>Compound</dt>
        <dd>
          <p>
            Compound data is encoded as a size and a count followed by a polymorphic sequence
            of <i>count</i> constituent values. Each constituent value is preceded by a constructor
            that indicates the semantics and encoding of the data that follows. The width of the
            size and count is determined by the subcategory of the format code for the compound
            value.
          </p>
        </dd>

        <dt>Array</dt>
        <dd>
          <p>
            Array data is encoded as a size and count followed by an array element constructor
            followed by a monomorphic sequence of values encoded according to the supplied array
            element constructor. The width of the size and count is determined by the subcategory of
            the format code for the array.
          </p>
        </dd>
      </dl>

      <p>
        The bits within a format code may be interpreted according to the following layout:
      </p>

      <picture><![CDATA[
Bit:  7    6    5    4    3    2    1    0
     +------------------------------------+ +----------+
     |   subcategory   |     subtype      | | ext-type |
     +------------------------------------+ +----------+
                   1 octet                    1 octet
     |                                                 |
     +-------------------------------------------------+
                             |
                        format-code

         ext-type: only present if subtype is 0xF
]]>
      </picture>

      <p>
        The following table describes the subcategories of format-codes:
      </p>

      <picture>
Subcategory  Category        Format
==============================================================================
0x4          Fixed Width     Zero octets of data.
0x5          Fixed Width     One octet of data.
0x6          Fixed Width     Two octets of data.
0x7          Fixed Width     Four octets of data.
0x8          Fixed Width     Eight octets of data.
0x9          Fixed Width     Sixteen octets of data.

0xA          Variable Width  One octet of size, 0-255 octets of data.
0xB          Variable Width  Four octets of size, 0-4294967295 octets of data.

0xC          Compound        One octet each of size and count, 0-255 distinctly
                             typed values.
0xD          Compound        Four octets each of size and count, 0-4294967295
                             distinctly typed values.

0xE          Array           One octet each of size and count, 0-255 uniformly
                             typed values.
0xF          Array           Four octets each of size and count, 0-4294967295
                             uniformly typed values.
      </picture>

      <p>
        Please note, unless otherwise specified, AMQP uses network byte order for all numeric
        values.
      </p>
    </doc>

    <doc title="Fixed Width">
      <p>
        The width of a specific fixed width encoding may be computed from the subcategory of the
        format code for the fixed width value:
      </p>

      <picture><![CDATA[
    n OCTETs
  +----------+
  |   data   |
  +----------+

Subcategory     n
=================
0x4             0
0x5             1
0x6             2
0x7             4
0x8             8
0x9             16
]]>
      </picture>
    </doc>

    <type class="primitive" name="null" label="indicates an empty value">
      <encoding code="0x40" category="fixed" width="0" label="the null value"/>
    </type>

    <type class="primitive" name="boolean" label="represents a true or false value">
      <encoding code="0x56" category="fixed" width="1"
                label="boolean with the octet 0x00 being false and octet 0x01 being true"/>
      <encoding name="true" code="0x41" category="fixed" width="0" label="the boolean value true"/>
      <encoding name="false" code="0x42" category="fixed" width="0"
                label="the boolean value false"/>
    </type>

    <type class="primitive" name="ubyte" label="integer in the range 0 to 2^8 - 1 inclusive">
      <encoding code="0x50" category="fixed" width="1" label="8-bit unsigned integer"/>
    </type>

    <type class="primitive" name="ushort" label="integer in the range 0 to 2^16 - 1 inclusive">
      <encoding code="0x60" category="fixed" width="2"
                label="16-bit unsigned integer in network byte order"/>
    </type>

    <type class="primitive" name="uint" label="integer in the range 0 to 2^32 - 1 inclusive">
      <encoding code="0x70" category="fixed" width="4"
                label="32-bit unsigned integer in network byte order"/>
      <encoding name="smalluint" code="0x52" category="fixed" width="1"
                label="unsigned integer value in the range 0 to 255 inclusive"/>
      <encoding name="uint0" code="0x43" category="fixed" width="0" label="the uint value 0"/>
    </type>

    <type class="primitive" name="ulong" label="integer in the range 0 to 2^64 - 1 inclusive">
      <encoding code="0x80" category="fixed" width="8"
                label="64-bit unsigned integer in network byte order"/>
      <encoding name="smallulong" code="0x53" category="fixed" width="1"
                label="unsigned long value in the range 0 to 255 inclusive"/>
      <encoding name="ulong0" code="0x44" category="fixed" width="0" label="the ulong value 0"/>
    </type>

    <type class="primitive" name="byte" label="integer in the range -(2^7) to 2^7 - 1 inclusive">
      <encoding code="0x51" category="fixed" width="1" label="8-bit two's-complement integer"/>
    </type>

    <type class="primitive" name="short" label="integer in the range -(2^15) to 2^15 - 1 inclusive">
      <encoding code="0x61" category="fixed" width="2"
                label="16-bit two's-complement integer in network byte order"/>
    </type>

    <type class="primitive" name="int" label="integer in the range -(2^31) to 2^31 - 1 inclusive">
      <encoding code="0x71" category="fixed" width="4"
                label="32-bit two's-complement integer in network byte order"/>
      <encoding name="smallint" code="0x54" category="fixed" width="1"
                label="signed integer value in the range -128 to 127 inclusive"/>
    </type>

    <type class="primitive" name="long" label="integer in the range -(2^63) to 2^63 - 1 inclusive">
      <encoding code="0x81" category="fixed" width="8"
                label="64-bit two's-complement integer in network byte order"/>
      <encoding name="smalllong" code="0x55" category="fixed" width="1"
                label="signed long value in the range -128 to 127 inclusive"/>
    </type>

    <type class="primitive" name="float"
          label="32-bit floating point number (IEEE 754-2008 binary32)">
      <encoding name="ieee-754" code="0x72" category="fixed" width="4"
                label="IEEE 754-2008 binary32"/>
    </type>

    <type class="primitive" name="double"
          label="64-bit floating point number (IEEE 754-2008 binary64)">
      <encoding name="ieee-754" code="0x82" category="fixed" width="8"
                label="IEEE 754-2008 binary64"/>
    </type>

    <type class="primitive" name="decimal32"
          label="32-bit decimal number (IEEE 754-2008 decimal32)">
      <encoding name="ieee-754" code="0x74" category="fixed" width="4"
                label="IEEE 754-2008 decimal32 using the Binary Integer Decimal encoding"/>
    </type>

    <type class="primitive" name="decimal64"
          label="64-bit decimal number (IEEE 754-2008 decimal64)">
      <encoding name="ieee-754" code="0x84" category="fixed" width="8"
                label="IEEE 754-2008 decimal64 using the Binary Integer Decimal encoding"/>
    </type>

    <type class="primitive" name="decimal128"
          label="128-bit decimal number (IEEE 754-2008 decimal128)">
      <encoding name="ieee-754" code="0x94" category="fixed" width="16"
                label="IEEE 754-2008 decimal128 using the Binary Integer Decimal encoding"/>
    </type>

    <type class="primitive" name="char" label="a single unicode character">
      <encoding name="utf32" code="0x73" category="fixed" width="4"
                label="a UTF-32BE encoded unicode character"/>
    </type>

    <type class="primitive" name="timestamp" label="an absolute point in time">
      <encoding name="ms64" code="0x83" category="fixed" width="8"
                label="64-bit signed integer representing milliseconds since the unix epoch">
        <doc>
          <p>
            Represents an approximate point in time using the Unix time_t encoding of UTC, but with
            a precision of milliseconds. For example, 1311704463521 represents the moment
            2011-07-26T18:21:03.521Z.
          </p>
        </doc>
      </encoding>
    </type>

    <type class="primitive" name="uuid"
          label="a universally unique id as defined by RFC-4122 section 4.1.2">
      <encoding code="0x98" category="fixed" width="16"
                label="UUID as defined in section 4.1.2 of RFC-4122"/>
    </type>

    <doc title="Variable Width">
      <p>
        All variable width encodings consist of a size in octets followed by <i>size</i> octets of
        encoded data. The width of the size for a specific variable width encoding may be computed
        from the subcategory of the format code:
      </p>

      <picture><![CDATA[
  n OCTETs   size OCTETs
+----------+-------------+
|   size   |    value    |
+----------+-------------+

    Subcategory     n
    =================
    0xA             1
    0xB             4
]]>
      </picture>
    </doc>

    <type class="primitive" name="binary" label="a sequence of octets">
      <encoding name="vbin8" code="0xa0" category="variable" width="1"
                label="up to 2^8 - 1 octets of binary data"/>

      <encoding name="vbin32" code="0xb0" category="variable" width="4"
                label="up to 2^32 - 1 octets of binary data"/>
    </type>

    <type class="primitive" name="string" label="a sequence of unicode characters">
      <doc>
        <p>
           A string represents a sequence of unicode characters as defined by the Unicode V6.0.0
           standard (see http://www.unicode.org/versions/Unicode6.0.0).
        </p>
      </doc>
      <encoding name="str8-utf8" code="0xa1" category="variable" width="1"
                label="up to 2^8 - 1 octets worth of UTF-8 unicode (with no byte order mark)"/>

      <encoding name="str32-utf8" code="0xb1" category="variable" width="4"
                label="up to 2^32 - 1 octets worth of UTF-8 unicode (with no byte order mark)"/>
    </type>

    <type class="primitive" name="symbol" label="symbolic values from a constrained domain">
      <doc>
        <p>
          Symbols are values from a constrained domain. Although the set of possible domains is
          open-ended, typically the both number and size of symbols in use for any given application
          will be small, e.g. small enough that it is reasonable to cache all the distinct values.
        </p>
      </doc>

      <encoding name="sym8" code="0xa3" category="variable" width="1"
                label="up to 2^8 - 1 seven bit ASCII characters representing a symbolic value"/>

      <encoding name="sym32" code="0xb3" category="variable" width="4"
                label="up to 2^32 - 1 seven bit ASCII characters representing a symbolic value"/>
    </type>

    <doc title="Compound">
      <p>
        All compound encodings consist of a size and a count followed by <i>count</i> encoded items.
        The width of the size and count for a specific compound encoding may be computed from the
        category of the format code:
      </p>

      <picture><![CDATA[
                      +----------= count items =----------+
                      |                                   |
  n OCTETs   n OCTETs |                                   |
+----------+----------+--------------+------------+-------+
|   size   |  count   |      ...    /|    item    |\ ...  |
+----------+----------+------------/ +------------+ \-----+
                                  / /              \ \
                                 / /                \ \
                                / /                  \ \
                               +-------------+----------+
                               | constructor |   data   |
                               +-------------+----------+

                   Subcategory     n
                   =================
                   0xC             1
                   0xD             4
]]>
      </picture>
    </doc>

    <type class="primitive" name="list" label="a sequence of polymorphic values">
      <encoding name="list0" code="0x45" category="fixed" width="0"
                label="the empty list (i.e. the list with no elements)"/>
      <encoding name="list8" code="0xc0" category="compound" width="1"
                label="up to 2^8 - 1 list elements with total size less than 2^8 octets"/>
      <encoding name="list32" code="0xd0" category="compound" width="4"
                label="up to 2^32 - 1 list elements with total size less than 2^32 octets"/>
    </type>

    <type class="primitive" name="map"
          label="a polymorphic mapping from distinct keys to values">
      <doc>
          <p>
            A map is encoded as a compound value where the constituent elements form alternating key
            value pairs.
          </p>

          <picture><![CDATA[
 item 0   item 1      item n-1    item n
+-------+-------+----+---------+---------+
| key 1 | val 1 | .. | key n/2 | val n/2 |
+-------+-------+----+---------+---------+
]]>
          </picture>
        <p>
          Map encodings must contain an even number of items (i.e. an equal number of keys and
          values). A map in which there exist two identical key values is invalid. Unless known to
          be otherwise, maps must be considered to be ordered - that is the order of the key-value
          pairs is semantically important and two maps which are different only in the order in
          which their key-value pairs are encoded are not equal.
        </p>
      </doc>
      <encoding name="map8" code="0xc1" category="compound" width="1"
                label="up to 2^8 - 1 octets of encoded map data"/>
      <encoding name="map32" code="0xd1" category="compound" width="4"
                label="up to 2^32 - 1 octets of encoded map data"/>
    </type>

    <doc title="Array">
      <p>
        All array encodings consist of a size followed by a count followed by an element constructor
        followed by <i>count</i> elements of encoded data formated as required by the element
        constructor:
      </p>

      <picture><![CDATA[
                                            +--= count elements =--+
                                            |                      |
  n OCTETs   n OCTETs                       |                      |
+----------+----------+---------------------+-------+------+-------+
|   size   |  count   | element-constructor |  ...  | data |  ...  |
+----------+----------+---------------------+-------+------+-------+

                        Subcategory     n
                        =================
                        0xE             1
                        0xF             4
]]>
      </picture>
    </doc>

    <type class="primitive" name="array" label="a sequence of values of a single type">
      <encoding name="array8" code="0xe0" category="array" width="1"
                label="up to 2^8 - 1 array elements with total size less than 2^8 octets"/>
      <encoding name="array32" code="0xf0" category="array" width="4"
                label="up to 2^32 - 1 array elements with total size less than 2^32 octets"/>
    </type>

    <doc title="List of Encodings">
      <!--EncodingListTable-->
    </doc>

  </section>

  <!-- == Section: composite-types ============================================================= -->

  <section name="composite-types" title="Composite Types"
           label="composite type notation and encoding">
    <doc>
      <p>
        AMQP defines a number of <i>composite types</i> used for encoding structured data such as
        frame bodies. A composite type describes a composite value where each constituent value is
        identified by a well known named <i>field</i>. Each composite type definition includes an
        ordered sequence of fields, each with a specified name, type, and multiplicity. Composite
        type definitions also include one or more descriptors (symbolic and/or numeric) for
        identifying their defined representations.
      </p>

      <p>
        Composite types are formally defined in the XML documents included with the specification.
        The following notation is used to define them:
      </p>

      <picture title="Example Composite Type"><![CDATA[
<type class="composite" name="book" label="example composite type">
  <doc>
    <p>An example composite type.</p>
  </doc>

  <descriptor name="example:book:list" code="0x00000003:0x00000002"/>

  <field name="title" type="string" mandatory="true" label="title of the book"/>

  <field name="authors" type="string" multiple="true"/>

  <field name="isbn" type="string" label="the ISBN code for the book"/>
</type>
]]>
      </picture>

      <p>
        The <i>mandatory</i> attribute of a field description controls whether a null element value
        is permitted in the representation.
      </p>
      <p>
        The <i>multiple</i> attribute of a field description controls whether multiple element
        values are permitted in the representation. A single element of the type specified in the
        field description is always permitted.  Multiple values are represented by the use of an
        array where the type of the elements in the array is the type defined in the field
        definition.  Note that a null value and a zero-length array (with a correct type for its
        elements) both describe an absence of a value and should be treated as semantically
        identical.
      </p>
      <p>
        A field which is defined as both multiple and mandatory MUST contain at least one value
        (i.e. for such a field both <i>null</i> and an array with no entries are invalid).
      </p>
    </doc>

    <doc title="List Encoding">
      <p>
        AMQP composite values are encoded as a described list. Each element in the list is
        positionally correlated with the fields listed in the composite type definition. The
        permitted element values are determined by the type specification and multiplicity of the
        corresponding field definitions. When the trailing elements of the list representation are
        null, they MAY be omitted. The descriptor of the list indicates the specific composite type
        being represented.
      </p>

      <p>
        The described list shown below is an example composite value of the <i>book</i> type defined
        above. A trailing null element corresponding to the absence of an ISBN value is depicted in
        the example, but may optionally be omitted according to the encoding rules.
      </p>

      <picture title="Example Composite Value"><![CDATA[
             constructor                  list representation of a book
                  |                                   |
+-----------------+-------------------+ +-------------+---------------+
|                                     | |                             |
0x00 0xA3 0x11 "example:book:list" 0xC0 0x40 0x03  title  authors  isbn
      |                 |                            |       |       |
      |      identifies composite type               |       |       |
      |                                              |       |     0x40
    sym8                      +----------------------+       |       |
  (symbol)                    |                              |  null value
               +--------------+----------------+             |
               |                               |             |
               0xA1 0x15 "AMQP for & by Dummies"             |
                                                             |
+------------------------------------------------------------+-----+
|                                                                  |
0xE0 0x25 0x02 0xA1 0x0E "Rob J. Godfrey" 0x13 "Rafael H. Schloming"
      |    |    |   |                   | |                        |
    size   |    |   +---------+---------+ +-----------+------------+
           |    |             |                       |
         count  |        first element          second element
                |
        element constructor
]]>
      </picture>
    </doc>
  </section>

</amqp>
