|
@@ -37,6 +37,10 @@ using System.IO;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections;
|
|
|
using System.Linq;
|
|
|
+using System.Buffers;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using System.Threading;
|
|
|
+using System.Runtime.CompilerServices;
|
|
|
#if !NET35
|
|
|
using System.Threading.Tasks;
|
|
|
#endif
|
|
@@ -218,6 +222,25 @@ namespace Google.Protobuf
|
|
|
CollectionAssert.AreEqual(data, ms.ToArray());
|
|
|
}
|
|
|
|
|
|
+ [Test]
|
|
|
+ public void WriteToStream_Stackalloc()
|
|
|
+ {
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes("Hello world");
|
|
|
+ Span<byte> s = stackalloc byte[data.Length];
|
|
|
+ data.CopyTo(s);
|
|
|
+
|
|
|
+ MemoryStream ms = new MemoryStream();
|
|
|
+
|
|
|
+ using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
|
|
|
+ {
|
|
|
+ ByteString bs = ByteString.AttachBytes(manager.Memory);
|
|
|
+
|
|
|
+ bs.WriteTo(ms);
|
|
|
+ }
|
|
|
+
|
|
|
+ CollectionAssert.AreEqual(data, ms.ToArray());
|
|
|
+ }
|
|
|
+
|
|
|
[Test]
|
|
|
public void ToStringUtf8()
|
|
|
{
|
|
@@ -232,6 +255,21 @@ namespace Google.Protobuf
|
|
|
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
|
|
|
}
|
|
|
|
|
|
+ [Test]
|
|
|
+ public void ToString_Stackalloc()
|
|
|
+ {
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes("Hello world");
|
|
|
+ Span<byte> s = stackalloc byte[data.Length];
|
|
|
+ data.CopyTo(s);
|
|
|
+
|
|
|
+ using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
|
|
|
+ {
|
|
|
+ ByteString bs = ByteString.AttachBytes(manager.Memory);
|
|
|
+
|
|
|
+ Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
[Test]
|
|
|
public void FromBase64_WithText()
|
|
|
{
|
|
@@ -248,6 +286,29 @@ namespace Google.Protobuf
|
|
|
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
|
|
|
}
|
|
|
|
|
|
+ [Test]
|
|
|
+ public void ToBase64_Array()
|
|
|
+ {
|
|
|
+ ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world"));
|
|
|
+
|
|
|
+ Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void ToBase64_Stackalloc()
|
|
|
+ {
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes("Hello world");
|
|
|
+ Span<byte> s = stackalloc byte[data.Length];
|
|
|
+ data.CopyTo(s);
|
|
|
+
|
|
|
+ using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
|
|
|
+ {
|
|
|
+ ByteString bs = ByteString.AttachBytes(manager.Memory);
|
|
|
+
|
|
|
+ Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
[Test]
|
|
|
public void FromStream_Seekable()
|
|
|
{
|
|
@@ -325,5 +386,38 @@ namespace Google.Protobuf
|
|
|
var copied = byteString.Memory.ToArray();
|
|
|
CollectionAssert.AreEqual(byteString, copied);
|
|
|
}
|
|
|
+
|
|
|
+ // Create Memory<byte> from non-array source.
|
|
|
+ // Use by ByteString tests that have optimized path for array backed Memory<byte>.
|
|
|
+ private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged
|
|
|
+ {
|
|
|
+ private readonly T* _pointer;
|
|
|
+ private readonly int _length;
|
|
|
+
|
|
|
+ public UnmanagedMemoryManager(Span<T> span)
|
|
|
+ {
|
|
|
+ fixed (T* ptr = &MemoryMarshal.GetReference(span))
|
|
|
+ {
|
|
|
+ _pointer = ptr;
|
|
|
+ _length = span.Length;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public override Span<T> GetSpan() => new Span<T>(_pointer, _length);
|
|
|
+
|
|
|
+ public override MemoryHandle Pin(int elementIndex = 0)
|
|
|
+ {
|
|
|
+ if (elementIndex < 0 || elementIndex >= _length)
|
|
|
+ {
|
|
|
+ throw new ArgumentOutOfRangeException(nameof(elementIndex));
|
|
|
+ }
|
|
|
+
|
|
|
+ return new MemoryHandle(_pointer + elementIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Unpin() { }
|
|
|
+
|
|
|
+ protected override void Dispose(bool disposing) { }
|
|
|
+ }
|
|
|
}
|
|
|
}
|