decodeCOBS function
Decode source
to decoded
using COBS and return DecodeResult status.
The DecodeResult instance returned will include the actual length of the
decoded byte array in outLen
and the status of the decoding attempt in
status
.
Implementation
DecodeResult decodeCOBS(ByteData decoded, ByteData source) {
int sourceCounter = 0;
int sourceEndCounter = source.lengthInBytes;
int decodedEndCounter = decoded.lengthInBytes;
int decodedWriteCounter = 0;
int remainingBytes;
int sourceByte;
int i;
int lengthCode;
var decodeStatus = DecodeStatus.OK;
if (source.lengthInBytes != 0) {
while (true) {
lengthCode = source.getUint8(sourceCounter++);
if (lengthCode == 0) {
return DecodeResult(status: DecodeStatus.ZERO_BYTE_IN_INPUT);
}
lengthCode--;
/* Check length code against remaining input bytes */
remainingBytes = sourceEndCounter - sourceCounter;
if (lengthCode > remainingBytes) {
decodeStatus = DecodeStatus.INPUT_TOO_SHORT;
lengthCode = remainingBytes;
}
/* Check length code against remaining output buffer space */
remainingBytes = decodedEndCounter - decodedWriteCounter;
if (lengthCode > remainingBytes) {
decodeStatus = DecodeStatus.OUT_BUFFER_OVERFLOW;
lengthCode = remainingBytes;
}
for (i = lengthCode; i != 0; i--) {
sourceByte = source.getUint8(sourceCounter++);
if (sourceByte == 0) {
decodeStatus = DecodeStatus.ZERO_BYTE_IN_INPUT;
}
decoded.setUint8(decodedWriteCounter++, sourceByte);
}
if (sourceCounter >= sourceEndCounter) {
break;
}
/* Add a zero to the end */
if (lengthCode != 0xFE) {
if (decodedWriteCounter >= decodedEndCounter) {
decodeStatus = DecodeStatus.OUT_BUFFER_OVERFLOW;
break;
}
decoded.setUint8(decodedWriteCounter++, 0);
}
}
}
return DecodeResult(outLen: decodedWriteCounter, status: decodeStatus);
}