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.Buffers;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
......@@ -806,7 +807,7 @@ public static RedisValue CreateFrom(MemoryStream stream)
{
if (stream == null) return Null;
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);
}
......@@ -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>
/// Indicates whether the current value has the supplied value as a prefix.
/// </summary>
......
using System.Linq;
using System.IO;
using System.Text;
using Xunit;
using Xunit.Abstractions;
......@@ -30,5 +30,22 @@ public void NullValueChecks()
Assert.False(emptyArr.HasValue);
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