interleaveWithECBytes static method
Interleave "bits" with corresponding error correction bytes. On success, store the result in "result". The interleave rule is complicated. See 8.6 of JISX0510:2004 (p.37) for details.
Implementation
static BitArray interleaveWithECBytes(
BitArray bits,
int numTotalBytes,
int numDataBytes,
int numRSBlocks,
) {
// "bits" must have "getNumDataBytes" bytes of data.
if (bits.sizeInBytes != numDataBytes) {
throw WriterException('Number of bits and data bytes does not match');
}
// Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll
// store the divided data bytes blocks and error correction bytes blocks into "blocks".
int dataBytesOffset = 0;
int maxNumDataBytes = 0;
int maxNumEcBytes = 0;
// Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.
final blocks = <BlockPair>[]; //numRSBlocks
for (int i = 0; i < numRSBlocks; ++i) {
final numDataBytesInBlock = [0];
final numEcBytesInBlock = [0];
getNumDataBytesAndNumECBytesForBlockID(
numTotalBytes,
numDataBytes,
numRSBlocks,
i,
numDataBytesInBlock,
numEcBytesInBlock,
);
final size = numDataBytesInBlock[0];
final dataBytes = Uint8List(size);
bits.toBytes(8 * dataBytesOffset, dataBytes, 0, size);
final ecBytes = generateECBytes(dataBytes, numEcBytesInBlock[0]);
blocks.add(BlockPair(dataBytes, ecBytes));
maxNumDataBytes = math.max(maxNumDataBytes, size);
maxNumEcBytes = math.max(maxNumEcBytes, ecBytes.length);
dataBytesOffset += numDataBytesInBlock[0];
}
if (numDataBytes != dataBytesOffset) {
throw WriterException('Data bytes does not match offset');
}
final result = BitArray();
// First, place data blocks.
for (int i = 0; i < maxNumDataBytes; ++i) {
for (BlockPair block in blocks) {
final dataBytes = block.dataBytes;
if (i < dataBytes.length) {
result.appendBits(dataBytes[i], 8);
}
}
}
// Then, place error correction blocks.
for (int i = 0; i < maxNumEcBytes; ++i) {
for (BlockPair block in blocks) {
final ecBytes = block.errorCorrectionBytes;
if (i < ecBytes.length) {
result.appendBits(ecBytes[i], 8);
}
}
}
if (numTotalBytes != result.sizeInBytes) {
// Should be same.
throw WriterException(
'Interleaving error: $numTotalBytes and ${result.sizeInBytes} differ.',
);
}
return result;
}