diff --git a/docbook-xsl.css b/docbook-xsl.css index 2841225..6df2944 100644 --- a/docbook-xsl.css +++ b/docbook-xsl.css @@ -1,314 +1,322 @@ -/* - CSS stylesheet for XHTML produced by DocBook XSL stylesheets. - Tested with XSL stylesheets 1.61.2, 1.67.2 -*/ - -span.strong { - font-weight: bold; -} - -body blockquote { - margin-top: .75em; - line-height: 1.5; - margin-bottom: .75em; -} - -html body { - margin: 1em 5% 1em 5%; - line-height: 1.2; -} - -body div { - margin: 0; -} - -h1, h2, h3, h4, h5, h6 -{ - color: #527bbd; - font-family: tahoma, verdana, sans-serif; -} - -div.toc p:first-child, -div.list-of-figures p:first-child, -div.list-of-tables p:first-child, -div.list-of-examples p:first-child, -div.example p.title, -div.sidebar p.title -{ - font-weight: bold; - color: #527bbd; - font-family: tahoma, verdana, sans-serif; - margin-bottom: 0.2em; -} - -body h1 { - margin: .0em 0 0 -4%; - line-height: 1.3; - border-bottom: 2px solid silver; -} - -body h2 { - margin: 0.5em 0 0 -4%; - line-height: 1.3; - border-bottom: 2px solid silver; -} - -body h3 { - margin: .8em 0 0 -3%; - line-height: 1.3; -} - -body h4 { - margin: .8em 0 0 -3%; - line-height: 1.3; -} - -body h5 { - margin: .8em 0 0 -2%; - line-height: 1.3; -} - -body h6 { - margin: .8em 0 0 -1%; - line-height: 1.3; -} - -body hr { - border: none; /* Broken on IE6 */ -} -div.footnotes hr { - border: 1px solid silver; -} - -div.navheader th, div.navheader td, div.navfooter td { - font-family: sans-serif; - font-size: 0.9em; - font-weight: bold; - color: #527bbd; -} -div.navheader img, div.navfooter img { - border-style: none; -} -div.navheader a, div.navfooter a { - font-weight: normal; -} -div.navfooter hr { - border: 1px solid silver; -} - -body td { - line-height: 1.2 -} - -body th { - line-height: 1.2; -} - -ol { - line-height: 1.2; -} - -ul, body dir, body menu { - line-height: 1.2; -} - -html { - margin: 0; - padding: 0; -} - -body h1, body h2, body h3, body h4, body h5, body h6 { - margin-left: 0 -} - -body pre { - margin: 0.5em 10% 0.5em 1em; - line-height: 1.0; - color: navy; -} - -tt.literal, code.literal { - color: navy; -} - -.programlisting, .screen { - border: 1px solid silver; - background: #f4f4f4; - margin: 0.5em 10% 0.5em 0; - padding: 0.5em 1em; -} - -div.sidebar { - background: #ffffee; - margin: 1.0em 10% 0.5em 0; - padding: 0.5em 1em; - border: 1px solid silver; -} -div.sidebar * { padding: 0; } -div.sidebar div { margin: 0; } -div.sidebar p.title { - margin-top: 0.5em; - margin-bottom: 0.2em; -} - -div.bibliomixed { - margin: 0.5em 5% 0.5em 1em; -} - -div.glossary dt { - font-weight: bold; -} -div.glossary dd p { - margin-top: 0.2em; -} - -dl { - margin: .8em 0; - line-height: 1.2; -} - -dt { - margin-top: 0.5em; -} - -dt span.term { - font-style: normal; - color: navy; -} - -div.variablelist dd p { - margin-top: 0; -} - -div.itemizedlist li, div.orderedlist li { - margin-left: -0.8em; - margin-top: 0.5em; -} - -ul, ol { - list-style-position: outside; -} - -div.sidebar ul, div.sidebar ol { - margin-left: 2.8em; -} - -div.itemizedlist p.title, -div.orderedlist p.title, -div.variablelist p.title -{ - margin-bottom: -0.8em; -} - -div.revhistory table { - border-collapse: collapse; - border: none; -} -div.revhistory th { - border: none; - color: #527bbd; - font-family: tahoma, verdana, sans-serif; -} -div.revhistory td { - border: 1px solid silver; -} - -/* Keep TOC and index lines close together. */ -div.toc dl, div.toc dt, -div.list-of-figures dl, div.list-of-figures dt, -div.list-of-tables dl, div.list-of-tables dt, -div.indexdiv dl, div.indexdiv dt -{ - line-height: normal; - margin-top: 0; - margin-bottom: 0; -} - -/* - Table styling does not work because of overriding attributes in - generated HTML. -*/ -div.table table, -div.informaltable table -{ - margin-left: 0; - margin-right: 5%; - margin-bottom: 0.8em; -} -div.informaltable table -{ - margin-top: 0.4em -} -div.table thead, -div.table tfoot, -div.table tbody, -div.informaltable thead, -div.informaltable tfoot, -div.informaltable tbody -{ - /* No effect in IE6. */ - border-top: 3px solid #527bbd; - border-bottom: 3px solid #527bbd; -} -div.table thead, div.table tfoot, -div.informaltable thead, div.informaltable tfoot -{ - font-weight: bold; -} - -div.mediaobject img { - margin-bottom: 0.8em; -} -div.figure p.title, -div.table p.title -{ - margin-top: 1em; - margin-bottom: 0.4em; -} - -div.calloutlist p -{ - margin-top: 0em; - margin-bottom: 0.4em; -} - -@media print { - div.navheader, div.navfooter { display: none; } -} - -span.aqua { color: aqua; } -span.black { color: black; } -span.blue { color: blue; } -span.fuchsia { color: fuchsia; } -span.gray { color: gray; } -span.green { color: green; } -span.lime { color: lime; } -span.maroon { color: maroon; } -span.navy { color: navy; } -span.olive { color: olive; } -span.purple { color: purple; } -span.red { color: red; } -span.silver { color: silver; } -span.teal { color: teal; } -span.white { color: white; } -span.yellow { color: yellow; } - -span.aqua-background { background: aqua; } -span.black-background { background: black; } -span.blue-background { background: blue; } -span.fuchsia-background { background: fuchsia; } -span.gray-background { background: gray; } -span.green-background { background: green; } -span.lime-background { background: lime; } -span.maroon-background { background: maroon; } -span.navy-background { background: navy; } -span.olive-background { background: olive; } -span.purple-background { background: purple; } -span.red-background { background: red; } -span.silver-background { background: silver; } -span.teal-background { background: teal; } -span.white-background { background: white; } -span.yellow-background { background: yellow; } - -span.big { font-size: 2em; } -span.small { font-size: 0.6em; } +/* + CSS stylesheet for XHTML produced by DocBook XSL stylesheets. + Tested with XSL stylesheets 1.61.2, 1.67.2 +*/ + +span.strong { + font-weight: bold; +} + +body blockquote { + margin-top: .75em; + line-height: 1.5; + margin-bottom: .75em; +} + +html body { + margin: 1em 5% 1em 5%; + line-height: 1.2; +} + +body div { + margin: 0; +} + +h1, h2, h3, h4, h5, h6 +{ + color: #527bbd; + font-family: tahoma, verdana, sans-serif; +} + +div.toc p:first-child, +div.list-of-figures p:first-child, +div.list-of-tables p:first-child, +div.list-of-examples p:first-child, +div.example p.title, +div.sidebar p.title +{ + font-weight: bold; + color: #527bbd; + font-family: tahoma, verdana, sans-serif; + margin-bottom: 0.2em; +} + +body h1 { + margin: .0em 0 0 -4%; + line-height: 1.3; + border-bottom: 2px solid silver; +} + +body h2 { + margin: 0.5em 0 0 -4%; + line-height: 1.3; + border-bottom: 2px solid silver; +} + +body h3 { + margin: .8em 0 0 -3%; + line-height: 1.3; +} + +body h4 { + margin: .8em 0 0 -3%; + line-height: 1.3; +} + +body h5 { + margin: .8em 0 0 -2%; + line-height: 1.3; +} + +body h6 { + margin: .8em 0 0 -1%; + line-height: 1.3; +} + +body hr { + border: none; /* Broken on IE6 */ +} +div.footnotes hr { + border: 1px solid silver; +} + +div.navheader th, div.navheader td, div.navfooter td { + font-family: sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #527bbd; +} +div.navheader img, div.navfooter img { + border-style: none; +} +div.navheader a, div.navfooter a { + font-weight: normal; +} +div.navfooter hr { + border: 1px solid silver; +} + +body td { + line-height: 1.2 +} + +body th { + line-height: 1.2; +} + +ol { + line-height: 1.2; +} + +ul, body dir, body menu { + line-height: 1.2; +} + +html { + margin: 0; + padding: 0; +} + +body h1, body h2, body h3, body h4, body h5, body h6 { + margin-left: 0 +} + +body pre { + margin: 0.5em 10% 0.5em 1em; + line-height: 1.0; + color: navy; +} + +tt.literal, code.literal { + color: navy; +} + +.programlisting, .screen { + border: 1px solid silver; + background: #f4f4f4; + margin: 0.5em 10% 0.5em 0; + padding: 0.5em 1em; +} + +div.sidebar { + background: #ffffee; + margin: 1.0em 10% 0.5em 0; + padding: 0.5em 1em; + border: 1px solid silver; +} +div.sidebar * { padding: 0; } +div.sidebar div { margin: 0; } +div.sidebar p.title { + margin-top: 0.5em; + margin-bottom: 0.2em; +} + +div.bibliomixed { + margin: 0.5em 5% 0.5em 1em; +} + +div.glossary dt { + font-weight: bold; +} +div.glossary dd p { + margin-top: 0.2em; +} + +dl { + margin: .8em 0; + line-height: 1.2; +} + +dt { + margin-top: 0.5em; +} + +dt span.term { + font-style: normal; + color: navy; +} + +div.variablelist dd p { + margin-top: 0; +} + +div.itemizedlist li, div.orderedlist li { + margin-left: -0.8em; + margin-top: 0.5em; +} + +ul, ol { + list-style-position: outside; +} + +div.sidebar ul, div.sidebar ol { + margin-left: 2.8em; +} + +div.itemizedlist p.title, +div.orderedlist p.title, +div.variablelist p.title +{ + margin-bottom: -0.8em; +} + +div.revhistory table { + border-collapse: collapse; + border: none; +} +div.revhistory th { + border: none; + color: #527bbd; + font-family: tahoma, verdana, sans-serif; +} +div.revhistory td { + border: 1px solid silver; +} + +/* Keep TOC and index lines close together. */ +div.toc dl, div.toc dt, +div.list-of-figures dl, div.list-of-figures dt, +div.list-of-tables dl, div.list-of-tables dt, +div.indexdiv dl, div.indexdiv dt +{ + line-height: normal; + margin-top: 0; + margin-bottom: 0; +} + +/* + Table styling does not work because of overriding attributes in + generated HTML. +*/ +div.table table, +div.informaltable table +{ + margin-left: 0; + margin-right: 5%; + margin-bottom: 0.8em; +} +div.informaltable table +{ + margin-top: 0.4em +} +div.table thead, +div.table tfoot, +div.table tbody, +div.informaltable thead, +div.informaltable tfoot, +div.informaltable tbody +{ + /* No effect in IE6. */ + border-top: 3px solid #527bbd; + border-bottom: 3px solid #527bbd; +} +div.table thead, div.table tfoot, +div.informaltable thead, div.informaltable tfoot +{ + font-weight: bold; +} + +div.mediaobject img { + margin-bottom: 0.8em; +} +div.figure p.title, +div.table p.title +{ + margin-top: 1em; + margin-bottom: 0.4em; +} + +div.calloutlist p +{ + margin-top: 0em; + margin-bottom: 0.4em; +} + +a img { + border-style: none; +} + +@media print { + div.navheader, div.navfooter { display: none; } +} + +span.aqua { color: aqua; } +span.black { color: black; } +span.blue { color: blue; } +span.fuchsia { color: fuchsia; } +span.gray { color: gray; } +span.green { color: green; } +span.lime { color: lime; } +span.maroon { color: maroon; } +span.navy { color: navy; } +span.olive { color: olive; } +span.purple { color: purple; } +span.red { color: red; } +span.silver { color: silver; } +span.teal { color: teal; } +span.white { color: white; } +span.yellow { color: yellow; } + +span.aqua-background { background: aqua; } +span.black-background { background: black; } +span.blue-background { background: blue; } +span.fuchsia-background { background: fuchsia; } +span.gray-background { background: gray; } +span.green-background { background: green; } +span.lime-background { background: lime; } +span.maroon-background { background: maroon; } +span.navy-background { background: navy; } +span.olive-background { background: olive; } +span.purple-background { background: purple; } +span.red-background { background: red; } +span.silver-background { background: silver; } +span.teal-background { background: teal; } +span.white-background { background: white; } +span.yellow-background { background: yellow; } + +span.big { font-size: 2em; } +span.small { font-size: 0.6em; } + +span.underline { text-decoration: underline; } +span.overline { text-decoration: overline; } +span.line-through { text-decoration: line-through; } diff --git a/images/ubf-flow-01.png b/images/ubf-flow-01.png index ff30ee2..9cc58e7 100644 Binary files a/images/ubf-flow-01.png and b/images/ubf-flow-01.png differ diff --git a/images/ubf-flow-02.png b/images/ubf-flow-02.png index e02f5b8..b830711 100644 Binary files a/images/ubf-flow-02.png and b/images/ubf-flow-02.png differ diff --git a/index.html b/index.html index 6f28eea..5da660e 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ -
UBF, a framework for Getting Erlang to talk to the outside world. +
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 diff --git a/misc-codes/ubf_bertrpc_plugin.erl b/misc-codes/ubf_bertrpc_plugin.erl index da73d9d..d4cddcb 100644 --- a/misc-codes/ubf_bertrpc_plugin.erl +++ b/misc-codes/ubf_bertrpc_plugin.erl @@ -4,7 +4,7 @@ %%% -module(ubf_bertrpc_plugin). --behavior(ubf_plugin_stateless). +-behaviour(ubf_plugin_stateless). %% Required (except keepalive/0) callback API for UBF stateless %% implementations. diff --git a/ubf-user-guide.en.html b/ubf-user-guide.en.html index be6f692..3e35846 100644 --- a/ubf-user-guide.en.html +++ b/ubf-user-guide.en.html @@ -1,12 +1,12 @@ -
Table of Contents
UBF is a framework that permits the Erlang to talk to the outside +
Table of Contents
UBF is a framework that permits the Erlang to talk to the outside world [UBFPAPER]. The acronym "UBF" stands for "Universal Binary Format", designed and implemented by Joe Armstrong.
This document and the corresponding open-source code repositories hosted on github [UBF] are based on Joe Armstrong’s original UBF site [UBFSITE] and UBF code with an MIT license file added to the distribution. Since then, a large number of enhancements and -improvements have been added.
UBF is a language for transporting and describing complex data +improvements have been added.
UBF is a language for transporting and describing complex data structures across a network. It has three components:
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.
Figure 1. Programming By Contract
UBF(a) is a transport format. UBF(a) was designed to be easy to parse +to the original UBF(a) implementation.
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 @@ -85,28 +85,28 @@ implementation, a "Float" type was added to UBF(b) for use in other network transports other than UBF(a). In future, UBF(a) could be enhanced to support a "Float" primitive type.
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.
Strings are written enclosed in double quotes. Within a string two +negative integer) and then a sequence of at least one digit.
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.
Uninterpreted blocks of binary data are encoded. First an integer, +written \\ - no other quotings are allowed.
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.
Atoms are encoded as strings, only using a single quote instead of a +added between the integer length and the data for readability.
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.
Tuples represent fixed numbers of objects. The byte codes for "{" +representing symbolic constants.
Tuples represent fixed numbers of objects. The byte codes for "{" and "}" are used to delimit a tuple. Obj1, Obj2, ObjN-1, and ObjN are -arbitrary UBF(a) objects.
Lists represent variable numbers of objects. The first object in +arbitrary UBF(a) objects.
Lists represent variable numbers 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.
Lisp programmers will recognize # as an operator that pushes NIL (or the end of list) onto the recognition stack and & as an operator that takes the top two items on the recognition stack and replaces -them by a list cell.
For convenience, blank, carriage return, line feed, tab, comma, and +them by a list cell.
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.
In addition any item can be followed by a semantic tag this is written +UBF(a) with the syntax %…% and the usual quoting convention applies.
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:
12456 ~...~ `jpg`
Represents 12,456 bytes of raw data with the semantic tag "jpg". @@ -126,7 +126,7 @@ stack. For caching optimizations, subsequent reuse of the single character C means push register C onto the recognition stack.
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 @@ -195,7 +195,7 @@ influenced by Erlang. For example, the difference between a string type and a binary type is directly due to Erlang’s implementation of binaries and strings. Similarly, the reason for supporting a record type and extended record type is also directly due to Erlang’s -implementation of records.
The UBF(b) type system has user-defined types and predefined types. +implementation of records.
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.
The primitive types are Integer, Range, Float, Binary, String, Atom, and Reference. The complex types are Alternative, Tuple, Record, @@ -207,15 +207,15 @@ syntax.
Positive and negative float constants are supported for network transports other than UBF(a).
In future, the implementation of UBF(b) could be enhanced to specify a float more compactly using scientific notation -(e.g. "6.02e23"). |
Binary constants are expressed similarly as strings in UBF(a) but having two leading "less than brackets" and two following "greater -than brackets".
Atom constants are expressed as UBF(a) atoms. Atom constants starting +than brackets".
Atom constants are expressed as UBF(a) atoms. Atom constants starting with lowercase letters do not require single quotes.
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.
A record type is syntactic sugar for a tuple of type "{name, T1, T2, -…, Tn}" where name, x, y, …, and z are atoms.
An extended record type is syntactic sugar for a tuple of type "{name, +T2.
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.
A record type is syntactic sugar for a tuple of type "{name, T1, T2, +…, Tn}" where name, x, y, …, and z are atoms.
An extended record type is syntactic sugar for a tuple of type "{name, T1, T2, …, Tn, $fields=[x,y,…,z], $extra=Extra}" where name, -x, y, …, and z are atoms and Extra is any valid term.
Predefined types are referenced by the notation:
P()
or by the notation:
P(A1, A2, ..., An)
The name of the predefined type is P. Using the second notation, +x, y, …, and z are atoms and Extra is any valid term.
Predefined types are referenced by the notation:
P()
or by the notation:
P(A1, A2, ..., An)
The name of the predefined type is P. Using the second notation, attributes can be specified to make the predefined type less general and thus more specific when matching objects.
ascii | asciiprintable | nonempty | nonundefined | |
integer | X | X | X | X |
float | X | X | X | X |
binary | O | O | O | X |
string | O | O | O | X |
atom | O | O | O | O |
tuple | X | X | O | X |
list | X | X | O | X |
proplist | X | X | O | X |
term | X | X | O | O |
void | X | X | X | X |
The above table summarizes the set of supported predefined types and their respective optional attributes.
The "integer", "float", "binary", "string", "atom", "tuple", and
@@ -253,9 +253,9 @@ response pairs and to define events that are valid in Events are checked based on direction first, on the current state’s
valid events next, and finally on the valid anystate events. Any cast
sent by the client or sent by the server that cannot match at least
-one valid event is ignored and dropped.
UBF(c) is a meta-level protocol used between a UBF client and a UBF server. UBF(c) has two primitives: synchronous "calls" and -asynchronous "casts".
Synchronous calls have the following form for the request:
Request $
and for the response:
{Response, NextState} $where "Request" is an UBF(a) type sent by the client and "Response" is +asynchronous "casts".
Synchronous calls have the following form for the request:
Request $
and for the response:
{Response, NextState} $where "Request" is an UBF(a) type sent by the client and "Response" is an UBF(a) type and "NextState" is an UBF(a) atom sent by the server.
If the client sends an invalid request, the server will respond with the following "client broke contract" error:
{{'clientBrokeContract', Request, ExpectsIn}, State} $where "ExpectsIn" is a UBF(a) type to describe the acceptable list of input types and "State" is an UBF(a) atom.
If the server sends an invalid response, the server will respond with @@ -269,9 +269,9 @@ dropped by the server.
See "Contracts" and "Plugins" are the basic building blocks of an Erlang
+in the future.
"Contracts" and "Plugins" are the basic building blocks of an Erlang UBF server. Contracts are a server’s specifications. Plugins are a -server’s implementations.
A contract is a UBF(b) specification stored to a file. By convention, +server’s implementations.
A contract is a UBF(b) specification stored to a file. By convention, a contract’s filename has ".con" as the suffix part. Since all sections of a UBF(b) specification are optional except for the "+NAME" and "+VERSION" sections, it is possible to have "+TYPES" only @@ -328,7 +328,7 @@ changeNameEvent() = {changesName, oldnick(), newnick(), group()}.
For ex +ANYSTATE info() => string(); description() => string(); - contract() => term().
A plugin is just a "normal" Erlang module that follows a few simple + contract() => term().
A plugin is just a "normal" Erlang module that follows a few simple rules. For a "+TYPES" only contract, the plugin contains just the name of it’s contract. Otherwise, the plugin contains the name of it’s contract plus the necessary Erlang "glue code" needed to bind the @@ -336,7 +336,7 @@ UBF server to the server’s application. In either case, a plugin can also import all or a subset of "+TYPES" from other plugins. This simple yet powerful import mechanism permits sharing and re-use of types between plugins and servers.
The necessary Erlang "glue code" is presented later in the -Section 6, “Servers” section. |
For the full example IRC contract described in a previous section, the +Section 6, “Servers” section.
For the full example IRC contract described in a previous section, the plugin having the filename "irc_plugin.erl" is as follows:
-module(irc_plugin).
-compile({parse_transform,contract_parser}).
@@ -344,7 +344,7 @@ plugin having the filename "irc_plugin.erl" is as follows:-module(irc_types_plugin).
-compile({parse_transform,contract_parser}).
--add_contract("irc_types_plugin").
The plugin for the "+STATE" and "+ANYSTATE" contract having the +-add_contract("irc_types_plugin").
The plugin for the "+STATE" and "+ANYSTATE" contract having the filename "irc_fsm_plugin.erl" is as follows:
-module(irc_fsm_plugin).
-compile({parse_transform,contract_parser}).
@@ -359,7 +359,7 @@ directives are listed before the "-add_contract" directive. A plugin
can have only one "-add_contract" directive.By using this Erlang "parse transform", the contract is parsed and the
imported types (if any) are processed during the compilation of the
plugin’s Erlang module. The normal search path used by Erlang’s
-compiler to locate modules is used to import types from other plugins.
The plugin will fail to compile if the plugin’s contract cannot be +compiler to locate modules is used to import types from other plugins.
The plugin will fail to compile if the plugin’s contract cannot be found, cannot be parsed properly, or if one of the following errors occurs:
where L is an Erlang list.
where L is an Erlang list.
As a by-product of a plugin’s compilation and if one or more "record" or "extended record" types were declared in a plugin’s contract, an Erlang "header" file containing the plugin’s record definitions is automatically created. This Erlang "header" file can be included by @@ -403,14 +403,14 @@ the same base filename as the plugin but having a ".huc" as the suffix part.
There are 2 experimental prototypes for extending UBF’s type and plugin framework. [UBF_ABNF] is a framework for integrating UBF and ABNF specifications. [UBF_EEP8] is a framework for integrating UBF -and EEP8 types. |
The original "UBF" network transport is UBF(a) over TCP/IP. Since then, a number of new transports not based on UBF(a) and not based on TCP/IP have been added. Nevertheless, these transports are still considered as part of the overall UBF framework. Most importantly, applications can share and re-use the same UBF contracts and plugins -irregardless of the network transport.
The name "UBF" is short for "Universal Binary Format". UBF is +irregardless of the network transport.
The name "UBF" is short for "Universal Binary Format". UBF is commonly used to refer to the network transport based on UBF(a) and to -the overall UBF framework.
See Section 3.1, “UBF(a)” for further information.
EBF is an implementation of UBF(b) but it does not use UBF(a) for the +the overall UBF framework.
See Section 3.1, “UBF(a)” for further information.
EBF is an implementation of UBF(b) but it does not use UBF(a) for the client and server communication. Instead, Erlang-style conventions are used instead:
record (defined in the contract as "foo() = with the "$R", "$T", and "$A" notation (for records, tuples, and atoms) into whatever object is most convenient.See [UBF_JSONRPC] for further information.
Gemini Mobile Technologies, Inc. has implemented and open-sourced a module for classifying the input character set to detect non-UTF8 -JSON inputs [GMTCHARSET].
TBF and NTBF is an implementation of UBF(b) but it does not use UBF(a) +JSON inputs [GMTCHARSET].
TBF and NTBF is an implementation of UBF(b) but it does not use UBF(a) for the client and server communication. Instead, Thrift [THRIFT] is used instead as the wire format. The name "TBF" is short for "Thrift Binary Format". The name "NTBF" is short for "Native Thrift -Binary Format".
TBF follows the conventions set forth by the Thrift community by +Binary Format". FTBF and FNTBF are framed versions of TBF and NTBF, +respectively.
TBF follows the conventions set forth by the Thrift community by re-using Thrift’s binary wire-protocol except for the following exceptions:
See [UBF_THRIFT] for further information.
It is worthwhile to mention two new TCP/IP transports namely PBF and ABF under investigation. The name "PBF" is short for "Google’s Protocol Buffers Format" [PROTOBUF]. The name "ABF" is short for -"Avro Binary Format" [AVRO].
JSON-RPC [JSONRPC] is a lightweight remote procedure call protocol similar to XML-RPC. The UBF framework implementation of JSON-RPC brings together JSF’s encoder/decoder, UBF(b)'s contract checking, and -an HTTP transport.
Figure 2. Programming By Contract w/ Multiple Transports
As previously stated, central to UBF is the idea of a "Contract" which regulates the set of legal conversations that can take place between a @@ -502,14 +503,14 @@ client and a server. The client-side is depicted in "red" and the server-side is depicted in "blue". The client and server communicate with each other via a TCP/IP and/or HTTP.
Central to UBF is the idea of contract(s) can be shared and re-used by multiple transports. Any data that violates the same contract(s) is -rejected regardless of the transport.
See [UBF_JSONRPC] for further information.
Several transports that do not require an explicit network socket have +rejected regardless of the transport.
See [UBF_JSONRPC] for further information.
Several transports that do not require an explicit network socket have been added to the UBF framework. These transports permit an application to call a plugin directly without the need for TCP/IP or HTTP.
The concept "ETF" was added to the UBF framework. This transport relies on Erlang’s Native Distribution for synchronous calls and asynchronous casts.
The name "ETF" is short for "Erlang Term Format".
The concept "LPC" was added to the UBF framework. This transport is a "non-transport" that invokes synchronous calls directly to a plugin. -Support for asynchronous casts has not been added (or designed) yet.
The name "LPC" is short for "Local Procedure Call".
LPC is used to implement the JSON-RPC transport. |
The UBF framework provides two types of Erlang servers: "stateless" and "stateful". The stateless server is an extension of Joe Armstrong’s original UBF server implementation. The "stateful" server is Joe Armstrong’s original UBF server implementation.
UBF servers are introspective - which means the servers can describe @@ -576,11 +577,22 @@ follows:
+ Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire + format with options. Default: {'ubf', []}. Supported options: +
The "ubf_server" Erlang module doesn’t provide a "stop" function. To stop the server, instead stop the TCP listener that controls it. See -the "proc_socket_server" Erlang module for extra details.
The NTBF transport protocol is indirectly enabled by specifying -the following options: [{'proto', 'tbf'}, {'serverhello', -'undefined'}, {'simplerpc', 'true'}]. |
The stateless server provides a simplified callback API and +the "proc_socket_server" Erlang module for extra details.
The NTBF and FNTBF transport protocol is indirectly enabled by +specifying the following options: [{'proto', 'tbf'}, +{'serverhello', 'undefined'}, {'simplerpc', 'true'}] or +[{'proto', 'ftbf'}, {'serverhello', 'undefined'}, {'simplerpc', +'true'}]. |
The stateless server provides a simplified callback API and implementation in comparision to Joe Armstrong’s original UBF server. The stateless server is helpful to applications that do not require explicit state management by the UBF server.
The "ubf_plugin_stateless.hrl" Erlang header file defines the callback @@ -668,7 +682,7 @@ source code for this implementation can be found on github %%% -module(ubf_bertrpc_plugin). --behavior(ubf_plugin_stateless). +-behaviour(ubf_plugin_stateless). %% Required (except keepalive/0) callback API for UBF stateless %% implementations. @@ -734,7 +748,7 @@ The "?S(X)" macro definition plus other helpers are located in the list of integers as the second element. A similar technique is also used for the implementation of a UBF proplist (i.e. '#P' and "?P(X)). -
The stateful server is Joe Armstrong’s original UBF server. The stateful server permits a plugin to transition from one state to another and also supports a manager framework for managing application state between multiple clients.
The "ubf_plugin_stateless.hrl" Erlang header file defines the callback @@ -772,7 +786,7 @@ handler. A handler uses the ubf_plugin_handler:ask_manager/2 function API to make a synchronous call to the manager.
For an example stateful server plugin, please see the "test/unit/irc_plugin.erl" Erlang module in the [UBF] repository. This plugin is the actual server-side implementation for -the IRC protocol application described earlier.
The UBF framework provides two types of Erlang clients: "rpc" and "lpc". The rpc client is the default client that supports TCP/IP-based and ETF transports. The lpc client is an alternative client for making a synchronous local procedure call to a plugin’s @@ -816,19 +830,19 @@ known) is returned. For TCP/IP transports, the default method is to connect to the specified host() and TCP ipport(). For the ETF transport, the alternative method is to connect to server() using the specified plugins(). The server() is either the process id or process -registered name for an already-started UBF server. See Section 6, “Servers” +registered name for an already-started UBF server. See Section 6, “Servers” for a description of options().
The rpc/{2,3} functions make a synchronous call to the server.
The stop/1 function closes the connection with the server and stops the client.
The sendEvent/2, install_default_handler/1, and install_handler/2 functions behave in the same way as the server-side implementation to send and receive asynchronous casts.
The lpc/{2,3,4} functions make a synchronous local procedure call to a plugin’s implementation. Regarding the tlogger(), see the section called “Transaction Logging” for -further information.
The unit tests in the "test/unit" directory provide small examples of +further information.
The unit tests in the "test/unit" directory provide small examples of how to use all of the public API. In particular, the *client*.erl files contain comments at the top with a list of prerequisites and small examples, recipe-style, for starting each server and using the client.
The eunit tests in the "test/eunit" directory perform several smoke and error handling uses cases.
The quickcheck tests and related helper libaries in the "test/eqc" -directory have not been open sourced yet. Please stay tuned!
See [QUVIQ] for further information about quickcheck.
For Erlang, the UBF server and the UBF "LPC" client can be configured +directory have not been open sourced yet. Please stay tuned!
See [QUVIQ] for further information about quickcheck.
For Erlang, the UBF server and the UBF "LPC" client can be configured to generate a transaction log. The transaction log module must implement the following tlog/6 callback API.
-type op() :: rpc | lpc | event_in | event_out.
-type now() :: {pos_integer(), pos_integer(), pos_integer()}.
@@ -838,7 +852,7 @@ implement the following tlog/6 callback API.-type op() :
version of a UBF contract. This feature is especially helpful when
importing UBF(b) types from one or more plugins.For UBF, the ubf_utils:ubf_contract/{1,2} functions are available for
this purpose. For JSON-RPC (and JSF indirectly), the
-jsf_utils:ubf_contract/{1,2} functions are available for this purpose.
This section describes the basic recipes for the following items:
The first step is to download the Git repositories from GitHub.
+further information regarding the usage of these tools.
The first step is to download the Git repositories from GitHub.
Configure your e-mail and name for Git
$ git config --global user.email "you@example.com" $ git config --global user.name "Your Name"
@@ -936,7 +950,7 @@ members having read-write access are recommended to use "repo init -u please append " -b dev" to the repo init command.
Download Git repositories
$ cd working-directory-name -$ repo sync
Build UBF
$ cd working-directory-name/src $ make compile
If the response is "make: erl: Command not found", please make @@ -944,7 +958,7 @@ sure Erlang/OTP is installed and "otp-installing-directory-name/bin" is added to your $PATH environment. |
Run the unit tests
$ cd working-directory-name/src -$ make eunit
Dialyzer Testing basic recipe
Build Dialyzer’s PLT (required once) @@ -970,7 +984,7 @@ $ git clone git://repo.or.cz/py_interface.git $ cd py_interface $ autoconf $ make
Then install as a normal Python package or run using "env -PYTHONPATH=working-directory-name/py_interface python your-script.py" |
This section is the first step to download and to build your own UBF documentation.
Building UBF’s "Guides" basic recipe
$ cd working-directory-name/src/lib/ubf/priv/doc/src/ubf
@@ -1009,7 +1023,7 @@ created by making a symlink to the lang-en.conf file.dif
def shell_rm(path):
if not os.path.exists(path):
-Only in 8.6.4/etc/asciidoc: lang-ja.confThis section is the first step to download, to build, and to install +Only in 8.6.4/etc/asciidoc: lang-ja.conf
This section is the first step to download, to build, and to install your own Erlang/OTP system.
Downloading basic recipe
Installing basic recipe
$ cd working-directory-name/otp_src_R14B01 $ sudo make install
Please make sure "otp-installing-directory-name/bin" is added -to your $PATH environment. |
If you are interested in making your own changes to UBF or to one or more of the other UBF-related repositories, it is a straigthforward process to fork and to build your own repositories using [GITHUB]. GitHub provides a friendly and easy to use environment for developers @@ -1049,118 +1063,118 @@ Choose all or a subset of the UBF-related repositories that you are Click on the "Fork" button near the top of the page. This action creates a clone of the ubf-bertrpc repository in your own account on GitHub. -
Under Construction - To Be Updated
[AVRO] "Avro is a serialization system.", http://avro.apache.org. -
[BERTRPC] "BERT and BERT-RPC 1.0 Specification", http://bert-rpc.org. -
[ERLANG] "A general-purpose programming language and runtime environment", http://www.erlang.org. -
[GIT] "Fast Version Control System", http://git-scm.com. -
[GMTCHARSET] "Gemini Mobile Technologies, Inc. charset module", https://github.com/norton/gmt-util/blob/master/src/gmt_charset.erl. -
[GITHUB] "Secure source code hosting and collaborative development ", https://github.com. -
[JSONRPC] "A lightweight remote procedure call protocol similar to XML-RPC", http://json-rpc.org. -
[MOCHIJSON2] "MochiWeb is an Erlang library for building lightweight HTTP servers.", https://github.com/mochi/mochiweb/blob/master/src/mochijson2.erl. -
[PROTOBUF] "Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data.", http://code.google.com/apis/protocolbuffers. -
[QUVIQ] "Quviq … amazing testing tools", http://www.quviq.com/. -
[RFC4627] D. Crockford, "The application/json Media Type for JavaScript Object Notation (JSON)", RFC4627, July 2006. -
[RFC5234] D. Crocker, Ed. Brandenburg, "Augmented BNF for Syntax Specifications: ABNF", RFC5234, January 2008. -
[THRIFT] "A software framework for scalable cross-language services development.", http://incubator.apache.org/thrift. -
[UBF] "Universal Binary Format", https://github.com/norton/ubf. -
[UBF_ABNF] "Universal Binary Format and Augmented Backus-Naur Form", https://github.com/norton/ubf-abnf. -
[UBF_BERTRPC] "Universal Binary Format and Binary ERlang Term RPC", https://github.com/norton/ubf-bertrpc. -
[UBF_EEP8] "Universal Binary Format and Erlang Enhancement Proposal 8", https://github.com/norton/ubf-eep8. -
[UBF_JSONRPC] "Universal Binary Format and JavaScript Object Notation RPC", https://github.com/norton/ubf-jsonrpc. -
[UBF_THRIFT] "Universal Binary Format and Thrift", https://github.com/norton/ubf-thrift. -
[UBFPAPER] Joe Armstrong, "Getting Erlang to talk to the outside world", Proceedings of the 2002 ACM SIGPLAN workshop on Erlang, pages 64-72, ACM Press, 2002. -
[UBFSITE] Joe Armstrong, http://www.sics.se/~joe/ubf/site/home.html, March 2003. -
Many, many thanks to Joe Armstrong, UBF’s designer and original implementor.
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.
The MIT License @@ -1183,7 +1197,7 @@ 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.
The formal syntax for UBF(a), UBF(b), and UBF(c) is defined in ABNF +THE SOFTWARE.
The formal syntax for UBF(a), UBF(b), and UBF(c) is defined in ABNF format per [RFC5234] except for one extension - single quoted strings are case-sensitive.
ubf-a = *ubf-a-wsp ubf-a-object *ubf-a-wsp "$" diff --git a/webpage-CHANGELOG.html b/webpage-CHANGELOG.html index 48c7ee3..a9c6590 100644 --- a/webpage-CHANGELOG.html +++ b/webpage-CHANGELOG.html @@ -1,3 +1,3 @@ -UBF CHANGELOG Page +UBF CHANGELOG Page diff --git a/webpage-FAQ.html b/webpage-FAQ.html index 2b1b396..fb72b7e 100644 --- a/webpage-FAQ.html +++ b/webpage-FAQ.html @@ -1,6 +1,6 @@ -UBF FAQ Page