Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
cddba70
:zap: optimize Encoder by caching sequence materialization and reduci…
techouse Aug 17, 2025
1b12570
:zap: improve Encoder performance by reducing allocations and optimiz…
techouse Aug 17, 2025
80db892
:zap: optimize dictionary traversal by replacing nested ifs with guar…
techouse Aug 17, 2025
3c6b006
:zap: optimize Decoder by reducing allocations and improving paramete…
techouse Aug 17, 2025
9918898
:zap: optimize Utils by reducing allocations and improving collection…
techouse Aug 17, 2025
647b635
:zap: optimize Qs by reducing allocations and improving collection ha…
techouse Aug 17, 2025
c4f4034
:art: reformat switch statement for improved readability in Utils
techouse Aug 17, 2025
fdbb6ab
:art: reformat conditional and loop blocks for improved readability i…
techouse Aug 17, 2025
172f9ae
:zap: optimize Decoder by reducing allocations and improving string h…
techouse Aug 17, 2025
04ee921
:zap: optimize Encoder by reducing allocations and improving collecti…
techouse Aug 17, 2025
83ebbb5
:zap: optimize SideChannelFrame by reducing allocations and improving…
techouse Aug 17, 2025
4a62dac
:zap: optimize HexTable by generating percent-encoded strings program…
techouse Aug 17, 2025
d559879
:bulb: add documentation to ConvertNestedDictionary and ReferenceEqua…
techouse Aug 17, 2025
0f254a6
:zap: optimize HexTable by using string.Create on supported framework…
techouse Aug 17, 2025
c6db734
:zap: optimize Decoder by delaying StringBuilder allocation in JoinAs…
techouse Aug 17, 2025
ade9e0b
:zap: optimize ConvertNestedDictionary by reducing type checks and im…
techouse Aug 17, 2025
754292f
:white_check_mark: add unit test for ToStringKeyDeepNonRecursive to v…
techouse Aug 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions QsNet.Tests/UtilsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,4 +1532,40 @@ public void Merge_MapsAndArrays()
.Should()
.BeEquivalentTo(new Dictionary<string, object?> { { "foo", "baz" }, { "bar", true } });
}

