Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions src/Nerdbank.MessagePack/Extension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,5 @@ public Extension(sbyte typeCode, ReadOnlyMemory<byte> data)

/// <inheritdoc/>
long IStructuralSecureEqualityComparer<Extension>.GetSecureHashCode()
{
// We don't have an incremental SipHash implementation, so we have to copy the data to a rented buffer.
byte[] rented = ArrayPool<byte>.Shared.Rent(checked((int)this.Data.Length));
try
{
this.Data.CopyTo(rented);
return SipHash.Default.Compute(rented.AsSpan(0, (int)this.Data.Length)) + this.TypeCode;
}
finally
{
ArrayPool<byte>.Shared.Return(rented);
}
}
=> SipHash.Default.Compute(this.Data) + this.TypeCode;
}
10 changes: 10 additions & 0 deletions src/Nerdbank.MessagePack/PolyfillExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ internal static unsafe int GetChars(this Encoding encoding, ReadOnlySpan<byte> s

internal static unsafe int GetChars(this Encoding encoding, ReadOnlySequence<byte> source, Span<char> destination)
{
if (source.IsEmpty)
{
return 0;
}

if (source.IsSingleSegment)
{
return GetChars(encoding, source.First.Span, destination);
Expand All @@ -100,6 +105,11 @@ internal static unsafe int GetChars(this Encoding encoding, ReadOnlySequence<byt
bool completed = true;
foreach (ReadOnlyMemory<byte> sourceSegment in source)
{
if (sourceSegment.IsEmpty)
{
continue;
}

fixed (byte* pSource = sourceSegment.Span)
{
fixed (char* pDestination = destination)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,42 +287,7 @@ private ReadOnlySequenceOfBytesEqualityComparer()

public override bool Equals(ReadOnlySequence<byte> x, ReadOnlySequence<byte> y) => x.SequenceEqual(y);

public override long GetSecureHashCode([DisallowNull] ReadOnlySequence<byte> obj)
{
int segmentCount = 0;
foreach (ReadOnlyMemory<byte> segment in obj)
{
if (++segmentCount > 64)
{
break;
}
}

if (segmentCount <= 64)
{
Span<long> hashesSpan = stackalloc long[segmentCount];
int i = 0;
foreach (ReadOnlyMemory<byte> segment in obj)
{
hashesSpan[i++] = SecureHash(segment.Span);
}

return SipHash.Default.Compute(MemoryMarshal.Cast<long, byte>(hashesSpan));
}

List<long> hashes = [];
foreach (ReadOnlyMemory<byte> segment in obj)
{
hashes.Add(SecureHash(segment.Span));
}

#if NET
Span<long> span = CollectionsMarshal.AsSpan(hashes);
#else
Span<long> span = hashes.ToArray();
#endif
return SipHash.Default.Compute(MemoryMarshal.Cast<long, byte>(span));
}
public override long GetSecureHashCode([DisallowNull] ReadOnlySequence<byte> obj) => SipHash.Default.Compute(obj);
}

internal class CollisionResistantEnumHasher<TEnum, TUnderlying>(SecureEqualityComparer<TUnderlying> equalityComparer) : SecureEqualityComparer<TEnum>
Expand Down
Loading
Loading