PHP/Java Bridge protocol version 2.1

Requests are marked with "->", responses with "<-".  The server
continues to process requests until EOF. Only the first character is
significant.

The communication must begin with [C]reateInstance or [I]nvoke. The
server responds with a single ARG which also carries the last request
context ID. The request context ID is your request context, for
example the location of a cell where the response should be stored; a
structure or something like that. In PHP for example we allocate a
pval and pass it as the ID to the Invoke or Create request. When the
response arrives, we receive our ID along with the result so we know
exactly where to store the result.

Example:

     $o = new java("java.lang.Long", 6);
     $o->toString(); // discard result

->  <CreateInstance value="java.lang.Long" predicate="Instance" id="78532"> 
      <Long value="6"/> 
    </CreateInstance>

<-  <Object value="1" id="78532"/>

->  <Invoke value="1" method="toString" predicate="Invoke" id="0">
    </Invoke>

<-  <String value="6" id="0"/>



Optional requests:

All aquired [O]bject handles may be destroyed by invoking U (destroy).
However, the server tracks all handles and automatically destroys them
after EOF. It is an error to further reference destroyed handles.



Main requests:

->
CreateInstance:
<C v=name p=C|I i=ID> ...ARGS...
</C>
v: string
p: char (Reference[C]lass, Create[I]nstance)
i: long

->
Invoke:
<I v=object m=method p=P|I i=ID> ...ARGS...
</I>
v: long
m: string
p: char (examine[P]roperty, [I]nvoke method)
i: long

When v=0, the call is directed to the current request-handling
instance of the java bridge.



ARGS or response:
<->
String:
<S v=str [i=ID] />
v: string
i: long (reply only)

<->
Boolean:
<B v=T|F [i=ID] />
v: char ([T]rue, [F]alse)
i: long (reply only)

<->
Long:
<L v=l [i=ID] />
v: long
i: long (reply only)

<->
Double:
<D v=d [i=ID] />
v: double
i: long (reply only)

->
Object:
<O v=object />
v: long
NULL values can be sent as either v="" or v="0"

<-
Object:
<O v=object p=TYPE i=ID />
v: long
p: char ([A]rray, [O]bject)
i: long 

<-
Null:
<N i=ID />
i: long 

<-
Apply:
<A v=object p=cname m=fname n=param# i=ID> ...ARGS...
</A>
v: long
p: string
m: string
n: long
i: long
Result can be used to send back the result of the current apply
call. If v is null, the function name p must be searched in the
"current" environment.

->
Result:
<R i=ID> ...ARG...
</R>
i: long

<->
Exception:
<E v=object m=stringRepresentation [i=ID] />
v: long
m: string
i: long

->  (or <->, see below)
Composite:
<X t=A|H [i=ID] /> ...PAIR...
</X>
t: char ([A]rray, [H]ashtable)
i: long (reply only)

->  (or <->, see below)
Pair:
<P [t=N|S v=key]> ...ARG...
</P>
t: char (key is [N]umeric, [S]tring or doesn't exist (if X=A))
v: long (if X=H and t=N)
v: string (if X=H and t=S)



OPTIONAL requests:
->
Destroy:
<U v=object />
v: long



NOTES:

If the first byte is neither a "<" nor a space, bits [0,1], [2,4] and
[6,7] have a special meaning:

Bit 0: 1 for PHP4, 0 for >= PHP5(enable backward compatibility
with "ext/java", the predecessor of the PHP/Java Bridge).

Bit 1: Client wants arrays as values. The server will return X and P
instead of O.

Bit 2,3,4: log level (from java.log_level)

Bit 5: always 0

Bit 6: set to 1 if bit[0,1] are used
Bit 7: set to 1 if bit[2,4] are used

The default is 0304 for PHP5 and 0307 for PHP4.


It is possible to "ping" the server by sending it the byte 0x0. If
alive it will send back a 0x0.
