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 Home Page

UBF Home Page


UBF, a framework for Getting Erlang to talk to the outside world. +UBF Home Page

UBF Home Page


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 @@ -UBF User’s Guide 1st DRAFT

UBF User’s Guide 1st DRAFT

Revision History
Revision 0.3.12011/04/24

1. Preface

UBF is a framework that permits the Erlang to talk to the outside +UBF User’s Guide 1st DRAFT

UBF User’s Guide 1st DRAFT

Revision History
Revision 0.3.22011/08/29

1. Preface

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.

2. Introduction

UBF is a language for transporting and describing complex data +improvements have been added.

2. Introduction

UBF is a language for transporting and describing complex data structures across a network. It has three components:

  • UBF(a) is a "language neutral" data transport format, roughly equivalent to well-formed XML. @@ -20,7 +20,7 @@ UBF(c) is a meta-level protocol used between a UBF client and a UBF server.

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

+"machine friendly" format. UBF is designed to be easy to implement.

Figure 1. Programming By Contract


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. @@ -33,7 +33,7 @@ rejected.

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.

3. Specifications

3.1. UBF(a)

UBF(a) is a transport format. UBF(a) was designed to be easy to parse +to the original UBF(a) implementation.

3. Specifications

3.1. UBF(a)

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.

Integer: [-][0-9]+

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.

String: "…"

Strings are written enclosed in double quotes. Within a string two +negative integer) and then a sequence of at least one digit.

String: "…"

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.

Binary: [0-9]+ ~…~

Uninterpreted blocks of binary data are encoded. First an integer, +written \\ - no other quotings are allowed.

Binary: [0-9]+ ~…~

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.

Atom: '…'

Atoms are encoded as strings, only using a single quote instead of a +added between the integer length and the data for readability.

Atom: '…'

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.

Tuple: { Obj1 Obj2 … ObjN-1 ObjN }

Tuples represent fixed numbers of objects. The byte codes for "{" +representing symbolic constants.

Tuple: { Obj1 Obj2 … ObjN-1 ObjN }

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.

List: # ObjN & ObjN-1 & … & Obj2 & Obj1

Lists represent variable numbers of objects. The first object in +arbitrary UBF(a) objects.

List: # ObjN & ObjN-1 & … & Obj2 & Obj1

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.

Term

Terms represent primitive types and compound types.

White space: \s \n \r \t , %…%

For convenience, blank, carriage return, line feed, tab, comma, and +them by a list cell.

Term

Terms represent primitive types and compound types.

White space: \s \n \r \t , %…%

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.

Tag: `…`

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.

Tag: `…`

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.

Object

Objects represent either a Term, a Register push, or a Register pop with an optional Tag. The operator $ signifies "end of object". When $ is encountered there should be only one item on the -recognition stack.

3.2. UBF(b)

UBF(b) is a language independent type system and protocol description +recognition stack.

3.2. UBF(b)

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.

Name: +NAME("…").

The name of the contract is specified as a double-quoted string.

Version: +VSN("…").

The version of the contract is specified as a double-quoted string.

Types: +TYPES.

The UBF(b) type system has user-defined types and predefined types. +implementation of records.

Name: +NAME("…").

The name of the contract is specified as a double-quoted string.

Version: +VSN("…").

The version of the contract is specified as a double-quoted string.

Types: +TYPES.

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.

Float: [-][0-9]+.[0-9]+

Positive and negative float constants are supported for network transports other than UBF(a).

[Note]

In future, the implementation of UBF(b) could be enhanced to specify a float more compactly using scientific notation -(e.g. "6.02e23").

Binary: <<"…">>

Binary constants are expressed similarly as strings in UBF(a) but +(e.g. "6.02e23").

Binary: <<"…">>

Binary constants are expressed similarly as strings in UBF(a) but having two leading "less than brackets" and two following "greater -than brackets".

String: "…"

String constants are expressed as in UBF(a).

Atom: '…' or [a-z][a-zA-Z0-9_]*

Atom constants are expressed as UBF(a) atoms. Atom constants starting +than brackets".

String: "…"

String constants are expressed as in UBF(a).

Atom: '…' or [a-z][a-zA-Z0-9_]*

Atom constants are expressed as UBF(a) atoms. Atom constants starting with lowercase letters do not require single quotes.

Reference: R()

Defined types are referenced by the notation:

R()

The name of the type is R.

Alternative: T1 | T2

A type X is of type "T1 | T2" if X is of type T1 or if X is of type -T2.

Tuple: {T1, T2, …, Tn}

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.

Record: name#T1, y=T2, …, z=Tn

A record type is syntactic sugar for a tuple of type "{name, T1, T2, -…, Tn}" where name, x, y, …, and z are atoms.

Extended Record: name##T1, y=T2, …, z=Tn

An extended record type is syntactic sugar for a tuple of type "{name, +T2.

Tuple: {T1, T2, …, Tn}

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.

Record: name#T1, y=T2, …, z=Tn

