Greetings,
in this article I intend to give a brief overview of the capabilities of the binary codec implemented in Titan.
This is not meant to be an exhaustive listing of all options -the details can be found in the reference guide-
I'd rather introduce the codec through a number of simple usage examples.
Let's start with a number of simple types:
Encoding of BOOLEAN
//Example number 1): boolean coded with default length
const boolean c_myvar:=true
//The resulting bitfield: 1
//Example number 2): boolean coded with fixed length
type boolean Mybool with { variant "FIELDLENGTH(8)"}
const Mybool c_ourvar:=true
//The resulting bitfield: 11111111
Encoding of ENUMERATED
//Example number 1)
type enumerated Enumm {zero, one, two, three, four, five}
const Enumm myenum:=two
//The maximum enumerated value: 5 (five)
//Minimum 3 to represent 5.
//The FIELDLENGTH will be 3
//The resulting bitfield: 010
//Example number 2)
type enumerated Enum { zero(2), one(23), two(4), three(1), four(0), five(5) }
const Enum c_myenum:=two
//The maximum enumerated value: 23 (one)
//Minimum 5 bits are needed to represent 23.
//The FIELDLENGTH will be 5
//The resulting bitfield: 00010
Encoding of INTEGER
//Example number 1)
type integer Int12
with{ variant "FIELDLENGTH(12)"}
const Int12 c_myint:=1052
//The resulting bitfield is 010000011100
//The encoding will have the following result:
// 00011100
// ....0100
//The same result represented as octetstring: \u20191C.4\u2019O
//Example number 2)
type integer Int12sg
with{ variant "FIELDLENGTH(12), COMP(signbit)"}
const Int12sg c_mysignedint:=-1052
//The resulting bitfield: 110000011100
//The encoding will have the following result:
// 00011100
// ....1100
//The same result represented as octetstring: \u20191C.C\u2019O
//Example number 3)
type integer Int12c
with{ variant "FIELDLENGTH(12), COMP(2scompl)"}
const Int12c c_hisint:=-1052
//The resulted bitfield: 101111100111
//The encoding will have the following result:
// 11100111
// ....1011
//The same result represented as octetstring: \u2019E7.B\u2019O
The attribute COMP (only valid for integer and enumerated types) specifies the type of encoding of negative integer numbers as follows:
nosign: negative numbers are not allowed;
2scompl: 2's complement encoding;
signbit: sign bit and the absolute value is coded.
Encoding of OCTETSTRING
//Example number 1): variable length octetstring
const octetstring c1_mystring:='25AF'O
//The resulting bitfield: 10101111 00100101
//The encoding will have the following result:
// 00100101 25
// 10101111 AF
//Example number 2): fixed length octetstring
type octetstring OCT_3 with { variant "FIELDLENGTH(3)" }
const OCT_3 c1_yourstring:='25AF'O
//const OCT3 c13_yourstring:='25AF'O --Error in compile time
//The resulting bitfield: 00000000 10101111 00100101
//The encoding will have the following result:
// 00100101 25
// 10101111 AF
// 00000000 00
//Example number 3): left aligned octetstring
type octetstring OCT_3align with {
variant "FIELDLENGTH(3), ALIGN(left)" }
const OCT_3align c_string:='25AF'O
//The resulting bitfield: 10101111 00100101 00000000
//The encoding will have the following result:
// 00000000 00
// 00100101 25
// 10101111 AF
Besides the above, order of bits in a bit-or octetstring (BITORDER) , order of bytes (BYTEORDER), padding etc. can be specified.
An interesting question that can be asked here is what happens if the compiler and the encoder will get contradictory instructions.
For example:
type octetstring OCT_mindboggling length(4) with { variant "FIELDLENGTH(3)" }
const OCT_mindboggling c_mindboggling:='AABBCCDD'O;
This assignment is correct from the compilers' point of view and will be compiled; however , when we will try to encode it , the codec will throw an error.
In the opposite direction, the codec might decode an octetstring of length 3 , but when assigning the decoded value to a variable of type OCT_mindboggling, a runtime error will be thrown.
So if you are not consistent across your declarations, you can trigger interesting and difficult to debug faults. Well, I have warned you.
Now let's look into encoding/decoding of some structured types.
LENGTHTO
In the below examples, LENGTHTO will instruct the codec to fill in the fields containing the length information of some other fields in the record.
The length field can be initialized with a dummy value, and the codec will do the rest.
//Example number 1)
type record Rec0 {
INT1 length_,
OCT3 field1,
octetstring field2
}
with {
variant (length_) "LENGTHTO(field1)"
variant (length_) "UNIT(bits)"
}
//Example number 2)
type record Rec2 {
INT1 length_,
OCT3 field1,
octetstring field2
}
with {
variant (length_) "LENGTHTO(length_, field1, field2)"
}
//Example number 3)
type record Rec3 {
INT1 length_,
OCT3 field1,
OCT1 field2,
octetstring field3
}
with {
variant (length_) "LENGTHTO(field1, field3)";
// field2 is excluded!
}
TAG
The attribute TAG can be used to identify 'set' or 'record' fields or union members at decoding.
//Example number 1): set
type record InnerRec {
INT1 tag,
OCT3 field
}
with { variant "" }
type set SomeSet {
InnerRec field1 optional,
InnerRec field2 optional,
InnerRec field3 optional
}
with {
variant "TAG(field1, tag = 1;
field2, tag = 2;
field3, tag = 3)"
}
//Example number 2): union
type union SomeUnion {
InnerRec field1,
InnerRec field2,
InnerRec field3
}
with {
variant "TAG(field1, tag = 1;
field2, tag = 2;
field3, OTHERWISE)"
}
//If neither tag=1 in field1 nor tag=2 in field2 are matched, field3 is selected.
CROSSTAG
The attribute CROSSTAG is used to identify union members when decoding.
The difference between TAG and CROSSTAG is that TAG refers to a structure within the union, while CROSSTAG refers to a structure outside the union.
type octetstring PduType1;
type integer PduType2;
type boolean PduType3;
type union AnyPdu {
PduType1 type1,
PduType2 type2,
PduType3 type3
}
with { variant "" }
type record PduWithId {
INT1 protocolId,
AnyPdu pdu
}
with {
variant (pdu) "CROSSTAG( type1, { protocolId = 1,
protocolId = 11 };
type2, protocolId = 2;
type3, protocolId = 3)"
}
Next, we will look into alternatives when declaring the codec external functions.
Regards
Elemer