Example NSDL

The Etch binary protocol is illustrated using the following example NSDL:

module org.apache.etch.example.binary
 
service binaryExample {
    struct A ( int c )
    int f(A[] as)
}

Hashed Values

Etch uses hashed values to identify names (such as names of parameters or functions). The values are computed by hashing the full qualified names of the elements. As an example, the computed hash values for the example above are:

org.apache.etch.example.binary.binaryExample.f = 0x28e34aa1
org.apache.etch.example.binary.binaryExample._result_f = 0x0972201e
org.apache.etch.example.binary.binaryExample.A = 0x28e34a7c
c = 0x150a2c9e
as = 0x5a1cfad7
_messageId = 0x6306b468
_inReplyTo = 0xeda8c9a6

Example Code

Consider the following Java program for the NSDL Idl:

binaryExample.A a1 = new binaryExample.A(1);
binaryExample.A a2 = new binaryExample.A(2);
binaryExample.A[] as = {a1, a2};
Integer res = server.f(as);

Request Message:

The request message for the call server.f(as) in the program above will be:

0xde,0xad,0xbe,0xef,0x0,0x0,0x0,0x41,0x3,0x86,0x28,0xe3,0x4a,0xa1,0x2,0x86,0x63,0x6,0xb4,0x68,0x87,0x0,0x0,0x1,0x2b,0x1f,0x33,0x1c,0x6b,0x86,0x5a,0x1c,0xfa,0xd7,0x91,0x95,0x86,0x28,0xe3,0x4a,0x7c,0x1,0x2,0x95,0x86,0x28,0xe3,0x4a,0x7c,0x1,0x86,0x15,0xa,0x2c,0x9e,0x1,0x81,0x95,0x86,0x28,0xe3,0x4a,0x7c,0x1,0x86,0x15,0xa,0x2c,0x9e,0x2,0x81,0x81,0x81

Lets explain this in detail:

 HEADER_______________________________________________________________________________________________ 
 0xde 0xad 0xbe 0xef                    etch identifier
 0x00 0x00 0x00 0x41                    etch message length (0x41 bytes)
 0x03                                   etch protocol version
 CALL of f____________________________________________________________________________________________ 
 0x86                                   type flag: INT
 0x28 0xe3 0x4a 0xa1                    INT value: hash for name of message: Call of F
 0x02                                   size of parameters (1 param for f + message ID)
 Message ID___________________________________________________________________________________________ 
 0x86                                   type flag: INT
 0x63 0x06 0xb4 0x68                    INT value: hash for "_messageId"
 0x87                                   type flag LONG
 0x0 0x0 0x1 0x2b 0x1f 0x33 0x1c 0x6b   LONG value: MessageID (unique for this call)
 param of call (array as)_____________________________________________________________________________
        0x86                                    type flag: INT
        0x5a 0x1c 0xfa 0xd7                     INT value: hash for "as"
        0x91                                    type flag: ARRAY
        type of array_________________________________________________________________________________
        0x95                                    type flag: (type of array elems) CUSTOM 
        0x86                                    type flag: INT
        0x28 0xe3 0x4a 0x7c                     INT value: hash for "A" (super type of all array elems)
        0x01                                    INT value: dimension of array
        0x02                                    INT value: number of array elements
        first array element___________________________________________________________________________
        0x95                                    type flag: CUSTOM
        0x86                                    type flag: INT
        0x28 0xe3 0x4a 0x7c                     INT value: hash for "A" (type of elem)
        0x1                                     INT value: number of fields of A (only one: c)
               field values of first array element____________________________________________________
                0x86                                    type flag: INT
                0x15 0x0a 0x2c 0x9e                     INT value: hash for "c" (name of A's field)
                0x01                                    INT value: value of A.c
        0x81                                    NONE value: end delimiter for struct A
        second array element__________________________________________________________________________
        0x95                                    type flag: CUSTOM
        0x86                                    type flag: INT
        0x28 0xe3 0x4a 0x7c                     INT value: hash for "A" (type of elem)
        0x1                                     INT value: number of fields of A (only one: c)
               field values of second array element____________________________________________________
               0x86                                     type flag: INT
               0x15 0xa 0x2c 0x9e                       INT value: hash for "c" (name of A's field)
                0x2                                     INT value: value of A.c
        0x81                                    NONE value: end delimiter for struct A
        0x81                                    NONE value: end delimiter for param array
        0x81                                    NONE value: end delimiter for call of f

Return Message:

The return message will be serialized just like that, but additionally contains a "_inReplyTo" ID. This ID is the _messageID value of the request message. This enables Etch to find the right caller for this response. Of course the message is much simpler, since it only contains a single integer return value, _inReplyTo and _messageID

Implementation

The BinaryTaggedDataOutput class implements the serialization in Etch. It's code is pretty good to understand and is - at the moment - the availble specification for the whole protocol. Start with the writeMessage function.

Type Codes:

Here are all current type codes, which Etch uses:

	ANY = 0x96
	CUSTOM = 0x95
	STRING = 0x93
	EMPTY_STRING = 0x92
	ARRAY = 0x91
	DOUBLES = 0x90
	BYTES = 0x8b
	DOUBLE = 0x89
	FLOAT = 0x88
	LONG = 0x87
	INT = 0x86
	SHORT = 0x85
	BYTE = 0x84
	NULL = 0x80
	NONE = 0x81
	BOOLEAN_FALSE = 0x82
	BOOLEAN_TRUE = 0x83

Optimization:
Any Integer value between

	MAX_TINY_INT = 0x7f = 127
	MIN_TINY_INT = 0xc0 = -64

will be serialized directly without specifying an own type flag. Bigger or smaller Integer Values will have their own type flag before the value.