closeStream method
Emits the complete file as a stream of byte chunks.
For CAR v2 with index the entire payload is still materialised in memory to build the index; the data is yielded as a stream for API consistency.
Implementation
Stream<Uint8List> closeStream() async* {
if (roots.isEmpty) {
throw CarHeaderException('CAR writer requires at least one root');
}
// Validate that every root is present in the data section.
final rootSet = roots.map((r) => r.encode()).toSet();
final writtenCids = _pending.map((s) => s.cid.encode()).toSet();
for (final root in rootSet) {
if (!writtenCids.contains(root)) {
throw CarHeaderException('Root CID $root must be written as a section');
}
}
// Build the CAR v1 payload first so we can compute offsets and index.
final v1Payload = await _buildV1Payload();
if (v2) {
// Pragma + CAR v2 header + data payload.
const pragmaSize = 11;
const v2HeaderSize = 40;
final dataOffset = pragmaSize + v2HeaderSize;
final dataSize = v1Payload.length;
var indexOffset = 0;
Uint8List? indexBytes;
if (index) {
indexBytes = _buildIndex(v1Payload);
indexOffset = dataOffset + dataSize;
}
yield _carV2Pragma;
yield _buildV2Header(dataOffset, dataSize, indexOffset);
yield v1Payload;
if (indexBytes != null) {
yield indexBytes;
}
} else {
yield v1Payload;
}
}