encodeSelf method
- RawWriter writer
override
Encodes this object.
Implementation
@override
void encodeSelf(RawWriter writer) {
final startOfHeader = writer.length;
// 4-byte span at index 0 will be filled in the end
writer.writeUint32(0);
// 4-byte span at index 4
writer.writeUint32(_v1);
// 4-byte span at index 8
// checksum (2-byte span at index 10) must have 0 during calculation
writer.writeUint32(transformUint32Bits(_v2, 0, 0xFFFF, 0));
// 4-byte source address at index 12
source.encodeSelf(writer);
// 4-byte destination address at index 16
destination.encodeSelf(writer);
// Options
options.encodeSelf(writer);
// Calculate header length
var headerLength = writer.length - startOfHeader;
// Add padding
while (headerLength % 4 != 0) {
writer.writeUint8(0);
headerLength++;
}
// Validate header length
if (headerLength ~/ 4 > 15) {
throw StateError("header length ($headerLength) exceeds maximum (60)");
}
// Payload
final startOfPayload = writer.length;
final payload = this.payload;
if (payload is IpPayload && !identical(payload.parentPacket, this)) {
final oldParentPacket = payload.parentPacket;
try {
payload.parentPacket = this;
payload.encodeSelf(writer);
} finally {
payload.parentPacket = oldParentPacket;
}
} else {
payload.encodeSelf(writer);
}
final payloadLength = writer.length - startOfPayload;
if (payloadLength >> 16 != 0) {
throw StateError(
"payload length ($payloadLength) does not fit in 16-bits");
}
// We finally know header and payload length.
// Set the first 4-byte span of the header.
final v0 = (4 << 28) |
((headerLength ~/ 4) << 24) |
(0x00FF0000 & _v0) |
payloadLength;
writer.bufferAsByteData.setUint32(startOfHeader, v0);
// Calculate and set checksum
final checksum =
calculateChecksum(writer.bufferAsByteData, startOfHeader, headerLength);
writer.bufferAsByteData.setUint16(startOfHeader + 10, checksum);
}