private void EncodeTS(int pIdx, long when) { int @base = infoOffset + pIdx; NB.EncodeInt32(info, @base, (int)(when / 1000)); NB.EncodeInt32(info, @base + 4, ((int)(when % 1000)) * 1000000); }
/// <exception cref="System.IO.IOException"></exception> internal void WriteFileHeader(int version, long objectCount) { System.Array.Copy(Constants.PACK_SIGNATURE, 0, headerBuffer, 0, 4); NB.EncodeInt32(headerBuffer, 4, version); NB.EncodeInt32(headerBuffer, 8, (int)objectCount); Write(headerBuffer, 0, 12); }
/// <exception cref="System.IO.IOException"></exception> private void PackHeader(TemporaryBuffer.Heap tinyPack, int cnt) { byte[] hdr = new byte[8]; NB.EncodeInt32(hdr, 0, 2); NB.EncodeInt32(hdr, 4, cnt); tinyPack.Write(Constants.PACK_SIGNATURE); tinyPack.Write(hdr, 0, 8); }
/// <exception cref="System.IO.IOException"></exception> private void WriteCRCs() { foreach (PackedObjectInfo oe in entries) { NB.EncodeInt32(tmp, 0, oe.GetCRC()); @out.Write(tmp, 0, 4); } }
/// <summary>Copy this ObjectId to a byte array.</summary> /// <remarks>Copy this ObjectId to a byte array.</remarks> /// <param name="b">the buffer to copy to.</param> /// <param name="o">the offset within b to write at.</param> public virtual void CopyRawTo(byte[] b, int o) { NB.EncodeInt32(b, o, w1); NB.EncodeInt32(b, o + 4, w2); NB.EncodeInt32(b, o + 8, w3); NB.EncodeInt32(b, o + 12, w4); NB.EncodeInt32(b, o + 16, w5); }
/// <exception cref="System.IO.IOException"></exception> internal virtual void WriteTo(OutputStream os) { MessageDigest foot = Constants.NewMessageDigest(); DigestOutputStream dos = new DigestOutputStream(os, foot); bool extended = false; for (int i = 0; i < entryCnt; i++) { extended |= sortedEntries[i].IsExtended; } // Write the header. // byte[] tmp = new byte[128]; System.Array.Copy(SIG_DIRC, 0, tmp, 0, SIG_DIRC.Length); NB.EncodeInt32(tmp, 4, extended ? 3 : 2); NB.EncodeInt32(tmp, 8, entryCnt); dos.Write(tmp, 0, 12); // Write the individual file entries. // if (snapshot == null) { // Write a new index, as no entries require smudging. // for (int i_1 = 0; i_1 < entryCnt; i_1++) { sortedEntries[i_1].Write(dos); } } else { int smudge_s = (int)(snapshot.LastModified() / 1000); int smudge_ns = ((int)(snapshot.LastModified() % 1000)) * 1000000; for (int i_1 = 0; i_1 < entryCnt; i_1++) { DirCacheEntry e = sortedEntries[i_1]; if (e.MightBeRacilyClean(smudge_s, smudge_ns)) { e.SmudgeRacilyClean(); } e.Write(dos); } } if (tree != null) { TemporaryBuffer bb = new TemporaryBuffer.LocalFile(); tree.Write(tmp, bb); bb.Close(); NB.EncodeInt32(tmp, 0, EXT_TREE); NB.EncodeInt32(tmp, 4, (int)bb.Length()); dos.Write(tmp, 0, 8); bb.WriteTo(dos, null); } os.Write(foot.Digest()); os.Close(); }
/// <exception cref="System.IO.IOException"></exception> protected internal override void WriteImpl() { WriteFanOutTable(); foreach (PackedObjectInfo oe in entries) { if (!CanStore(oe)) { throw new IOException(JGitText.Get().packTooLargeForIndexVersion1); } NB.EncodeInt32(tmp, 0, (int)oe.GetOffset()); oe.CopyRawTo(tmp, 4); @out.Write(tmp); } WriteChecksumFooter(); }
/// <exception cref="System.IO.IOException"></exception> protected internal override void OnEndThinPack() { byte[] tailHash = this.tailDigest.Digest(); byte[] buf = Buffer(); MessageDigest origDigest = Constants.NewMessageDigest(); MessageDigest tailDigest = Constants.NewMessageDigest(); MessageDigest packDigest = Constants.NewMessageDigest(); long origRemaining = origEnd; @out.Seek(0); @out.ReadFully(buf, 0, 12); origDigest.Update(buf, 0, 12); origRemaining -= 12; NB.EncodeInt32(buf, 8, GetObjectCount()); @out.Seek(0); @out.Write(buf, 0, 12); packDigest.Update(buf, 0, 12); for (; ;) { int n = @out.Read(buf); if (n < 0) { break; } if (origRemaining != 0) { int origCnt = (int)Math.Min(n, origRemaining); origDigest.Update(buf, 0, origCnt); origRemaining -= origCnt; if (origRemaining == 0) { tailDigest.Update(buf, origCnt, n - origCnt); } } else { tailDigest.Update(buf, 0, n); } packDigest.Update(buf, 0, n); } if (!Arrays.Equals(origDigest.Digest(), origHash) || !Arrays.Equals(tailDigest.Digest (), tailHash)) { throw new IOException(JGitText.Get().packCorruptedWhileWritingToFilesystem); } packHash = packDigest.Digest(); }
/// <summary>Output the standard 256 entry first-level fan-out table.</summary> /// <remarks> /// Output the standard 256 entry first-level fan-out table. /// <p> /// The fan-out table is 4 KB in size, holding 256 32-bit unsigned integer /// counts. Each count represents the number of objects within this index /// whose /// <see cref="NGit.AnyObjectId.FirstByte()">NGit.AnyObjectId.FirstByte()</see> /// matches the count's position in the /// fan-out table. /// </remarks> /// <exception cref="System.IO.IOException">an error occurred while writing to the output stream. /// </exception> protected internal virtual void WriteFanOutTable() { int[] fanout = new int[256]; foreach (PackedObjectInfo po in entries) { fanout[po.FirstByte & unchecked ((int)(0xff))]++; } for (int i = 1; i < 256; i++) { fanout[i] += fanout[i - 1]; } foreach (int n in fanout) { NB.EncodeInt32(tmp, 0, n); @out.Write(tmp, 0, 4); } }
/// <exception cref="System.IO.IOException"></exception> private void WriteOffset32() { int o64 = 0; foreach (PackedObjectInfo oe in entries) { long o = oe.GetOffset(); if (o <= MAX_OFFSET_32) { NB.EncodeInt32(tmp, 0, (int)o); } else { NB.EncodeInt32(tmp, 0, IS_OFFSET_64 | o64++); } @out.Write(tmp, 0, 4); } }
/// <exception cref="System.IO.IOException"></exception> private void WriteOffset32() { int o64 = 0; foreach (PackedObjectInfo oe in entries) { long o = oe.GetOffset(); if (o < int.MaxValue) { NB.EncodeInt32(tmp, 0, (int)o); } else { NB.EncodeInt32(tmp, 0, (1 << 31) | o64++); } @out.Write(tmp, 0, 4); } }
/// <summary>Output the version 2 (and later) TOC header, with version number.</summary> /// <remarks> /// Output the version 2 (and later) TOC header, with version number. /// <p> /// Post version 1 all index files start with a TOC header that makes the /// file an invalid version 1 file, and then includes the version number. /// This header is necessary to recognize a version 1 from a version 2 /// formatted index. /// </remarks> /// <param name="version">version number of this index format being written.</param> /// <exception cref="System.IO.IOException">an error occurred while writing to the output stream. /// </exception> protected internal virtual void WriteTOC(int version) { @out.Write(TOC); NB.EncodeInt32(tmp, 0, version); @out.Write(tmp, 0, 4); }
/// <summary>Set the cached size (in bytes) of this file.</summary> /// <remarks>Set the cached size (in bytes) of this file.</remarks> /// <param name="sz"> /// new cached size of the file, as bytes. If the file is larger /// than 2G, cast it to (int) before calling this method. /// </param> public virtual void SetLength(int sz) { NB.EncodeInt32(info, infoOffset + P_SIZE, sz); }
/// <exception cref="System.IO.IOException"></exception> internal virtual void WriteTo(OutputStream os) { MessageDigest foot = Constants.NewMessageDigest(); DigestOutputStream dos = new DigestOutputStream(os, foot); bool extended = false; for (int i = 0; i < entryCnt; i++) { extended |= sortedEntries[i].IsExtended; } // Write the header. // byte[] tmp = new byte[128]; System.Array.Copy(SIG_DIRC, 0, tmp, 0, SIG_DIRC.Length); NB.EncodeInt32(tmp, 4, extended ? 3 : 2); NB.EncodeInt32(tmp, 8, entryCnt); dos.Write(tmp, 0, 12); // Write the individual file entries. int smudge_s; int smudge_ns; if (myLock != null) { // For new files we need to smudge the index entry // if they have been modified "now". Ideally we'd // want the timestamp when we're done writing the index, // so we use the current timestamp as a approximation. myLock.CreateCommitSnapshot(); snapshot = myLock.GetCommitSnapshot(); smudge_s = (int)(snapshot.LastModified() / 1000); smudge_ns = ((int)(snapshot.LastModified() % 1000)) * 1000000; } else { // Used in unit tests only smudge_ns = 0; smudge_s = 0; } // Check if tree is non-null here since calling updateSmudgedEntries // will automatically build it via creating a DirCacheIterator bool writeTree = tree != null; if (repository != null && entryCnt > 0) { UpdateSmudgedEntries(); } for (int i_1 = 0; i_1 < entryCnt; i_1++) { DirCacheEntry e = sortedEntries[i_1]; if (e.MightBeRacilyClean(smudge_s, smudge_ns)) { e.SmudgeRacilyClean(); } e.Write(dos); } if (writeTree) { TemporaryBuffer bb = new TemporaryBuffer.LocalFile(); tree.Write(tmp, bb); bb.Close(); NB.EncodeInt32(tmp, 0, EXT_TREE); NB.EncodeInt32(tmp, 4, (int)bb.Length()); dos.Write(tmp, 0, 8); bb.WriteTo(dos, null); } writeIndexChecksum = foot.Digest(); os.Write(writeIndexChecksum); os.Close(); }