IdxFile.decode constructor

IdxFile.decode(
  1. Uint8List bytes
)

Implementation

IdxFile.decode(Uint8List bytes) {
  var allBytes = bytes.toList();
  var reader = ByteDataReader(endian: Endian.big, copy: false);
  reader.add(allBytes);

  // Read the signature
  var sig = reader.readUint32();
  if (sig != _PACK_IDX_SIGNATURE) {
    throw Exception('GitIdxFileCorrupted: Invalid signature $sig');
  }

  // Version
  var version = reader.readUint32();
  if (version != _PACK_VERSION) {
    throw Exception('GitIdxFileCorrupted: Unsupported version: $version');
  }

  // Fanout Table
  for (var i = 0; i < _FAN_TABLE_LENGTH; i++) {
    fanTable[i] = reader.readUint32();
  }
  var numObjects = fanTable.last;

  // Read Hashes
  var hashes = List<GitHash>.filled(numObjects, GitHash.zero());
  for (var i = 0; i < numObjects; i++) {
    var hash = GitHash.fromBytes(reader.read(20));

    hashes[i] = hash;
  }

  // Read crc32
  var crcValues = List<int>.filled(numObjects, 0);
  for (var i = 0; i < numObjects; i++) {
    crcValues[i] = reader.readUint32();
  }

  // Read offsets
  var offsets = List<int>.filled(numObjects, 0);
  var offset64BitPos = <int>[];
  for (var i = 0; i < numObjects; i++) {
    offsets[i] = reader.readUint32();

    // MSB is 1
    var msbSet = offsets[i] & 0x80000000;
    if (msbSet > 0) {
      offset64BitPos.add(i);
    }
  }

  // 64-bit offsets
  for (var i = 0; i < offset64BitPos.length; i++) {
    var pos = offset64BitPos[i];
    var offset = reader.readUint64();

    offsets[pos] = offset;
  }

  packFileHash = GitHash.fromBytes(reader.read(20));

  var bytesRead = reader.offsetInBytes;
  var idxFileHash = GitHash.fromBytes(reader.read(20));
  var fileHash = GitHash.compute(bytes.sublistView(0, bytesRead));
  if (fileHash != idxFileHash) {
    throw Exception('GitIdxFileCorrupted: Invalid file hash');
  }

  if (reader.remainingLength != 0) {
    throw Exception('GitIdxFileCorrupted: Extra bytes in the end');
  }

  entries = List<IdxFileEntry>.generate(numObjects, (i) {
    return IdxFileEntry(
      hash: hashes[i],
      crc32: crcValues[i],
      offset: offsets[i],
    );
  });
}