summary refs log tree commit diff
path: root/LibGit/Extensions/StreamExtensions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'LibGit/Extensions/StreamExtensions.cs')
-rw-r--r--LibGit/Extensions/StreamExtensions.cs80
1 files changed, 67 insertions, 13 deletions
diff --git a/LibGit/Extensions/StreamExtensions.cs b/LibGit/Extensions/StreamExtensions.cs

index 6555783..41e4b4f 100644 --- a/LibGit/Extensions/StreamExtensions.cs +++ b/LibGit/Extensions/StreamExtensions.cs
@@ -38,13 +38,14 @@ public static class StreamExtensions int peek = stream.ReadByte(); if (peek == -1) { - if(_debug) Console.WriteLine($"Can't peek {count} bytes, only {i} bytes remaining"); + if (_debug) Console.WriteLine($"Can't peek {count} bytes, only {i} bytes remaining"); stream.Seek(-i, SeekOrigin.Current); yield break; } yield return (byte)peek; } + stream.Seek(-i, SeekOrigin.Current); } @@ -76,7 +77,7 @@ public static class StreamExtensions Console.WriteLine($"Expected: {sequence.AsHexString()} ({sequence.AsString()})"); Console.WriteLine($"Actual: {stream.Peek(sequence.Count()).AsHexString()} ({stream.Peek(sequence.Count()).AsString()})"); } - + int readCount = 0; foreach (int b in sequence) { @@ -87,7 +88,7 @@ public static class StreamExtensions stream.Seek(-readCount, SeekOrigin.Current); return false; } - + if (read != b) { if (_debug) @@ -101,8 +102,9 @@ public static class StreamExtensions return false; } } + stream.Seek(-readCount, SeekOrigin.Current); - + return true; } @@ -119,8 +121,12 @@ public static class StreamExtensions return stream; } - public static IEnumerable<byte> ReadNullTerminatedField(this Stream stream, IEnumerable<byte>? binaryPrefix = null, string? asciiPrefix = null) => ReadTerminatedField(stream: stream, terminator: 0x00, binaryPrefix: binaryPrefix, asciiPrefix: asciiPrefix); - public static IEnumerable<byte> ReadSpaceTerminatedField(this Stream stream, IEnumerable<byte>? binaryPrefix = null, string? asciiPrefix = null) => ReadTerminatedField(stream: stream, terminator: 0x20, binaryPrefix: binaryPrefix, asciiPrefix: asciiPrefix); + public static IEnumerable<byte> ReadNullTerminatedField(this Stream stream, IEnumerable<byte>? binaryPrefix = null, string? asciiPrefix = null) => + ReadTerminatedField(stream: stream, terminator: 0x00, binaryPrefix: binaryPrefix, asciiPrefix: asciiPrefix); + + public static IEnumerable<byte> ReadSpaceTerminatedField(this Stream stream, IEnumerable<byte>? binaryPrefix = null, string? asciiPrefix = null) => + ReadTerminatedField(stream: stream, terminator: 0x20, binaryPrefix: binaryPrefix, asciiPrefix: asciiPrefix); + public static IEnumerable<byte> ReadTerminatedField(this Stream stream, byte terminator, IEnumerable<byte>? binaryPrefix = null, string? asciiPrefix = null) { if (!stream.CanRead) @@ -131,7 +137,8 @@ public static class StreamExtensions else stream.Skip(binaryPrefix.Count()); else if (asciiPrefix != null) if (!stream.StartsWith(asciiPrefix)) - throw new InvalidDataException($"Text prefix {stream.Peek(asciiPrefix.Length).AsHexString()} ({stream.Peek(asciiPrefix.Length).AsString()}) does not match expected value of {asciiPrefix.AsBytes().AsHexString()} ({asciiPrefix})!"); + throw new InvalidDataException( + $"Text prefix {stream.Peek(asciiPrefix.Length).AsHexString()} ({stream.Peek(asciiPrefix.Length).AsString()}) does not match expected value of {asciiPrefix.AsBytes().AsHexString()} ({asciiPrefix})!"); else stream.Skip(asciiPrefix.Length); var read = 0; @@ -150,7 +157,7 @@ public static class StreamExtensions if (stream.Peek() == terminator) stream.Skip(); } - + public static IEnumerable<byte> ReadToEnd(this Stream stream) { if (!stream.CanRead) @@ -159,21 +166,49 @@ public static class StreamExtensions while (stream.Peek() != -1) yield return (byte)stream.ReadByte(); } - + public static int ReadInt32BE(this Stream stream) { if (!stream.CanRead) throw new InvalidOperationException("Can't read a non-readable stream"); var bytes = stream.ReadBytes(4).ToArray(); - + if (BitConverter.IsLittleEndian) Array.Reverse(bytes); - - Console.WriteLine("ReadInt32BE: " + bytes.AsHexString() + " => " + BitConverter.ToInt32(bytes)); + + // Console.WriteLine("ReadInt32BE: " + bytes.AsHexString() + " => " + BitConverter.ToInt32(bytes)); return BitConverter.ToInt32(bytes); } - + + public static uint ReadUInt32BE(this Stream stream) + { + if (!stream.CanRead) + throw new InvalidOperationException("Can't read a non-readable stream"); + + var bytes = stream.ReadBytes(4).ToArray(); + + if (BitConverter.IsLittleEndian) + Array.Reverse(bytes); + + // Console.WriteLine("ReadUInt32BE: " + bytes.AsHexString() + " => " + BitConverter.ToUInt32(bytes)); + return BitConverter.ToUInt32(bytes); + } + + public static ulong ReadUInt64BE(this Stream stream) + { + if (!stream.CanRead) + throw new InvalidOperationException("Can't read a non-readable stream"); + + var bytes = stream.ReadBytes(8).ToArray(); + + if (BitConverter.IsLittleEndian) + Array.Reverse(bytes); + + // Console.WriteLine("ReadUInt64BE: " + bytes.AsHexString() + " => " + BitConverter.ToUInt64(bytes)); + return BitConverter.ToUInt64(bytes); + } + //read variable length number public static int ReadVLQ(this Stream stream) { @@ -192,6 +227,7 @@ public static class StreamExtensions return result; } + public static int ReadVLQBigEndian(this Stream stream) { if (!stream.CanRead) @@ -208,4 +244,22 @@ public static class StreamExtensions return result; } + + // for some reason this is special... + public static int ReadGitPackOffsetModifiedVLQ(this Stream stream) + { + if (!stream.CanRead) + throw new InvalidOperationException("Can't read a non-readable stream"); + + int b = stream.ReadByte(); + int result = b & 0x7F; + + while ((b & 0x80) != 0) + { + b = stream.ReadByte(); + result = ((result + 1) << 7) | (b & 0x7F); + } + + return result; + } } \ No newline at end of file