public DirCacheEntry(byte[] sharedInfo, int infoAt, Stream @in, MessageDigest md)
{
_info = sharedInfo;
_infoOffset = infoAt;
IO.ReadFully(@in, _info, _infoOffset, INFO_LEN);
md.Update(_info, _infoOffset, INFO_LEN);
int pathLen = NB.decodeUInt16(_info, _infoOffset + PFlags) & NameMask;
int skipped = 0;
if (pathLen < NameMask)
{
_path = new byte[pathLen];
IO.ReadFully(@in, _path, 0, pathLen);
md.Update(_path, 0, pathLen);
}
else
{
var tmp = new MemoryStream();
{
var buf = new byte[NameMask];
IO.ReadFully(@in, buf, 0, NameMask);
tmp.Write(buf, 0, buf.Length);
}
while (true)
{
int c = @in.ReadByte();
if (c < 0)
{
throw new EndOfStreamException("Short Read of block.");
}
if (c == 0) break;
tmp.Write(new[] { (byte)c }, 0, 1);
}
_path = tmp.ToArray();
pathLen = _path.Length;
skipped = 1; // we already skipped 1 '\0' above to break the loop.
md.Update(_path, 0, pathLen);
md.Update(0);
}
// Index records are padded out to the next 8 byte alignment
// for historical reasons related to how C Git Read the files.
//
int actLen = INFO_LEN + pathLen;
int expLen = (actLen + 8) & ~7;
int padLen = expLen - actLen - skipped;
if (padLen > 0)
{
IO.skipFully(@in, padLen);
md.Update(NullPad, 0, padLen);
}
}