Skip to content

Commit 04d305f

Browse files
authored
Adding SpanByte to System (#109)
1 parent a76a470 commit 04d305f

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

Diff for: nanoFramework.CoreLibrary.NoReflection/CoreLibrary.NoReflection.nfproj

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
<Compile Include="..\nanoFramework.CoreLibrary\System\Version.cs" Link="System\Version.cs" />
190190
<Compile Include="..\nanoFramework.CoreLibrary\System\Void.cs" Link="System\Void.cs" />
191191
<Compile Include="..\nanoFramework.CoreLibrary\System\WeakReference.cs" Link="System\WeakReference.cs" />
192+
<Compile Include="..\nanoFramework.CoreLibrary\System\SpanByte.cs" Link="System\SpanByte.cs" />
192193
</ItemGroup>
193194
<ItemGroup>
194195
<NFMDP_PE_ExcludeClassByName Include="System.AttributeTargets">

Diff for: nanoFramework.CoreLibrary/CoreLibrary.nfproj

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
<Compile Include="System\SByte.cs" />
163163
<Compile Include="System\SerializableAttribute.cs" />
164164
<Compile Include="System\Single.cs" />
165+
<Compile Include="System\SpanByte.cs" />
165166
<Compile Include="System\String.cs" />
166167
<Compile Include="System\SystemException.cs" />
167168
<Compile Include="System\TargetFrameworkAttribute.cs" />

Diff for: nanoFramework.CoreLibrary/System/SpanByte.cs

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
4+
// See LICENSE file in the project root for full license information.
5+
//
6+
7+
namespace System
8+
{
9+
/// <summary>
10+
/// Provides a type- and memory-safe representation of a contiguous region of arbitrary byte array
11+
/// </summary>
12+
[Serializable, CLSCompliant(false)]
13+
public readonly ref struct SpanByte
14+
{
15+
private readonly byte[] _array;
16+
private readonly int _start;
17+
private readonly int _length;
18+
19+
/// <summary>
20+
/// Creates a new System.SpanByte object over the entirety of a specified array.
21+
/// </summary>
22+
/// <param name="array">The array from which to create the System.Span object.</param>
23+
public SpanByte(byte[] array)
24+
{
25+
_array = array;
26+
_length = array != null ? array.Length : 0;
27+
_start = 0;
28+
}
29+
30+
/// <summary>
31+
/// Creates a new System.SpanByte object that includes a specified number of elements
32+
/// of an array starting at a specified index.
33+
/// </summary>
34+
/// <param name="array">The source array.</param>
35+
/// <param name="start">The index of the first element to include in the new System.Span</param>
36+
/// <param name="length">The number of elements to include in the new System.Span</param>
37+
/// <exception cref="System.ArgumentOutOfRangeException">
38+
/// array is null, but start or length is non-zero. -or- start is outside the bounds
39+
/// of the array. -or- start and length exceeds the number of elements in the array.
40+
/// </exception>
41+
public SpanByte(byte[] array, int start, int length)
42+
{
43+
if (array != null)
44+
{
45+
if ((length > array.Length - start) || (start > array.Length))
46+
{
47+
throw new ArgumentOutOfRangeException($"Array length too small");
48+
}
49+
}
50+
else
51+
{
52+
if ((start != 0) || (length != 0))
53+
{
54+
throw new ArgumentOutOfRangeException($"Array is null but start and length are not 0");
55+
}
56+
}
57+
58+
_array = array;
59+
_start = start;
60+
_length = length;
61+
}
62+
63+
/// <summary>
64+
/// Gets the element at the specified zero-based index.
65+
/// </summary>
66+
/// <param name="index">The zero-based index of the element.</param>
67+
/// <returns>The element at the specified index.</returns>
68+
public byte this[int index]
69+
{
70+
get
71+
{
72+
if (index > _length)
73+
{
74+
throw new ArgumentOutOfRangeException($"Index out of range");
75+
}
76+
77+
return _array[_start + index];
78+
}
79+
set
80+
{
81+
if (index > _length)
82+
{
83+
throw new ArgumentOutOfRangeException($"Index out of range");
84+
}
85+
86+
_array[_start + index] = value;
87+
}
88+
}
89+
90+
/// <summary>
91+
/// Returns an empty System.Span object.
92+
/// </summary>
93+
public static SpanByte Empty => new SpanByte();
94+
95+
/// <summary>
96+
/// Returns the length of the current span.
97+
/// </summary>
98+
public int Length => _length;
99+
100+
/// <summary>
101+
/// Returns a value that indicates whether the current System.Span is empty.
102+
/// true if the current span is empty; otherwise, false.
103+
/// </summary>
104+
public bool IsEmpty => _length == 0;
105+
106+
/// <summary>
107+
/// Copies the contents of this System.Span into a destination System.Span.
108+
/// </summary>
109+
/// <param name="destination"> The destination System.Span object.</param>
110+
/// <exception cref="System.ArgumentException">
111+
/// destination is shorter than the source System.Span.
112+
/// </exception>
113+
public void CopyTo(SpanByte destination)
114+
{
115+
if (destination.Length < _length - _start)
116+
{
117+
throw new ArgumentException($"Destination too small");
118+
}
119+
120+
for (int i = 0; i < _array.Length; i++)
121+
{
122+
destination[i] = _array[i];
123+
}
124+
}
125+
126+
/// <summary>
127+
/// Forms a slice out of the current span that begins at a specified index.
128+
/// </summary>
129+
/// <param name="start">The index at which to begin the slice.</param>
130+
/// <returns>A span that consists of all elements of the current span from start to the end of the span.</returns>
131+
/// <exception cref="System.ArgumentOutOfRangeException">start is less than zero or greater than System.Span.Length.</exception>
132+
public SpanByte Slice(int start)
133+
{
134+
if ((start > _length) || (start < 0))
135+
{
136+
throw new ArgumentOutOfRangeException($"start is less than zero or greater than length");
137+
}
138+
139+
return new SpanByte(_array, _start + start, _length - start);
140+
}
141+
142+
/// <summary>
143+
/// Forms a slice out of the current span starting at a specified index for a specified length.
144+
/// </summary>
145+
/// <param name="start">The index at which to begin this slice.</param>
146+
/// <param name="length">The desired length for the slice.</param>
147+
/// <returns>A span that consists of length elements from the current span starting at start.</returns>
148+
/// <exception cref="System.ArgumentOutOfRangeException">start or start + length is less than zero or greater than System.Span.Length.</exception>
149+
public SpanByte Slice(int start, int length)
150+
{
151+
if ((start < 0) || (length < 0) || (start + length > _length))
152+
{
153+
throw new ArgumentOutOfRangeException($"start or start + length is less than zero or greater than length");
154+
}
155+
156+
return new SpanByte(_array, _start + start, length);
157+
}
158+
159+
/// <summary>
160+
/// Copies the contents of this span into a new array.
161+
/// </summary>
162+
/// <returns> An array containing the data in the current span.</returns>
163+
public byte[] ToArray()
164+
{
165+
byte[] array = new byte[_length];
166+
for (int i = 0; i < _length; i++)
167+
{
168+
array[i] = _array[_start + i];
169+
}
170+
171+
return array;
172+
}
173+
174+
/// <summary>
175+
/// Implicit conversion of an array to a span of byte
176+
/// </summary>
177+
/// <param name="array"></param>
178+
public static implicit operator SpanByte(byte[] array)
179+
{
180+
return new SpanByte(array);
181+
}
182+
}
183+
}

0 commit comments

Comments
 (0)