Skip to content

Commit a373657

Browse files
committed
Add poly fills for ReadOnlySpan<T> methods on Encoding/Stream
1 parent 015935a commit a373657

File tree

7 files changed

+51
-49
lines changed

7 files changed

+51
-49
lines changed

BencodeNET.Tests/Objects/BDictionaryTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class BDictionaryTests
1717
public void Add_NullStringValue_ResultsInEmptyBString()
1818
{
1919
var dict = new BDictionary {{"key", (string) null}};
20-
dict.Get<BString>("key").Value.Should().BeEmpty();
20+
dict.Get<BString>("key").Value.ToArray().Should().BeEmpty();
2121
}
2222

2323
[Fact]

BencodeNET.Tests/Objects/BStringTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ public class BStringTests
1414
public void ConstructorEmpty_ResultsInEmptyValue()
1515
{
1616
var bstring = new BString();
17-
bstring.Value.Should().BeEmpty();
17+
bstring.Value.ToArray().Should().BeEmpty();
1818
}
1919

2020
[Fact]
2121
public void ConstructorWithNullValue_ResultsInEmptyValue()
2222
{
2323
var bstring = new BString((string)null);
24-
bstring.Value.Should().BeEmpty();
24+
bstring.Value.ToArray().Should().BeEmpty();
2525
}
2626

2727
#region Equals

BencodeNET/BencodeNET.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;netcoreapp2.1;netcoreapp3.0</TargetFrameworks>
55
<LangVersion>7.3</LangVersion>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
67
<GenerateDocumentationFile>True</GenerateDocumentationFile>
78
<CodeAnalysisRuleSet>BencodeNET.ruleset</CodeAnalysisRuleSet>
89
</PropertyGroup>

BencodeNET/Objects/BNumber.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,8 @@ protected override void EncodeObject(PipeWriter writer)
6464
buffer[0] = (byte) 'i';
6565
buffer = buffer.Slice(1);
6666

67-
#if NETCOREAPP
6867
Encoding.ASCII.GetBytes(Value.ToString().AsSpan(), buffer);
69-
#else
70-
var bytes = Encoding.ASCII.GetBytes(Value.ToString());
71-
bytes.CopyTo(buffer);
72-
#endif
68+
7369
buffer[buffer.Length - 1] = (byte) 'e';
7470

7571
writer.Advance(size);
@@ -135,9 +131,7 @@ public static implicit operator bool(BNumber bint)
135131

136132
public static bool operator ==(BNumber bnumber, BNumber other)
137133
{
138-
if (ReferenceEquals(bnumber, null) && ReferenceEquals(other, null)) return true;
139-
if (ReferenceEquals(bnumber, null) || ReferenceEquals(other, null)) return false;
140-
return bnumber.Value == other.Value;
134+
return bnumber?.Value == other?.Value;
141135
}
142136

143137
public static bool operator !=(BNumber bnumber, BNumber other) => !(bnumber == other);

BencodeNET/Objects/BObjectExtensions.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System.Buffers;
1+
using System;
2+
using System.Buffers;
23
using System.IO;
34
using System.Text;
45

5-
#if NETCOREAPP
6-
using System;
7-
#endif
8-
96
namespace BencodeNET.Objects
107
{
118
/// <summary>
@@ -41,11 +38,7 @@ public static string EncodeAsString(this IBObject bobject, Encoding encoding)
4138
using (var stream = new MemoryStream(buffer))
4239
{
4340
bobject.EncodeTo(stream);
44-
#if NETCOREAPP
4541
return encoding.GetString(buffer.AsSpan().Slice(0, size));
46-
#else
47-
return encoding.GetString(buffer, 0, size);
48-
#endif
4942
}
5043
}
5144
finally { ArrayPool<byte>.Shared.Return(buffer); }

BencodeNET/PolyFillExtensions.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Buffers;
3+
using System.IO;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
7+
namespace BencodeNET
8+
{
9+
#if !NETCOREAPP3_0
10+
internal static class PolyFillExtensions
11+
{
12+
public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan<char> chars, Span<byte> bytes)
13+
{
14+
fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
15+
fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
16+
{
17+
return encoding.GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length);
18+
}
19+
}
20+
21+
public static unsafe string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
22+
{
23+
fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
24+
{
25+
return encoding.GetString(bytesPtr, bytes.Length);
26+
}
27+
}
28+
29+
public static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
30+
{
31+
var array = ArrayPool<byte>.Shared.Rent(buffer.Length);
32+
try
33+
{
34+
buffer.CopyTo(array);
35+
stream.Write(array, 0, buffer.Length);
36+
}
37+
finally { ArrayPool<byte>.Shared.Return(array); }
38+
}
39+
}
40+
#endif
41+
}

BencodeNET/UtilityExtensions.cs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.IO.Pipelines;
55
using System.Linq;
66
using System.Text;
77

8-
#if !NETCOREAPP
9-
using System.Buffers;
10-
#endif
11-
128
namespace BencodeNET
139
{
1410
internal static class UtilityExtensions
@@ -105,46 +101,23 @@ public static bool TrySetLength(this Stream stream, long length)
105101

106102
public static void Write(this Stream stream, int number)
107103
{
108-
#if NETCOREAPP
109104
Span<byte> buffer = stackalloc byte[11];
110105
var bytesRead = Encoding.ASCII.GetBytes(number.ToString().AsSpan(), buffer);
111106
stream.Write(buffer.Slice(0, bytesRead));
112-
#else
113-
var str = number.ToString();
114-
var buffer = ArrayPool<byte>.Shared.Rent(str.Length);
115-
var count = Encoding.ASCII.GetBytes(str, 0, str.Length, buffer, 0);
116-
stream.Write(buffer, 0, count);
117-
ArrayPool<byte>.Shared.Return(buffer);
118-
#endif
119107
}
120108

121109
public static void Write(this Stream stream, long number)
122110
{
123-
#if NETCOREAPP
124111
Span<byte> buffer = stackalloc byte[20];
125112
var bytesRead = Encoding.ASCII.GetBytes(number.ToString().AsSpan(), buffer);
126113
stream.Write(buffer.Slice(0, bytesRead));
127-
#else
128-
var str = number.ToString();
129-
var buffer = ArrayPool<byte>.Shared.Rent(str.Length);
130-
var count = Encoding.ASCII.GetBytes(str, 0, str.Length, buffer, 0);
131-
stream.Write(buffer, 0, count);
132-
ArrayPool<byte>.Shared.Return(buffer);
133-
#endif
134114
}
135115

136116
public static void Write(this Stream stream, char c)
137117
{
138118
stream.WriteByte((byte) c);
139119
}
140120

141-
#if !NETCOREAPP
142-
public static void Write(this Stream stream, byte[] bytes)
143-
{
144-
stream.Write(bytes, 0, bytes.Length);
145-
}
146-
#endif
147-
148121
public static void WriteChar(this PipeWriter writer, char c)
149122
{
150123
writer.GetSpan(1)[0] = (byte) c;

0 commit comments

Comments
 (0)