Skip to content
Xiayun Sun edited this page Jun 22, 2014 · 3 revisions

Erlang Users Guide

After running the sbetool a number of Erlang source files will be created. These files represent the types and messages declared in the schema. For a quick start look at this schema and its usage here.

The general API design is that for each field, a setter method for encoding and a getter method for decoding is provided. For array fields, a length method is provided as well.

Due to Erlang being a functional language and direct buffer manipulation is not allowed, each setter methods described below will return a newly allocated buffer. Apart from performance impact, this also means sometimes you'll need to bear with code like this:

 M  = messageHeader:wrap(Buffer, BufferOffset, MessageTemplateVersion),
 M1 = messageHeader:setBlockLength(M, car:sbeBlockLength()),
 M2 = messageHeader:setTemplateId(M1, car:sbeTemplateId()),
 M3 = messageHeader:setSchemaId(M2, car:sbeSchemaId()),
 MessageHeader = messageHeader:setVersion(M3, car:sbeSchemaVersion()),

A setAll method that could potentially resolve the issue is work-in-progress.

Message Header

The message header contains the fields that allows the decoder to identify which codec should be used as the template for a message. It contains the following fields, each being a primitive type:

  1. blockLength: the length of the message root block before variable length data commences.
  2. templateId: the identifier for the template type of the message that is to follow
  3. schemaId: the identifier for the schema the message belongs to.
  4. version: The version of the schema allowing for extension. (not implemented yet)

To encode a message header:

M = messageHeader:wrap(Buffer, BufferOffset, MessageTemplateVersion),
M1 = messageHeader:setBlockLength(M, car:sbeBlockLength()),
M2 = messageHeader:setTemplateId(M1, car:sbeTemplateId()),
M3 = messageHeader:setSchemaId(M2, car:sbeSchemaId()),
MessageHeader = messageHeader:setVersion(M3, car:sbeSchemaVersion()),

To decode a message header:

MessageHeaderForDecode = messageHeader:wrap(MessageBuffer, BufferOffset, MessageTemplateVersion),
TemplateId = messageHeader:getTemplateId(MessageHeaderForDecode),
ActingBlockLength = messageHeader:getBlockLength(MessageHeaderForDecode),
SchemaId = messageHeader:getSchemaId(MessageHeaderForDecode),
ActingVersion = messageHeader:getVersion(MessageHeaderForDecode),

Single Fixed Size Fields

Encode:

Message = car:wrapForEncode(Buffer, Offset),
M1 = car:setserialNumber(Message, 1234),
M2 = car:setmodelYear(M1, 2023),

Decode:

Message = car:wrapForDecode(Buffer, Offset, ActingBlockLength, ActingVersion), 
car:getserialNumber(Message),
car:getmodelYear(Message),

Fixed Size Array Fields

The setter and getter method takes in an additional Index parameter for fixed size array fields of primitive types.

Encode:

lists:foldl(fun(X, AccM) -> car:setsomeNumbers(AccM, X, X) end,
            Message, lists:seq(0, car:someNumbersLength() - 1)).

Decode:

lists:foreach(fun(X) -> 
                    car:getsomeNumbers(Message, X) end, 
                    lists:seq(0, car:someNumbersLength() - 1)),

Fixed Size String

The setter method takes the binary string and an additional SrcOffset field to encode the string component after the SrcOffset. The getter method takes in an Index parameter the same as that in fixed size array fields for primitive types.

Encode:

SrcOffset = 0, % encode the complete string
VehicleCode = <<"abcdef">>,
M3 = car:setvehicleCode(M2, VehicleCode, SrcOffset),

Decode:

VehicleCode = lists:reverse(
                  lists:foldl(fun(X, Acc) -> [car:getvehicleCode(Message, X)|Acc] end,
                  [], lists:seq(0, car:vehicleCodeLength() - 1))),

Variable Length String

The setter method takes the binary string, SrcOffset as in fixed size string, and Length of the string to be encoded.

The getter method takes in an additional Length that should be larger than or equal to the length of the string encoded. Unlike other getter methods, it returns a {MessageBuffer, Value} tuple. This is because the Limit property of the underlying buffer is changed.

Encode:

SrcOffset = 0, % encode the complete string
Make = <<"Honda">>,
M4 = car:setmake(M3, Make, SrcOffset, size(Make)),

Decode:

{Message2, Make} = car:getmake(Message, 128),