<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">

<rfc category="std" ipr="full3978" docName="hessian.txt">

<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>

<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>

  <front>
    <title>Hessian 2.0 Serialization Protocol</title>
    <author initials="S." surname="Ferguson" fullname="Scott Ferguson">
      <organization>Caucho Technology Inc.</organization>
      <address>
        <postal>
          <street>P.O. Box 9001</street>
          <city>La Jolla</city>
          <region>CA</region>
          <code>92038</code>
          <country>USA</country>
        </postal>
        <email>ferg@caucho.com</email>
      </address>
    </author>
    <author initials="E." surname="Ong" fullname="Emil Ong">
      <organization>Caucho Technology Inc.</organization>
      <address>
        <postal>
          <street>P.O. Box 9001</street>
          <city>La Jolla</city>
          <region>CA</region>
          <code>92038</code>
          <country>USA</country>
        </postal>
        <email>emil@caucho.com</email>
      </address>
    </author>
    <date month="August" year="2007" />
  </front>
  
  <middle>
    <section title="Introduction">
      <t>
        Hessian is a dynamically-typed, binary serialization and Web
Services protocol designed for object-oriented transmission.
      </t>
    </section>

    <section title="Design Goals">
      <t>
        Hessian is dynamically-typed, compact, and portable across languages.
      </t>
      <t>
      The Hessian protocol has the following design goals:
      </t>
      <list style="symbols">
        <t>
          It must self-describe the serialized types, i.e. not require
external schema or interface definitions.
        </t>
        <t>It must be language-independent, including supporting
scripting languages.</t>
        <t>It must be readable or writable in a single pass.</t>
        <t>It must be as compact as possible.</t>
        <t>
          It must be simple so it can be effectively tested and implemented.
        </t>
        <t>It must be as fast as possible.</t>
        <t>It must support Unicode strings.</t>
        <t>
          It must support 8-bit binary data without escaping or using 
          attachments.
        </t>
        <t>
          It must support encryption, compression, signature, and
          transaction context envelopes.
        </t>
      </list>
    </section>

    <section title="Hessian Grammar">
      <figure anchor="serialization_grammar">
        <preamble>Serialization Grammar</preamble>
        <artwork>
           # starting production
top        ::= value

           # 8-bit binary data split into 64k chunks
binary     ::= 'b' b1 b0 &lt;binary-data> binary # non-final chunk
           ::= 'B' b1 b0 &lt;binary-data>        # final chunk
           ::= [x20-x2f] &lt;binary-data>        # binary data of 
                                                 #  length 0-15

           # boolean true/false
boolean    ::= 'T'
           ::= 'F'

           # definition for an object (compact map)
class-def  ::= 'O' type int string*

           # time in UTC encoded as 64-bit long milliseconds since 
           #  epoch
date       ::= 'd' b7 b6 b5 b4 b3 b2 b1 b0

           # 64-bit IEEE double
double     ::= 'D' b7 b6 b5 b4 b3 b2 b1 b0
           ::= x67                   # 0.0
           ::= x68                   # 1.0
           ::= x69 b0                # byte cast to double 
                                     #  (-128.0 to 127.0)
           ::= x6a b1 b0             # short cast to double
           ::= x6b b3 b2 b1 b0       # 32-bit float cast to double

           # 32-bit signed integer
int        ::= 'I' b3 b2 b1 b0
           ::= [x80-xbf]             # -x10 to x3f
           ::= [xc0-xcf] b0          # -x800 to x7ff
           ::= [xd0-xd7] b1 b0       # -x40000 to x3ffff

           # list/vector length 
length     ::= 'l' b3 b2 b1 b0
           ::= x6e int

           # list/vector
list       ::= 'V' type? length? value* 'z'
           ::= 'v' int int value*    # type-ref, length

           # 64-bit signed long integer
long       ::= 'L' b7 b6 b5 b4 b3 b2 b1 b0
           ::= [xd8-xef]             # -x08 to x0f
           ::= [xf0-xff] b0          # -x800 to x7ff
           ::= [x38-x3f] b1 b0       # -x40000 to x3ffff
           ::= x77 b3 b2 b1 b0       # 32-bit integer cast to long

           # map/object
map        ::= 'M' type? (value value)* 'z'  # key, value map pairs

           # null value
null       ::= 'N'

           # Object instance
object     ::= 'o' int value*

           # value reference (e.g. circular trees and graphs)
