From dc6120af4321e0fc8d2fe03cbd7a58144928acc9 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Wed, 30 Nov 2022 20:15:19 +0000 Subject: [PATCH] Reduce cyclomatic complexity of Coordinates.Serialization Again just... all of it --- VpSharp/src/Coordinates.Serialization.cs | 213 +++++++++++++++-------- 1 file changed, 145 insertions(+), 68 deletions(-) diff --git a/VpSharp/src/Coordinates.Serialization.cs b/VpSharp/src/Coordinates.Serialization.cs index a914ee7..0f0db35 100644 --- a/VpSharp/src/Coordinates.Serialization.cs +++ b/VpSharp/src/Coordinates.Serialization.cs @@ -99,7 +99,7 @@ public readonly partial struct Coordinates public static Coordinates Deserialize(ReadOnlySpan value) { - using Utf8ValueStringBuilder builder = ZString.CreateUtf8StringBuilder(); + Utf8ValueStringBuilder builder = ZString.CreateUtf8StringBuilder(); string? world = null; var isRelative = false; double x = 0.0, y = 0.0, z = 0.0, yaw = 0.0; @@ -119,7 +119,7 @@ public readonly partial struct Coordinates builder.Append(current); } - ProcessBuffer(); + ProcessBuffer(ref builder, ref world, word, ref isRelative, ref z, ref x, ref y, ref yaw); word++; } @@ -131,73 +131,8 @@ public readonly partial struct Coordinates } } + builder.Dispose(); return new Coordinates(world, x, y, z, yaw, isRelative); - - void ProcessBuffer() - { - ReadOnlySpan bytes = builder.AsSpan(); - Span chars = stackalloc char[bytes.Length]; - Encoding.UTF8.GetChars(bytes, chars); - bool hasWorld = !string.IsNullOrWhiteSpace(world); - - if (word == 0 && !IsUnitString(bytes)) - { - world = chars.ToString().AsNullIfWhiteSpace(); - } - else if (IsRelativeUnit(bytes)) - { - isRelative = true; - - switch (word) - { - case 0 when !hasWorld: - case 1 when hasWorld: - double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out z); - break; - case 1 when !hasWorld: - case 2 when hasWorld: - double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out x); - break; - case 2 when !hasWorld: - case 3 when hasWorld: - double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out y); - break; - case 3 when !hasWorld: - case 4 when hasWorld: - double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out yaw); - break; - } - } - else - { - if (((!hasWorld && word == 1) || (hasWorld && word == 2)) && chars[^1] is 'x' or 'X' or 'w' or 'W') - { - _ = double.TryParse(chars[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out x); - } - else if (((!hasWorld && word == 0) || (hasWorld && word == 1)) && chars[^1] is 'z' or 'Z' or 'n' or 'N') - { - _ = double.TryParse(chars[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out z); - } - else if (((!hasWorld && word == 1) || (hasWorld && word == 2)) && chars[^1] is 'e' or 'E') - { - _ = double.TryParse(chars[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out x); - x = -x; - } - else if (((!hasWorld && word == 0) || (hasWorld && word == 1)) && chars[^1] is 's' or 'S') - { - _ = double.TryParse(chars[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out z); - z = -z; - } - else if (((!hasWorld && word == 2) || (hasWorld && word == 3)) && chars[^1] is 'a' or 'A') - { - _ = double.TryParse(chars[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out y); - } - else if (((!hasWorld && word == 3) || (hasWorld && word == 4)) && double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out double temp)) - { - yaw = temp; - } - } - } } /// @@ -300,5 +235,147 @@ public readonly partial struct Coordinates // thicc char span return IsRelativeUnit(chars) || IsAbsoluteUnit(chars); } + + + private static bool IsAtWordIndex(int expected, int actual, bool hasWorld) + { + return hasWorld ? actual == expected + 1 : actual == expected; + } + + private static void ProcessBuffer( + ref Utf8ValueStringBuilder builder, + ref string? world, + int word, + ref bool isRelative, + ref double z, + ref double x, + ref double y, + ref double yaw + ) + { + ReadOnlySpan bytes = builder.AsSpan(); + Span chars = stackalloc char[bytes.Length]; + Encoding.UTF8.GetChars(bytes, chars); + bool hasWorld = !string.IsNullOrWhiteSpace(world); + + if (word == 0 && !IsUnitString(bytes)) + { + world = chars.ToString().AsNullIfWhiteSpace(); + } + else if (IsRelativeUnit(bytes)) + { + isRelative = true; + ProcessRelativeUnit(word, ref z, ref x, ref y, ref yaw, hasWorld, chars); + } + else + { + ProcessAbsoluteUnit(word, ref z, ref x, ref y, ref yaw, hasWorld, chars); + } + } + + private static void ProcessAbsoluteUnit(int word, ref double z, ref double x, ref double y, ref double yaw, bool hasWorld, + Span chars) + { + const StringComparison comparison = StringComparison.OrdinalIgnoreCase; + char lastChar = chars[^1]; + + bool isAt0 = IsAtWordIndex(0, word, hasWorld); + bool isAt1 = IsAtWordIndex(1, word, hasWorld); + bool isAt2 = IsAtWordIndex(2, word, hasWorld); + bool isAt3 = IsAtWordIndex(3, word, hasWorld); + + Span charsExceptLast = chars[..^1]; + double.TryParse(charsExceptLast, NumberStyles.Float, CultureInfo.InvariantCulture, out double value); + + if (isAt0) + { + if ("nzNZ".AsSpan().Contains(lastChar)) + { + z = value; + } + else if ("sS".AsSpan().Contains(lastChar)) + { + z = -value; + } + } + else if (isAt1) + { + if ("xwXW".AsSpan().Contains(lastChar)) + { + x = value; + } + else if ("eE".AsSpan().Contains(lastChar)) + { + x = -value; + } + } + else if (isAt2 && "aA".AsSpan().Contains(lastChar)) + { + y = value; + } + else if (isAt3 && double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) + { + yaw = value; + } + + /* + if (isAt1 && "XW".Contains(lastChar, comparison)) + { + x = value; + } + else if (isAt0 && "ZN".Contains(lastChar, comparison)) + { + z = value; + } + else if (isAt1 && "E".Contains(lastChar, comparison)) + { + x = -value; + } + else if (isAt0 && "S".Contains(lastChar, comparison)) + { + z = -value; + } + else if (isAt2 && "A".Contains(lastChar, comparison)) + { + y = value; + } + else if (isAt3 && double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) + { + yaw = value; + }*/ + } + + private static void ProcessRelativeUnit( + int word, + ref double z, + ref double x, + ref double y, + ref double yaw, + bool hasWorld, + Span chars + ) + { + if (!double.TryParse(chars, NumberStyles.Float, CultureInfo.InvariantCulture, out double value)) + { + return; + } + + if (IsAtWordIndex(0, word, hasWorld)) + { + z = value; + } + else if (IsAtWordIndex(1, word, hasWorld)) + { + x = value; + } + else if (IsAtWordIndex(2, word, hasWorld)) + { + y = value; + } + else if (IsAtWordIndex(3, word, hasWorld)) + { + yaw = value; + } + } } }