BlockReader constructor
Parses a block starting at offset; length defaults to the rest of
buffer.
Implementation
factory BlockReader(
Uint8List buffer, {
int offset = 0,
int? length,
bool verifyChecksum = true,
}) {
final end = length == null ? buffer.length : offset + length;
if (end > buffer.length || end - offset < blockHeaderSize) {
throw VxsFormatException('block shorter than its header', offset: offset);
}
if (buffer[offset] != blockMagic) {
throw VxsFormatException(
'bad block magic 0x${buffer[offset].toRadixString(16)}',
offset: offset,
);
}
if (buffer[offset + 1] != blockVersion) {
throw VxsFormatException(
'unsupported block version ${buffer[offset + 1]}',
offset: offset,
);
}
final flags = buffer[offset + 2];
if (flags & ~blockFlagCrc32c != 0 || buffer[offset + 3] != 0) {
throw VxsFormatException(
'reserved block header bits set',
offset: offset,
);
}
final hasCrc = flags & blockFlagCrc32c != 0;
final payloadStart = offset + blockHeaderSize;
final payloadEnd = end - (hasCrc ? 4 : 0);
if (payloadEnd < payloadStart) {
throw VxsFormatException('block has no payload', offset: offset);
}
if (hasCrc && verifyChecksum) {
final stored = VxsLe.u32(buffer, payloadEnd);
final actual = VxsCrc32c.compute(buffer, payloadStart, payloadEnd);
if (stored != actual) {
throw VxsFormatException(
'block checksum mismatch: stored 0x${stored.toRadixString(16)}, '
'computed 0x${actual.toRadixString(16)}',
offset: payloadEnd,
);
}
}
return BlockReader._(buffer, offset, payloadStart, payloadEnd, flags);
}