ref        ::= 'R' b3 b2 b1 b0    # reference to nth map/list/object in 
                                  #  stream
           ::= x4a b0             # reference to 1-255th map/list/object
           ::= x4b b1 b0          # reference to 1-65535th map/list/object

           # UTF-8 encoded character string split into 64k chunks
string     ::= 's' b1 b0 &lt;utf8-data> string  # non-final chunk
           ::= 'S' b1 b0 &lt;utf8-data>         # string of length 
                                             #  0-65535
           ::= [x00-x1f] &lt;utf8-data>         # string of length 
                                             #  0-31

           # map/list types for OO languages
type       ::= 't' b1 b0 &lt;type-string>         # type name
           ::= x75 int                         # type reference

           # main production
value      ::= null
           ::= binary
           ::= boolean
           ::= date
           ::= double
           ::= int
           ::= list
           ::= long
           ::= map
           ::= class-def value
           ::= ref
           ::= string
        </artwork>
      </figure>
    </section>

    <section title="Serialization">
      <t>Hessian's object serialization has 8 primitive types:</t>
      <list style="numbers">
        <t>raw <xref target="#binary">binary</xref> data</t>
        <t><xref target="#boolean">boolean</xref></t>
        <t>64-bit <xref target="#date">date</xref></t>
        <t>64-bit <xref target="#double">double</xref></t>
        <t>32-bit <xref target="#int">int</xref></t>
        <t>64-bit <xref target="#long">long</xref></t>
        <t><xref target="#null">null</xref></t>
        <t>UTF8-encoded <xref target="#string">string</xref></t>
      </list>

      <t>It has 3 recursive types:</t>
      <list style="numbers">
        <t><xref target="#list">list</xref> for lists and arrays</t>
        <t><xref target="#map">map</xref> for maps and dictionaries</t>
        <t><xref target="#object">object</xref> for objects</t>
      </list>

      <t>Finally, it has one special contruct:</t>
      <list style="numbers">
        <t>
          <xref target="#ref">ref</xref> for shared and circular object 
          references.
        </t>
      </list>

      <t>Hessian 2.0 has 3 internal reference maps:</t>
      <list style="numbers">
        <t>An <xref target="#ref-map">object/list reference map</xref>.</t>
        <t>An <xref target="#class-map">class definition reference map</xref>.</t>
        <t>A <xref target="#type-map">type (class name) reference map</xref>.</t>
      </list>

      <section title="binary data" anchor="#binary">
        <figure anchor="binary_grammar">
          <preamble>Binary Grammar</preamble>
          <artwork>
binary ::= b b1 b0 &lt;binary-data> binary
       ::= B b1 b0 &lt;binary-data>
       ::= [x20-x2f] &lt;binary-data>
          </artwork>
        </figure>

        <t>
          Binary data is encoded in chunks.  The octet x42 ('B') encodes
          the final chunk and x62 ('b') represents any non-final chunk.
          Each chunk has a 16-bit length value.
        </t>

        <t>
          len = 256 * b1 + b0
        </t>

        <section title="Compact: short binary">
          <t>
            Binary data with length less than 15 may be encoded by a single
            octet length [x20-x2f].
          </t>

          <t>
            len = code - 0x20
          </t>
        </section>

        <section title="Binary Examples">
          <figure anchor="binary_examples">
            <artwork>
x20               # zero-length binary data

x23 x01 x02 x03   # 3 octet data

B x10 x00 ....    # 4k final chunk of data

b x04 x00 ....    # 1k non-final chunk of data
            </artwork>
          </figure>
        </section>
      </section>

      <section title="boolean" anchor="#boolean">
        <figure anchor="boolean_grammar">
          <preamble>Boolean Grammar</preamble>
          <artwork>
boolean ::= T
        ::= F
          </artwork>
        </figure>

        <t>The octet 'F' represents false and the octet T represents true.</t>

        <section title="Boolean Examples">
          <figure anchor="boolean_examples">
            <artwork>
T   # true
F   # false
            </artwork>
          </figure>
        </section>
      </section>

      <section title="date" anchor="#date">
        <figure anchor="date_grammar">
          <preamble>Date Grammar</preamble>
          <artwork>
date ::= d b7 b6 b5 b4 b3 b2 b1 b0
          </artwork>
        </figure>

        <t>
          Date represented by a 64-bit long of milliseconds since the
          Jan 1 1970 00:00H, UTC.
        </t>

        <section title="Date Examples">
          <figure anchor="date_examples">
            <artwork>
