Further reading of the Packet Specification 1.2 reveals that each
Packet has an additional crc
field. The content of this field
is derived from both the payload bytes and the control bytes.
But this is no vulgar CRC we are talking about. On the contrary, it is a special function developed by the CRC Foundation in partnership with the Packet Foundation, called superCRC (patented, TM).
Fortunately, the CRC Foundation distributes a pickle
supercrc.pk
, that provides a calculate_crc
function with
the following spec:
fun calculate_crc = (byte[] data, byte[] control) int:
So let’s use the function like this in our type, after loading the supercrc pickle:
load supercrc; type Packet = struct { byte magic == 0xab; byte size; var real_size = (size == 0xff ? 0 : size); byte[real_size] payload; byte[real_size] control; int crc = calculate_crc (payload, control); };
However, there is a caveat: it happens that the calculation of the CRC
may involve arithmetic and division, so the CRC Foundation warns us
that the calculate_crc
function may raise E_div_by_zero.
However, the Packet 1.2 Specification tells us that in these
situations, the crc
field of the packet should contain zero.
If we used the type above, any exception raised by
calculate_crc
would be propagated by the mapper/constructor:
(poke) Packet @ 12#B unhandled division by zero exception
A solution is to use a function that takes care of the extra needed logic, wrapping calculate_crc:
load supercrc; type Packet = struct { byte magic == 0xab; byte size; var real_size = (size == 0xff ? 0 : size); byte[real_size] payload; byte[real_size] control; fun corrected_crc = int: { try return calculate_crc (payload, control); catch if E_div_by_zero { return 0; } } int crc == corrected_crc; };
Again, note how the function is accessible after its definition. Note as well how both fields and variables and other functions can be used in the function body. There is no difference to define variables and functions in struct types than to define them inside other functions or in the top-level environment: the same lexical rules apply.