AMP Argument Types =========================================================== .. toctree:: :maxdepth: 2 :caption: Contents: types Values in **AMP** are strongly, statically typed. `This is a good thing `_. The standard types are defined below, however you may also define arbitrary types with a serialization format of your choosing. Provided, of course, that both sides of the connection can handle them. Other implementations may, or may not, provide all of these types; however it is generally not difficult to implement additional **AMP** types yourself, given a particular implementation. Basic Types +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The basic **AMP** types represent simple values common in many programming languages. Integer ----------------------------------------------------------- * Integers are encoded as their base-10 string representation in UTF-8, e.g. ``123`` or ``-20``. * **AMP** does not impose any restriction on the range of integer values, but specific implementations may impose restrictions depending on how integers are stored in the implementation language. Bytes (or *String* in Twisted) ----------------------------------------------------------- * A sequence of bytes. (e.g. a C# ``byte[]`` or a Python 2.x ``str`` object). * Values are placed on the wire as they are; no encoding necessary. Text (or *Unicode*) ----------------------------------------------------------- * A sequence of Unicode code-points. (e.g a C# ``string`` or a Python 2.x ``unicode`` object). * Encoded on the wire in UTF-8. Boolean ----------------------------------------------------------- * A truth value. * Encoded as either the UTF-8 string ``True`` or ``False``. Float ----------------------------------------------------------- * A hardware-precision floating-point value. (e.g. a C# ``double`` or a Python ``float``). * Encoded as a UTF-8 string, e.g. ``123``, ``10.`` or ``-123.40000000000001``. * **AMP** places no restriction on the range of valid floating-point values, however specific implementations may impose restrictions depending on how floats are stored in the underlying language. * Special values are encoded as special UTF-8 strings: - Positive infinity is encoded as ``inf``. - Negative infinity is encoded as ``-inf``. - Not-a-number is encoded as ``nan``. Decimal ----------------------------------------------------------- * An exact-precision decimal number. (e.g. a C# ``decimal`` or a Python ``decimal.Decimal`` object). * Special values are encoded as special UTF-8 strings: - Positive infinity is encoded as ``Infinity``. - Negative infinity is encoded as ``-Infinity``. - Quiet not-a-number is encoded as either ``NaN`` or ``-NaN``. - Signaling not-a-number is encoded as either ``sNaN`` or ``-sNaN``. * Normal values are encoded using the base-ten string representation, using engineering notation to indicate magnitude without precision, and "normal" digits to indicate precision. For example: - ``1`` represents the value *1* with precision to one place. - ``-1`` represents the value *-1* with precision to one place. - ``1.0`` represents the value *1* with precision to two places. - ``10`` represents the value *10* with precision to two places. - ``1E+2`` represents the value *10* with precision to one place. - ``1E-1`` represents the value *0.1* with precision to one place. - ``1.5E+2`` represents the value *150* with precision to two places. DateTime ----------------------------------------------------------- * An exact wall-clock date and time. * Encoded in UTF-8 according to the following *format string*: - ``%04i-%02i-%02iT%02i:%02i:%02i.%06i%s%02i:%02i`` * Fields, in order, are: - ``year (1-9999)`` - ``month (1-12)`` - ``day (1-31)`` - ``hour (0-23)`` - ``minute (0-59)`` - ``second (0-59)`` - ``microsecond (0-999999)`` - ``timezone direction (+ or -)`` - ``timezone hour (0-23)`` - ``timezone minute (0-59)`` * The encoded string is always exactly 32 characters long. This format is compatible with ``ISO 8601``, but that does not mean all ``ISO 8601`` dates can be accepted. * The timezone fields give the offset from ``UTC`` of the Time Zone that the ``DateTime`` falls in to. An **AMP** ``DateTime`` does not encode Day Light Savings information - such information should be transferred separately if needed. - Example: ``1969-08-15T12:00:00.000000+00:00`` - Example: ``2012-01-23T12:34:56.054321-01:23`` Compound Types +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * Compound types encode one or more basic **AMP** types, as detailed above, in to a single **AMP** value. ListOf ----------------------------------------------------------- * A sequence of another **AMP** Type. e.g. ``ListOf(Integer)``. All objects in the list must be of the same type. Arbitrary nesting is allowed so you could have e.g. ``ListOf(ListOf(Bytes))`` for a 2-D matrix of byte-strings. * The value of a ``ListOf`` is comprised of zero or more adjacent, individually-encoded elements. ``ListOf`` is just another ``AMP`` type, and as such it has its own 16-bit length-prefix, meaning the total encoded length of all elements in the list must not exceed ``65,535`` bytes. * Each element of the list is `encoded according to the normal rules `__ for **AMP** values (a 16-bit prefix value is placed on the wire, followed by the data for that element, not exceeding 64k). Each element is encoded and placed on the wire one after another. AmpList ----------------------------------------------------------- * An **AMP** **message** is a collection of key/value pairs that follow a common schema, and is also known as a *box*, or *packet* - ``AmpList``, then, is just a sequence of zero or more **AMP messages**, encoded adjacently on the wire. For example, is pseudo-code you might define an ``AmpList`` like this:: MyAmpList: "foo" => Integer() "bar" => Text() "baz" => ListOf(Float()) * Then arguments of this type would comprise a sequence of zero or more **messages** (dictionaries), each with a ``foo``, ``bar`` and ``baz`` key. Values conform to the given types, in this case ``Integer``, ``Text`` and ``ListOf(Float)``. Any value types supported by your **AMP** implementation may be used. As with ``ListOf``, arbitrary nesting is allowed, so a value in your ``AmpList`` could contain another ``AmpList`` with a different key/value schema. * ``AmpList`` is just another ``AMP`` type, and as such it has its own 16-bit length-prefix, meaning the total encoded length of all **messages** in the sequence must not exceed ``65,535`` bytes. * An ``AmpList`` value is encoded as follows. Each **message** in the sequence is encoded and placed on the wire, one after another. A **message** is `encoded following the normal AMP protocol rules `__. (That is, the key length is encoded as a 16-bit big-endian integer and placed on the wire, followed by the bytes that make up the key name. As normal, keys may not be longer than 255 bytes. Then the value length is encoded as a 16-bit big-endian integer and placed on the wire, followed by the bytes that make up the value). * The **message** is terminated with an empty key (2 ``null`` bytes - ``0x0000``).