d x00 x00 x00 xd0 x4b x92 x84 xb8   # 2:51:31 May 8, 1998 UTC
            </artwork>
          </figure>
        </section>
      </section>

      <section title="double" anchor="#double">
        <figure anchor="double_grammar">
          <preamble>Double Grammar</preamble>
          <artwork>
double ::= D b7 b6 b5 b4 b3 b2 b1 b0
       ::= x67
       ::= x68
       ::= x69 b0
       ::= x6a b1 b0
       ::= x6b b3 b2 b1 b0
          </artwork>
        </figure>

        <t>A 64-bit IEEE floating pointer number.</t>

        <section title="Compact: double zero">
          <t>The double 0.0 can be represented by the octet x67</t>
        </section>

        <section title="Compact: double one">
          <t>The double 1.0 can be represented by the octet x68</t>
        </section>

        <section title="Compact: double octet">
          <t>
            Doubles between -128.0 and 127.0 with no fractional component
            can be represented in two octets by casting the byte value to a 
            double.
          </t>

          <t>
            value = (double) b0
          </t>
        </section>

        <section title="Compact: double short">
          <t>
            Doubles between -32768.0 and 32767.0 with no fractional component
            can be represented in three octets by casting the short value to a 
            double.
          </t>

          <t>
            value = (double) (256 * b1 + b0)
          </t>
        </section>

        <section title="Compact: double float">
          <t>
            Doubles which are equivalent to their 32-bit float representation
            can be represented as the 4-octet float and then cast to double.
          </t>
        </section>

        <section title="Double Examples">
          <figure anchor="double_examples">
            <artwork>
x67          # 0.0
x68          # 1.0

x69 x00      # 0.0
x69 x80      # -128.0
x69 xff      # 127.0

x70 x00 x00  # 0.0
x70 x80 x00  # -32768.0
x70 xff xff  # 32767.0

D x40 x28 x80 x00 x00 x00 x00 x00  # 12.25
            </artwork>
          </figure>
        </section>
      </section>

      <section title="int" anchor="#int">
        <figure anchor="integer_grammar">
          <preamble>Integer Grammar</preamble>
          <artwork>
int ::= 'I' b3 b2 b1 b0
    ::= [x80-xbf]
    ::= [xc0-xcf] b0
    ::= [xd0-xd7] b1 b0
          </artwork>
        </figure>

        <t>
          A 32-bit signed integer.  An integer is represented by the
          octet x49 ('I') followed by the 4 octets of the integer
          in big-endian order.
        </t>

        <t>
          value = (b3 &lt;&lt; 24) + (b2 &lt;&lt; 16) + (b1 &lt;&lt; 8) + b0;
        </t>

        <section title="Compact: single octet integers">
          <t>
            Integers between -16 and 47 can be encoded by a single octet in the
            range x80 to xbf.
          </t>

          <t>
            value = code - 0x90
          </t>
        </section>

        <section title="Compact: two octet integers">
          <t>
            Integers between -2048 and 2047 can be encoded in two octets with
            the leading byte in the range xc0 to xcf.
          </t>

          <t>
            value = ((code - 0xc8) &lt;&lt; 8) + b0;
          </t>
        </section>

        <section title="Compact: three octet integers">
          <t>
            Integers between -262144 and 262143 can be encoded in three bytes 
            with the leading byte in the range xd0 to xd7.
          </t>

          <t>
            value = ((code - 0xd4) &lt;&lt; 16) + (b1 &lt;&lt; 8) + b0;
          </t>
        </section>

        <section title="Integer Examples">
          <figure anchor="integer_examples">
            <artwork>
x90                # 0
x80                # -16
xbf                # 47

xc8 x00            # 0
xc0 x00            # -2048
xc7 x00            # -256
xcf xff            # 2047

xd4 x00 x00        # 0
xd0 x00 x00        # -262144
xd7 xff xff        # 262143

I x00 x00 x00 x00  # 0
I x00 x00 x01 x2c  # 300
            </artwork>
          </figure>
        </section>
      </section>

      <section title="list" anchor="#list">
        <figure anchor="list_grammar">
          <preamble>List Grammar</preamble>
          <artwork>
