fromBytes static method

GitIndexEntry fromBytes(
  1. int versionNo,
  2. int indexFileSize,
  3. ByteDataReader reader,
  4. GitIndexEntry? lastEntry,
)

Implementation

static GitIndexEntry fromBytes(
  int versionNo,
  int indexFileSize,
  ByteDataReader reader,
  GitIndexEntry? lastEntry,
) {
  var startingBytes = indexFileSize - reader.remainingLength;

  var ctimeSeconds = reader.readUint32();
  var ctimeNanoSeconds = reader.readUint32();

  var cTime = DateTime.fromMicrosecondsSinceEpoch(0, isUtc: true);
  cTime = cTime.add(Duration(seconds: ctimeSeconds));
  cTime = cTime.add(Duration(microseconds: ctimeNanoSeconds ~/ 1000));

  var mtimeSeconds = reader.readUint32();
  var mtimeNanoSeconds = reader.readUint32();

  var mTime = DateTime.fromMillisecondsSinceEpoch(0, isUtc: true);
  mTime = mTime.add(Duration(seconds: mtimeSeconds));
  mTime = mTime.add(Duration(microseconds: mtimeNanoSeconds ~/ 1000));

  var dev = reader.readUint32();
  var ino = reader.readUint32();

  // Mode
  var mode = GitFileMode(reader.readUint32());

  var uid = reader.readUint32();
  var gid = reader.readUint32();

  var fileSize = reader.readUint32();
  var hash = GitHash.fromBytes(reader.read(20));

  var flags = reader.readUint16();
  var stage = GitFileStage((flags >> 12) & 0x3);

  var intentToAdd = false;
  var skipWorkTree = false;

  const hasExtendedFlag = 0x4000;
  if (flags & hasExtendedFlag != 0) {
    if (versionNo <= 2) {
      throw Exception('Index version 2 must not have an extended flag');
    }

    var extended = reader.readUint16(); // extra Flags

    const intentToAddMask = 1 << 13;
    const skipWorkTreeMask = 1 << 14;

    intentToAdd = (extended & intentToAddMask) > 0;
    skipWorkTree = (extended & skipWorkTreeMask) > 0;
  }

  // Read name
  var path = '';
  switch (versionNo) {
    case 2:
    case 3:
      const nameMask = 0xfff;
      var len = flags & nameMask;
      path = utf8.decode(reader.read(len));
      break;

    case 4:
      var l = reader.readVariableWidthInt();
      var base = '';
      if (lastEntry != null) {
        base = lastEntry.path.substring(0, lastEntry.path.length - l);
      }
      var name = reader.readUntil(0x00);
      path = base + utf8.decode(name);
      break;

    default:
      throw Exception('Index version not supported');
  }

  // Discard Padding
  if (versionNo != 4) {
    var endingBytes = indexFileSize - reader.remainingLength;
    var entrySize = endingBytes - startingBytes;
    var padLength = 8 - (entrySize % 8);
    reader.read(padLength);
  }

  return GitIndexEntry(
    cTime: cTime,
    mTime: mTime,
    dev: dev,
    ino: ino,
    mode: mode,
    uid: uid,
    gid: gid,
    fileSize: fileSize,
    hash: hash,
    stage: stage,
    path: path,
    skipWorkTree: skipWorkTree,
    intentToAdd: intentToAdd,
  );
}