Skip to content

Commit 9061b57

Browse files
committed
More copy-less
1 parent 8e8a9d3 commit 9061b57

File tree

4 files changed

+99
-88
lines changed

4 files changed

+99
-88
lines changed

Bencodex/Decoder.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Globalization;
55
using System.IO;
66
using System.Numerics;
7+
using System.Runtime.CompilerServices;
78
using System.Text;
89
using Bencodex.Misc;
910
using Bencodex.Types;
@@ -12,7 +13,6 @@ namespace Bencodex
1213
{
1314
internal sealed class Decoder
1415
{
15-
private readonly byte[] _tinyBuffer = new byte[1];
1616
private readonly Stream _stream;
1717
private readonly IndirectValue.Loader? _indirectValueLoader;
1818
private byte _lastRead;
@@ -74,7 +74,7 @@ private IValue DecodeValue()
7474
return ReadTextAfterPrefix();
7575

7676
case 0x6c: // 'l'
77-
var indirElements = new List<IndirectValue>();
77+
var indirBuilder = ImmutableArray.CreateBuilder<IndirectValue>();
7878
while (true)
7979
{
8080
byte b = ReadByte() ?? throw new DecodingException(
@@ -87,17 +87,17 @@ private IValue DecodeValue()
8787
else if (b == indir)
8888
{
8989
Fingerprint fp = DecodeFingerprint();
90-
indirElements.Add(new IndirectValue(fp));
90+
indirBuilder.Add(new IndirectValue(fp));
9191
continue;
9292
}
9393

9494
Back();
9595
IValue element = DecodeValue();
96-
indirElements.Add(new IndirectValue(element));
96+
indirBuilder.Add(new IndirectValue(element));
9797
}
9898

9999
return new Bencodex.Types.List(
100-
indirElements.ToImmutableArray(),
100+
indirBuilder.MoveToImmutable().AsSpan(),
101101
_indirectValueLoader
102102
);
103103

@@ -255,15 +255,15 @@ private byte[] Read(byte[] buffer)
255255
return _lastRead;
256256
}
257257

258-
int read = _stream.Read(_tinyBuffer, 0, 1);
258+
int read = _stream.ReadByte();
259259
if (read > 0)
260260
{
261-
_lastRead = _tinyBuffer[0];
261+
_lastRead = (byte)read;
262262
}
263263

264264
_offset++;
265265
_didBack = false;
266-
return read == 0 ? (byte?)null : _tinyBuffer[0];
266+
return read == -1 ? (byte?)null : _lastRead;
267267
}
268268

269269
private void Back()
@@ -363,12 +363,7 @@ Func<string, IFormatProvider, T> converter
363363
)
364364
{
365365
byte[] buffer = ReadDigits(takeMinusSign, delimiter);
366-
var digits = new char[buffer.Length];
367-
for (int i = 0; i < buffer.Length; i++)
368-
{
369-
digits[i] = (char)buffer[i];
370-
}
371-
366+
var digits = Unsafe.As<byte[], char[]>(ref buffer);
372367
return converter(new string(digits), CultureInfo.InvariantCulture);
373368
}
374369

@@ -399,7 +394,7 @@ Func<string, IFormatProvider, T> converter
399394
private Binary ReadBinary()
400395
{
401396
(byte[] bytes, _) = ReadByteArray();
402-
return new Binary(bytes);
397+
return new Binary(bytes.AsSpan());
403398
}
404399

405400
private Text ReadTextAfterPrefix()

Bencodex/Types/Binary.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,24 @@ namespace Bencodex.Types
3030
private readonly int?[] _hashCode;
3131
private readonly ImmutableArray<byte>?[] _digest;
3232

33-
public Binary(ImmutableArray<byte> value)
33+
public Binary(ReadOnlySpan<byte> value)
3434
{
35-
_value = value;
35+
var builder = ImmutableArray.CreateBuilder<byte>(value.Length);
36+
foreach (byte b in value)
37+
{
38+
builder.Add(b);
39+
}
40+
41+
_value = builder.MoveToImmutable();
3642
_hashCode = new int?[1];
3743
_digest = new[] { (ImmutableArray<byte>?)null };
3844
}
3945

46+
public Binary(ImmutableArray<byte> value)
47+
: this(value.AsSpan())
48+
{
49+
}
50+
4051
public Binary(params byte[] value)
4152
: this(value is byte[] bytes
4253
? ImmutableArray.Create(bytes)
@@ -90,7 +101,7 @@ public Fingerprint Fingerprint
90101
public string Inspection => Inspect(true);
91102

92103
public static implicit operator Binary(ImmutableArray<byte> bytes) =>
93-
new Binary(bytes);
104+
new Binary(bytes.AsSpan());
94105

95106
public static implicit operator ImmutableArray<byte>(Binary binary) =>
96107
binary.ByteArray;
@@ -179,7 +190,7 @@ byte ParseNibble(char hex)
179190
bytes.Add((byte)(ParseNibble(upper) << 4 | ParseNibble(lower)));
180191
}
181192

182-
return new Binary(bytes.MoveToImmutable());
193+
return new Binary(bytes.MoveToImmutable().AsSpan());
183194
}
184195

185196
#if !NETSTANDARD2_0
@@ -225,8 +236,7 @@ public static Binary FromBase64(ReadOnlySpan<char> base64)
225236
public static Binary FromBase64(string base64)
226237
{
227238
byte[] bytes = Convert.FromBase64String(base64);
228-
ImmutableArray<byte> moved = Unsafe.As<byte[], ImmutableArray<byte>>(ref bytes);
229-
return new Binary(moved);
239+
return new Binary(bytes.AsSpan());
230240
}
231241

232242
bool IEquatable<ImmutableArray<byte>>.Equals(ImmutableArray<byte> other) =>
@@ -325,10 +335,10 @@ public byte[] ToByteArray()
325335
{
326336
if (ByteArray.IsDefaultOrEmpty)
327337
{
328-
return new byte[0];
338+
return Array.Empty<byte>();
329339
}
330340

331-
return ByteArray.ToBuilder().ToArray();
341+
return ByteArray.ToArray();
332342
}
333343

334344
/// <summary>

0 commit comments

Comments
 (0)