/// <summary> /// Searches for a span of bytes in the <see cref="ReadableBuffer"/> and returns a sliced <see cref="ReadableBuffer"/> that /// contains all data up to and excluding the first byte of the span, and a <see cref="ReadCursor"/> that points to the last byte of the span. /// </summary> /// <param name="span">The <see cref="Span{Byte}"/> byte to search for</param> /// <param name="slice">A <see cref="ReadableBuffer"/> that matches all data up to and excluding the first byte</param> /// <param name="cursor">A <see cref="ReadCursor"/> that points to the second byte</param> /// <returns>True if the byte sequence was found, false if not found</returns> public static bool TrySliceTo(this ReadableBuffer buffer, Span <byte> span, out ReadableBuffer slice, out ReadCursor cursor) { var result = false; var subBuffer = buffer; do { // Find the first byte if (!subBuffer.TrySliceTo(span[0], out slice, out cursor)) { break; } // Move the buffer to where you fonud the first byte then search for the next byte subBuffer = buffer.Slice(cursor); if (subBuffer.StartsWith(span)) { slice = buffer.Slice(buffer.Start, cursor); result = true; break; } // REVIEW: We need to check the performance of Slice in a loop like this // Not a match so skip(1) subBuffer = subBuffer.Slice(1); } while (!subBuffer.IsEmpty); return(result); }
private static T ReadMultiLittle <[Primitive] T>(ReadableBuffer buffer, int len) where T : struct { Span <byte> localSpan = stackalloc byte[len]; buffer.Slice(0, len).CopyTo(localSpan); return(localSpan.ReadLittleEndian <T>()); }
private static unsafe T ReadMultiBig <[Primitive] T>(ReadableBuffer buffer, int len) where T : struct { byte *local = stackalloc byte[len]; var localSpan = new Span <byte>(local, len); buffer.Slice(0, len).CopyTo(localSpan); return(localSpan.ReadBigEndian <T>()); }
/// <summary> /// Checks to see if the <see cref="ReadableBuffer"/> starts with the specified <see cref="Span{Byte}"/>. /// </summary> /// <param name="value">The <see cref="Span{Byte}"/> to compare to</param> /// <returns>True if the bytes StartsWith, false if not</returns> public static bool StartsWith(this ReadableBuffer buffer, Span <byte> value) { if (buffer.Length < value.Length) { // just nope return(false); } return(buffer.Slice(0, value.Length).EqualsTo(value)); }
/// <summary> /// Searches for a byte in the <see cref="ReadableBuffer"/> and returns a sliced <see cref="ReadableBuffer"/> that /// contains all data up to and excluding the byte, and a <see cref="ReadCursor"/> that points to the byte. /// </summary> /// <param name="b1">The first byte to search for</param> /// <param name="slice">A <see cref="ReadableBuffer"/> slice that contains all data up to and excluding the first byte.</param> /// <param name="cursor">A <see cref="ReadCursor"/> that points to the second byte</param> /// <returns>True if the byte sequence was found, false if not found</returns> public static bool TrySliceTo(this ReadableBuffer buffer, byte b1, out ReadableBuffer slice, out ReadCursor cursor) { if (buffer.IsEmpty) { slice = default(ReadableBuffer); cursor = default(ReadCursor); return(false); } var byte0Vector = GetVector(b1); var seek = 0; foreach (var memory in buffer) { var currentSpan = memory.Span; var found = false; if (Vector.IsHardwareAccelerated) { while (currentSpan.Length >= VectorWidth) { var data = currentSpan.Read <Vector <byte> >(); var byte0Equals = Vector.Equals(data, byte0Vector); if (byte0Equals.Equals(Vector <byte> .Zero)) { currentSpan = currentSpan.Slice(VectorWidth); seek += VectorWidth; } else { var index = FindFirstEqualByte(ref byte0Equals); seek += index; found = true; break; } } } if (!found) { // Slow search for (int i = 0; i < currentSpan.Length; i++) { if (currentSpan[i] == b1) { found = true; break; } seek++; } } if (found) { cursor = buffer.Move(buffer.Start, seek); slice = buffer.Slice(buffer.Start, cursor); return(true); } } slice = default(ReadableBuffer); cursor = default(ReadCursor); return(false); }