A record type is syntactic sugar for a tuple of type "{name, T1, T2, +…, Tn}" where name, x, y, …, and z are atoms.

Extended Record: name##T1, y=T2, …, z=Tn

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.

List: [T]

A type [X1, X2, …, Xn] is of type [T] if all of Xi are of type T.

Predefined: P() or P(A1, A2, …, An)

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.

List: [T]

A type [X1, X2, …, Xn] is of type [T] if all of Xi are of type T.

Predefined: P() or P(A1, A2, …, An)

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.

3.3. UBF(c)

UBF(c) is a meta-level protocol used between a UBF client and a UBF +one valid event is ignored and dropped.

3.3. UBF(c)

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".

Calls: Request $ ⇒ {Response, NextState} $

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".

Calls: Request $ ⇒ {Response, NextState} $

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

4. Contracts & Plugins

"Contracts" and "Plugins" are the basic building blocks of an Erlang +in the future.

4. Contracts & Plugins

"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.

4.1. Contract

A contract is a UBF(b) specification stored to a file. By convention, +server’s implementations.

4.1. Contract

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().

4.2. Plugin

A plugin is just a "normal" Erlang module that follows a few simple + contract() => term().

4.2. Plugin

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.

[Note]

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").

4.3. Importing Types

The plugin for the "+STATE" and "+ANYSTATE" contract having the +-add_contract("irc_types_plugin").

4.3. Importing Types

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.

4.4. Compilation Errors

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.

4.4. Compilation Errors

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:

{'duplicated_records', L} @@ -393,7 +393,7 @@ occurs:

One or more types were found to be unused in the contract. Unused types are permitted as long as the unused type(s) are imported. -

where L is an Erlang list.

4.5. Miscellaneous

As a by-product of a plugin’s compilation and if one or more "record" +

where L is an Erlang list.

4.5. Miscellaneous

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.

[Tip]

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.

5. Transports

The original "UBF" network transport is UBF(a) over TCP/IP. Since +and EEP8 types.

5. Transports

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.

5.1. TCP/IP

UBF: Universal Binary Format

The name "UBF" is short for "Universal Binary Format". UBF is +irregardless of the network transport.

5.1. TCP/IP

UBF: Universal Binary Format

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: Erlang Binary Format

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: Erlang Binary Format

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:

  • Structured terms are serialized via the Erlang BIFs term_to_binary() @@ -455,11 +455,12 @@ like this:

       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.

    [Tip]

    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 / NTBF: Thrift Binary Format / Native Thrift Binary Format

TBF and NTBF is an implementation of UBF(b) but it does not use UBF(a) +JSON inputs [GMTCHARSET].

TBF / FTBF / NTBF / FNTBF: Binary Format - Thrift / Framed Thrift / Native Thrift / Framed Native Thrift

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:

  • The name of Thrift messages are hard-coded to the Thrift name @@ -491,10 +492,10 @@ servers, a NTBF client and server must "manually" implement the features provided by the Thrift IDL.

See [UBF_THRIFT] for further information.

Miscellaneous

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].

5.2. HTTP

JSON-RPC

JSON-RPC [JSONRPC] is a lightweight remote procedure call protocol +"Avro Binary Format" [AVRO].

5.2. HTTP

JSON-RPC

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

+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.

5.3. Miscellaneous

Several transports that do not require an explicit network socket have +rejected regardless of the transport.

See [UBF_JSONRPC] for further information.

5.3. Miscellaneous

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.

ETF: Erlang Term Format

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".

LPC: Local Procedure Call

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".

[Note]

LPC is used to implement the JSON-RPC transport.

6. Servers

The UBF framework provides two types of Erlang servers: "stateless" +Support for asynchronous casts has not been added (or designed) yet.

The name "LPC" is short for "Local Procedure Call".

[Note]

LPC is used to implement the JSON-RPC transport.

6. Servers

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:

Maximum number of simultaneous TCP connections allowed. Default: 10000.
-{'proto', {'ubf' | 'ebf' | 'jsf' | 'tbf' | atom()}} +{'proto', {'ubf' | 'ebf' | 'jsf' | 'tbf' | 'ftbf' | atom()}}
- Enable the UBF, EBF, JSF, TBF, or an alternative protocol wire + Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire format. Default: 'ubf'.
+{'proto', {'ubf' | 'ebf' | 'jsf' | 'tbf' | 'ftbf' | atom(), proplist()}} +

+ Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire + format with options. Default: {'ubf', []}. Supported options: +

+'safe' +
+ Prevents decoding data that may be used to attack the Erlang + system. In the event of receiving unsafe data, decoding fails + with a badarg error. +
{'registeredname', name()}
Set the name to be registered for the TCP listener. If @@ -634,9 +646,11 @@ follows:

garbage collection options. Default: [].

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.

[Note]

The NTBF transport protocol is indirectly enabled by specifying -the following options: [{'proto', 'tbf'}, {'serverhello', -'undefined'}, {'simplerpc', 'true'}].

