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 ...@@ -6,8 +6,9 @@ namespace StackExchange.Redis
{ {
internal readonly struct RawResult internal readonly struct RawResult
{ {
public static readonly RawResult EmptyArray = new RawResult(new RawResult[0]); internal static readonly RawResult NullMultiBulk = new RawResult((RawResult[])null);
public static readonly RawResult Nil = new RawResult(); internal static readonly RawResult EmptyMultiBulk = new RawResult(new RawResult[0]);
internal static readonly RawResult Nil = new RawResult();
private readonly ReadOnlySequence<byte> _payload; private readonly ReadOnlySequence<byte> _payload;
...@@ -36,8 +37,9 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN ...@@ -36,8 +37,9 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN
public RawResult(RawResult[] arr) public RawResult(RawResult[] arr)
{ {
_type = ResultType.MultiBulk; _type = ResultType.MultiBulk;
if (arr == null) _type |= NullResultTypeBit;
_payload = default; _payload = default;
_subArray = arr ?? throw new ArgumentNullException(nameof(arr)); _subArray = arr;
} }
public bool HasValue => Type != ResultType.None; public bool HasValue => Type != ResultType.None;
...@@ -298,7 +300,7 @@ internal string[] GetItemsAsStrings() ...@@ -298,7 +300,7 @@ internal string[] GetItemsAsStrings()
internal RawResult[] GetItemsAsRawResults() => GetItems(); internal RawResult[] GetItemsAsRawResults() => GetItems();
internal string GetString() internal unsafe string GetString()
{ {
if (IsNull) return null; if (IsNull) return null;
if (_payload.IsEmpty) return ""; if (_payload.IsEmpty) return "";
...@@ -306,15 +308,44 @@ internal string GetString() ...@@ -306,15 +308,44 @@ internal string GetString()
if (_payload.IsSingleSegment) if (_payload.IsSingleSegment)
{ {
var span = _payload.First.Span; 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) internal bool TryGetDouble(out double val)
......
...@@ -1233,7 +1233,7 @@ private static GeoRadiusResult Parse(GeoRadiusOptions options, RawResult item) ...@@ -1233,7 +1233,7 @@ private static GeoRadiusResult Parse(GeoRadiusOptions options, RawResult item)
return new GeoRadiusResult(item.AsRedisValue(), null, null, null); 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. // 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; int index = 0;
// the first item in the sub-array is always the name of the returned item. // 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) ...@@ -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.WithGeoHash) != 0) { hash = (long?)arr[index++].AsRedisValue(); }
if ((options & GeoRadiusOptions.WithCoordinates) != 0) 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(); double longitude = (double)coords[0].AsRedisValue(), latitude = (double)coords[1].AsRedisValue();
position = new GeoPosition(longitude, latitude); position = new GeoPosition(longitude, latitude);
} }
...@@ -1451,7 +1451,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes ...@@ -1451,7 +1451,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
switch (result.Type) switch (result.Type)
{ {
case ResultType.MultiBulk: case ResultType.MultiBulk:
var arrayOfArrays = result.GetArrayOfRawResults(); var arrayOfArrays = result.GetItems();
var returnArray = new KeyValuePair<string, string>[arrayOfArrays.Length][]; 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