This document describes portions of version 0.99 of the PSYC Protocol for
SYnchronous Conferencing. You may consider it an Internet-Draft and as such
subject to all provisions of Section 10 of RFC2026 except that the right to
produce derivative works is not granted.
In all matters of intellectual property rights and procedures, the
intention is to benefit the Internet community and the public at
large, while respecting the design decision to keep the original author
of the protocol in charge. We don't like the bloat effects other efforts
are experiencing.
Only if you have developed an application in accordance to this specification
you may call it PSYC-compliant to the version mentioned above.
Abstract
This document describes the syntax of variable modifiers
as used by PSYC and its carrier protocol
MMP. Variables are semantically comparable to RFC822
headers as they are popular with text-based protocols like HTTP and SMTP,
but kept in a more compact syntax.
Syntax
MMP or PSYC modifiers are defined as follows:
{modifier} :=
"=" {type}* {variable} [ "\t" {arguments} "\n" ]*
| "+" {type}* {variable} [ "\t" {arguments} "\n" ]*
| "-" {type}* {variable} [ "\t" {arguments} "\n" ]*
| ":" {type}* {variable} [ "\t" {arguments} "\n" ]*
| "?" {type}* {variable} [ "\t" {arguments} "\n" ]*
| {glyph} {opaque string} [ "\t" {opaque string} "\n" ]*
Your implementation may also accept a space character instead of the
tab character ("\t"), but no application should rely on that.
It may only be useful for debugging. It is legitimate to make a parser that
only accepts the tab character as the grammar above suggests.
Variable names follow the Keyword Naming
conventions of PSYC and MMP as described in its own document.
Variable arguments may be missing or split over several lines.
All other glyphs are available for experimental extensions,
not for widespread use though. Variable modifiers using unknown glyphs
SHOULD be ignored silently.
Types
{type} := "@" | "|" | "$"
NEW: Types are a new extension which avoids such naming tricks such as _list.
Currently they are not necessary for basic applications, so they are
available only upon negotiation of the _types module.
The default is to have no type glyph, which means the value of the
variable can be interpreted as a string or as a number where appropriate.
However when a type glyph is present, it indicates that the following
data is structured as follows:
"@" stands for an array. All the values are kept in one {argument} seperated
by a ";" semi-colon, so you can create the array in your respective programming
language simply by splitting at the semi-colon. Data may not contain a
semi-colon in arrays.
"|" stands for a list. The list is defined over several lines, each line
being an {argument} consisting of
{key} "\t" {value}
. The parser
should pass this information on to the applications in form of both a
hash of key and value, but also an array of keys to keep the order intact.
{value} may not contain newlines.
Syntactically any compound of types is possible, but we shall only define
the combination of "|@" as being a list of arrays. We need this for the
room member lists, for instance.
"$" indicates a transparent variable. Useful for binary data or any situations
where the content may contain characters which would otherwise be misunderstood
by the syntax. The {argument} for a {variable} prefixed by "$" is
{length} "\t" {data}
where {length} is the decimal amount of octets
contained in {data} to be read without parsing.
Treatment
Receiption of variable information SHOULD be passed to the target object
of the message by doing method calls on it. The technique used to translate
the combination of glyph and variable into a method name works like this:
Warning: Most implementations do not use methods like this, they simply
operate on the variables at parsing time. The final results are the same
however. So the spec needs an update here. TODO
"=" triggers a method "_assign_{variable}"
"+" triggers a method "_augment_{variable}"
"-" triggers a method "_diminish_{variable}"
":" triggers a method "_set_{variable}"
"?" triggers a method "_query_{variable}"
Semantics
Methods of the _assign family are used to set or reset variables
available in the appropriate operative layer and its namespace
(which are different for PSYC and MMP, although the syntax is the same).
Methods of the _augment family append arguments to existing variables,
which must be of the _list family to be applicable. Methods of the
_diminish family remove elements from such _list variables.
Methods of the _set family temporarely give a value to
a variable valid for this message or packet only. When stateless
communication is selected, only the _set methods may be used!
TODO: Semantics of _query are as yet undefined.
In many cases modification of variables will also trigger appropriate
functionality as specified with the definition of those variables.
Extension
PSYC defines an extension to the variable
modifiers syntax for its _struct_group variable.
Discussion
Is it bad to talk in implementation terms like methods? Or is it
useful that a PSYC variable may be set both via a :_variable modifier
and a _set_variable method call. Should this be ensured or forbidden?
So far the semantic distinction is, that while a method call is
immediately delivered to the target object, a variable modification
is normally silently applied to the set of variables, and delivered
to the target object only when the next method call comes in.
Yet again the protocol syntax allows for messages to contain variable
modifications only - so one could deliver the changes each time a
message is finished, even if no method has been called. The problem
with that, is that identifying which variables have been modified
can turn out hairy.