list ::= V type? length? value* z
     ::= v int int value*
          </artwork>
        </figure>

        <t>
          An ordered list, like an array.  All lists have a type string, a 
          length, a list of values, and a trailing octet x7a ('z').
          The type string may be an arbitrary UTF-8 string understood by
          the service. The length may be omitted to indicate that
          the list is variable length.
        </t>

        <t>
          Each list item is added to the reference list to handle shared and 
          circular elements.  See the ref element.
        </t>

        <t>
          Any parser expecting a list must also accept a null or a shared ref.
        </t>

        <t>
          The valid values of type are not specified in this document and 
          may depend on the specific application.  For example, a server 
          implemented in a language with static typing which exposes an Hessian 
          interface can use the type information to instantiate the specific 
          array type.  On the other hand, a server written in a dynamicly-typed 
          language would likely ignore the contents of type entirely and create 
          a generic array.
        </t>

        <section title="Compact: repeated list">
          <t>
            Hessian 2.0 allows a compact form of the list for successive lists 
            of the same type where the length is known beforehand.  The type 
            and length are encoded by integers, where the type is a reference 
            to an earlier specified type.
          </t>
        </section>

        <section title="List examples">
          <figure anchor="list_example_1">
            <preamble>
              Serialization of a typed int array: int[] = {0, 1}
            </preamble>
            <artwork>
