closeStream method

Stream<Uint8List> closeStream()

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;
  }
}