[Fact]
public void ToStringKeyDeepNonRecursive_Converts_Nested_Lists_And_Dicts()
{
// root: { "x": [ {"a":1}, [ {"b":2}, {"c":3} ], 4 ] }
var dict1 = new Dictionary<object, object?> { ["a"] = 1 };
var dict2 = new Dictionary<object, object?> { ["b"] = 2 };
var dict3 = new Dictionary<object, object?> { ["c"] = 3 };

var innerList = new List<object?> { dict2, dict3 };
var topList = new List<object?> { dict1, innerList, 4 };

var root = new Dictionary<object, object?> { ["x"] = topList };

var result = Utils.ToStringKeyDeepNonRecursive(root);

result.Should().ContainKey("x");
var outTopList = result["x"] as List<object?>;
outTopList.Should().NotBeNull();

var outDict1 = outTopList![0] as Dictionary<string, object?>;
outDict1.Should().NotBeNull();
outDict1!["a"].Should().Be(1);

var outInnerList = outTopList[1] as List<object?>;
outInnerList.Should().NotBeNull();

var outDict2 = outInnerList![0] as Dictionary<string, object?>;
var outDict3 = outInnerList[1] as Dictionary<string, object?>;
outDict2.Should().NotBeNull();
outDict3.Should().NotBeNull();
outDict2!["b"].Should().Be(2);
outDict3!["c"].Should().Be(3);

outTopList[2].Should().Be(4);
}
}
289 changes: 30 additions & 259 deletions QsNet/Constants/HexTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,263 +8,34 @@ public static class HexTable
/// <summary>
/// Hex table containing percent-encoded strings for all 256 byte values
/// </summary>
internal static readonly string[] Table =
[
"%00",
"%01",
"%02",
"%03",
"%04",
"%05",
"%06",
"%07",
"%08",
"%09",
"%0A",
"%0B",
"%0C",
"%0D",
"%0E",
"%0F",
"%10",
"%11",
"%12",
"%13",
"%14",
"%15",
"%16",
"%17",
"%18",
"%19",
"%1A",
"%1B",
"%1C",
"%1D",
"%1E",
"%1F",
"%20",
"%21",
"%22",
"%23",
"%24",
"%25",
"%26",
"%27",
"%28",
"%29",
"%2A",
"%2B",
"%2C",
"%2D",
"%2E",
"%2F",
"%30",
"%31",
"%32",
"%33",
"%34",
"%35",
"%36",
"%37",
"%38",
"%39",
"%3A",
"%3B",
"%3C",
"%3D",
"%3E",
"%3F",
"%40",
"%41",
"%42",
"%43",
"%44",
"%45",
"%46",
"%47",
"%48",
"%49",
"%4A",
"%4B",
"%4C",
"%4D",
"%4E",
"%4F",
"%50",
"%51",
"%52",
"%53",
"%54",
"%55",
"%56",
"%57",
"%58",
"%59",
"%5A",
"%5B",
"%5C",
"%5D",
"%5E",
"%5F",
"%60",
"%61",
"%62",
"%63",
"%64",
"%65",
"%66",
"%67",
"%68",
"%69",
"%6A",
"%6B",
"%6C",
"%6D",
"%6E",
"%6F",
"%70",
"%71",
"%72",
"%73",
"%74",
"%75",
"%76",
"%77",
"%78",
"%79",
"%7A",
"%7B",
"%7C",
"%7D",
"%7E",
"%7F",
"%80",
"%81",
"%82",
"%83",
"%84",
"%85",
"%86",
"%87",
"%88",
"%89",
"%8A",
"%8B",
"%8C",
"%8D",
"%8E",
"%8F",
"%90",
"%91",
"%92",
"%93",
"%94",
"%95",
"%96",
"%97",
"%98",
"%99",
"%9A",
"%9B",
"%9C",
"%9D",
"%9E",
"%9F",
"%A0",
"%A1",
"%A2",
"%A3",
"%A4",
"%A5",
"%A6",
"%A7",
"%A8",
"%A9",
"%AA",
"%AB",
"%AC",
"%AD",
"%AE",
"%AF",
"%B0",
"%B1",
"%B2",
"%B3",
"%B4",
"%B5",
"%B6",
"%B7",
"%B8",
"%B9",
"%BA",
"%BB",
"%BC",
"%BD",
"%BE",
"%BF",
"%C0",
"%C1",
"%C2",
"%C3",
"%C4",
"%C5",
"%C6",
"%C7",
"%C8",
"%C9",
"%CA",
"%CB",
"%CC",
"%CD",
"%CE",
"%CF",
"%D0",
"%D1",
"%D2",
"%D3",
"%D4",
"%D5",
"%D6",
"%D7",
"%D8",
"%D9",
"%DA",
"%DB",
"%DC",
"%DD",
"%DE",
"%DF",
"%E0",
"%E1",
"%E2",
"%E3",
"%E4",
"%E5",
"%E6",
"%E7",
"%E8",
"%E9",
"%EA",
"%EB",
"%EC",
"%ED",
"%EE",
"%EF",
"%F0",
"%F1",
"%F2",
"%F3",
"%F4",
"%F5",
"%F6",
"%F7",
"%F8",
"%F9",
"%FA",
"%FB",
"%FC",
"%FD",
"%FE",
"%FF"
];
internal static readonly string[] Table = Create();

private static string[] Create()
{
var arr = new string[256];
for (var i = 0; i < 256; i++)
{
#if NETSTANDARD2_0
var chars = new char[3];
chars[0] = '%';
chars[1] = GetHexChar((i >> 4) & 0xF);
chars[2] = GetHexChar(i & 0xF);
arr[i] = new string(chars);
#else
arr[i] = string.Create(3, i, static (span, val) =>
{
span[0] = '%';
span[1] = GetHexChar((val >> 4) & 0xF);
span[2] = GetHexChar(val & 0xF);
});
#endif
}

return arr;
}

private static char GetHexChar(int n)
{
return (char)(n < 10 ? '0' + n : 'A' + (n - 10));
}
}
Loading
Loading