StreamsComparer
Comparator for two Streams.
using System;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Constraints.Comparers
{
internal static class StreamsComparer
{
private const int BUFFER_SIZE = 4096;
[NullableContext(1)]
public static EqualMethodResult Equal(object x, object y, ref Tolerance tolerance, ComparisonState state, NUnitEqualityComparer equalityComparer)
{
Stream stream = x as Stream;
if (stream != null) {
Stream stream2 = y as Stream;
if (stream2 != null) {
if (tolerance.HasVariance)
return EqualMethodResult.ToleranceNotSupported;
if (stream == stream2)
return EqualMethodResult.ComparedEqual;
if (!stream.CanRead)
throw new ArgumentException("Stream is not readable", "expected");
if (!stream2.CanRead)
throw new ArgumentException("Stream is not readable", "actual");
bool flag = stream.CanSeek && stream2.CanSeek;
if (flag) {
if (stream.Length != stream2.Length)
return EqualMethodResult.ComparedNotEqual;
if (stream.Length == 0)
return EqualMethodResult.ComparedEqual;
}
BinaryReader binaryReader = new BinaryReader(stream);
BinaryReader binaryReader2 = new BinaryReader(stream2);
long position = flag ? stream.Position : 0;
long position2 = flag ? stream2.Position : 0;
byte[] array = null;
byte[] array2 = null;
try {
array = ArrayPool<byte>.Shared.Rent(4096);
array2 = ArrayPool<byte>.Shared.Rent(4096);
if (stream.CanSeek)
binaryReader.BaseStream.Seek(0, SeekOrigin.Begin);
if (stream2.CanSeek)
binaryReader2.BaseStream.Seek(0, SeekOrigin.Begin);
int num = 1;
int num2 = 1;
long num3 = 0;
while (num > 0 && num2 > 0) {
num = binaryReader.Read(array, 0, 4096);
num2 = binaryReader2.Read(array2, 0, 4096);
if (array.AsSpan(0, num).SequenceEqual(array2.AsSpan(0, num2)))
num3 += num2;
else {
for (int i = 0; i < 4096; i++) {
if (array[i] != array2[i]) {
NUnitEqualityComparer.FailurePoint failurePoint = new NUnitEqualityComparer.FailurePoint();
failurePoint.Position = num3 + i;
failurePoint.ExpectedHasData = true;
failurePoint.ExpectedValue = array[i];
failurePoint.ActualHasData = true;
failurePoint.ActualValue = array2[i];
equalityComparer.FailurePoints.Insert(0, failurePoint);
return EqualMethodResult.ComparedNotEqual;
}
}
}
}
} finally {
if (stream.CanSeek)
stream.Position = position;
if (stream2.CanSeek)
stream2.Position = position2;
if (array != null)
ArrayPool<byte>.Shared.Return(array, false);
if (array2 != null)
ArrayPool<byte>.Shared.Return(array2, false);
}
return EqualMethodResult.ComparedEqual;
}
}
return EqualMethodResult.TypesNotSupported;
}
}
}