<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="lib/rfc2629.xslt"?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes"?>
<?rfc subcompact="no" ?>
<?rfc linkmailto="no" ?>
<?rfc editing="no" ?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc-ext allow-markup-in-artwork="yes" ?>
<?rfc-ext include-index="no" ?>

<rfc ipr="trust200902"
     category="exp"
     docName="draft-thierry-bulk-00"
     xmlns:x="http://purl.org/net/xml2rfc/ext">
  <x:feedback template="mailto:pierre@nothos.net"/>
  <front>
    <title abbrev="BULK1">Binary Uniform Language Kit 1.0</title>

    <author initials="P." surname="Thierry" fullname="Pierre Thierry">
      <organization>Thierry Technologies</organization>
      <address>
        <email>pierre@nothos.net</email>
      </address>
    </author>

    <date day="1" month="August" year="2013" />
    <keyword>binary</keyword>

    <abstract>
      <t>
        This specification describes a uniform, decentrally extensible and efficient format for data
        serialization.
      </t>
    </abstract>

  </front>

  <middle>
    <section anchor="intro" title="Introduction">
      <section title="Rationale">
        <t>
          This specification aims at finding an original trade-off between uniformity, generality,
          extensibility, decentralization, compactness and processing speed for a data format. It is
          our opinion that every widely used existing format occupy a different position in the
          solution space for formats, hence this new design. It is also our opinion that most of
          those existing formats constitute an optimal solution for their specific use case, either
          in a absolute sense, or at least at the time of their design. But the ever-changing field
          of IT now faces new challenges that call for a new approach.
        </t>
	<t>
	  In particular, whereas the previous trend for Internet and Web standards and programming
	  tools has been to create human-readable syntaxes for data and protocols, the advent of
	  technologies like <xref target="protobuf">protocol buffers</xref>, <xref
	  target="Thrift">Thrift</xref>, the various binary serializations for JSON like <xref
	  target="Avro">Avro</xref> or <xref target="Smile">Smile</xref>, or the binary <xref
	  target="HTTP2">HTTP/2.0</xref> currently in development seem to indicate that the time is
	  ripe for a generalized use of binary, reserved until now for the low-level protocols. The
	  lessons about flexibility learnt in the previous switch from binary to plain text can now
	  be applied to efficient binary syntaxes.
	</t>
	<section title="Definitions">
	  <t>
	    By uniformity, we mean the property of a syntax that can be parsed even by an
	    application that doesn't understand the semantics of every part of the processed
	    data. Of course, almost all syntaxes that feature uniformity contain a limited number of
	    non uniform elements. Also, uniformity really only has value in the face of extension,
	    as a fixed syntax doesn't need uniformity (it only makes the implementation simpler).
	  </t>
	  <t>
	    Almost all extensible syntaxes have their extensible part uniform to a great degree. In
	    this specification, uniformity is hence evaluated on two criteria: first, the number of
	    non uniform elements (and, incidentally, their diversity), second, the fact that the
	    uniformity of the extensible part is not a limitation to the users (i.e. that the
	    temptation to extend the language in a non-uniform way is as absent as possible).
	  </t>
	  <t>
	    A good counter-example is found in most programming languages. Adding a new branching
	    construct cannot be done in a terse way without modifying the underlying
	    implementation. Such a construct either cannot be defined by user code (because of
	    evaluation rules) or can in a terribly verbose and inconvenient way (with lot of
	    boilerplate code). Notable exceptions to this limitation of programming languages are
	    Lisp, Haskell and stack programming languages.
	  </t>
	  <t>
	    On the other hand, a stack programming language is the canonical example of a non-uniform
	    language. Each operator takes a number of operands from the stack. Not knowing the arity
	    of an operator makes it impossible to continue parsing, even when its evaluation was
	    optional to the final processing. In the design space, stack programming languages
	    completely sacrifice uniformity to achieve one the highest combination of extensibility,
	    compactness and speed of processing.
	  </t>
	  <t>
	    By generality, we mean the ability of a syntax to lend itself to describe any kind of
	    data with a reasonable (or better yet, high) level of compactness and simplicity. For
	    example, although both arrays and linked lists could be considered very general as they
	    are both able to store any kind of data, they actually are at the respective cost of
	    complexity (arrays need the embedding of data structure in the data or in the processing
	    logic) and size (in-memory linked lists can waste as much as half or two third of the
	    space for the overhead of the data structure).
	  </t>
	  <t>
	    By decentralization, we mean the ability to extend the syntax in a way that avoid naming
	    collisions without the use of a central registry. Note that the DNS is NOT decentralized
	    in this sense, it is distributed (it cannot work without its root servers and not even
	    without prior knowledge of their location).
	  </t>
	</section>
	<section title="State of the art">
	  <t>
	    Uniformity, generality and extensibility are usually highly-valued traits in formats
	    design. Programming languages obviouly feature them foremost, although their generality
	    usually stops at what they are supposed to express: procedures. Most of them are
	    ill-suited to represent arbitrary data, but notable exceptions include Lisp (where "code
	    is data") and Javascript, from which a subset has been extracted to exchange data, JSON,
	    which has seen a tremendous success for this purpose. JSON may lack in generality and
	    compactness, but its design makes its parsing really straightforward and fast. All of
	    them, though, lack decentralization. Some of them make it possible to extend them in a
	    relatively decentralized way if some discipline is followed (for example, by naming
	    modules after domaine names), but the discipline is not mandatory.
	  </t>
	  <t>
	    The SGML/XML family of formats also feature these traits and actually fare much better
	    than programming languages on the three fronts. XML namespaces also make it fairly
	    decentralized and there have been attempts at making it compact (Efficient XML
	    Interchange).
	  </t>
	  <t>
	    But all the previously cited formats clearly lack compactness, although just applying
	    standard compression techniques would sacrifice only very little processing time to gain
	    huge size reductions on most of their intended use cases.
	  </t>
	  <t>
	    So-called binary formats pretty much exhibit the opposite trade-offs. Most of them are
	    not uniform to achieve better compactness. Some are specifically designed for a great
	    generality, but many lack extensibility. When they are extensible, it's never in a
	    decentralized way, again for reasons that have to do with compactness. They are usually
	    extremely fast to parse.
	  </t>
	  <t>
	    Actually, many binary formats are not so much formats but formats frameworks, and
	    exclude extensibility by design. For each use case, an IDL compiler creates a brand new
	    format that is essentially incompatible with all other formats created by the same
	    compiler. If the IDL compiler and framework are correctly designed, such a format
	    usually represent an optimum in compactness and speed of processing, as the compiler can
	    also automatically generate an ad-hoc optimized parser.
	  </t>
	</section>
      </section>
      <section title="Format overview">
	<t>
	  A BULK stream is a stream of 8-bit bytes, in big-endian order. Parsing a BULK stream
	  yields a sequence of expressions, which can be either atoms or forms, composed of
	  atoms. The syntax of forms is entirely uniform, without a single exception: a starting
	  byte marker, a sequence of atoms and an ending byte marker. Among atoms, only nil (the
	  null byte), arrays, words and fixed-sized integers have a special syntax, for efficiency
	  purposes. Even booleans and floating-point numbers follow the uniform syntax that every
	  other expression follow.
	</t>
	<t>
	  Non uniform atoms start with a marker byte, followed by a static or dynamic number of
	  bytes, depending on the type (none for nil, static for words and fixed-size integers,
	  dynamic for arrays).
	</t>
	<t>
	  Any other atom is a reference, which consists of a namespace marker (in most of the cases,
	  a single byte) followed by a identifier within this namespace (a single byte). All in all,
	  a very little sacrifice is made in compactness for the benefit of a very simple syntax:
	  apart from nil, nothing is smaller than 2 bytes, and as most forms involve a reference
	  followed by some content, a form is 4 bytes + its content.
	</t>
	<t>
	  A namespace marker in a BULK stream is associated by either of two simple forms to a
	  namespace identified by a UUID, thus ensuring decentralized extension. One of the two
	  forms declares that the stream can be processed even if the application doesn't reckognize
	  the namespace. Parsing remains possible thanks to the uniform syntax.
	</t>
      </section>
      <section title="Conventions and Terminology">
        <t>
          The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
          NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
          described in <xref target="RFC2119">RFC 2119</xref>.
        </t>
        <t>
          Literal numerical values are provided in decimal or hexadecimal as appropriate.
          Hexadecimal literals are prefixed with <spanx style="verb">0x</spanx> to distinguish them
          from decimal literals.
        </t>
	<t>
	  In the grammar, types are named by a capitalized word, like "Foo". The text representation
	  of the BULK stream uses mnemonics for some bytes sequences. Mnemonics are series of
	  characters, excluding all capital letters and white space, like "this-is-one-mnemonic" or
	  "what-the-%§!?#-is-that?". They are always separated by white space.
	</t>
	<t>
	  In the grammar, a shape is a pattern of bytes, following the rules of the text
	  representation for a BULK stream. Apart from mnemonics and types, a shape can contain:
	  <list style="symbols">
	    <t>a fixed byte, represented by its value as an unsigned integer (i.e. 0x3F)</t>
	    <t>an arbitrary sequence of a fixed number of bytes, represented by the number of bytes
	    in decimal immediately followed by a B uppercase letter (i.e. 4B)</t>
	  </list>
	  An arbitrary byte or sequence of bytes can be preceded by a name to make its description
	  clearer. The name is a series of character between { and } immediately followed by a
	  semi-colon (i.e. {quux}:4B).
	</t>
      </section>
    </section>

    <section title="BULK syntax">
      <t>
	A BULK stream is a sequence of 8-bit bytes. Bits and bytes are in big-endian order. The
	result of parsing a BULK stream is a sequence of abstract data, called the abstract
	yield. BULK parsing is injective: a BULK stream has only one abstract yield, but different
	BULK streams can have the same abstract yield.
      </t>
      <t>
	A processing application is not expected to actually produce the abstract yield, but an
	adaptation of the abstract yield to its own implementation, called the concrete yield. Also,
	some expressions in a BULK stream may have the semantics of a transformation of the abstract
	yield. A processing application may thus not produce or retain the concrete yield but the
	result of its transformation. This specification deals mainly with the byte sequence and the
	abstract yield and occasionnally provide guidelines about the concrete yield.
      </t>
      <t>
	The abstract yield is a sequence of expressions. Expressions can be atoms or forms. Forms
	are sequences of expressions. If a byte sequence is parsed as an expression, this byte
	sequence is said to denote this expression.
      </t>

      <section title="Parsing algorithm">
	<t>
	  The parser operates with a context, which is a sequence of expressions. Each time an
	  expression is parsed, it is appended at the end of the context. The initial context is the
	  abstract yield.
	</t>
	<t>
	  At the beginning of a BULK stream and after having consumed the byte sequence denoting a
	  complete expression, the parser is at the dispatch stage. At this stage, the next byte is
	  a marker byte, which tells the parser what kind of expression comes next (the marker byte
	  is the first byte of the sequence that denotes an expression).
	</t>
	<t>
	  The 0x1 and 0x2 marker bytes are special cases. When the parser reads 0x1, it immediately
	  appends an empty sequence to the current context. This sequence becomes the new
	  context. This new context has the previous context as parent. Then the parser returns to
	  its dispatch stage. When the parser reads 0x2, it appends nothing to the context, but
	  instead the parent of the current context becomes the new context and the parser returns
	  to the dispatch stage. Thus it is a parsing error to read 0x2 when the context is the
	  abstract yield.
	</t>
	<t>
	  Whenever a parsing error is encountered, parsing of the BULK stream MUST stop.
	</t>
      </section>

      <section title="Forms">
	<section title="starting marker byte">
	  <t>
	    <list style="hanging">
	      <t hangText="value">0x1</t>
	      <t hangText="mnemonic">(</t>
	    </list>
	  </t>
	</section>
	<section title="ending marker byte">
	  <t>
	    <list style="hanging">
	      <t hangText="value">0x2</t>
	      <t hangText="mnemonic">)</t>
	    </list>
	  </t>
	</section>
      </section>

      <section title="Atoms">
	<section title="nil">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x0 (mnemonic: nil)</t>
	      <t hangText="shape">nil</t>
	    </list>
	  </t>
	  <t>
	    Apart from being a possible short marker value, the fact that the 0x0 byte represents a
	    valid atom means that a sequence of null bytes is a valid part of a BULK stream, thus
	    making the format less fragile. In a network communication, nil atoms can also be sent
	    to keep the channel open.
	  </t>
	</section>

	<section title="Array">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x3 (mnemonic: #)</t>
	      <t hangText="shape"># Int …</t>
	    </list>
	  </t>
	  <t>
	    Arrays have a special parsing rule. After consuming the marker byte, the parser returns
	    to the dispatch stage. It is a parser error if the parsed expression is not of type Int
	    or if its value cannot be reckognized. This integer is not added to any context, but the
	    parser consumes as many bytes as this integer and they constitute the content of this
	    array.
	  </t>
	  <t>Type: Array</t>
	</section>

	<section title="32 bits word">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x4 (mnemonic: word32)</t>
	      <t hangText="shape">word32 4B</t>
	    </list>
	  </t>
	  <t>Types: Word, Word32</t>
	</section>

	<section title="64 bits word">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x5 (mnemonic: word64)</t>
	      <t hangText="shape">word64 8B</t>
	    </list>
	  </t>
	  <t>Types: Word, Word64</t>
	</section>

	<section title="128 bits word">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x6 (mnemonic: word128)</t>
	      <t hangText="shape">word128 16B</t>
	    </list>
	  </t>
	  <t>Types: Word, Word128</t>
	</section>

	<section title="Unsigned 8 bits integer">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x7 (mnemonic: int8)</t>
	      <t hangText="shape">int8 1B</t>
	    </list>
	  </t>
	  <t>
	    The value of this integer is the value of its contained byte.
	  </t>
	  <t>Type: Number, Int</t>
	</section>

	<section title="Unsigned 32, 64 and 128 bits integer">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x8 (mnemonic: uint)</t>
	      <t hangText="shape">uint Word</t>
	    </list>
	  </t>
	  <t>
	    The value of this integer is the value of its contained word.
	  </t>
	  <t>Type: Number, Int</t>
	</section>

	<section title="Signed 32, 64 and 128 bits integer">
	  <t>
	    <list style="hanging">
	      <t hangText="marker">0x9 (mnemonic: sint)</t>
	      <t hangText="shape">sint Word</t>
	    </list>
	  </t>
	  <t>
	    The value of its contained word is the value of this integer in two's-complement
	    notation.
	  </t>
	  <t>Type: Number, Int</t>
	</section>

	<section title="Reserved marker bytes">
	  <t>
	    Marker bytes 0xA−0xF are reserved for future major versions of BULK. It is a parser
	    error if a BULK stream with major version 1 contains such a marker byte.
	  </t>
	</section>

	<section title="Reference">
	  <t><list style="hanging">
	      <t hangText="marker">0x10−0xFF</t>
	      <t hangText="shape">{ns}:1B {name}:1B</t>
	    </list>
	  </t>
	  <t>
	    The {ns} byte is a value associated with a namespace. Values 0x10−0x1F are reserved for
	    namespaces defined by BULK specifications. Greater values can be associated with
	    namespaces identified by a UUID.
	  </t>
	  <t>
	    The {name} byte is the name within the namespace. Vocabularies with more than 256 names
	    thus need to be spread accross several namespaces.
	  </t>
	  <t>
	    The specification of a namespace SHOULD include a mnemonic for the namespace and for
	    each defined name. When descriptions use several namespaces, the mnemonic of a reference
	    SHOULD be the concatenation of the namespace mnemonic, ":" and the name mnemonic. For
	    example, the fp name in namespace math becomes math:fp.
	  </t>
	  <section title="Speciale case">
	    <t>
	      References have a special parsing rule. In case a BULK stream needs an important
	      number of namespaces, if the marker byte is 0xFF, the parser continues to read bytes
	      until it finds a byte different than 0xFF. The value of this sequence of bytes is the
	      value associated with a namespace. For example, the reference denoted by the bytes
	      0xFF 0xFF 0x8C 0x1A is the name 26 in the namespace associated with 16777100.
	    </t>
	  </section>
	</section>

      </section>
    </section>

    <section title="Standard namespaces">
      <t>
	Standard namespaces have a fixed namespace value and are not identified by a UUID.
      </t>

      <section title="BULK core namespace">
	<t>
	  <list style="hanging">
	      <t hangText="marker">0x10 (mnemonic: bulk)</t>
	  </list>
	</t>

	<section title="Version">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x1 (mnemonic: version)</t>
	      <t hangText="shape">( version {major}:Int {minor}:Int )</t>
	    </list>
	  </t>
	  <t>
	    This form MUST be the first in a BULK stream. It is a parsing error otherwise. This
	    specification defines BULK 1.0. When writing a BULK stream, a processing application
	    MUST denote  {major} and {minor} by the smallest byte sequence possible.
	  </t>
	  <t>
	    Two BULK versions with the same major version MUST share the same parsing rules and the
	    same definitions of marker bytes. Changing the syntax or semantics of existing marker
	    bytes and using marker bytes in the reserved interval warrants a new major
	    version. Changing the syntax or semantics of existing names in standard namespaces also.
	  </t>
	  <t>
	    Adding standard namespaces or adding names in existing standard namespaces warrants a
	    new minor version.
	  </t>
	</section>

	<section title="Required namespace">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x2 (mnemonic: ns)</t>
	      <t hangText="shape">( ns {mark}:Int {uuid}:Word128 )</t>
	    </list>
	  </t>
	  <t>
	    This associates the namespace identified by {uuid} to the value {mark}. It is a parsing
	    error if a processin application doesn't reckognise the designated namespace.
	  </t>
	</section>

	<section title="Optional namespace">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x3 (mnemonic: ns*)</t>
	      <t hangText="shape">( ns* {mark}:Int {uuid}:Word128 )</t>
	    </list>
	  </t>
	  <t>
	    This associates the namespace identified by {uuid} to the value {mark}.
	  </t>
	</section>

	<section title="Strings encoding">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x4 (mnemonic: stringenc)</t>
	      <t hangText="shape">( stringenc {enc}:Encoding )</t>
	    </list>
	  </t>
	  <t>
	    This tells the processing application that all following expressions in the current
	    context that are understood by the application as character strings will be encoded with
	    the encoding designated by {enc}.
	  </t>
	  <t>
	    As the abstract yield doesn't contains strings but expressions that will be used as
	    strings by the application, it is not a parsing error if the application doesn't
	    reckognize {enc}. In this situation, it is a parsing error when the application actually
	    needs to decode a byte sequence as a string. It is not a parsing error when a processing
	    application only transmits a byte sequence encoding a string, if it can accurately
	    convey the encoding to the receiving application.
	  </t>
	</section>

	<section title="IANA registered character set">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x5 (mnemonic: iana-charset)</t>
	      <t hangText="shape">( iana-charset {id}:Int )</t>
	    </list>
	  </t>
	  <t>
	    This designates the string encoding registered among the <xref
	    target="IANA-Charsets">IANA Character Sets</xref> whose MIBenum is {id}.
	  </t>
	  <t>
	    Type: Encoding.
	  </t>
	</section>

	<section title="Windows code page">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x6 (mnemonic: code-page)</t>
	      <t hangText="shape">( code-page {id}:Int )</t>
	    </list>
	  </t>
	  <t>
	    This designates the string encoding among Windows code pages whose identifier is {id}.
	  </t>
	  <t>
	    Type: Encoding.
	  </t>
	</section>

	<section title="true">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x7 (mnemonic: true)</t>
	      <t hangText="shape">true</t>
	    </list>
	  </t>
	  <t>
	    Type: Boolean.
	  </t>
	</section>

	<section title="false">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x8 (mnemonic: false)</t>
	      <t hangText="shape">false</t>
	    </list>
	  </t>
	  <t>
	    Type: Boolean.
	  </t>
	</section>

      </section>

      <section title="arithmetic namespace">
	<t>
	  <list style="hanging">
	      <t hangText="marker">0x11 (mnemonic: math)</t>
	  </list>
	</t>

	<t>
	  A processing application must reckognize the type of all expressions that have the type
	  Number, but an application MAY consider a number as having an unknown value if it has no
	  adequate data type to store it.
	</t>

	<section title="fraction">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x1 (mnemonic: frac)</t>
	      <t hangText="shape">( frac {num}:Int {div}:Int )</t>
	    </list>
	  </t>
	  <t>
	    This is the number {num}/{div}.
	  </t>
	  <t>
	    Type: Number.
	  </t>
	</section>

	<section title="Arbitrary precision signed integer">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x2 (mnemonic: bigint)</t>
	      <t hangText="shape">( bigint {bits}:Array )</t>
	    </list>
	  </t>
	  <t>
	    The bits contained in {bits} is the value of this integer in two's-complement notation.
	  </t>
	  <t>
	    Type: Number, Int.
	  </t>
	</section>

	<section title="Binary floating-point number">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x3 (mnemonic: binary)</t>
	      <t hangText="shape">( binary {bits}:Word )</t>
	      <t hangText="shape">( binary {bits}:Array )</t>
	    </list>
	  </t>
	  <t>
	    This is a floating-point number expressed in IEEE 754-2008 binary interchange format. If
	    {bits} is an Array, the size of its contents must be a multiple of 32 bits, as per IEEE
	    754-2008 rules.
	  </t>
	  <t>
	    Type: Number.
	  </t>
	</section>

	<section title="Decimal floating-point number">
	  <t>
	    <list style="hanging">
	      <t hangText="name">0x4 (mnemonic: decimal)</t>
	      <t hangText="shape">( decimal {bits}:Word )</t>
	      <t hangText="shape">( decimal {bits}:Array )</t>
	    </list>
	  </t>
	  <t>
	    This is a floating-point number expressed in IEEE 754-2008 decimal interchange
	    format. If {bits} is an Array, the size of its contents must be a multiple of 32 bits,
	    as per IEEE 754-2008 rules.
	  </t>
	  <t>
	    Type: Number.
	  </t>
	</section>

      </section>
    </section>

    <section title="Extension namespaces">
      <t>
	Extension namespaces are defined with an identifier UUID, to be associated by a ns or ns*
	form.
      </t>

      <section title="Official namespaces">
	<t>
	  Extension namespaces defined as part of the official BULK suite MUST be identified by a v4
	  UUID. The namespace UUID used to generate it MUST be <eref
	  target="urn:uuid:abaddeed-face-11e2-9605-74de2b4102f1"/>. The name used to generate it
	  SHOULD be a URI designating the described vocabulary when one exists.
	</t>
      </section>

      <section title="User-defined namespaces">
	<t>
	  User-defined namespaces are actually no different than official namespaces, apart from the
	  choice of UUID.
	</t>
      </section>
    </section>

    <section title="Security Considerations" anchor="sec">
      <section title="Parsing">
	<t>
	  Parsing a BULK stream is designed to be free of side-effects for the processing application,
	  apart from storing the parsed results.
	</t>
	<t>
	  Arrays in BULK carry their size, so as for the application to know in advance the size of
	  the data to read and store, thus making it easier to build robust code. A malicious
	  software, however, may announce an array with a size choosen to get an application to
	  exhaust its available memory. When a BULK stream has been completely received, an array
	  bigger than the remaining data SHOULD trigger an error. When a BULK stream's size is not
	  known in advance, the application SHOULD use a growable data structure.
	</t>
      </section>
      <section title="Forwarding">
	<t>
	  When a processing application forwards all or part of the data in a BULK stream to another
	  application, care must be taken if part of the forwarded data was not entirely
	  reckognized, as it could be used by an attacker to benefit from the authority the
	  forwarding application has on the recipient of the data.
	</t>
      </section>
    </section>

    <section title="IANA Considerations">
      <t>
	This specification defines a new media type, application/bulk. Here are the informations for
	its registration to IANA:
      </t>
      <t>
	<list style="hanging">
	  <t hangText="Type name">application</t>
	  <t hangText="Subtype name">bulk</t>
	  <t hangText="Required parameters">none</t>
	  <t hangText="Optional parameters">none</t>
	  <t hangText="Encoding considerations">none, content is self-describing</t>
	  <t hangText="Security considerations">cf. <xref target="sec"/></t>
	  <t hangText="Interoperability considerations">the constraint to start any BULK stream with
	  a version form has the side-effect that classes of BULK streams can be identified by a
	  sequence of bytes acting as "magic number":
	  <list style="hanging">
	    <t hangText="0x011001">any BULK stream</t>
	    <t hangText="0x01100107">a BULK stream of any major version beneath 256</t>
	    <t hangText="0x0110010701">a BULK stream of major version 1</t>
	    <t hangText="0x0110010701070202">a BULK stream of version 1.2</t>
	  </list>
	  </t>
	  <t hangText="Published specification">this document</t>
	  <t hangText="Applications that use this media type">none so far</t>
	  <t hangText="Fragment identifier considerations">this specification defines no semantics for
	  addressing the data with a fragment identifier; a future specification could define fragment
	  identifier syntaxes to address the content by byte offset or the parsed results by their
	  number in the yielded sequence</t>
	  <t hangText="Additional information">a future specification may define a naming convention
	  for media types based on bulk with a +bulk suffix, as for XML with +xml</t>
	</list>
      </t>
    </section>

    <section title="Acknowledgements">
      <t>
	The original author of this specification read <eref
	target="http://www.schnada.de/grapt/eriknaggum-xmlrant.html">Erik Naggum's famous rant about
	XML</eref> several years before, and it may well have unconsciouly influenced this
	design. He happened to stumble upon it again while writing the earliest draft of this
	specification and it struck him how much it embodies Erik's ideas. In any case, this format
	is dedicated to Erik.
      </t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <reference anchor="RFC2119">
        <front>
          <title>
            Key words for use in RFCs to Indicate Requirement Levels
          </title>
          <author initials="S." surname="Bradner" fullname="Scott Bradner">
            <organization>Harvard University</organization>
            <address><email>sob@harvard.edu</email></address>
          </author>
          <date month="March" year="1997"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
      </reference>

      <reference anchor="IANA-Charsets" target="http://www.iana.org/assignments/character-sets">
        <front>
          <title>
	    IANA Charset Registry (archived at):
          </title>
	  <date/>
        </front>
      </reference>

    </references>


    <references title="Informative references">

      <reference anchor="HTTP2">
	<front>
	  <title>Hypertext Transfer Protocol version 2.0</title>
	  <author initials="M." surname="Belshe" fullname="Mike Belshe">
	    <organization>Twist</organization>
	    <address>
	      <email>mbelshe@chromium.org</email>
	    </address>
	  </author>

	  <author initials="R." surname="Peon" fullname="Roberto Peon">
	    <organization>Google, Inc</organization>
	    <address>
	      <email>fenix@google.com</email>
	    </address>
	  </author>

	  <author initials="M." surname="Thomson" fullname="Martin Thomson" role="editor">
	    <organization>Microsoft</organization>
	    <address>
	      <postal>
		<street>3210 Porter Drive</street>
		<city>Palo Alto</city>
		<code>94304</code>
		<country>US</country>
	      </postal>
	      <email>martin.thomson@skype.net</email>
	    </address>
	  </author>

	  <author initials="A." surname="Melnikov" fullname="Alexey Melnikov" role="editor">
	    <organization>Isode Ltd</organization>
	    <address>
	      <postal>
		<street>5 Castle Business Village</street>
		<street>36 Station Road</street>
		<city>Hampton</city>
		<region>Middlesex</region>

		<code>TW12 2BX</code>
		<country>UK</country>
	      </postal>
	      <email>Alexey.Melnikov@isode.com</email>
	    </address>
	  </author>
	  <date month="July" year="2013"/>
	</front>
	<seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-http2-04"/>
      </reference>
      <reference anchor="Avro" target="http://avro.apache.org/docs/1.7.4/spec.html">
	<front>
	  <title>Apache Avro™ 1.7.4 Specification</title>
	  <author initials="D." surname ="Cutting" fullname="Doug Cutting">
            <organization>Cloudera</organization>
	  </author>
	  <date month="February" year="2013"/>
	</front>
      </reference>

      <reference anchor="protobuf" target="https://developers.google.com/protocol-buffers/">
	<front>
	  <title>Protocol Buffers</title>
	  <date month="July" year="2008"/>
	</front>
      </reference>

      <reference anchor="Smile" target="http://wiki.fasterxml.com/SmileFormat">
	<front>
	  <title>Smile Data Format</title>
	  <author initials="T." surname ="Saloranta" fullname="Tatu Saloranta">
	    <address><email>tsaloranta@gmail.com</email></address>
	  </author>
	  <date month="September" year="2010"/>
	</front>
      </reference>

      <reference anchor="Thrift" target="http://thrift.apache.org/static/files/thrift-20070401.pdf">
	<front>
	  <title>Thrift: Scalable Cross-Language Services Implementation</title>
	  <author initials="M." surname ="Slee" fullname="Mark Slee">
	    <organization>Facebook</organization>
	    <address><email>mcslee@facebook.com</email></address>
	  </author>
	  <author initials="A." surname ="Agarwal" fullname="Aditya Agarwal">
	    <organization>Facebook</organization>
	    <address><email>aditya@facebook.com</email></address>
	  </author>
	  <author initials="M." surname ="Kwiatkowski" fullname="Marc Kwiatkowski">
	    <organization>Facebook</organization>
	    <address><email>marc@facebook.com</email></address>
	  </author>
	  <date month="April" year="2007"/>
	</front>
      </reference>

    </references>

<!--
      <reference anchor="" target="">
	<front>
	  <title></title>
	  <author initials="" surname ="" fullname="">
            <organization></organization>
	    <address><email></email></address>
	  </author>
	  <date month="" year=""/>
	</front>
      </reference>
-->
  </back>
</rfc>

