Skip to content

Commit

Permalink
Merge pull request #20 from skbkontur/core-dict-fix
Browse files Browse the repository at this point in the history
fix Dictionary serialization for net core 3 (issue #18 )
  • Loading branch information
AndrewKostousov authored Apr 3, 2020
2 parents 6aca8d0 + b7eef58 commit 2f75e5c
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# 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.

## v1.4 - 2018.09.14
- Use [Nerdbank.GitVersioning](https://github.com/AArnott/Nerdbank.GitVersioning) to automate generation of assembly
and nuget package versions.
Expand Down
Binary file added GroBuf.Tests/Files/dict0.buf
Binary file not shown.
Binary file added GroBuf.Tests/Files/dict1.buf
Binary file not shown.
Binary file added GroBuf.Tests/Files/dict2.buf
Binary file not shown.
Binary file added GroBuf.Tests/Files/dict3.buf
Binary file not shown.
Binary file added GroBuf.Tests/Files/dict4.buf
Binary file not shown.
20 changes: 19 additions & 1 deletion GroBuf.Tests/GroBuf.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<IsPackable>false</IsPackable>
<TargetFrameworks>netcoreapp2.1;net45</TargetFrameworks>
<TargetFrameworks>net45;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand All @@ -21,4 +21,22 @@
<ProjectReference Include="..\GroBuf\GroBuf.csproj" />
</ItemGroup>

<ItemGroup>
<Content Include="Files\dict0.buf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\dict1.buf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\dict2.buf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\dict3.buf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Files\dict4.buf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
34 changes: 34 additions & 0 deletions GroBuf.Tests/TestDictionary.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

using FluentAssertions;

using GroBuf.DataMembersExtracters;

Expand All @@ -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<string, Zzz>();
for (int j = 0; j < count; j++)
dict[$"{i}{j}{count}{rnd.Next(1000, 10000)}"] = new Zzz
{
Properties = new Dictionary<string, byte[]>
{
{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<Dictionary<string, Zzz>>(buf);
dict2.Should().BeEquivalentTo(dict);
}

[Test]
public void TestGetSize()
{
Expand Down
14 changes: 12 additions & 2 deletions GroBuf/SizeCounters/DictionarySizeCounterBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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]

Expand Down
14 changes: 12 additions & 2 deletions GroBuf/Writers/DictionaryWriterBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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: []
Expand All @@ -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: []

Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -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"
},
Expand Down

0 comments on commit 2f75e5c

Please sign in to comment.