encodeSelf method

  1. @override
void encodeSelf(
  1. 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);
}