private T ReadPackFile <T>(FileStream fileStream, string hash, long offset, Func <Stream, long, bool, T> extractFunc) { byte[] lengthBuffer = new byte[1]; fileStream.Seek(offset, SeekOrigin.Begin); fileStream.Read(lengthBuffer, 0, 1); PackFileObjectType packFileObjectType = (PackFileObjectType)((lengthBuffer[0] & 0b0111_0000) >> 4); long length = lengthBuffer[0] & 0b0000_1111; //First four bits are dropped as they are they are readNextByte indicator and packFileObjectType int counter = 0; while ((lengthBuffer[0] & 0b1000_0000) != 0) { counter++; fileStream.Read(lengthBuffer, 0, 1); length = length + ((lengthBuffer[0] & 0b0111_1111) << (4 + (7 * (counter - 1)))); //First bit is dropped as it is the readNextByte indicator } switch (packFileObjectType) { case PackFileObjectType.Commit: return(extractFunc(fileStream, length, true)); case PackFileObjectType.Blob: return(extractFunc(fileStream, length, true)); case PackFileObjectType.Tree: return(extractFunc(fileStream, length, true)); case PackFileObjectType.ObjOfsDelta: long baseObjOffset = ReadVariableLengthOffset(fileStream); DeflateStream deflateStream = GetDeflateStreamForZlibData(fileStream); int deltaDataLength = (int)length; var sourceDataTuple = ReadVariableLengthSize(deflateStream); deltaDataLength -= sourceDataTuple.bytesRead; var targetLengthTuple = ReadVariableLengthSize(deflateStream); deltaDataLength -= targetLengthTuple.bytesRead; byte[] deltaBytes = new byte[deltaDataLength]; deflateStream.Read(deltaBytes, 0, deltaDataLength); byte[] baseBytes = ReadPackFile(fileStream, null, offset - baseObjOffset, ReadBytes); if (baseBytes.Length != sourceDataTuple.length) { throw new Exception("Base object did not match expected length"); } byte[] undeltifiedData = Undeltify(baseBytes, deltaBytes, targetLengthTuple.length); return(extractFunc(new MemoryStream(undeltifiedData), undeltifiedData.Length, false)); } return(default(T)); }
private T ReadPackFile <T>(FileStream fileStream, string hash, long offset, Func <Stream, long, bool, T> extractFunc) { byte[] buffer = new byte[1]; fileStream.Seek(offset, (SeekOrigin)SeekOrigin.Begin); fileStream.Read(buffer, 0, 1); PackFileObjectType type = (PackFileObjectType)((byte)((buffer[0] & 0x70) >> 4)); long num = buffer[0] & 15; int num2 = 0; while ((buffer[0] & 0x80) != 0) { num2++; fileStream.Read(buffer, 0, 1); num += (buffer[0] & 0x7f) << ((4 + (7 * (num2 - 1))) & 0x1f); } switch (type) { case PackFileObjectType.Commit: return(extractFunc(fileStream, num, true)); case PackFileObjectType.Tree: return(extractFunc(fileStream, num, true)); case PackFileObjectType.Blob: return(extractFunc(fileStream, num, true)); case PackFileObjectType.ObjOfsDelta: { long num3 = this.ReadVariableLengthOffset(fileStream); DeflateStream deflateStreamForZlibData = this.GetDeflateStreamForZlibData(fileStream); (int, long)tuple = this.ReadVariableLengthSize((Stream)deflateStreamForZlibData); (int, long)tuple2 = this.ReadVariableLengthSize((Stream)deflateStreamForZlibData); int count = (((int)num) - tuple.Item1) - tuple2.Item1; byte[] buffer2 = new byte[count]; deflateStreamForZlibData.Read(buffer2, 0, count); byte[] baseBytes = this.ReadPackFile <byte[]>(fileStream, null, offset - num3, new Func <Stream, long, bool, byte[]>(this.ReadBytes)); if (baseBytes.Length != tuple.Item2) { throw new Exception(______________________________("QmFzZSBvYmplY3QgZGlkIG5vdCBtYXRjaCBleHBlY3RlZCBsZW5ndGg=")); } byte[] buffer4 = this.Undeltify(baseBytes, buffer2, tuple2.Item2); return(extractFunc((Stream) new MemoryStream(buffer4), (long)buffer4.Length, false)); } } return(default(T)); }