diff --git a/src/StackExchange.Redis/RawResult.cs b/src/StackExchange.Redis/RawResult.cs index 025c938ed..305bf24af 100644 --- a/src/StackExchange.Redis/RawResult.cs +++ b/src/StackExchange.Redis/RawResult.cs @@ -385,14 +385,18 @@ private static GeoPosition AsGeoPosition(in Sequence coords) internal GeoPosition?[]? GetItemsAsGeoPositionArray() => this.ToArray((in RawResult item) => item.IsNull ? default : AsGeoPosition(item.GetItems())); - internal unsafe string? GetString() + internal unsafe string? GetString() => GetString(out _); + internal unsafe string? GetString(out ReadOnlySpan verbatimPrefix) { + verbatimPrefix = default; if (IsNull) return null; if (Payload.IsEmpty) return ""; + string s; if (Payload.IsSingleSegment) { - return Format.GetString(Payload.First.Span); + s = Format.GetString(Payload.First.Span); + return Resp3Type == ResultType.VerbatimString ? GetVerbatimString(s, out verbatimPrefix) : s; } var decoder = Encoding.UTF8.GetDecoder(); int charCount = 0; @@ -409,7 +413,7 @@ private static GeoPosition AsGeoPosition(in Sequence coords) decoder.Reset(); - string s = new string((char)0, charCount); + s = new string((char)0, charCount); fixed (char* sPtr = s) { char* cPtr = sPtr; @@ -426,26 +430,25 @@ private static GeoPosition AsGeoPosition(in Sequence coords) } } } - return s; - } + return Resp3Type == ResultType.VerbatimString ? GetVerbatimString(s, out verbatimPrefix) : s; - internal string? GetVerbatimString(out ReadOnlySpan type) - { - // the first three bytes provide information about the format of the following string, which - // can be txt for plain text, or mkd for markdown. The fourth byte is always `:` - // Then the real string follows. - var value = GetString(); - if (value is not null && Resp3Type == ResultType.VerbatimString - && value.Length >= 4 && value[3] == ':') - { - type = value.AsSpan().Slice(0, 3); - value = value.Substring(4); - } - else + static string? GetVerbatimString(string? value, out ReadOnlySpan type) { - type = default; + // the first three bytes provide information about the format of the following string, which + // can be txt for plain text, or mkd for markdown. The fourth byte is always `:` + // Then the real string follows. + if (value is not null + && value.Length >= 4 && value[3] == ':') + { + type = value.AsSpan().Slice(0, 3); + value = value.Substring(4); + } + else + { + type = default; + } + return value; } - return value; } internal bool TryGetDouble(out double val) diff --git a/src/StackExchange.Redis/ResultProcessor.cs b/src/StackExchange.Redis/ResultProcessor.cs index 95aa186d8..c4d2311e5 100644 --- a/src/StackExchange.Redis/ResultProcessor.cs +++ b/src/StackExchange.Redis/ResultProcessor.cs @@ -1278,7 +1278,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes { string category = Normalize(null); var list = new List>>(); - var raw = result.GetVerbatimString(out _); + var raw = result.GetString(); if (raw is not null) { using var reader = new StringReader(raw);