From 643a95e0a903a2ca985814104d67c6dd87dd2d06 Mon Sep 17 00:00:00 2001 From: Pavel Vostretsov Date: Thu, 2 Apr 2020 23:45:03 +0500 Subject: [PATCH 1/4] fix Dictionary serialization for net core 3 --- .travis.yml | 2 ++ GroBuf.Tests/GroBuf.Tests.csproj | 2 +- .../SizeCounters/DictionarySizeCounterBuilder.cs | 14 ++++++++++++-- GroBuf/Writers/DictionaryWriterBuilder.cs | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e0a9384..87cefcd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,6 @@ script: - dotnet restore ./GroBuf.sln --verbosity m - dotnet build --configuration Release --framework netstandard2.0 ./GroBuf/GroBuf.csproj - dotnet build --configuration Release --framework netcoreapp2.1 ./GroBuf.Tests/GroBuf.Tests.csproj + - dotnet build --configuration Release --framework netcoreapp3.1 ./GroBuf.Tests/GroBuf.Tests.csproj - dotnet test --no-build --configuration Release --framework netcoreapp2.1 --filter TestCategory!=LongRunning ./GroBuf.Tests/GroBuf.Tests.csproj + - dotnet test --no-build --configuration Release --framework netcoreapp3.1 --filter TestCategory!=LongRunning ./GroBuf.Tests/GroBuf.Tests.csproj diff --git a/GroBuf.Tests/GroBuf.Tests.csproj b/GroBuf.Tests/GroBuf.Tests.csproj index 60dbaac..f36ac10 100644 --- a/GroBuf.Tests/GroBuf.Tests.csproj +++ b/GroBuf.Tests/GroBuf.Tests.csproj @@ -2,7 +2,7 @@ false - netcoreapp2.1;net45 + net45;netcoreapp2.1;netcoreapp3.1 diff --git a/GroBuf/SizeCounters/DictionarySizeCounterBuilder.cs b/GroBuf/SizeCounters/DictionarySizeCounterBuilder.cs index c3598c8..ff643e9 100644 --- a/GroBuf/SizeCounters/DictionarySizeCounterBuilder.cs +++ b/GroBuf/SizeCounters/DictionarySizeCounterBuilder.cs @@ -58,6 +58,8 @@ protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext contex context.LoadObj(); // stack: [size, obj] var entryType = Type.GetNestedType("Entry", BindingFlags.NonPublic).MakeGenericType(Type.GetGenericArguments()); + var hashCodeType = entryType.GetField("hashCode", BindingFlags.Public | BindingFlags.Instance).FieldType; + var isNetCore3 = hashCodeType == typeof(uint); var entries = il.DeclareLocal(entryType.MakeArrayType()); il.Ldfld(Type.GetPrivateInstanceField(PlatformHelpers.DictionaryEntriesFieldNames)); il.Stloc(entries); @@ -73,8 +75,16 @@ protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext contex il.Dup(); // stack: [size, &entries[i], &entries[i]] var entry = il.DeclareLocal(entryType.MakeByRefType()); il.Stloc(entry); // entry = &entries[i]; stack: [size, entry] - il.Ldfld(entryType.GetField("hashCode")); // stack: [size, entry.hashCode] - il.Ldc_I4(0); // stack: [size, entry.hashCode, 0] + if (!isNetCore3) + { + il.Ldfld(entryType.GetField("hashCode")); // stack: [entry.hashCode] + il.Ldc_I4(0); // stack: [entry.hashCode, 0] + } + else + { + il.Ldfld(entryType.GetField("next")); // stack: [entry.next] + il.Ldc_I4(-1); // stack: [entry.next, -1] + } var nextLabel = il.DefineLabel("next"); il.Blt(nextLabel, false); // if(entry.hashCode < 0) goto next; stack: [size] diff --git a/GroBuf/Writers/DictionaryWriterBuilder.cs b/GroBuf/Writers/DictionaryWriterBuilder.cs index b33b7df..cd664aa 100644 --- a/GroBuf/Writers/DictionaryWriterBuilder.cs +++ b/GroBuf/Writers/DictionaryWriterBuilder.cs @@ -70,6 +70,8 @@ protected override void WriteNotEmpty(WriterMethodBuilderContext context) context.LoadObj(); // stack: [obj] var entryType = Type.GetNestedType("Entry", BindingFlags.NonPublic).MakeGenericType(Type.GetGenericArguments()); + var hashCodeType = entryType.GetField("hashCode", BindingFlags.Public | BindingFlags.Instance).FieldType; + var isNetCore3 = hashCodeType == typeof(uint); var entries = il.DeclareLocal(entryType.MakeArrayType()); il.Ldfld(Type.GetPrivateInstanceField(PlatformHelpers.DictionaryEntriesFieldNames)); // stack: [obj.entries] il.Stloc(entries); // entries = obj.entries; stack: [] @@ -85,8 +87,16 @@ protected override void WriteNotEmpty(WriterMethodBuilderContext context) il.Dup(); // stack: [&entries[i], &entries[i]] var entry = il.DeclareLocal(entryType.MakeByRefType()); il.Stloc(entry); // entry = &entries[i]; stack: [entry] - il.Ldfld(entryType.GetField("hashCode")); // stack: [entry.hashCode] - il.Ldc_I4(0); // stack: [entry.hashCode, 0] + if (!isNetCore3) + { + il.Ldfld(entryType.GetField("hashCode")); // stack: [entry.hashCode] + il.Ldc_I4(0); // stack: [entry.hashCode, 0] + } + else + { + il.Ldfld(entryType.GetField("next")); // stack: [entry.next] + il.Ldc_I4(-1); // stack: [entry.next, -1] + } var nextLabel = il.DefineLabel("next"); il.Blt(nextLabel, false); // if(entry.hashCode < 0) goto next; stack: [] From e5c068528a83f15b27bf396acc8033a442553424 Mon Sep 17 00:00:00 2001 From: Pavel Vostretsov Date: Fri, 3 Apr 2020 12:25:39 +0500 Subject: [PATCH 2/4] Add compatibility test --- GroBuf.Tests/Files/dict0.buf | Bin 0 -> 4669 bytes GroBuf.Tests/Files/dict1.buf | Bin 0 -> 1614 bytes GroBuf.Tests/Files/dict2.buf | Bin 0 -> 4994 bytes GroBuf.Tests/Files/dict3.buf | Bin 0 -> 1939 bytes GroBuf.Tests/Files/dict4.buf | Bin 0 -> 5254 bytes GroBuf.Tests/GroBuf.Tests.csproj | 18 ++++++++++++++++ GroBuf.Tests/TestDictionary.cs | 34 +++++++++++++++++++++++++++++++ 7 files changed, 52 insertions(+) create mode 100644 GroBuf.Tests/Files/dict0.buf create mode 100644 GroBuf.Tests/Files/dict1.buf create mode 100644 GroBuf.Tests/Files/dict2.buf create mode 100644 GroBuf.Tests/Files/dict3.buf create mode 100644 GroBuf.Tests/Files/dict4.buf diff --git a/GroBuf.Tests/Files/dict0.buf b/GroBuf.Tests/Files/dict0.buf new file mode 100644 index 0000000000000000000000000000000000000000..86bd96cfce5cf601ccc90993550bf211314128f1 GIT binary patch literal 4669 zcmai%&5qMR5QJwDNSqKt95^i}#0e?>x8HyVLE^c%^Mst}&$Y9$d!n+UL`pnU(_LL% zJ$YU~mGZNc^5J8A+~T#AzN}>^Q@ozO#g9M!{Qmdr>-WFUU*gLXOW()GQnu2?($8<= z%e%KP+q-@H958)AnC+Y~l`(Da58F4lowM8R!@hlt$cWCIt_4dvecZPX5!LL2A7TNa zo^zk}?NdCtdFtlazQqaW?epvQ-f!Rb@@#4QvTvs%iw}N{1#{4MKAm6th-!NA4?tlt=zhYieKftoc^}X^$dOUIRe( zw^)(^q`oDRSv`f*p2EEXH3I2RiCFpear%0wK?SG^giH%ShRXv0X%K;Jo&y#>ia;vl z86r0%R-tARrNc2|qmTxG8o+Y~kP-Pb~agC>#iAeztI41*0iBkY{@zem&vVAPd08*m-z@`9!TSSooq(n$WsV0Isazri} zpt|7@@HPU-I!*%h0>8>oh|c-}GG-d(2&6=LrACmfRu=o;m822yNsp=KuYWa8pkpK2>CdfC1r+cb)*YZrInFOPN8}tZeU%R zdUJI<17I^mfE!(OBPxWj3{X9h*==o|^Xd5vASDt3u4qW)TFHeX14xOgkrfiYiz8$J zDG{$);{X!@_XAGL08%2Omv%A$ETo|`fRuZT2tlX0|z(~gU3WL?{Pwz!IslMg*$8NsK3y92ydZ!fBYbUe?s?lb zoGa(s;rDP4C((UZvFoh*p^^WeK%K|NqAg!VHLjU~dXFk_83Gb~DqwFx-N)*b(M-S| zH~aJi>OT&U4m1*Ez}<=adjh3iz%JP$(k!&etbuxv^Pn0A1KKp~Fi;nEGZ_ggdJH>0 zP^d=(j8mJTbbp|XWL2NRmNdq2goIe{pbA+)150X(tzGDJ{c@7#3cucvS n1nR_sy)!;w2#@KRfjUv$U^i8*}_sz97iCvb~%hj^|o{1Purk>xpj zKElTU2Ed%Y1$CZt_;L%Mg2C>>!C#y3^+tXP>h|AZx_XY%_k zoa`-m^lb}wJ;Dhc0>DUzL7-nx|8Q6dMdZ67zP0CHLZ0^z0+oT>M^DT>4faT&Wg!1;QJpCm8U_SUFK8eK(pYqd0ibopcqwZj50ZbU z3iBc2z5l8Pav|N%2r&${I3KMu1No5tr_3FIEm&lLyAwMDj4Yvf2B;Gd1$YdD%K?xz zKzUSHBA7}T05asY%s@_L0@4izfM%r|GeDh#>J^kQCt$$Dv}(1WsZBvnq}fT* z7>QfeL9EpmjD9X#s#kIwE3M zZmXGrocJGO9mnyL0qRU-xY;UjQtJb5&!nJf)mbd)oqa%y1Hk=d2pA(GC$)P)S1T@> zh-kZ!a4ytY0~L`^Y-SkHjgZU$)rll%MT7x!Cj-cdc%Wlt8kWg-24E6HpUK2-Fez{b zAQ_-;XL`|!$h<-G3?L^`%+7V6freliKu%=2GA~RDc#YRGfSkzMgP#T9{OkkdLqrmx XBMkrx9KkXJ%|t#s+nJGuOgDgkA6XIh literal 0 HcmV?d00001 diff --git a/GroBuf.Tests/Files/dict3.buf b/GroBuf.Tests/Files/dict3.buf new file mode 100644 index 0000000000000000000000000000000000000000..79102fe937cdcf1394b4fee0a8814eabd37965b2 GIT binary patch literal 1939 zcmah~%TB~F4D=!poDf1BI4vi{38{It>Hi?{H~a&4zK|0$aRVf+998XVw;p>uo_Nn6 z*CJ;TxxK?9$W-n{yeyLC^o$>0Ki|LKo?gDrkN9$8=nWpZ1Vnkbz?ZAb4eknD!LtRQ zQ7PhT;eLb9sGlr&C;_g6hXP*#9l)cIXzt*#z{$$VYE@6D;CAp-;2E{EO`hs9Mceya z;12Kj-ca5lU{9XEO`y%jOzAvAc(v7YfoGYK!kjy8LHaFxEpX~S=-nfKz+K_@a8Cdm z^_|Y$G)}^JR)qHn)OplqF#8qo_^*M=K)uJoPPYCDBGDi{19e}*8?rD4NS`eS3DkdV zaKUXP2w*^>Jp*+hBpvtsrpP;&s;~b2Uwf;_Eor3x>7L%E0 zko)I|fjW^kri_LLv@z+nE%?oe93wY@nV{VQ+5&aqNz@4qG~h|-jpV_L321YE8Vn*r zNw{yJI*~&*HDC>P+9yyavIXvGgMn^?WtTvm=l~xu;1s5V7OE37*qPffLvNDoTTmzR jIowEWV&6jDh!a#WHzIdlJYb;X<5}b%iYX!$_+6<#mrKkm literal 0 HcmV?d00001 diff --git a/GroBuf.Tests/Files/dict4.buf b/GroBuf.Tests/Files/dict4.buf new file mode 100644 index 0000000000000000000000000000000000000000..54d6e58e0f21bcb9906011c88f2efc454f6034d1 GIT binary patch literal 5254 zcmai&O>Wgd5QH5B5-WsI7OcVwu|j(Oe?A6xK;j%6g*_)^MSre0vfUHa=qU+_-R0`) zn(j6)zn{DAN7r>9KE}7HyLI=j@3#2#@vo<^@yG9fe*OFT<=fwv&+*F>x4w^WOWeA4 zbNBovetGxy5l&DaFzbHRg!ge90N3zg4+mh2t0sKyxOGb5;~qXoD2bTxIl|{)aDDo; zhp)j3AQL|BIc_O@-ouv&COH#61-&U4T%W!?$Zx@Ha^d&L4T9J3^$|`@78ef9EuL@< zzdyo<$lm78)0Y6ahHrcLJ%Xvc&AkuuhiyKEd!~>}zN4gz&mMgAEzd6i#d&bB47iaj zGeGek>NLtn0yTi#Hw1m;H5yRqG>`-5-2oPW4A1^A0P$c5xTco%X&&n_$sMU3dFe+Bb0L6*$vl@&6aGpd(138guU?rmg0&-w7 z137UEfIb)+fOW5SP5}$!0~Des831lO&tj#(9O4S+1WOqJ!WmrG6vjPF&~z*VKniRG z89+U8jB9iR1Atj?uK>u2JiReg={MYz8OVv)7(Fb5TTslW5$cEty9NWM0#3*b6HNo91$5i7}_$R z^X9{Zd1PgN+VM`V9NEl3PLvNV15JfG1vyd6tpz{RN>Gk~0^Ez-6$reD3G@KjRJD~|%yC6E(T56FIDmjtn3tYGbu+9Us&S2KFTd zjKm&mt*l)jGmsP2uWU=h2h7I|P@KrNZW{_I;DihyC+d~VIuWPS)-r&c2sgfr2B=;4 nM8XkK0F5%DbzXI01%Uns%L1^W)IQMOLJ85ripZLKdiDJe^BF9t literal 0 HcmV?d00001 diff --git a/GroBuf.Tests/GroBuf.Tests.csproj b/GroBuf.Tests/GroBuf.Tests.csproj index f36ac10..7c7b39a 100644 --- a/GroBuf.Tests/GroBuf.Tests.csproj +++ b/GroBuf.Tests/GroBuf.Tests.csproj @@ -21,4 +21,22 @@ + + + Always + + + Always + + + Always + + + Always + + + Always + + + diff --git a/GroBuf.Tests/TestDictionary.cs b/GroBuf.Tests/TestDictionary.cs index 859da45..ffd24e1 100644 --- a/GroBuf.Tests/TestDictionary.cs +++ b/GroBuf.Tests/TestDictionary.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; + +using FluentAssertions; using GroBuf.DataMembersExtracters; @@ -17,6 +20,37 @@ public void SetUp() serializer = new Serializer(new PropertiesExtractor()); } + [TestCase(0)] + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + [TestCase(4)] + public void TestRandom(int i, bool generateFiles = false) + { + var rnd = new Random(i); + var count = rnd.Next(1, 100); + var dict = new Dictionary(); + for (int j = 0; j < count; j++) + dict[$"{i}{j}{count}{rnd.Next(1000, 10000)}"] = new Zzz + { + Properties = new Dictionary + { + {rnd.Next(1000, 10000).ToString(), new byte[] {5, 4}} + } + }; + + var buf = serializer.Serialize(dict); + + if (generateFiles) + File.WriteAllBytes($"{TestContext.CurrentContext.TestDirectory}/../../../Files/dict{i}.buf", buf); + + var expectedBuf = File.ReadAllBytes($"{TestContext.CurrentContext.TestDirectory}/Files/dict{i}.buf"); + buf.Should().BeEquivalentTo(expectedBuf); + + var dict2 = serializer.Deserialize>(buf); + dict2.Should().BeEquivalentTo(dict); + } + [Test] public void TestGetSize() { From d7a1a733ad0335b698234d7a6703ee6cc3beb45b Mon Sep 17 00:00:00 2001 From: Pavel Vostretsov Date: Fri, 3 Apr 2020 17:54:44 +0500 Subject: [PATCH 3/4] Update CHANGELOG.md and version --- CHANGELOG.md | 5 +++++ version.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0db3f..84ae4eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v1.5 - 2020.04.03 +- Use [SourceLink](https://github.com/dotnet/sourcelink) to help ReSharper decompiler show actual code. +- Update deps +- Fix GroBuf to work on .NET Core 3 + ## v1.4 - 2018.09.14 - Use [Nerdbank.GitVersioning](https://github.com/AArnott/Nerdbank.GitVersioning) to automate generation of assembly and nuget package versions. diff --git a/version.json b/version.json index 50e008f..2ca7511 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.4", + "version": "1.5", "assemblyVersion": { "precision": "build" }, From b7eef5895bc471cd3558713c0cb0245010073471 Mon Sep 17 00:00:00 2001 From: Andrew Kostousov Date: Fri, 3 Apr 2020 18:29:09 +0500 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ae4eb..6cc0ae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ # Changelog ## v1.5 - 2020.04.03 +- Fix GroBuf to work on .NET Core 3 (issue [#18](https://github.com/skbkontur/GroBuf/issues/18)). - Use [SourceLink](https://github.com/dotnet/sourcelink) to help ReSharper decompiler show actual code. -- Update deps -- Fix GroBuf to work on .NET Core 3 ## v1.4 - 2018.09.14 - Use [Nerdbank.GitVersioning](https://github.com/AArnott/Nerdbank.GitVersioning) to automate generation of assembly