Commit 3d057200 authored by Marc Gravell's avatar Marc Gravell

do a much better job of ripping the inner buffer from MemoryStream

parent c767a3f7
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO; using System.IO;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
...@@ -806,7 +807,7 @@ public static RedisValue CreateFrom(MemoryStream stream) ...@@ -806,7 +807,7 @@ public static RedisValue CreateFrom(MemoryStream stream)
{ {
if (stream == null) return Null; if (stream == null) return Null;
if (stream.Length == 0) return Array.Empty<byte>(); if (stream.Length == 0) return Array.Empty<byte>();
if(stream.TryGetBuffer(out var segment)) if(stream.TryGetBuffer(out var segment) || ReflectionTryGetBuffer(stream, out segment))
{ {
return new Memory<byte>(segment.Array, segment.Offset, segment.Count); return new Memory<byte>(segment.Array, segment.Offset, segment.Count);
} }
...@@ -817,6 +818,27 @@ public static RedisValue CreateFrom(MemoryStream stream) ...@@ -817,6 +818,27 @@ public static RedisValue CreateFrom(MemoryStream stream)
} }
} }
private static readonly FieldInfo
s_origin = typeof(MemoryStream).GetField("_origin", BindingFlags.NonPublic | BindingFlags.Instance),
s_buffer = typeof(MemoryStream).GetField("_buffer", BindingFlags.NonPublic | BindingFlags.Instance);
private static bool ReflectionTryGetBuffer(MemoryStream ms, out ArraySegment<byte> buffer)
{
if (s_origin != null && s_buffer != null)
{
try
{
int offset = (int)s_origin.GetValue(ms);
byte[] arr = (byte[])s_buffer.GetValue(ms);
buffer = new ArraySegment<byte>(arr, offset, checked((int)ms.Length));
return true;
}
catch { }
}
buffer = default;
return false;
}
/// <summary> /// <summary>
/// Indicates whether the current value has the supplied value as a prefix. /// Indicates whether the current value has the supplied value as a prefix.
/// </summary> /// </summary>
......
using System.Linq; using System.IO;
using System.Text; using System.Text;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
...@@ -30,5 +30,22 @@ public void NullValueChecks() ...@@ -30,5 +30,22 @@ public void NullValueChecks()
Assert.False(emptyArr.HasValue); Assert.False(emptyArr.HasValue);
Assert.True(emptyArr.IsNullOrEmpty); Assert.True(emptyArr.IsNullOrEmpty);
} }
[Fact]
public void FromStream()
{
var arr = Encoding.UTF8.GetBytes("hello world");
var ms = new MemoryStream(arr);
var val = RedisValue.CreateFrom(ms);
Assert.Equal("hello world", (string)val);
ms = new MemoryStream(arr, 1, 6, false, false);
val = RedisValue.CreateFrom(ms);
Assert.Equal("ello w", (string)val);
ms = new MemoryStream(arr, 2, 6, false, true);
val = RedisValue.CreateFrom(ms);
Assert.Equal("llo wo", (string)val);
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment