diff --git a/build-system/nightly-builds.yaml b/build-system/nightly-builds.yaml
index c8e91b27..273c5533 100644
--- a/build-system/nightly-builds.yaml
+++ b/build-system/nightly-builds.yaml
@@ -2,7 +2,7 @@
# See https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema for reference
pool:
- vmImage: vs2017-win2016
+ vmImage: windows-2019
demands: Cmd
trigger: none
diff --git a/build-system/pr-validation.yaml b/build-system/pr-validation.yaml
index 99a80dfb..6a62781c 100644
--- a/build-system/pr-validation.yaml
+++ b/build-system/pr-validation.yaml
@@ -18,7 +18,7 @@ jobs:
parameters:
name: 'windows_pr'
displayName: 'Windows PR Validation'
- vmImage: 'vs2017-win2016'
+ vmImage: 'windows-2019'
scriptFileName: build.cmd
scriptArgs: all
- template: azure-pipeline.template.yaml
diff --git a/build-system/windows-pr-validation.yaml b/build-system/windows-pr-validation.yaml
index 47f6ea3b..0b50b03e 100644
--- a/build-system/windows-pr-validation.yaml
+++ b/build-system/windows-pr-validation.yaml
@@ -17,6 +17,6 @@ jobs:
- template: azure-pipeline.template.yaml
parameters:
name: Windows
- vmImage: 'vs2017-win2016'
+ vmImage: 'windows-2019'
scriptFileName: build.cmd
scriptArgs: all
\ No newline at end of file
diff --git a/build-system/windows-release.yaml b/build-system/windows-release.yaml
index 6e3b17e4..43fe3dfb 100644
--- a/build-system/windows-release.yaml
+++ b/build-system/windows-release.yaml
@@ -2,7 +2,7 @@
# See https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema for reference
pool:
- vmImage: vs2017-win2016
+ vmImage: windows-2019
demands: Cmd
trigger:
diff --git a/src/Hyperion.Tests.FSharpData/Hyperion.Tests.FSharpData.fsproj b/src/Hyperion.Tests.FSharpData/Hyperion.Tests.FSharpData.fsproj
index ae47fb53..dac98890 100644
--- a/src/Hyperion.Tests.FSharpData/Hyperion.Tests.FSharpData.fsproj
+++ b/src/Hyperion.Tests.FSharpData/Hyperion.Tests.FSharpData.fsproj
@@ -8,4 +8,8 @@
+
+
+
+
diff --git a/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs b/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs
new file mode 100644
index 00000000..08d5690f
--- /dev/null
+++ b/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs
@@ -0,0 +1,37 @@
+using System.IO;
+using Hyperion.Tests.Generator;
+using Xunit;
+
+namespace Hyperion.Tests
+{
+ public class CrossFrameworkSerializationTests
+ {
+ private readonly Serializer _serializer;
+ private readonly CrossFrameworkClass _originalObject;
+
+ public CrossFrameworkSerializationTests()
+ {
+ _serializer = new Serializer();
+ _originalObject = CrossFrameworkInitializer.Init();
+ }
+
+ [Fact]
+ public void CanSerializeCrossFramework()
+ {
+ const string defaultOutputPath = CrossFrameworkInitializer.DefaultOutputPath;
+ var testFiles = Directory.GetFiles(defaultOutputPath, "*.tf");
+
+ Assert.NotEmpty(testFiles);
+
+ foreach (string testFile in testFiles)
+ {
+ using (var fileStream = new FileStream(testFile, FileMode.Open))
+ {
+ var crossFrameworkClass = _serializer.Deserialize(fileStream);
+
+ Assert.Equal(_originalObject, crossFrameworkClass);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs b/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs
new file mode 100644
index 00000000..081021c0
--- /dev/null
+++ b/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs
@@ -0,0 +1,125 @@
+using System;
+
+namespace Hyperion.Tests.Generator
+{
+ public class CrossFrameworkClass
+ {
+ public sbyte Sbyte { get; set; }
+
+ public short Short { get; set; }
+
+ public int Int { get; set; }
+
+ public long Long { get; set; }
+
+ public byte Byte { get; set; }
+
+ public ushort UShort { get; set; }
+
+ public uint UInt { get; set; }
+
+ public ulong ULong { get; set; }
+
+ public char Char { get; set; }
+
+ public float Float { get; set; }
+
+ public double Double { get; set; }
+
+ public decimal Decimal { get; set; }
+
+ public bool Boolean { get; set; }
+
+ public string String { get; set; }
+
+ public DateTime DateTime { get; set; }
+
+ public Exception Exception { get; set; }
+
+ public CrossFrameworkEnum Enum { get; set; }
+
+ public CrossFrameworkStruct Struct { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is CrossFrameworkClass))
+ {
+ return false;
+ }
+
+ var objectToCompare = (CrossFrameworkClass) obj;
+
+
+ //return Sbyte == objectToCompare.Sbyte
+ // && Short == objectToCompare.Short
+ // && Int == objectToCompare.Int
+ // && Long == objectToCompare.Long
+ // && Byte == objectToCompare.Byte
+ // && UShort == objectToCompare.UShort
+ // && UInt == objectToCompare.UInt
+ // && ULong == objectToCompare.ULong
+ // && Char == objectToCompare.Char
+ // && Math.Abs(Float - objectToCompare.Float) < float.Epsilon
+ // && Math.Abs(Double - objectToCompare.Double) < double.Epsilon
+ // && Decimal == objectToCompare.Decimal
+ // && Boolean == objectToCompare.Boolean
+ // && String == objectToCompare.String
+ // && DateTime == objectToCompare.DateTime
+ // && Exception == objectToCompare.Exception
+ // && Enum == objectToCompare.Enum
+ // && Struct.Equals(objectToCompare.Struct);
+
+ return Equals(objectToCompare);
+
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = Sbyte.GetHashCode();
+ hashCode = (hashCode * 397) ^ Short.GetHashCode();
+ hashCode = (hashCode * 397) ^ Int;
+ hashCode = (hashCode * 397) ^ Long.GetHashCode();
+ hashCode = (hashCode * 397) ^ Byte.GetHashCode();
+ hashCode = (hashCode * 397) ^ UShort.GetHashCode();
+ hashCode = (hashCode * 397) ^ (int) UInt;
+ hashCode = (hashCode * 397) ^ ULong.GetHashCode();
+ hashCode = (hashCode * 397) ^ Char.GetHashCode();
+ hashCode = (hashCode * 397) ^ Float.GetHashCode();
+ hashCode = (hashCode * 397) ^ Double.GetHashCode();
+ hashCode = (hashCode * 397) ^ Decimal.GetHashCode();
+ hashCode = (hashCode * 397) ^ Boolean.GetHashCode();
+ hashCode = (hashCode * 397) ^ (String != null ? String.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ DateTime.GetHashCode();
+ hashCode = (hashCode * 397) ^ (Exception != null ? Exception.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ (int) Enum;
+ hashCode = (hashCode * 397) ^ Struct.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ private bool Equals(CrossFrameworkClass other)
+ {
+ return Sbyte == other.Sbyte
+ && Short == other.Short
+ && Int == other.Int
+ && Long == other.Long
+ && Byte == other.Byte
+ && UShort == other.UShort
+ && UInt == other.UInt
+ && ULong == other.ULong
+ && Char == other.Char
+ && Math.Abs(Float - other.Float) < float.Epsilon
+ && Math.Abs(Double - other.Double) < double.Epsilon
+ && Decimal == other.Decimal
+ && Boolean == other.Boolean
+ && string.Equals(String, other.String)
+ && DateTime.Equals(other.DateTime)
+ // && Equals(Exception, other.Exception)
+ && Exception.Message == other.Exception.Message
+ && Enum == other.Enum
+ && Struct.Equals(other.Struct);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkEnum.cs b/src/Hyperion.Tests/Generator/CrossFrameworkEnum.cs
new file mode 100644
index 00000000..aaf0c112
--- /dev/null
+++ b/src/Hyperion.Tests/Generator/CrossFrameworkEnum.cs
@@ -0,0 +1,13 @@
+namespace Hyperion.Tests.Generator
+{
+ public enum CrossFrameworkEnum
+ {
+ ShortSword,
+ LongSword,
+ BastardSword,
+ Claymore,
+ Scimitar,
+ Yatagan,
+ Katana
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs b/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs
new file mode 100644
index 00000000..dae3431f
--- /dev/null
+++ b/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace Hyperion.Tests.Generator
+{
+ public static class CrossFrameworkInitializer
+ {
+ public const string DefaultOutputPath = "../../../testfiles";
+
+ public static CrossFrameworkClass Init()
+ {
+ return new CrossFrameworkClass()
+ {
+ Exception = new Exception("Test message", new ArgumentNullException("param", "Cannot be null")),
+ DateTime = new DateTime(1944, 6, 6), // DDay
+ Enum = CrossFrameworkEnum.Yatagan,
+ String = "On June 6, 1944, more than 160,000 Allied troops landed along a 50-mile stretch of heavily-fortified French coastline",
+ Struct = new CrossFrameworkStruct()
+ {
+ Boolean = true,
+ Long = long.MaxValue,
+ Decimal = decimal.MinusOne,
+ Double = double.MaxValue,
+ Int = int.MaxValue,
+ Short = short.MaxValue,
+ ULong = ulong.MinValue,
+ Byte = byte.MaxValue,
+ Char = char.MaxValue,
+ Float = float.MinValue,
+ UShort = ushort.MinValue,
+ UInt = uint.MaxValue,
+ Sbyte = sbyte.MaxValue
+ },
+ Decimal = decimal.MaxValue,
+ Float = float.MaxValue,
+ Long = long.MinValue,
+ Int = int.MinValue,
+ Double = double.Epsilon,
+ Char = char.MaxValue,
+ Byte = byte.MaxValue,
+ Sbyte = sbyte.MaxValue,
+ Short = short.MaxValue,
+ UInt = uint.MaxValue,
+ ULong = ulong.MaxValue,
+ UShort = ushort.MaxValue,
+ Boolean = true
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkStruct.cs b/src/Hyperion.Tests/Generator/CrossFrameworkStruct.cs
new file mode 100644
index 00000000..8bda1963
--- /dev/null
+++ b/src/Hyperion.Tests/Generator/CrossFrameworkStruct.cs
@@ -0,0 +1,83 @@
+using System;
+
+namespace Hyperion.Tests.Generator
+{
+ public struct CrossFrameworkStruct
+ {
+ public sbyte Sbyte { get; set; }
+
+ public short Short { get; set; }
+
+ public int Int { get; set; }
+
+ public long Long { get; set; }
+
+ public byte Byte { get; set; }
+
+ public ushort UShort { get; set; }
+
+ public uint UInt { get; set; }
+
+ public ulong ULong { get; set; }
+
+ public char Char { get; set; }
+
+ public float Float { get; set; }
+
+ public double Double { get; set; }
+
+ public decimal Decimal { get; set; }
+
+ public bool Boolean { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is CrossFrameworkStruct))
+ {
+ return false;
+ }
+
+ var objectToCompare = (CrossFrameworkStruct)obj;
+
+ return Equals(objectToCompare);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = Sbyte.GetHashCode();
+ hashCode = (hashCode * 397) ^ Short.GetHashCode();
+ hashCode = (hashCode * 397) ^ Int;
+ hashCode = (hashCode * 397) ^ Long.GetHashCode();
+ hashCode = (hashCode * 397) ^ Byte.GetHashCode();
+ hashCode = (hashCode * 397) ^ UShort.GetHashCode();
+ hashCode = (hashCode * 397) ^ (int) UInt;
+ hashCode = (hashCode * 397) ^ ULong.GetHashCode();
+ hashCode = (hashCode * 397) ^ Char.GetHashCode();
+ hashCode = (hashCode * 397) ^ Float.GetHashCode();
+ hashCode = (hashCode * 397) ^ Double.GetHashCode();
+ hashCode = (hashCode * 397) ^ Decimal.GetHashCode();
+ hashCode = (hashCode * 397) ^ Boolean.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ private bool Equals(CrossFrameworkStruct other)
+ {
+ return Sbyte == other.Sbyte
+ && Short == other.Short
+ && Int == other.Int
+ && Long == other.Long
+ && Byte == other.Byte
+ && UShort == other.UShort
+ && UInt == other.UInt
+ && ULong == other.ULong
+ && Char == other.Char
+ && Math.Abs(Float - other.Float) < float.Epsilon
+ && Math.Abs(Double - other.Double) < double.Epsilon
+ && Decimal == other.Decimal
+ && Boolean == other.Boolean;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/Generator/Program.cs b/src/Hyperion.Tests/Generator/Program.cs
new file mode 100644
index 00000000..c0ae7045
--- /dev/null
+++ b/src/Hyperion.Tests/Generator/Program.cs
@@ -0,0 +1,43 @@
+using System.IO;
+using System.Reflection;
+using System.Runtime.Versioning;
+using System.Text.RegularExpressions;
+
+namespace Hyperion.Tests.Generator
+{
+ internal static class Program
+ {
+ private static readonly Serializer Serializer = new Serializer();
+ private static readonly string FullFrameworkName = Assembly
+ .GetEntryAssembly()?
+ .GetCustomAttribute()?
+ .FrameworkName;
+
+ private static readonly string FrameworkName = Regex.Replace(FullFrameworkName, "[^\\w\\._]", string.Empty);
+
+ private static void Main(string[] args)
+ {
+ if (args.Length != 1 || args[0] != "generate")
+ {
+ return;
+ }
+
+ string outputPath = args.Length == 2 ? args[1] : CrossFrameworkInitializer.DefaultOutputPath;
+
+ if (!Directory.Exists(outputPath))
+ {
+ Directory.CreateDirectory(outputPath);
+ }
+
+ CrossFrameworkClass crossFrameworkClass = CrossFrameworkInitializer.Init();
+
+ string fileName = $"test_file_{FrameworkName.ToLowerInvariant()}.tf";
+ string fullPath = Path.Combine(outputPath, fileName);
+
+ using (var fileStream = new FileStream(fullPath, FileMode.Create))
+ {
+ Serializer.Serialize(crossFrameworkClass, fileStream);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/Hyperion.Tests.csproj b/src/Hyperion.Tests/Hyperion.Tests.csproj
index f97c9736..8bebdc43 100644
--- a/src/Hyperion.Tests/Hyperion.Tests.csproj
+++ b/src/Hyperion.Tests/Hyperion.Tests.csproj
@@ -2,7 +2,11 @@
+ Exe
net461;netcoreapp2.1;netcoreapp3.0
+ true
+ latest
+ Hyperion.Tests.Generator.Program
diff --git a/src/Hyperion.Tests/Properties/launchSettings.json b/src/Hyperion.Tests/Properties/launchSettings.json
new file mode 100644
index 00000000..39bea140
--- /dev/null
+++ b/src/Hyperion.Tests/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Hyperion.Tests": {
+ "commandName": "Project",
+ "commandLineArgs": "generate"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.0.tf b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.0.tf
new file mode 100644
index 00000000..d5a25698
Binary files /dev/null and b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.0.tf differ
diff --git a/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.1.tf b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.1.tf
new file mode 100644
index 00000000..d5a25698
Binary files /dev/null and b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.1.tf differ
diff --git a/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.2.tf b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.2.tf
new file mode 100644
index 00000000..d5a25698
Binary files /dev/null and b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv2.2.tf differ
diff --git a/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv3.0.tf b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv3.0.tf
new file mode 100644
index 00000000..d5a25698
Binary files /dev/null and b/src/Hyperion.Tests/testfiles/test_file_.netcoreappversionv3.0.tf differ
diff --git a/src/Hyperion.Tests/testfiles/test_file_.netframeworkversionv4.6.1.tf b/src/Hyperion.Tests/testfiles/test_file_.netframeworkversionv4.6.1.tf
new file mode 100644
index 00000000..9e96ef28
Binary files /dev/null and b/src/Hyperion.Tests/testfiles/test_file_.netframeworkversionv4.6.1.tf differ
diff --git a/src/Hyperion/Extensions/TypeEx.cs b/src/Hyperion/Extensions/TypeEx.cs
index a2aa56f7..32f31f1e 100644
--- a/src/Hyperion/Extensions/TypeEx.cs
+++ b/src/Hyperion/Extensions/TypeEx.cs
@@ -118,11 +118,23 @@ private static Type GetTypeFromManifestName(Stream stream, DeserializerSession s
return TypeNameLookup.GetOrAdd(byteArr, b =>
{
var shortName = StringEx.FromUtf8Bytes(b.Bytes, 0, b.Bytes.Length);
+#if NET45
+ if (shortName.Contains("System.Private.CoreLib,%core%"))
+ {
+ shortName = shortName.Replace("System.Private.CoreLib,%core%", "mscorlib,%core%");
+ }
+#endif
+#if NETSTANDARD
+ if (shortName.Contains("mscorlib,%core%"))
+ {
+ shortName = shortName.Replace("mscorlib,%core%", "System.Private.CoreLib,%core%");
+ }
+#endif
+
var typename = ToQualifiedAssemblyName(shortName);
return Type.GetType(typename, true);
});
}
-
public static Type GetTypeFromManifestFull(Stream stream, DeserializerSession session)
{
var type = GetTypeFromManifestName(stream, session);
@@ -195,7 +207,7 @@ public static int GetTypeSize(this Type type)
throw new NotSupportedException();
}
-
+ private static readonly string CoreAssemblyQualifiedName = 1.GetType().AssemblyQualifiedName;
private static readonly string CoreAssemblyName = GetCoreAssemblyName();
private static readonly Regex cleanAssemblyVersionRegex = new Regex(
@@ -204,8 +216,7 @@ public static int GetTypeSize(this Type type)
private static string GetCoreAssemblyName()
{
- var name = 1.GetType().AssemblyQualifiedName;
- var part = name.Substring( name.IndexOf(", Version", StringComparison.Ordinal));
+ var part = CoreAssemblyQualifiedName.Substring(CoreAssemblyQualifiedName.IndexOf(", Version", StringComparison.Ordinal));
return part;
}