blob: ea5fa12a718185db5b9890e0ffd4e16b3f3727fc [file] [log] [blame]
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace DotPulsar.Internal.Extensions
{
using System;
using System.Buffers;
public static class ReadOnlySequenceExtensions
{
public static bool StartsWith<T>(this ReadOnlySequence<T> sequence, ReadOnlyMemory<T> target) where T : IEquatable<T>
{
if (target.Length > sequence.Length)
return false;
var targetIndex = 0;
var targetSpan = target.Span;
foreach (var memory in sequence)
{
var span = memory.Span;
for (var i = 0; i < span.Length; ++i)
{
if (!span[i].Equals(targetSpan[targetIndex]))
return false;
++targetIndex;
if (targetIndex == targetSpan.Length)
return true;
}
}
return false;
}
public static uint ReadUInt32(this ReadOnlySequence<byte> sequence, long start, bool isBigEndian)
{
if (sequence.Length < 4 + start)
throw new ArgumentOutOfRangeException(nameof(start), start, "Sequence must be at least 4 bytes long from 'start' to end");
var reverse = isBigEndian != BitConverter.IsLittleEndian;
var union = new UIntUnion();
var read = 0;
foreach (var memory in sequence)
{
if (start > memory.Length)
{
start -= memory.Length;
continue;
}
var span = memory.Span;
for (var i = (int) start; i < span.Length; ++i, ++read)
{
switch (read)
{
case 0:
if (reverse) union.B0 = span[i];
else union.B3 = span[i];
continue;
case 1:
if (reverse) union.B1 = span[i];
else union.B2 = span[i];
continue;
case 2:
if (reverse) union.B2 = span[i];
else union.B1 = span[i];
continue;
case 3:
if (reverse) union.B3 = span[i];
else union.B0 = span[i];
break;
}
}
if (read == 3)
break;
start = 0;
}
return union.UInt;
}
}
}