1
0
mirror of https://github.com/ubf/ubf.git synced 2026-04-21 20:25:57 +00:00
Files
ubf/ubf-user-guide.en.html
2010-10-25 09:40:44 +09:00

505 lines
40 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>UBF Users Guide DRAFT - UNDER CONSTRUCTION</title><link rel="stylesheet" href="./docbook-xsl.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.74.3" /></head><body><div class="article" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id2577851"></a>UBF Users Guide <span class="emphasis"><em>DRAFT - UNDER CONSTRUCTION</em></span></h2></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="2"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.1</td><td align="left">2010/10/24</td></tr></table></div></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#_preface">1. Preface</a></span></dt><dt><span class="section"><a href="#_introduction">2. Introduction</a></span></dt><dt><span class="section"><a href="#_specifications">3. Specifications</a></span></dt><dd><dl><dt><span class="section"><a href="#_ubf_a">3.1. UBF(a)</a></span></dt><dd><dl><dt><span class="section"><a href="#_integer_0_9">3.1.1. Integer: [-][0-9]+</a></span></dt><dt><span class="section"><a href="#_string_8230">3.1.2. String: "…"</a></span></dt><dt><span class="section"><a href="#_binary_0_9_8230">3.1.3. Binary: [0-9]+ ~…~</a></span></dt><dt><span class="section"><a href="#_atom_8230">3.1.4. Atom: '…'</a></span></dt><dt><span class="section"><a href="#_tuple_obj1_obj2_8230_objn_1_objn">3.1.5. Tuple: { Obj1 Obj2 … ObjN-1 ObjN }</a></span></dt><dt><span class="section"><a href="#_list_objn_amp_objn_1_amp_8230_amp_obj2_amp_obj1">3.1.6. List: # ObjN &amp; ObjN-1 &amp;&amp; Obj2 &amp; Obj1</a></span></dt><dt><span class="section"><a href="#_term">3.1.7. Term</a></span></dt><dt><span class="section"><a href="#_whitespace_s_n_r_t_8230">3.1.8. Whitespace: \s \n \r \t , %…%</a></span></dt><dt><span class="section"><a href="#_tag_8230">3.1.9. Tag: `…`</a></span></dt><dt><span class="section"><a href="#_register_gt_c_c">3.1.10. Register: &gt;C C</a></span></dt><dt><span class="section"><a href="#_object">3.1.11. Object</a></span></dt></dl></dd><dt><span class="section"><a href="#_ubf_b">3.2. UBF(b)</a></span></dt><dd><dl><dt><span class="section"><a href="#_name_name_8230">3.2.1. Name: +NAME("…").</a></span></dt><dt><span class="section"><a href="#_version_vsn_8230">3.2.2. Version: +VSN("…").</a></span></dt><dt><span class="section"><a href="#_types_types">3.2.3. Types: +TYPES.</a></span></dt><dt><span class="section"><a href="#_states">3.2.4. States</a></span></dt><dt><span class="section"><a href="#_anystate">3.2.5. Anystate</a></span></dt></dl></dd><dt><span class="section"><a href="#_ubf_c">3.3. UBF(c)</a></span></dt><dd><dl><dt><span class="section"><a href="#_request">3.3.1. Request</a></span></dt><dt><span class="section"><a href="#_response">3.3.2. Response</a></span></dt><dt><span class="section"><a href="#_event">3.3.3. Event</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="#_contracts">4. Contracts</a></span></dt><dt><span class="section"><a href="#_transports">5. Transports</a></span></dt><dd><dl><dt><span class="section"><a href="#_tcp_ip">5.1. TCP/IP</a></span></dt><dd><dl><dt><span class="section"><a href="#_ubf">5.1.1. UBF</a></span></dt><dt><span class="section"><a href="#_ebf">5.1.2. EBF</a></span></dt><dt><span class="section"><a href="#_jsf">5.1.3. JSF</a></span></dt><dt><span class="section"><a href="#_tbf">5.1.4. TBF</a></span></dt></dl></dd><dt><span class="section"><a href="#_http">5.2. HTTP</a></span></dt><dd><dl><dt><span class="section"><a href="#_json_rpc">5.2.1. JSON RPC</a></span></dt></dl></dd><dt><span class="section"><a href="#_misc">5.3. Misc</a></span></dt><dd><dl><dt><span class="section"><a href="#_etf">5.3.1. ETF</a></span></dt><dt><span class="section"><a href="#_lpc">5.3.2. LPC</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="#_servers">6. Servers</a></span></dt><dd><dl><dt><span class="section"><a href="#_stateless">6.1. Stateless</a></span></dt><dt><span class="section"><a href="#_stateful">6.2. Stateful</a></span></dt></dl></dd><dt><span class="section"><a href="#_clients">7. Clients</a></span></dt><dd><dl><dt><span class="section"><a href="#_erlang">7.1. Erlang</a></span></dt><dt><span class="section"><a href="#_python">7.2. Python</a></span></dt><dt><span class="section"><a href="#_java">7.3. Java</a></span></dt></dl></dd><dt><span class="section"><a href="#_miscellaneous">8. Miscellaneous</a></span></dt><dt><span class="section"><a href="#_reference">9. Reference</a></span></dt><dt><span class="section"><a href="#_appendix">10. Appendix</a></span></dt><dd><dl><dt><span class="section"><a href="#_acknowledgements">10.1. Acknowledgements</a></span></dt><dt><span class="section"><a href="#_abnf_definition">10.2. ABNF Definition</a></span></dt><dd><dl><dt><span class="section"><a href="#ABNF-UBFa">10.2.1. UBF(a)</a></span></dt><dt><span class="section"><a href="#ABNF-UBFb">10.2.2. UBF(b)</a></span></dt><dt><span class="section"><a href="#ABNF-UBFc">10.2.3. UBF(c)</a></span></dt></dl></dd></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_preface"></a>1. Preface</h2></div></div></div><p>UBF, a framework for Getting Erlang to talk to the outside world.
This document and the corresponding open-source code repositories are
based on Joe Armstrongs original UBF site and code with an MIT
license file added to the distribution. Since then, a large number of
enhancements and improvements have been added.</p><p>UBF is the "Universal Binary Format", designed and implemented by Joe
Armstrong. See <a class="xref" href="#UBF">[UBF]</a> for UBFs original website.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_introduction"></a>2. Introduction</h2></div></div></div><p>UBF is a language for transporting and describing complex data
structures across a network. It has three components:</p><div class="itemizedlist"><ul type="disc"><li>
UBF(a) is a "language neutral" data transport format, roughly
equivalent to well-formed XML.
</li><li>
UBF(b) is a programming langauge for describing types in UBF(a) and
protocols between clients and servers. This layer is typically
called the "protocol contract". UBF(b) is roughly equivalent to
Verified XML, XML-schemas, SOAP and WDSL.
</li><li>
UBF(c) is a meta-level protocol used between a UBF client and a UBF
server.
</li></ul></div><p>While the XML series of languages had the goal of having a human
readable format the UBF languages take the opposite view and provide a
"machine friendly" format. UBF is designed to be easy to implement.</p><div class="figure"><a id="id2653065"></a><p class="title"><b>Figure 1. Programming By Contract</b></p><div class="figure-contents"><a class="ulink" href="images/ubf-flow-01.svg" target="_top">
<div class="mediaobject"><img src="images/ubf-flow-01.png" alt="Programming By Contract" /></div>
</a></div></div><br class="figure-break" /><p>Central to UBF is the idea of a "Contract" which regulates the set of
legal conversations that can take place between a client and a server.
All data sent by both the client and the server is verified by the
"Contract Manager" (an Erlang process on the "server" side of the
protocol). Any data that violates the contract is rejected.</p><p>The UBF framework itself is designed to be easy to extend for
supporting other data transport formats and other network transports.
For example, JSON, Thrift, and Erlang native binary serialization data
formats over TCP/IP and JSON-RPC over HTTP are supported alternatives
to the original UBF(a) implementation.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_specifications"></a>3. Specifications</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_ubf_a"></a>3.1. UBF(a)</h3></div></div></div><p>UBF(a) is a transport format. UBF(a) was designed to be easy to parse
and to be easy to write with a text editor. UBF(a) is based on a byte
encoded virtual machine, 26 byte codes are reserved. Instead of
allocating the byte codes from 0, the printable character codes are
used to make the format easy to read.</p><p>UBF(a) has four primitive types, when a primitive type is recognized
it is pushed onto the "recognition stack" in our decoder. The
primitive types are Integer, String, Binary, and Atom. UBF(a) has two
types of "glue" for making compound objects. The compound types are
Tuple and List. Lastly, the operator <span class="emphasis"><em>$</em></span> (i.e. "end of object")
signifies when objects are finished.</p><p>For example, the following UBF(a) object:</p><pre class="screen">'person'&gt;p # {p,"Joe",123} &amp; {p, 'fred', 3~abc~} &amp; $</pre><p>Represents the following UBF(b) term:</p><pre class="screen">[{person, fred, &lt;&lt;"abc"&gt;&gt;}, {person, "Joe", 123}].</pre><p>See <a class="xref" href="#ABNF-UBFa" title="10.2.1.&#xA0;UBF(a)">Section 10.2.1, “UBF(a)”</a> for a formal definition of the UBF(a) syntax.</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_integer_0_9"></a>3.1.1. Integer: [-][0-9]+</h4></div></div></div><p>Integers are sequences of bytes which could be described by the
regular expression [-][0-9]+, that is an optional minus (to denote a
negative integer) and then a sequence of at least one digit.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_string_8230"></a>3.1.2. String: "…"</h4></div></div></div><p>Strings are written enclosed in double quotes. Within a string two
quoting conventions are observed, " must be written \" and \ must be
written \\ - no other quotings are allowed.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_binary_0_9_8230"></a>3.1.3. Binary: [0-9]+ ~…~</h4></div></div></div><p>Uninterpreted blocks of binary data are encoded. First an integer,
representing the length of the binary data is encoded, this is
followed by a tilde, the data itself which must be exactly the length
given in the integer and than a closing tilde. The closing tilde has
no significance and is retained for readability. White space can be
added between the integer length and the data for readability.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_atom_8230"></a>3.1.4. Atom: '…'</h4></div></div></div><p>Atoms are encoded as strings, only using a single quote instead of a
double quote. Atoms are commonly found in symbolic languages like
Lisp, Prolog or Erlang. In C, they would be represented by hashed
strings. The essential property of an atom is that two atoms can be
compared for equality in constant time. These are used for
representing symbolic constants.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_tuple_obj1_obj2_8230_objn_1_objn"></a>3.1.5. Tuple: { Obj1 Obj2 … ObjN-1 ObjN }</h4></div></div></div><p>Tuples are used to represent <span class="emphasis"><em>fixed numbers</em></span> of objects. The byte
codes for "{" and "}" are used to delimit a tuple. Obj1, Obj2, ObjN-1,
and ObjN are arbitrary UBF(a) objects.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_list_objn_amp_objn_1_amp_8230_amp_obj2_amp_obj1"></a>3.1.6. List: # ObjN &amp; ObjN-1 &amp;&amp; Obj2 &amp; Obj1</h4></div></div></div><p>Lists are used to represent <span class="emphasis"><em>variable numbers</em></span> of objects. The first
object in the list is Obj1, the second object in the list is Obj2,
etc. Objects are presented in reverse order.</p><p>Lisp programmers will recognize <span class="emphasis"><em>#</em></span> as an operator that pushes NIL (or
the end of list) onto the recognition stack and <span class="emphasis"><em>&amp;</em></span> as an operator
that takes the top two items on the recognition stack and replaces
them by a list cell.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_term"></a>3.1.7. Term</h4></div></div></div><p>Terms represent primitive types and compound types.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_whitespace_s_n_r_t_8230"></a>3.1.8. Whitespace: \s \n \r \t , %…%</h4></div></div></div><p>For convenience, blank, carriage return, line feed, tab, comma, and
comments are treated as white space. Comments can be included in
UBF(a) with the syntax %…% and the usual quoting convention applies.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_tag_8230"></a>3.1.9. Tag: `…`</h4></div></div></div><p>In addition any item can be followed by a semantic tag this is written
`…` - with in the tag the close quote is quoted as in the strings
encoding. This tag has no meaning in UBF(a) but might have a meaning
in UBF(b). For example:</p><pre class="screen">12456 ~...~ `jpg`</pre><p>Represents 12456 bytes of raw data with the semantic tag "jpg". UBF(a)
does not know what "jpg" means - this is passed on to UBF(b) which
might know what it means - finally the end application is expected to
know what to do with an object of type "jpg", it might for example
know that this represents an image. UBF(a) will just encode the tag,
UBF(b) will type check the tag, and the application should be able to
understand the tag.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_register_gt_c_c"></a>3.1.10. Register: &gt;C C</h4></div></div></div><p>So far, exactly 26 control characters have been used, namely:
%"~'`{}#&amp;\s\n\t\r,-01234567890</p><p>This leaves us with 230 unallocated byte codes. These are used as
follows:</p><pre class="screen">&gt;C</pre><p>Where <span class="emphasis"><em>C</em></span> is not one of the reserved byte codes, &gt; means store the top
of the recognition stack in the register <span class="emphasis"><em>C</em></span> and pop the recognition
stack. For caching optimizations, subsequent reuse of the single
character <span class="emphasis"><em>C</em></span> means push register <span class="emphasis"><em>C</em></span> onto the recognition stack.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_object"></a>3.1.11. Object</h4></div></div></div><p>Objects represent either a Term, a Register push, or a Register pop
with an optional Tag. The operator <span class="emphasis"><em>$</em></span> signifies "end of object".
When <span class="emphasis"><em>$</em></span> is encountered there should be only one item on the
recognition stack.</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_ubf_b"></a>3.2. UBF(b)</h3></div></div></div><p>UBF(b) is a language independent type system and protocol description
language. The protocol description language allows one to specify
client server interaction in terms of a non-deterministic finite state
machine. The type system allows one to specify the asynchronous
events and synchronous request/response pairs that define transitions
of this finite state machine.</p><p>The type system and protocol description language together define the
basis of "Contracts" between clients and servers. All data sent by
both the client and the server is verified by the "Contract Manager"
(an Erlang process on the "server" side of the protocol). Any data
that violates the contract is rejected.</p><p>A UBF(b) contract is defined by 2 mandatory sections and 3 optional
sections. The mandatory sections are the "name" and the "version" of
the contract. The optional sections are the "types", the "states",
and the "anystates" of the contract.</p><p>For example, the following UBF(b) contract defines a simple IRC
(Internet Relay Chat) protocol between clients and a server:</p><pre class="programlisting">+NAME("irc").
+VSN("ubf1.0").
+TYPES
info() = info;
description() = description;
contract() = contract;
ok() = ok;
bool() = true | false;
nick() = string();
oldnick() = nick();
newnick() = nick();
group() = string();
groups() = [group()];
logon() = logon;
proceed() = {ok, nick()};
listGroups() = groups;
joinGroup() = {join, group()};
leaveGroup() = {leave, group()};
changeNick() = {nick, nick()};
msg() = {msg, group(), string()};
msgEvent() = {msg, nick(), group(), string()};
joinEvent() = {joins, nick(), group()};
leaveEvent() = {leaves, nick(), group()};
changeNameEvent() = {changesName, oldnick(), newnick(), group()}.
+STATE start
logon() =&gt; proceed() &amp; active. %% Nick randomly assigned
+STATE active
listGroups() =&gt; groups() &amp; active;
joinGroup() =&gt; ok() &amp; active;
leaveGroup() =&gt; ok() &amp; active;
changeNick() =&gt; bool() &amp; active;
msg() =&gt; bool() &amp; active; %% False if you have not joined a group
EVENT =&gt; msgEvent(); %% Group sends me a message
EVENT =&gt; joinEvent(); %% Nick joins group
EVENT =&gt; leaveEvent(); %% Nick leaves group
EVENT =&gt; changeNameEvent(). %% Nick changes name
+ANYSTATE
info() =&gt; string();
description() =&gt; string();
contract() =&gt; term().</pre><p>See <a class="xref" href="#ABNF-UBFb" title="10.2.2.&#xA0;UBF(b)">Section 10.2.2, “UBF(b)”</a> for a formal definition of the UBF(b) syntax.</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_name_name_8230"></a>3.2.1. Name: +NAME("…").</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_version_vsn_8230"></a>3.2.2. Version: +VSN("…").</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_types_types"></a>3.2.3. Types: +TYPES.</h4></div></div></div><p>The UBF(b) type system has user-defined types and predefined types.
User-defined types and predefined types are either primitive types or
complex types.</p><p>The primitive types are Integer, Range, Float, Binary, String, Atom,
and Reference. The complex types are Alternative, Tuple, Record,
Extended Record, and List. User-defined "complex types" are defined
recursively.</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_definition_x_t"></a>3.2.3.1. Definition: X() = T</h5></div></div></div><p>New types are defined by the notation:</p><pre class="screen">X() = T</pre><p>The name of the type is <span class="emphasis"><em>X</em></span> and the types definition <span class="emphasis"><em>T</em></span> is either a
user-defined type or a predefined type.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_integer_0_9_emphasis_or_emphasis_0_9_0_9a_f"></a>3.2.3.2. Integer: [-][0-9]+ <span class="emphasis"><em>or</em></span> [0-9]+#[0-9a-f]+</h5></div></div></div><p>Postive and negative integer constants are expressed as in UBF(a).
Integer constants may also be expressed in other bases using Erlang
syntax.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_range_0_9_0_9_emphasis_or_emphasis_0_9_emphasis_or_emphasis_0_9"></a>3.2.3.3. Range: [-][0-9]+..[-][0-9]+ <span class="emphasis"><em>or</em></span> [-][0-9]+.. <span class="emphasis"><em>or</em></span> ..[-][0-9]+</h5></div></div></div><p>Bounded, left unbounded, and right unbounded integer ranges are
supported.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_float_0_9_0_9"></a>3.2.3.4. Float: [-][0-9]+.[0-9]+</h5></div></div></div><p>Positive and negative float constants are supported for network
transports other than UBF(a).</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_binary_lt_lt_8230_gt_gt"></a>3.2.3.5. Binary: &lt;&lt;"…"&gt;&gt;</h5></div></div></div><p>Binary constants are expressed similiarly as strings in UBF(a) but
having two leading "less than brackets" and two following "greater
than brackets".</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_string_8230_2"></a>3.2.3.6. String: "…"</h5></div></div></div><p>String constants are expressed as in UBF(a).</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_atom_8230_emphasis_or_emphasis_a_z_a_za_z0_9"></a>3.2.3.7. Atom: '…' <span class="emphasis"><em>or</em></span> [a-z][a-zA-Z0-9_]*</h5></div></div></div><p>Atom constants are expressed as UBF(a) atoms. Atom constants starting
with lowercase letters do not require single quotes.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_reference_r"></a>3.2.3.8. Reference: R()</h5></div></div></div><p>Defined types are referenced by the notation:</p><pre class="screen">R()</pre><p>The name of the type is <span class="emphasis"><em>R</em></span>.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_alternative_t1_t2"></a>3.2.3.9. Alternative: T1 | T2</h5></div></div></div><p>A type X is of type "T1 | T2" if X is of type T1 or if X is of type
T2.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_tuple_t1_t2_8230_tn"></a>3.2.3.10. Tuple: {T1, T2, …, Tn}</h5></div></div></div><p>A type {X1, X2, …, Xn} is of type "{T1, T2, …, Tn}" if X1 is of
type T1, X2 is of type T2, … and Xn is of type Tn.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_record_name_t1_y_t2_8230_z_tn"></a>3.2.3.11. Record: name#T1, y=T2, …, z=Tn</h5></div></div></div><p>A record type is syntactic sugar for a tuple of type "{name, T1, T2,
…, Tn}" where name, x, y, …, and z are atoms.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_extended_record_name_t1_y_t2_8230_z_tn"></a>3.2.3.12. Extended Record: name##T1, y=T2, …, z=Tn</h5></div></div></div><p>An extended record type is syntactic sugar for a tuple of type "{name,
T1, T2, …, Tn, <span class="emphasis"><em>$fields</em></span>=[x,y,…,z], <span class="emphasis"><em>$extras</em></span>=[T1, T2, …, Tn]}"
where name, x, y, …, and z are atoms.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_list_t"></a>3.2.3.13. List: [T]</h5></div></div></div><p>A type [X1, X2, …, Xn] is of type [T] if all of Xi are of type T.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="_predefined_p_emphasis_or_emphasis_p_a1_a2_8230_an"></a>3.2.3.14. Predefined: P() <span class="emphasis"><em>or</em></span> P(A1, A2, …, An)</h5></div></div></div><p>Predefined types are referenced by the notation:</p><pre class="screen">P()</pre><p>or by the notation:</p><pre class="screen">P(A1, A2, ..., An)</pre><p>The name of the predefined type is <span class="emphasis"><em>P</em></span>. Using the second notation,
attributes can be specified to make the predefined type more specific.</p><p>The following predefined types and optional attributes are supported:</p><div class="variablelist"><dl><dt><span class="term">
atom
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
ascii
</li><li>
asciiprintable
</li><li>
nonempty
</li><li>
nonundefined
</li></ul></div></dd><dt><span class="term">
binary
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
ascii
</li><li>
asciiprintable
</li><li>
nonempty
</li></ul></div></dd><dt><span class="term">
float
</span></dt><dd>
<span class="emphasis"><em>no optional attributes are supported</em></span>
</dd><dt><span class="term">
integer
</span></dt><dd>
<span class="emphasis"><em>no optional attributes are supported</em></span>
</dd><dt><span class="term">
list
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
nonempty
</li></ul></div></dd><dt><span class="term">
proplist
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
nonempty
</li></ul></div></dd><dt><span class="term">
string
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
ascii
</li><li>
asciiprintable
</li><li>
nonempty
</li></ul></div></dd><dt><span class="term">
term
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
nonempty
</li><li>
nonundefined
</li></ul></div></dd><dt><span class="term">
tuple
</span></dt><dd><div class="itemizedlist"><ul type="disc"><li>
nonempty
</li><li>
nonundefined
</li></ul></div></dd><dt><span class="term">
void
</span></dt><dd>
<span class="emphasis"><em>no optional attributes are supported</em></span>
</dd></dl></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_states"></a>3.2.4. States</h4></div></div></div><div class="itemizedlist"><ul type="disc"><li>
Name
</li><li><p>
Transitions
</p><div class="itemizedlist"><ul type="circle"><li>
Request
</li><li>
Response
</li><li>
Next State
</li></ul></div></li><li>
Events
</li></ul></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_anystate"></a>3.2.5. Anystate</h4></div></div></div><div class="itemizedlist"><ul type="disc"><li>
Requests
</li><li>
Responses
</li><li>
Events
</li></ul></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_ubf_c"></a>3.3. UBF(c)</h3></div></div></div><p>See <a class="xref" href="#ABNF-UBFc" title="10.2.3.&#xA0;UBF(c)">Section 10.2.3, “UBF(c)”</a> for a formal definition of the UBF(c) syntax.</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_request"></a>3.3.1. Request</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_response"></a>3.3.2. Response</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_event"></a>3.3.3. Event</h4></div></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_contracts"></a>4. Contracts</h2></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_transports"></a>5. Transports</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_tcp_ip"></a>5.1. TCP/IP</h3></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_ubf"></a>5.1.1. UBF</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_ebf"></a>5.1.2. EBF</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_jsf"></a>5.1.3. JSF</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_tbf"></a>5.1.4. TBF</h4></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_http"></a>5.2. HTTP</h3></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_json_rpc"></a>5.2.1. JSON RPC</h4></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_misc"></a>5.3. Misc</h3></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_etf"></a>5.3.1. ETF</h4></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="_lpc"></a>5.3.2. LPC</h4></div></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_servers"></a>6. Servers</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_stateless"></a>6.1. Stateless</h3></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_stateful"></a>6.2. Stateful</h3></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_clients"></a>7. Clients</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_erlang"></a>7.1. Erlang</h3></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_python"></a>7.2. Python</h3></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_java"></a>7.3. Java</h3></div></div></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_miscellaneous"></a>8. Miscellaneous</h2></div></div></div><div class="itemizedlist"><ul type="disc"><li>
download
</li><li>
build
</li><li>
test
</li></ul></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_reference"></a>9. Reference</h2></div></div></div><div class="bibliomixed"><a id="id2663670"></a><p class="bibliomixed">
<span class="bibliomisc">
<a id="RFC5234"></a>[RFC5234] D. Crocker, Ed. Brandenburg, "Augmented BNF for Syntax
Specifications: ABNF", RFC5234, January 2008.
</span>
</p></div><div class="bibliomixed"><a id="id2688730"></a><p class="bibliomixed">
<span class="bibliomisc">
<a id="UBF"></a>[UBF] Joe Armstrong, <a class="ulink" href="http://www.sics.se/~joe/ubf.html" target="_top">http://www.sics.se/~joe/ubf.html</a>, March
2003.
</span>
</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_appendix"></a>10. Appendix</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_acknowledgements"></a>10.1. Acknowledgements</h3></div></div></div><p>Many, many thanks to Joe Armstrong, UBFs designer and original
implementor.</p><p>Gemini Mobile Technologies, Inc. has approved the release of its
extensions, improvements, etc. under an MIT license. Joe Armstrong
has also given his blessing to Geminis license choice.</p><pre class="screen">The MIT License
Copyright (c) 2009,2010 Gemini Mobile Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="_abnf_definition"></a>10.2. ABNF Definition</h3></div></div></div><p>The formal syntax for UBF(a), UBF(b), and UBF(c) is defined in ABNF
format per <a class="xref" href="#RFC5234">[RFC5234]</a> except for one extension - single quoted
strings are case-sensitive.</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="ABNF-UBFa"></a>10.2.1. UBF(a)</h4></div></div></div><pre class="programlisting">ubf-a = *ubf-a-wsp ubf-a-object *ubf-a-wsp "$"
ubf-a-object = (ubf-a-term / ubf-a-pop / ubf-a-push) *ubf-a-wsp [ubf-a-tag] *ubf-a-wsp
ubf-a-wsp = ubf-a-comment / ubf-a-ignore
ubf-a-term = ubf-a-atom
/ ubf-a-string
/ ubf-a-binary
/ ubf-a-integer
/ ubf-a-list
/ ubf-a-tuple
ubf-a-pop = "&gt;" ubf-a-register
ubf-a-push = ubf-a-register
ubf-a-atom = "'" *(%x20-26 / %x28-5B / %x5D-7E / "\\" / "\'") "'"
ubf-a-string = '"' *(%x20-21 / %x23-5B / %x5D-7E / '\\' / '\"') '"'
ubf-a-binary = ubf-a-integer *ubf-a-wsp "~" *OCTET "~"
ubf-a-integer = ["-"] 1*DIGIT
ubf-a-list = "#" *ubf-a-wsp [ubf-a-object *ubf-a-wsp "&amp;"]
ubf-a-tuple = "{" *ubf-a-wsp [ubf-a-object *ubf-a-wsp] "}"
ubf-a-tag = "`" 1*(%x20-5B / %x5D-5F / %x61-7E / "\\" / "\`") "`"
ubf-a-comment = "%" *(%x20-24 / %x26-5B / %x5D-7E / "\\" / "\%") "%"
ubf-a-ignore = SP ;; %x20
/ LF ;; %x0A
/ CR ;; %x0D
/ HTAB ;; %x09
/ "," ;; %x2C
ubf-a-control = "%" ;; %x25
/ '"' ;; %x22
/ "~" ;; %x7E
/ "'" ;; %x27
/ "`" ;; %x60
/ "{" ;; %x7B
/ "}" ;; %x7D
/ "#" ;; %x23
/ "&amp;" ;; %x26
/ "-" ;; %x2D
/ DIGIT ;; %x30-39
/ ubf-a-ignore
ubf-a-register = %x21 ;; any octet except ubf-a-control
/ %x00-08
/ %x0B-0C
/ %x0E-1F
/ %x23-24
/ %x28-2B
/ %x2F
/ %x3A-5F
/ %x61-7A
/ %x7C
/ %x7F</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="ABNF-UBFb"></a>10.2.2. UBF(b)</h4></div></div></div><pre class="programlisting">ubf-b = ubf-b-name ubf-b-vsn [ubf-b-type] *ubf-b-state [ubf-b-anystate]
ubf-b-name = "+" 'NAME' "(" NONEMTPYSTRING ")" dot
ubf-b-vsn = "+" 'VSN' "(" NONEMTPYSTRING ")" dot
ubf-b-type = "+" 'TYPES' 1*WSP types dot
ubf-b-state = "+" 'STATE' 1*WSP statename 1*WSP transitions dot
ubf-b-anystate = "+" 'ANYSTATE' 1*WSP anyrules dot
dot = "." *c-wsp c-nl
semi = ";" *c-wsp c-nl
comment = "%" *(WSP / VCHAR) CRLF
c-nl = comment / CRLF
c-wsp = WSP / (c-nl WSP)
statename = NONEMTPYATOM
typename = NONEMTPYATOM
recordname = NONEMTPYATOM
fieldname = NONEMTPYATOM
types = typedef
/ (typedef semi types)
typedef = typeref *c-wsp "=" *c-wsp type [1*WSP annotation] *c-wsp
transitions = transition
/ (transition semi transitions)
transition = typeref *c-wsp "=&gt;" *c-wsp outputs *c-wsp
/ event
anyrules = anyrule
/ (anyrule semi anyrules)
anyrule = typeref *c-wsp "=&gt;" *c-wsp typeref *c-wsp
/ event
event = 'EVENT' *c-wsp ("=&gt;" / "&lt;=") *c-wsp typeref *c-wsp
type = primtype
/ (primtype *c-wsp "|" *c-wsp type)
annotation = STRING / BINARY
outputs = output
/ (output *c-wsp "|" *c-wsp outputs)
output = typeref *c-wsp "&amp;" *c-wsp statename
primtype = (typeref [ "?" ])
/ ("{" [typeseq] "}")
/ ("#" recordname "{" [typerec] "}")
/ ("##" recordname "{" [typerec] "}")
/ typelist
/ (INTEGER *WSP ".." *WSP INTEGER)
/ (".." *WSP INTEGER)
/ (INTEGER *WSP "..")
/ ATOM
/ BINARY
/ FLOAT
/ INTEGER
/ STRING
/ (predefinedtype [ "?" ])
typelist = ("[" [type] "]" [ "?" / ("{" listrange "}") ])
typeref = typename "()"
typeseq = type
/ (type *WSP "," *WSP typeseq)
typerec = (fieldname *WSP "=" *WSP type)
/ (fieldname *WSP "=" *WSP type "," *WSP typerec)
listrange = (1*DIGIT)
/ (1*DIGIT *WSP ",")
/ (1*DIGIT *WSP "," *WSP 1*DIGIT)
ATOM = (%x61-7A *(ALPHA / DIGIT / "_" / "@")) ;; a-z
/ ("'" *(%x20-26 / %x28-7E) "'")
NONEMTPYATOM = (%x61-7A 1*(ALPHA / DIGIT / "_" / "@")) ;; a-z
/ ("'" 1*(%x20-26 / %x28-7E) "'")
BINARY = "&lt;&lt;" STRING "&gt;&gt;"
FLOAT = ["-"] 1*DIGIT "." 1*DIGIT
INTEGER = (["-"] 1*DIGIT)
/ (1*DIGIT "#" 1*(DIGIT / 'a' / 'b' / 'c' / 'd' / 'e' / 'f'))
STRING = DQUOTE *(%x20-21 / %x23-7E) DQUOTE
NONEMTPYSTRING = DQUOTE 1*(%x20-21 / %x23-7E) DQUOTE
predefinedtype = ('atom' "(" [atomattrs] ")")
/ ('binary' "(" [binaryattrs] ")")
/ ('float' "(" [floatattrs] ")")
/ ('integer' "(" [integerattrs] ")")
/ ('list' "(" [listattrs] ")")
/ ('proplist' "(" [proplistattrs] ")")
/ ('string' "(" [stringattrs] ")")
/ ('term' "(" [termattrs] ")")
/ ('tuple' "(" [tupleattrs] ")")
/ ('void' "(" [voidattrs] ")")
atomattrs = atomattr
/ (atomattr *WSP "," *WSP atomattrs)
binaryattrs = binaryattr
/ (binaryattr *WSP "," *WSP binaryattrs)
floatattrs = *WSP
integerattrs = *WSP
listattrs = listattr
/ (listattr *WSP "," *WSP listattrs)
proplistattrs = proplistattr
/ (proplistattr *WSP "," *WSP proplistattrs)
stringattrs = stringattr
/ (stringattr *WSP "," *WSP stringattrs)
termattrs = termattr
/ (termattr *WSP "," *WSP termattrs)
tupleattrs = tupleattr
/ (tupleattr *WSP "," *WSP tupleattrs)
voidattrs = *WSP
atomattr = 'ascii' / 'asciiprintable' / 'nonempty' / 'nonundefined'
binaryattr = 'ascii' / 'asciiprintable' / 'nonempty'
listattr = 'nonempty'
proplistattr = 'nonempty'
stringattr = 'ascii' / 'asciiprintable' / 'nonempty'
termattr = 'nonempty' / 'nonundefined'
tupleattr = 'nonempty' / 'nonundefined'</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="ABNF-UBFc"></a>10.2.3. UBF(c)</h4></div></div></div><pre class="programlisting">ubf-c = ubf-c-rpc-req
/ ubf-c-rpc-res
/ ubf-c-event-in
/ ubf-c-event-out
ubf-c-rpc-req = ubf-msg "$"
ubf-c-rpc-res = "{" (ubf-msg / ubf-error) "," ubf-nextstate "}" "$"
ubf-c-event-in = "{" 'event_in' "," ubf-msg "}" "$"
ubf-c-event-out = "{" 'event_out' "," ubf-msg "}" "$"
ubf-msg = ubf-a-term
ubf-nextstate = ubf-a-atom
ubf-error = ubf-client-error
/ ubf-server-error
ubf-client-error = "{" 'clientBrokeContract' "," ubf-msg "," ubf-expects-in "}" "$"
ubf-server-error = "{" 'serverBrokeContract' "," ubf-msg "," ubf-expects-out "}" "$"
ubf-expects-in = ubf-a-term ;; list of acceptable input types (for debugging purposes)
ubf-expects-out = ubf-a-term ;; list of acceptable output types (for debugging purposes)</pre></div></div></div></div></body></html>