mirror of
https://github.com/ubf/ubf.git
synced 2026-04-21 20:25:57 +00:00
505 lines
40 KiB
HTML
505 lines
40 KiB
HTML
<?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 User’s 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 User’s 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 & ObjN-1 & … & Obj2 & 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: >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 Armstrong’s 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 UBF’s 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'>p # {p,"Joe",123} & {p, 'fred', 3~abc~} & $</pre><p>Represents the following UBF(b) term:</p><pre class="screen">[{person, fred, <<"abc">>}, {person, "Joe", 123}].</pre><p>See <a class="xref" href="#ABNF-UBFa" title="10.2.1. 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 & ObjN-1 & … & Obj2 & 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>&</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: >C C</h4></div></div></div><p>So far, exactly 26 control characters have been used, namely:
|
||
%"~'`{}#&\s\n\t\r,-01234567890</p><p>This leaves us with 230 unallocated byte codes. These are used as
|
||
follows:</p><pre class="screen">>C</pre><p>Where <span class="emphasis"><em>C</em></span> is not one of the reserved byte codes, > 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() => proceed() & active. %% Nick randomly assigned
|
||
|
||
+STATE active
|
||
listGroups() => groups() & active;
|
||
joinGroup() => ok() & active;
|
||
leaveGroup() => ok() & active;
|
||
changeNick() => bool() & active;
|
||
msg() => bool() & active; %% False if you have not joined a group
|
||
|
||
EVENT => msgEvent(); %% Group sends me a message
|
||
EVENT => joinEvent(); %% Nick joins group
|
||
EVENT => leaveEvent(); %% Nick leaves group
|
||
EVENT => changeNameEvent(). %% Nick changes name
|
||
|
||
+ANYSTATE
|
||
info() => string();
|
||
description() => string();
|
||
contract() => term().</pre><p>See <a class="xref" href="#ABNF-UBFb" title="10.2.2. 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 type’s 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: <<"…">></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. 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, UBF’s 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 Gemini’s 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 = ">" 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 "&"]
|
||
|
||
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
|
||
/ "&" ;; %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 "=>" *c-wsp outputs *c-wsp
|
||
/ event
|
||
|
||
anyrules = anyrule
|
||
/ (anyrule semi anyrules)
|
||
|
||
anyrule = typeref *c-wsp "=>" *c-wsp typeref *c-wsp
|
||
/ event
|
||
|
||
event = 'EVENT' *c-wsp ("=>" / "<=") *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 "&" *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 = "<<" STRING ">>"
|
||
|
||
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>
|