readHeader static method

Future<TArchiveHeader> readHeader(
  1. String path, {
  2. String mime = tArchiveMime,
})

Implementation

static Future<TArchiveHeader> readHeader(
  String path, {
  String mime = tArchiveMime,
}) async {
  final raf = File(path).openSync();

  int pos = 0;

  // --- MAGIC ---
  final magicBytes = raf.readSync(4); // adjust if your `mime` is longer
  final magic = utf8.decode(magicBytes);
  if (magic != mime) throw Exception('invalid MIME type');
  pos += magicBytes.length;

  // --- VERSION ---
  final version = raf.readByteSync();
  pos++;

  // --- FLAGS ---
  final flags = raf.readByteSync();
  pos++;

  // --- Optional Cover ---
  Uint8List? coverImage;
  if ((flags & (1 << 0)) != 0) {
    final coverSizeBytes = raf.readSync(4);
    final coverSize = ByteData.sublistView(coverSizeBytes).getUint32(0);
    coverImage = raf.readSync(coverSize);
    pos += 4 + coverSize;
  }

  // --- Config JSON ---
  final configSizeBytes = raf.readSync(4);
  final configSize = ByteData.sublistView(configSizeBytes).getUint32(0);
  final configBytes = raf.readSync(configSize);
  final config = jsonDecode(utf8.decode(configBytes));
  pos += 4 + configSize;

  // --- Index Section ---
  final indexSizeBytes = raf.readSync(4);
  final indexSize = ByteData.sublistView(indexSizeBytes).getUint32(0);
  final indexBytes = raf.readSync(indexSize);
  pos += 4 + indexSize;

  final files = <TFileEntryInfo>[];

  int offset = 0;
  int currentFileDataStart = pos; // total so far = where file data starts

  while (offset < indexBytes.length) {
    final nameLen = ByteData.sublistView(
      indexBytes,
      offset,
      offset + 2,
    ).getUint16(0);
    offset += 2;

    final name = utf8.decode(indexBytes.sublist(offset, offset + nameLen));
    offset += nameLen;

    final fileOffset = ByteData.sublistView(
      indexBytes,
      offset,
      offset + 8,
    ).getInt64(0);
    offset += 8;

    final fileLength = ByteData.sublistView(
      indexBytes,
      offset,
      offset + 8,
    ).getInt64(0);
    offset += 8;

    files.add(
      TFileEntryInfo(
        path: path,
        name: name,
        length: fileLength,
        offset: currentFileDataStart + fileOffset,
      ),
    );
  }

  raf.closeSync();

  return TArchiveHeader(
    mime: magic,
    version: version,
    flags: flags,
    coverImage: coverImage,
    config: config,
    files: files,
  );
}