|
|
|
@ -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) { } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |