encodeCOBS function

EncodeResult encodeCOBS(
  1. ByteData encoded,
  2. ByteData source, {
  3. bool withZero = false,
})

Encode source to encoded using COBS and return EncodeResult status.

If withZero is true, a 0x00 byte is appended to encoded The EncodeResult instance returned will include the actual length of the encoded byte array in outLen and the status of the encoding attempt in status.

Implementation

EncodeResult encodeCOBS(
  ByteData encoded,
  ByteData source, {
  bool withZero = false,
}) {
  int encodedWriteCounter = 1;
  int encodedCodeWriteCounter = 0;
  int encodedEndCounter = encoded.lengthInBytes;

  int sourceCounter = 0;
  int sourceEndCounter = source.lengthInBytes;

  int searchLen = 1;

  if (source.lengthInBytes != 0) {
    /* Iterate over the source bytes */
    while (true) {
      /* Check for running out of output buffer space */
      if (encodedWriteCounter >= encodedEndCounter) {
        return EncodeResult(status: EncodeStatus.OUT_BUFFER_OVERFLOW);
      }

      int sourceByte = source.getUint8(sourceCounter++);
      if (sourceByte == 0) {
        /* We found a zero byte */
        encoded.setUint8(encodedCodeWriteCounter, searchLen & 0xFF);
        encodedCodeWriteCounter = encodedWriteCounter++;
        searchLen = 1;
        if (sourceCounter >= sourceEndCounter) {
          break;
        }
      } else {
        /* Copy the non-zero byte to the destination buffer */
        encoded.setUint8(encodedWriteCounter++, sourceByte & 0xFF);
        searchLen++;

        if (sourceCounter >= sourceEndCounter) {
          break;
        }

        if (searchLen == 0xFF) {
          /* We have a long string of non-zero bytes, so we need
           * to write out a length code of 0xFF. */
          encoded.setUint8(encodedCodeWriteCounter, searchLen & 0xFF);
          encodedCodeWriteCounter = encodedWriteCounter++;
          searchLen = 1;
        }
      }
    }
  }

  if (withZero) {
    encoded.setUint8(encodedWriteCounter++, 0x00);
  }

  /* We've reached the end of the source data (or possibly run out of output buffer)
   * Finalise the remaining output. In particular, write the code (length) byte.
   * Update the pointer to calculate the final output length.
   */
  if (encodedCodeWriteCounter >= encodedEndCounter) {
    /* We've run out of output buffer to write the code byte. */
    encodedWriteCounter = encodedEndCounter;

    return EncodeResult(
      outLen: encodedWriteCounter,
      status: EncodeStatus.OUT_BUFFER_OVERFLOW,
    );
  } else {
    /* Write the last code (length) byte. */
    encoded.setUint8(encodedCodeWriteCounter, searchLen & 0xFF);
  }

  /* Calculate the output length, from the value of dst_code_write_ptr */
  return EncodeResult(outLen: encodedWriteCounter);
}