Commit 86949f20 authored by Marc Gravell's avatar Marc Gravell

hot damn, it compiles; this could be very good or very bad

parent 996b182f
......@@ -6,8 +6,9 @@ namespace StackExchange.Redis
{
internal readonly struct RawResult
{
public static readonly RawResult EmptyArray = new RawResult(new RawResult[0]);
public static readonly RawResult Nil = new RawResult();
internal static readonly RawResult NullMultiBulk = new RawResult((RawResult[])null);
internal static readonly RawResult EmptyMultiBulk = new RawResult(new RawResult[0]);
internal static readonly RawResult Nil = new RawResult();
private readonly ReadOnlySequence<byte> _payload;
......@@ -36,8 +37,9 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN
public RawResult(RawResult[] arr)
{
_type = ResultType.MultiBulk;
if (arr == null) _type |= NullResultTypeBit;
_payload = default;
_subArray = arr ?? throw new ArgumentNullException(nameof(arr));
_subArray = arr;
}
public bool HasValue => Type != ResultType.None;
......@@ -298,7 +300,7 @@ internal string[] GetItemsAsStrings()
internal RawResult[] GetItemsAsRawResults() => GetItems();
internal string GetString()
internal unsafe string GetString()
{
if (IsNull) return null;
if (_payload.IsEmpty) return "";
......@@ -306,15 +308,44 @@ internal string GetString()
if (_payload.IsSingleSegment)
{
var span = _payload.First.Span;
unsafe
fixed (byte* ptr = &span[0])
{
fixed (byte* ptr = &span[0])
return Encoding.UTF8.GetString(ptr, span.Length);
}
}
var decoder = Encoding.UTF8.GetDecoder();
int charCount = 0;
foreach(var segment in _payload)
{
var span = segment.Span;
if (span.IsEmpty) continue;
fixed(byte* bPtr = &span[0])
{
charCount += decoder.GetCharCount(bPtr, span.Length, false);
}
}
decoder.Reset();
string s = new string((char)0, charCount);
fixed (char* sPtr = s)
{
char* cPtr = sPtr;
foreach (var segment in _payload)
{
var span = segment.Span;
if (span.IsEmpty) continue;
fixed (byte* bPtr = &span[0])
{
return Encoding.UTF8.GetString(ptr, span.Length);
var written = decoder.GetChars(bPtr, span.Length, cPtr, charCount, false);
cPtr += written;
charCount -= written;
}
}
}
return Encoding.UTF8.GetString(blob, offset, count);
return s;
}
internal bool TryGetDouble(out double val)
......
......@@ -1233,7 +1233,7 @@ private static GeoRadiusResult Parse(GeoRadiusOptions options, RawResult item)
return new GeoRadiusResult(item.AsRedisValue(), null, null, null);
}
// If WITHCOORD, WITHDIST or WITHHASH options are specified, the command returns an array of arrays, where each sub-array represents a single item.
var arr = item.GetArrayOfRawResults();
var arr = item.GetItems();
int index = 0;
// the first item in the sub-array is always the name of the returned item.
......@@ -1251,7 +1251,7 @@ private static GeoRadiusResult Parse(GeoRadiusOptions options, RawResult item)
if ((options & GeoRadiusOptions.WithGeoHash) != 0) { hash = (long?)arr[index++].AsRedisValue(); }
if ((options & GeoRadiusOptions.WithCoordinates) != 0)
{
var coords = arr[index++].GetArrayOfRawResults();
var coords = arr[index++].GetItems();
double longitude = (double)coords[0].AsRedisValue(), latitude = (double)coords[1].AsRedisValue();
position = new GeoPosition(longitude, latitude);
}
......@@ -1451,7 +1451,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
switch (result.Type)
{
case ResultType.MultiBulk:
var arrayOfArrays = result.GetArrayOfRawResults();
var arrayOfArrays = result.GetItems();
var returnArray = new KeyValuePair<string, string>[arrayOfArrays.Length][];
......
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