V
  t x00 x04 [int     # encoding of int[] type
  x6e x02            # length = 2
  x90                # integer 0
  x91                # integer 1
  z
            </artwork>
          </figure>

          <figure anchor="list_example_2">
            <preamble>Anonymous variable-length list = {0, "foobar"}</preamble>
            <artwork>
V
  t x00 x04 [int     # encoding of int[] type
  x6e x02            # length = 2
  x90                # integer 0
  x91                # integer 1
  z
            </artwork>
          </figure>

          <figure anchor="list_example_3">
            <preamble>Repeated list type</preamble>
            <artwork>
V
  t x00 x04 [int   # type for int[] (save as type #1)
  x63 x02          # length 2
  x90              # integer 0
  x91              # integer 1
  z

v
  x91              # type reference to int[] (integer #1)
  x92              # length 2
  x92              # integer 2
  x93              # integer 3
            </artwork>
          </figure>
        </section>
      </section>

      <section title="long" anchor="#long">
        <figure anchor="long_grammar">
          <preamble>Long Grammar</preamble>
          <artwork>
long ::= L b7 b6 b5 b4 b3 b2 b1 b0
     ::= [xd8-xef]
     ::= [xf0-xff] b0
     ::= [x38-x3f] b1 b0
     ::= x77 b3 b2 b1 b0
          </artwork>
        </figure>

        <t>
          A 64-bit signed integer.  An long is represented by the
          octet x4c ('L' )
          followed by the 8-bytes of the integer in big-endian order.
        </t>

        <section title="Compact: single octet longs">
          <t>
            Longs between -8 and 15 are represented by a single octet in the
            range xd8 to xef.
          </t>

          <t>
             value = (code - 0xe0)
          </t>
        </section>

        <section title="Compact: two octet longs">
          <t>
            Longs between -2048 and 2047 are encoded in two octets with
            the leading byte in the range xf0 to xff.
          </t>

          <t>
             value = ((code - 0xf8) &lt;&lt; 8) + b0
          </t>
        </section>

        <section title="Compact: three octet longs">
          <t>
            Longs between -262144 and 262143 are encoded in three octets with
            the leading byte in the range x38 to x3f.
          </t>

          <t>
             value = ((code - 0x3c) &lt;&lt; 16) + (b1 &lt;&lt; 8) + b0
          </t>
        </section>

        <section title="Compact: four octet longs">
          <t>
            Longs between which fit into 32-bits are encoded in five octets with
            the leading byte x77.
          </t>

          <t>
             value = (b3 &lt;&lt; 24) + (b2 &lt;&lt; 16) + (b1 &lt;&lt; 8) + b0
          </t>
        </section>

        <section title="Long Examples">
          <figure anchor="long_examples">
            <artwork>
xe0                  # 0
xd8                  # -8
xef                  # 15

xf8 x00              # 0
xf0 x00              # -2048
xf7 x00              # -256
xff xff              # 2047

x3c x00 x00          # 0
x38 x00 x00          # -262144
x3f xff xff          # 262143

x77 x00 x00 x00 x00  # 0
x77 x00 x00 x01 x2c  # 300

L x00 x00 x00 x00 x00 x00 x01 x2c  # 300
            </artwork>
          </figure>
        </section>
      </section>

      <section title="map" anchor="#map">
        <figure anchor="map_grammar">
          <preamble>Map Grammar</preamble>
          <artwork>
map        ::= M type? (value value)* z
          </artwork>
        </figure>

        <t>
          Represents serialized maps and can represent objects.
          The type element describes the type of the map.
        </t>

        <t>
          The type may be empty, i.e. a zero length.  The parser is responsible 
          for choosing a type if one is not specified.  For objects, 
          unrecognized keys will be ignored.
        </t>

        <t>
          Each map is added to the reference list.  Any time the parser expects 
          a map, it must also be able to support a null or a ref.
        </t>

        <t>The type is chosen by the service.</t>

        <section title="Map examples">
          <figure anchor="map_example_1">
            <preamble>A sparse array</preamble>
            <artwork>
map = new HashMap();
map.put(new Integer(1), "fee");
map.put(new Integer(16), "fie");
map.put(new Integer(256), "foe");

---

M
  x91       # 1
  x03 fee   # "fee"

  xa0       # 16
  x03 fie   # "fie"

  xb9 x00   # 256
  x03 foe   # "foe"

  z
            </artwork>
          </figure>

          <figure anchor="map_example_2">
            <preamble>Map Representation of a Java Object</preamble>
            <artwork>
public class Car implements Serializable {
  String color = "aquamarine";
  String model = "Beetle";
  int mileage = 65536;
}

---
M
  t x00 x13 com.caucho.test.Car  # type

  x05 color                # color field
  x0a aquamarine

  x05 model                # model field
  x06 Beetle

  x07 mileage              # mileage field
  I x00 x01 x00 x00
  z
            </artwork>
          </figure>
      </section>
      </section>

      <section title="null" anchor="#null">
        <figure anchor="null_grammar">
          <preamble>Null Grammar</preamble>
          <artwork>
null ::= N
          </artwork>
        </figure>

        <t>Null represents a null pointer.</t>

        <t>The octet 'N' represents the null value.</t>
      </section>

      <section title="object" anchor="#object">
        <figure anchor="object_grammar">
          <preamble>Object Grammar</preamble>
          <artwork>
object     ::= 'o' int value*

class-def  ::= 'O' type int string*
          </artwork>
        </figure>

        <section title="Compact: class definition">
          <t>
            Hessian 2.0 has a compact object form where the field names
            are only serialized once.  Following objects only need to serialize
            their values.
          </t>

          <t>
            The object definition includes a mandatory type string, the number 
            of fields, and the field names.  The object definition is stored in 
            the object definition map and will be referenced by object 
            instances with an integer reference.
          </t>
        </section>

        <section title="Compact: object instantiation">
          <t>
            Hessian 2.0 has a compact object form where the field names
            are only serialized once.  Following objects only need to serialize
            their values.
          </t>

          <t>
            The object instantiation creates a new object based on a previous
            definition.  The integer value refers to the object definition.
          </t>
        </section>

        <section title="Object examples">

          <figure anchor="object_example_1">
            <preamble>Object serialization</preamble>
            <artwork>
class Car {
  String color;
  String model;
}

out.writeObject(new Car("red", "corvette"));
out.writeObject(new Car("green", "civic"));

---

O                        # object definition (#0)
  t x00 x0b example.Car  # type is example.Car
  x92                    # two fields
  x05 color              # color field name
  x05 model              # model field name

o
  x90                    # object definition #0
  x03 red                # color field value
  x08 corvette           # model field value

o
  x90                    # object definition #0
  x05 green              # color field value
  x05 civic              # model field value
            </artwork>
          </figure>

          <figure anchor="object_example_2">
            <preamble></preamble>
            <artwork>
enum Color {
  RED,
  GREEN,
  BLUE,
}

out.writeObject(Color.RED);
out.writeObject(Color.GREEN);
out.writeObject(Color.BLUE);
out.writeObject(Color.GREEN);

---

O                         # object definition #0
  t x00 x0b example.Color # type is example.Color
  x91                     # one field
  x04 name                # enumeration field is "name"

o                         # object #0
  x90                     # object definition ref #0
  x03 RED                 # RED value

o                         # object #1
  x90                     # object definition ref #0
  x05 GREEN               # GREEN value

o                         # object #2
  x90                     # object definition ref #0
  x04 BLUE                # BLUE value

x4a x01                   # object ref #1, i.e. Color.GREEN
            </artwork>
          </figure>
        </section>
      </section>

      <section title="ref" anchor="#ref">
        <figure anchor="ref_grammar">
          <preamble>Ref Grammar</preamble>
          <artwork>
ref ::= R b3 b2 b1 b0
    ::= x4a b0
    ::= x4b b1 b0
          </artwork>
        </figure>

        <t>
          An integer referring to a previous list, map, or object instance.
          As each list, map or object is read from the input stream,
          it is assigned the integer position in the stream, i.e. the first
          list or map is '0', the next 
          is '1', etc.  A later ref can then use the previous object.  Writers 
          MAY generate refs.  Parsers MUST be able to 
          recognize them.
        </t>

        <t>
          ref can refer to incompletely-read items.  For example, a circular 
          linked-list will refer to the first link before the entire list has 
          been read.
        </t>

        <t>
          A possible implementation would add each map, list, and object
          to an array as it is read.  The ref will return the corresponding
          value from the array.  To support circular structures, the
          implementation would store the map, list or object immediately,
          before filling in the contents.
        </t>

        <t>
          Each map or list is stored into an array as it is
          parsed.  ref selects one of the stored objects.  The first
          object is numbered '0'.
        </t>

        <section title="Compact: two octet reference">
          <t>
            References between 0 and 255 can be encoded by two octets
          </t>

          <t>
            value = b0
          </t>
        </section>

        <section title="Compact: three octet reference">
          <t>
            References between 0 and 255 can be encoded in three octets
          </t>

          <t>
            value = (b1 &lt;&lt; 8) + b0
          </t>
        </section>

        <section title="Ref Examples">
          <figure anchor="ref_examples">
            <preamble>Circular list</preamble>
            <artwork>
list = new LinkedList();
list.data = 1;
list.tail = list;

---
O
  x9a LinkedList
  x92
  x04 head
  x04 tail

o x90      # object stores ref #0
  x91      # data = 1
  x4b x00  # next field refers to itself, i.e. ref #0
            </artwork>
          </figure>
        </section>

        <t>
          ref only refers to list, map and objects elements.
          Strings and binary data, in particular, will only share references
          if they're wrapped in a list or map.
        </t>
      </section>

      <section title="string" anchor="#string">
        <figure anchor="string_grammar">
          <preamble>String Grammar</preamble>
          <artwork>
string ::= s b1 b0 &lt;utf8-data> string
       ::= S b1 b0 &lt;utf8-data>
       ::= [x00-x1f] &lt;utf8-data>
          </artwork>
        </figure>

        <t> 
          A 16-bit unicode character string encoded in UTF-8.  Strings are 
          encoded in chunks. x53 ('S') represents the final chunk
          and x73 ('s') represents any non-final chunk.  Each chunk
          has a 16-bit length value.
        </t>

        <t>
          The length is the number of characters, which may be different than
          the number of bytes.
        </t>

        <t>String chunks may not split surrogate pairs.</t>

        <section title="Compact: short strings">
          <t>
            Strings with length less than 32 may be encoded with a single
            octet length [x00-x1f].
          </t>

          <t>
            value = code
          </t>
        </section>

        <section title="String Examples">
          <figure anchor="string_examples">
            <artwork>
x00               # "", empty string
x05 hello         # "hello"
x01 xc3 x83       # "\u00c3"

S x00 x05 hello   # "hello" in long form

s x00 x07 hello,  # "hello, world" split into two chunks
  x05 world
            </artwork>
          </figure>
        </section>
      </section>

      <section title="type" anchor="#type">
        <figure anchor="type_grammar">
          <preamble>Type Grammar</preamble>
          <artwork>
type ::= 't' b1 b0 &lt;type-string>
     ::= x4a b0
          </artwork>
        </figure>

        <t>A <xref target="#map">map</xref> or <xref target="#list">list</xref>
        MAY include a type attribute indicating the type name of the
        map or list for object-oriented languages.</t>

        <t>Each type is added to the <xref target="#type-map">type map</xref>
        for future reference.</t>
      </section>

        <section title="Compact: type references">
          <t>
            Repeated type strings MAY use the
            <xref target="#type-map">type map</xref> to refer to a previously
            used type.  The type reference is zero-based over all the
            types encountered during parsing.
          </t>
        </section>
    </section>

    <section title="Reference Maps">
      <t>Hessian 2.0 has 3 internal reference maps:</t>
      <list style="numbers">
        <t>An map/object/list reference map.</t>
        <t>An class definition map.</t>
        <t>A type (class name) map.</t>
      </list>

      <t>The value reference map lets Hessian support arbitrary
      graphs, and recursive and circular data structures.</t>

      <t>The class and type maps improve Hessian efficiency by
      avoiding repetition of common string data.</t>

      <section title="value reference" anchor="#ref-map">
        <t>Hessian supports arbitrary graphs by
        adding <xref target="#list">list</xref>,
        <xref target="#object">object</xref>, and 
        <xref target="#map">map</xref> as it encounters them in
        the bytecode stream.</t>

        <t>Parsers MUST store each list, object and map in the reference
        map as they are encountered.</t>

        <t>The stored objects can be used with a <xref target="#ref">ref</xref>
        bytecode.</t>
      </section>

      <section title="class reference" anchor="#class-map">
        <t>Each <xref target="#object">object definition</xref> is
        automatically added to the class-map.  Parsers MUST add a
        class definition to the class map as each is encountered.
        Following object instances will refer to the defined class.</t>
      </section>

      <section title="type reference" anchor="#type-map">
        <t>The <xref target="#type">type</xref> strings for
        <xref target="#map">map</xref> and <xref target="#list">list</xref>
        values are stored in a type map for reference.</t>

        <t>Parsers MUST add a type string to the type map as
        each is encountered.</t>
    </section>
    </section>

    <section title="Bytecode map">

      <t>
        Hessian is organized as a bytecode protocol.  A Hessian reader 
        is essentially a switch statement on the initial octet.
      </t>

      <figure anchor="bytecode_encoding">
        <preamble>Bytecode Encoding</preamble>
        <artwork>
x00 - x1f    # utf-8 string length 0-32
x20 - x2f    # binary data length 0-16
x30 - x37    # reserved
x38 - x3f    # long from -x40000 to x3ffff
x40 - x41    # reserved
x42          # 8-bit binary data final chunk ('B')
x43          # reserved ('C' streaming call)
x44          # 64-bit IEEE encoded double ('D')
x45          # reserved ('E' envelope)
x46          # boolean false ('F')
x47          # reserved
x48          # reserved ('H' header)
x49          # 32-bit signed integer ('I')
x4a          # reference to 1-256th map/list
x4b          # reference to 1-65536th map/list
x4c          # 64-bit signed long integer ('L')
x4d          # map with optional type ('M')
x4e          # null ('N')
x4f          # object definition ('O')
x50          # reserved ('P' streaming message/post)
x51          # reserved
x52          # reference to map/list - integer ('R')
x53          # utf-8 string final chunk ('S')
x54          # boolean true ('T')
x55          # reserved
x56          # list/vector ('V')
x57 - x62    # reserved
x62          # 8-bit binary data non-final chunk ('b')
x63          # reserved ('c' call for RPC)
x64          # UTC time encoded as 64-bit long milliseconds since 
             #  epoch ('d')
x65          # reserved
x66          # reserved ('f' for fault for RPC)
x67          # double 0.0
x68          # double 1.0
x69          # double represented as byte (-128.0 to 127.0)
x6a          # double represented as short (-32768.0 to 327676.0)
x6b          # double represented as float
x6c          # list/vector length ('l')
x6d          # reserved ('m' method for RPC call)
x6e          # list/vector compact length
x6f          # object instance ('o')
x70          # reserved ('p' - message/post)
x71          # reserved
x72          # reserved ('r' reply for message/RPC)
x73          # utf-8 string non-final chunk ('s')
x74          # map/list type ('t')
x75          # type-ref
x76          # compact vector ('v')
x77          # long encoded as 32-bit int
x78 - x79    # reserved
x7a          # list/map terminator ('z')
x7b - x7f    # reserved
x80 - xbf    # one-octet compact int (-x10 to x3f, x90 is 0)
xc0 - xcf    # two-octet compact int (-x800 to x3ff)
xd0 - xd7    # three-octet compact int (-x40000 to x3ffff)
xd8 - xef    # one-octet compact long (-x8 to x10, xe0 is 0)
xf0 - xff    # two-octet compact long (-x800 to x3ff, xf8 is 0)
        </artwork>
      </figure>

    </section>
  </middle>

  <back>
  </back>
 
</rfc>