6.1. Stateless

The stateless server provides a simplified callback API and +the "proc_socket_server" Erlang module for extra details.

[Note]

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'}].

6.1. Stateless

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)). -

6.2. Stateful

The stateful server is Joe Armstrong’s original UBF server. The +

6.2. Stateful

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.

7. Clients

7.1. Erlang

The UBF framework provides two types of Erlang clients: "rpc" and +the IRC protocol application described earlier.

7. Clients

7.1. Erlang

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.

7.2. Python

EBF

Under Construction - To Be Added

JSON-RPC

Under Construction - To Be Added

7.3. Java

UBF

Under Construction - To Be Added

8. Miscellaneous

8.1. Testing

Unit Tests

The unit tests in the "test/unit" directory provide small examples of +further information.

7.2. Python

EBF

Under Construction - To Be Added

JSON-RPC

Under Construction - To Be Added

7.3. Java

UBF

Under Construction - To Be Added

8. Miscellaneous

8.1. Testing

Unit Tests

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.

EUnit Tests

The eunit tests in the "test/eunit" directory perform several smoke and error handling uses cases.

QuickCheck Tests

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.

8.2. Utilities

Transaction Logging

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.

8.2. Utilities

Transaction Logging

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.

9. Building UBF from Source

This section describes the basic recipes for the following items:

  • +jsf_utils:ubf_contract/{1,2} functions are available for this purpose.

9. Building UBF from Source

This section describes the basic recipes for the following items:

Python (Mandatory) @@ -918,7 +932,7 @@ Rebar -

9.1. Download

The first step is to download the Git repositories from GitHub.

  1. +further information regarding the usage of these tools.

    9.1. Download

    The first step is to download the Git repositories from GitHub.

    1. Configure your e-mail and name for Git

      $ git config --global user.email "you@example.com"
       $ git config --global user.name "Your Name"
    2. @@ -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.

  2. Download Git repositories

    $ cd working-directory-name
    -$ repo sync

9.2. Build - Mandatory

  1. +$ repo sync

9.2. Build - Mandatory

  1. Build UBF

    $ cd working-directory-name/src
     $ make compile
    [Tip]

    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.

  2. Run the unit tests

    $ cd working-directory-name/src
    -$ make eunit

9.3. Build - Optional

  1. +$ make eunit

9.3. Build - Optional

  1. Dialyzer Testing basic recipe

    1. Build Dialyzer’s PLT (required once) @@ -970,7 +984,7 @@ $ git clone git://repo.or.cz/py_interface.git $ cd py_interface $ autoconf $ make

      [Tip]

      Then install as a normal Python package or run using "env -PYTHONPATH=working-directory-name/py_interface python your-script.py"

9.4. UBF Documentation

This section is the first step to download and to build your own +PYTHONPATH=working-directory-name/py_interface python your-script.py"

9.4. UBF Documentation

This section is the first step to download and to build your own UBF documentation.

  1. 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.conf

9.5. Erlang/OTP System

This section is the first step to download, to build, and to install +Only in 8.6.4/etc/asciidoc: lang-ja.conf

9.5. Erlang/OTP System

This section is the first step to download, to build, and to install your own Erlang/OTP system.

  1. Downloading basic recipe

    1. @@ -1032,7 +1046,7 @@ $ make
  2. Installing basic recipe

    $ cd working-directory-name/otp_src_R14B01
     $ sudo make install
[Caution]

Please make sure "otp-installing-directory-name/bin" is added -to your $PATH environment.

9.6. GitHub - Forking Your Own Repositories

If you are interested in making your own changes to UBF or to one or +to your $PATH environment.

9.6. GitHub - Forking Your Own Repositories

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

10. Reference

Optional list title

+

Under Construction - To Be Updated

10. Reference

Optional list title

[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/. -

+

[RFC20] Vint Cerf, "ASCII format for Network Interchange", RFC20, October 16, 1969. -

+

[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. -

11. Appendix

11.1. Acknowledgments

Many, many thanks to Joe Armstrong, UBF’s designer and original +

11. Appendix

11.1. Acknowledgments

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.

11.2. ABNF Definition

The formal syntax for UBF(a), UBF(b), and UBF(c) is defined in ABNF +THE SOFTWARE.

11.2. ABNF Definition

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          = *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


TODO

+UBF CHANGELOG Page

UBF CHANGELOG Page


TODO

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

UBF FAQ Page


Table of Contents

1. TODO

This FAQ may help answer some of your questions.

1. TODO

1.1.

+UBF FAQ Page

UBF FAQ Page


Table of Contents

1. TODO

This FAQ may help answer some of your questions.

1. TODO

1.1.

Question

Answer. diff --git a/webpage-README.html b/webpage-README.html index 6c8a7ff..50b370b 100644 --- a/webpage-README.html +++ b/webpage-README.html @@ -1,3 +1,3 @@ -UBF README Page

UBF README Page


TODO

+UBF README Page

UBF README Page


TODO