/// <summary> /// Read all the packs and indexes from the source stream and return a <see cref="PackAndIndex"/> for each pack /// and index. Caller must consume pack stream fully before the index stream. /// </summary> public IEnumerable <PackAndIndex> EnumeratePacks() { this.ValidateHeader(); byte[] buffer = new byte[NumPackHeaderBytes]; int packCount = this.ReadPackCount(buffer); for (int i = 0; i < packCount; i++) { long timestamp; long packLength; long indexLength; this.ReadPackHeader(buffer, out timestamp, out packLength, out indexLength); using (Stream packData = new RestrictedStream(this.source, packLength)) using (Stream indexData = indexLength > 0 ? new RestrictedStream(this.source, indexLength) : null) { yield return(new PackAndIndex(packData, indexData, timestamp)); } } }
/// <summary> /// Read all the objects from the source stream and call <see cref="OnLooseObject"/> for each. /// </summary> /// <returns>The total number of objects read</returns> public int ProcessObjects() { this.ValidateHeader(); // Start reading objects int numObjectsRead = 0; byte[] curObjectHeader = new byte[NumObjectHeaderBytes]; while (true) { bool keepReading = this.ShouldContinueReading(curObjectHeader); if (!keepReading) { break; } // Get the length long curLength = BitConverter.ToInt64(curObjectHeader, NumObjectIdBytes); // Handle the loose object using (Stream rawObjectData = new RestrictedStream(this.source, curLength)) { string objectId = SHA1Util.HexStringFromBytes(curObjectHeader, NumObjectIdBytes); if (objectId.Equals(GSDConstants.AllZeroSha)) { throw new RetryableException("Received all-zero SHA before end of stream"); } this.onLooseObject(rawObjectData, objectId); numObjectsRead++; } } return(numObjectsRead); }