From 8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 12 Oct 2023 22:09:49 +0800 Subject: +hazel-networking --- Tools/Hazel-Networking/Hazel/ByteSpan.cs | 191 +++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 Tools/Hazel-Networking/Hazel/ByteSpan.cs (limited to 'Tools/Hazel-Networking/Hazel/ByteSpan.cs') diff --git a/Tools/Hazel-Networking/Hazel/ByteSpan.cs b/Tools/Hazel-Networking/Hazel/ByteSpan.cs new file mode 100644 index 0000000..7cfa3b5 --- /dev/null +++ b/Tools/Hazel-Networking/Hazel/ByteSpan.cs @@ -0,0 +1,191 @@ +using System; + +namespace Hazel +{ + /// + /// This is a minimal implementation of `System.Span` in .NET 5.0 + /// + public struct ByteSpan + { + private readonly byte[] array_; + + /// + /// Createa a new span object containing an entire array + /// + public ByteSpan(byte[] array) + { + if (array == null) + { + this.array_ = null; + this.Offset = 0; + this.Length = 0; + } + else + { + this.array_ = array; + this.Offset = 0; + this.Length = array.Length; + } + } + + /// + /// Creates a new span object containing a subset of an array + /// + public ByteSpan(byte[] array, int offset, int length) + { + if (array == null) + { + if (offset != 0) + { + throw new ArgumentException("Invalid offset", nameof(offset)); + } + if (length != 0) + { + throw new ArgumentException("Invalid length", nameof(offset)); + } + + this.array_ = null; + this.Offset = 0; + this.Length = 0; + } + else + { + if (offset < 0 || offset > array.Length) + { + throw new ArgumentException("Invalid offset", nameof(offset)); + } + if (length < 0) + { + throw new ArgumentException($"Invalid length: {length}", nameof(length)); + } + if ((offset + length) > array.Length) + { + throw new ArgumentException($"Invalid length. Length: {length} Offset: {offset} Array size: {array.Length}", nameof(length)); + } + + this.array_ = array; + this.Offset = offset; + this.Length = length; + } + } + + /// + /// Returns the underlying array. + /// + /// WARNING: This does not return the span, but the entire underlying storage block + /// + public byte[] GetUnderlyingArray() + { + return this.array_; + } + + /// + /// Returns the offset into the underlying array + /// + public int Offset { get; } + + /// + /// Returns the length of the current span + /// + public int Length { get; } + + /// + /// Gets the span element at the specified index + /// + public byte this[int index] + { + get + { + if (index < 0 || index >= this.Length) + { + throw new IndexOutOfRangeException(); + } + + return this.array_[this.Offset + index]; + } + set + { + if (index < 0 || index >= this.Length) + { + throw new IndexOutOfRangeException(); + } + + this.array_[this.Offset + index] = value; + } + } + + /// + /// Create a new span that is a subset of this span [offset, this.Length-offset) + /// + public ByteSpan Slice(int offset) + { + return Slice(offset, this.Length - offset); + } + + /// + /// Create a new span that is a subset of this span [offset, length) + /// + public ByteSpan Slice(int offset, int length) + { + return new ByteSpan(this.array_, this.Offset + offset, length); + } + + /// + /// Copies the contents of the span to an array + /// + public void CopyTo(byte[] array, int offset) + { + CopyTo(new ByteSpan(array, offset, array.Length - offset)); + } + + /// + /// Copies the contents of the span to another span + /// + public void CopyTo(ByteSpan destination) + { + if (destination.Length < this.Length) + { + throw new ArgumentException("Destination span is shorter than source", nameof(destination)); + } + + if (Length > 0) + { + Buffer.BlockCopy(this.array_, this.Offset, destination.array_, destination.Offset, this.Length); + } + } + + /// + /// Create a new array with the contents of this span + /// + public byte[] ToArray() + { + byte[] result = new byte[Length]; + CopyTo(result); + return result; + } + + public override string ToString() + { + return string.Join(" ", this.ToArray()); + } + + /// + /// Implicit conversion from byte[] -> ByteSpan + /// + public static implicit operator ByteSpan(byte[] array) + { + return new ByteSpan(array); + } + + /// + /// Retuns an empty span object + /// + public static ByteSpan Empty + { + get + { + return new ByteSpan(null); + } + } + } +} -- cgit v1.1-26-g67d0