/// <summary> /// Copy the ObjectId and other meta fields from an existing entry. /// <para /> /// This method copies everything except the path from one entry to another, /// supporting renaming. /// </summary> /// <param name="src"> /// The entry to copy ObjectId and meta fields from. /// </param> public void copyMetaData(DirCacheEntry src) { int pLen = NB.decodeUInt16(_info, _infoOffset + PFlags) & NameMask; Array.Copy(src._info, src._infoOffset, _info, _infoOffset, INFO_LEN); NB.encodeInt16(_info, _infoOffset + PFlags, pLen | NB.decodeUInt16(_info, _infoOffset + PFlags) & ~NameMask); }
public void testDecodeUInt16() { Assert.AreEqual(0, NB.decodeUInt16(b(0, 0), 0)); Assert.AreEqual(0, NB.decodeUInt16(Padb(3, 0, 0), 3)); Assert.AreEqual(3, NB.decodeUInt16(b(0, 3), 0)); Assert.AreEqual(3, NB.decodeUInt16(Padb(3, 0, 3), 3)); Assert.AreEqual(0xde03, NB.decodeUInt16(b(0xde, 3), 0)); Assert.AreEqual(0xde03, NB.decodeUInt16(Padb(3, 0xde, 3), 3)); Assert.AreEqual(0x03de, NB.decodeUInt16(b(3, 0xde), 0)); Assert.AreEqual(0x03de, NB.decodeUInt16(Padb(3, 3, 0xde), 3)); Assert.AreEqual(0xffff, NB.decodeUInt16(b(0xff, 0xff), 0)); Assert.AreEqual(0xffff, NB.decodeUInt16(Padb(3, 0xff, 0xff), 3)); }
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); } }