private void WriteAllEntries(uint version) { try { using (Stream indexStream = new FileStream(this.indexLockPath, FileMode.Create, FileAccess.Write, FileShare.None)) using (BinaryWriter writer = new BinaryWriter(indexStream)) { writer.Write(IndexHeader); writer.Write(EndianHelper.Swap(version)); writer.Write((uint)0); // Number of entries placeholder uint lastStringLength = 0; LsTreeEntry entry; while (this.entryQueue.TryTake(out entry, Timeout.Infinite)) { this.WriteEntry(writer, version, entry.Sha, entry.Filename, ref lastStringLength); } // Update entry count writer.BaseStream.Position = EntryCountOffset; writer.Write(EndianHelper.Swap(this.entryCount)); writer.Flush(); } this.AppendIndexSha(); this.ReplaceExistingIndex(); } catch (Exception e) { this.tracer.RelatedError("Failed to generate index: {0}", e.ToString()); this.HasFailures = true; } }
private void WriteEntry(BinaryWriter writer, uint version, string sha, string filename, ref uint lastStringLength) { long startPosition = writer.BaseStream.Position; this.entryCount++; writer.Write(EntryHeader, 0, EntryHeader.Length); writer.Write(SHA1Util.BytesFromHexString(sha)); byte[] filenameBytes = Encoding.UTF8.GetBytes(filename); ushort flags = (ushort)(filenameBytes.Length & 0xFFF); writer.Write(EndianHelper.Swap(flags)); if (version >= 4) { this.WriteReplaceLength(writer, lastStringLength); lastStringLength = (uint)filenameBytes.Length; } writer.Write(filenameBytes); writer.Flush(); long endPosition = writer.BaseStream.Position; // Version 4 requires a nul-terminated string. int numPaddingBytes = 1; if (version < 4) { // Version 2-3 has between 1 and 8 padding bytes including nul-terminator. numPaddingBytes = 8 - ((int)(endPosition - startPosition) % 8); if (numPaddingBytes == 0) { numPaddingBytes = 8; } } writer.Write(PaddingBytes, 0, numPaddingBytes); writer.Flush(); }