diff options
author | Maxim Mikhisor <40904997+MaximMikhisor@users.noreply.github.com> | 2022-06-28 04:08:56 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-28 04:08:56 +0300 |
commit | 8ef5aec97ec309b0cda153d6735961542f034e4e (patch) | |
tree | 59fec9a4c92c7549a3a6625db1e93e03a23f4ecc /src | |
parent | 7a4a9ef9fbe1d8eb2b9139afa10e6d8f691ff976 (diff) | |
parent | 64ee45cdba4f8c06828107f3eca7ee919972c4ce (diff) |
Merge pull request #1 from neuecc/master
Merging
Diffstat (limited to 'src')
41 files changed, 792 insertions, 176 deletions
diff --git a/src/MessagePack.Generator/MessagePack.Generator.csproj b/src/MessagePack.Generator/MessagePack.Generator.csproj index b684a5b8..42b02f30 100644 --- a/src/MessagePack.Generator/MessagePack.Generator.csproj +++ b/src/MessagePack.Generator/MessagePack.Generator.csproj @@ -3,12 +3,13 @@ <PropertyGroup> <AssemblyName>mpc</AssemblyName> <OutputType>Exe</OutputType> - <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks> - <LangVersion>9</LangVersion> + <TargetFrameworks>netcoreapp3.1;net6.0</TargetFrameworks> + <LangVersion>10</LangVersion> <Nullable>enable</Nullable> <IsPackable>true</IsPackable> <PackAsTool>true</PackAsTool> <ToolCommandName>mpc</ToolCommandName> + <RollForward>Major</RollForward> <!-- NuGet Info --> <PackageId>MessagePack.Generator</PackageId> @@ -18,11 +19,11 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="ConsoleAppFramework" Version="2.0.0" /> + <PackageReference Include="ConsoleAppFramework" Version="3.3.2" /> <PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" /> <PackageReference Include="Microsoft.Build.Framework" Version="16.5.0" ExcludeAssets="runtime" /> <PackageReference Include="Microsoft.Build" Version="16.5.0" ExcludeAssets="runtime" /> - <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.10.0" /> + <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.0.1" /> </ItemGroup> <ItemGroup> diff --git a/src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs b/src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs index 532cdc71..30aaedb9 100644 --- a/src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs +++ b/src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs @@ -170,7 +170,7 @@ namespace MessagePackCompiler.CodeAnalysis } else { - return $"formatterResolver.GetFormatterWithVerify<{this.Type}>().Serialize(ref writer, value.{this.Name}, options)"; + return $"global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify<{this.Type}>(formatterResolver).Serialize(ref writer, value.{this.Name}, options)"; } } @@ -182,12 +182,18 @@ namespace MessagePackCompiler.CodeAnalysis } else if (this.primitiveTypes.Contains(this.Type)) { - string suffix = this.Type == "byte[]" ? "?.ToArray()" : string.Empty; - return $"reader.Read{this.ShortTypeName!.Replace("[]", "s")}()" + suffix; + if (this.Type == "byte[]") + { + return "global::MessagePack.Internal.CodeGenHelpers.GetArrayFromNullableSequence(reader.ReadBytes())"; + } + else + { + return $"reader.Read{this.ShortTypeName!.Replace("[]", "s")}()"; + } } else { - return $"formatterResolver.GetFormatterWithVerify<{this.Type}>().Deserialize(ref reader, options)"; + return $"global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify<{this.Type}>(formatterResolver).Deserialize(ref reader, options)"; } } } diff --git a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs index d2537dcd..935ceb87 100644 --- a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs +++ b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs @@ -971,10 +971,11 @@ namespace MessagePackCompiler.CodeAnalysis { var name = type.ContainingType is object ? GetMinimallyQualifiedClassName(type.ContainingType) + "_" : string.Empty; name += type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); - name = name.Replace(".", "_"); - name = name.Replace("<", "_"); - name = name.Replace(">", "_"); + name = name.Replace('.', '_'); + name = name.Replace('<', '_'); + name = name.Replace('>', '_'); name = Regex.Replace(name, @"\[([,])*\]", match => $"Array{match.Length - 1}"); + name = name.Replace("?", string.Empty); return name; } diff --git a/src/MessagePack.GeneratorCore/CodeGenerator.cs b/src/MessagePack.GeneratorCore/CodeGenerator.cs index f9654693..1f48973e 100644 --- a/src/MessagePack.GeneratorCore/CodeGenerator.cs +++ b/src/MessagePack.GeneratorCore/CodeGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -16,6 +17,8 @@ namespace MessagePackCompiler { public class CodeGenerator { + private static readonly HashSet<char> InvalidFileCharSet = new(Path.GetInvalidFileNameChars()); + private static readonly Encoding NoBomUtf8 = new UTF8Encoding(false); private readonly Action<string> logger; @@ -212,15 +215,76 @@ namespace MessagePackCompiler private Task OutputToDirAsync(string dir, string ns, string name, string multipleOutSymbol, string text) { - if (multipleOutSymbol == string.Empty) + var builder = new StringBuilder(); + void AppendDir(string dir) + { + if (dir.Length != 0) + { + builder.Append(dir); + if (dir[dir.Length - 1] != Path.DirectorySeparatorChar && dir[dir.Length - 1] != Path.AltDirectorySeparatorChar) + { + builder.Append(Path.DirectorySeparatorChar); + } + } + } + + void AppendChar(char c) + { + if (c == '.' || InvalidFileCharSet.Contains(c)) + { + builder.Append('_'); + } + else + { + builder.Append(c); + } + } + + void Append(string text) { - return OutputAsync(Path.Combine(dir, $"{ns}_{name}".Replace(".", "_").Replace("global::", string.Empty) + ".cs"), text); + var span = text.AsSpan(); + while (!span.IsEmpty) + { + var index = span.IndexOf("global::".AsSpan()); + if (index == -1) + { + foreach (var c in span) + { + AppendChar(c); + } + + break; + } + + if (index == 0) + { + span = span.Slice("global::".Length); + continue; + } + + foreach (var c in span.Slice(0, index)) + { + AppendChar(c); + } + + span = span.Slice(index + "global::".Length); + } } - else + + AppendDir(dir); + + if (!string.IsNullOrWhiteSpace(multipleOutSymbol)) { text = $"#if {multipleOutSymbol}" + Environment.NewLine + text + Environment.NewLine + "#endif"; - return OutputAsync(Path.Combine(dir, MultiSymbolToSafeFilePath(multipleOutSymbol), $"{ns}_{name}".Replace(".", "_").Replace("global::", string.Empty) + ".cs"), text); + AppendDir(MultiSymbolToSafeFilePath(multipleOutSymbol)); } + + Append(ns); + builder.Append('_'); + Append(name); + builder.Append(".cs"); + + return OutputAsync(builder.ToString(), text); } private Task OutputAsync(string path, string text) diff --git a/src/MessagePack.GeneratorCore/Generator/EnumTemplate.cs b/src/MessagePack.GeneratorCore/Generator/EnumTemplate.cs index b64b4912..382112a3 100644 --- a/src/MessagePack.GeneratorCore/Generator/EnumTemplate.cs +++ b/src/MessagePack.GeneratorCore/Generator/EnumTemplate.cs @@ -1,10 +1,10 @@ // ------------------------------------------------------------------------------ // <auto-generated> -// このコードはツールによって生成されました。 -// ランタイム バージョン: 16.0.0.0 +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 // -// このファイルへの変更は、正しくない動作の原因になる可能性があり、 -// コードが再生成されると失われます。 +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // </auto-generated> // ------------------------------------------------------------------------------ namespace MessagePackCompiler.Generator @@ -17,7 +17,7 @@ namespace MessagePackCompiler.Generator /// <summary> /// Class to produce the template output /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class EnumTemplate : EnumTemplateBase { /// <summary> @@ -33,28 +33,29 @@ namespace MessagePackCompiler.Generator #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1649 // File name should match first type name namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - this.Write("\r\n{\r\n using System;\r\n using System.Buffers;\r\n using MessagePack;\r\n"); + this.Write("\r\n{\r\n"); foreach(var info in EnumSerializationInfos) { this.Write("\r\n public sealed class "); this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<"); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - this.Write(">\r\n {\r\n public void Serialize(ref MessagePackWriter writer, "); + this.Write(">\r\n {\r\n public void Serialize(ref global::MessagePack.MessagePackWriter" + + " writer, "); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); this.Write(" value, global::MessagePack.MessagePackSerializerOptions options)\r\n {\r\n " + - " writer.Write(("); + " writer.Write((global::System."); this.Write(this.ToStringHelper.ToStringWithCulture(info.UnderlyingType)); this.Write(")value);\r\n }\r\n\r\n public "); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - this.Write(" Deserialize(ref MessagePackReader reader, global::MessagePack.MessagePackSeriali" + - "zerOptions options)\r\n {\r\n return ("); + this.Write(" Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePac" + + "k.MessagePackSerializerOptions options)\r\n {\r\n return ("); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); this.Write(")reader.Read"); this.Write(this.ToStringHelper.ToStringWithCulture(info.UnderlyingType)); @@ -67,7 +68,6 @@ namespace "); #pragma warning restore 618 #pragma warning restore 612 -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1403 // File may only contain a single namespace #pragma warning restore SA1649 // File name should match first type name "); @@ -78,7 +78,7 @@ namespace "); /// <summary> /// Base class for this transformation /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public class EnumTemplateBase { #region Fields diff --git a/src/MessagePack.GeneratorCore/Generator/EnumTemplate.tt b/src/MessagePack.GeneratorCore/Generator/EnumTemplate.tt index 28d34550..74214c6c 100644 --- a/src/MessagePack.GeneratorCore/Generator/EnumTemplate.tt +++ b/src/MessagePack.GeneratorCore/Generator/EnumTemplate.tt @@ -11,26 +11,23 @@ #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1649 // File name should match first type name namespace <#= Namespace #> { - using System; - using System.Buffers; - using MessagePack; <# foreach(var info in EnumSerializationInfos) { #> public sealed class <#= info.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= info.FullName #>> { - public void Serialize(ref MessagePackWriter writer, <#= info.FullName #> value, global::MessagePack.MessagePackSerializerOptions options) + public void Serialize(ref global::MessagePack.MessagePackWriter writer, <#= info.FullName #> value, global::MessagePack.MessagePackSerializerOptions options) { - writer.Write((<#= info.UnderlyingType #>)value); + writer.Write((global::System.<#= info.UnderlyingType #>)value); } - public <#= info.FullName #> Deserialize(ref MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) + public <#= info.FullName #> Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) { return (<#= info.FullName #>)reader.Read<#= info.UnderlyingType #>(); } @@ -43,6 +40,5 @@ namespace <#= Namespace #> #pragma warning restore 618 #pragma warning restore 612 -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1403 // File may only contain a single namespace #pragma warning restore SA1649 // File name should match first type name diff --git a/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.cs b/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.cs index e153d5eb..396d6a52 100644 --- a/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.cs +++ b/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version: 16.0.0.0 +// Runtime Version: 17.0.0.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -17,7 +17,7 @@ namespace MessagePackCompiler.Generator /// <summary> /// Class to produce the template output /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class FormatterTemplate : FormatterTemplateBase { /// <summary> @@ -33,9 +33,9 @@ namespace MessagePackCompiler.Generator #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs #pragma warning disable SA1129 // Do not use default value type constructor -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1309 // Field names should not begin with underscore #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1403 // File may only contain a single namespace @@ -43,10 +43,10 @@ namespace MessagePackCompiler.Generator namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - this.Write("\r\n{\r\n using global::System.Buffers;\r\n using global::MessagePack;\r\n"); + this.Write("\r\n{\r\n"); foreach (var objInfo in ObjectSerializationInfos) { bool isFormatterResolverNecessary = ShouldUseFormatterResolverHelper.ShouldUseFormatterResolver(objInfo.Members); - this.Write("\r\n public sealed class "); + this.Write(" public sealed class "); this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FormatterNameWithoutNameSpace)); this.Write(" : global::MessagePack.Formatters.IMessagePackFormatter<"); this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName)); @@ -205,7 +205,7 @@ namespace "); } this.Write(" reader.Depth--;\r\n return ____result;\r\n"); } - this.Write(" }\r\n }\r\n"); + this.Write(" }\r\n }\r\n\r\n"); } this.Write(@"} @@ -215,7 +215,6 @@ namespace "); #pragma warning restore 612 #pragma warning restore SA1129 // Do not use default value type constructor -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1309 // Field names should not begin with underscore #pragma warning restore SA1312 // Variable names should begin with lower-case letter #pragma warning restore SA1403 // File may only contain a single namespace @@ -228,7 +227,7 @@ namespace "); /// <summary> /// Base class for this transformation /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public class FormatterTemplateBase { #region Fields diff --git a/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.tt b/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.tt index 631dc9f1..240b107f 100644 --- a/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.tt +++ b/src/MessagePack.GeneratorCore/Generator/FormatterTemplate.tt @@ -11,9 +11,9 @@ #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs #pragma warning disable SA1129 // Do not use default value type constructor -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1309 // Field names should not begin with underscore #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1403 // File may only contain a single namespace @@ -21,11 +21,8 @@ namespace <#= Namespace #> { - using global::System.Buffers; - using global::MessagePack; <# foreach (var objInfo in ObjectSerializationInfos) { bool isFormatterResolverNecessary = ShouldUseFormatterResolverHelper.ShouldUseFormatterResolver(objInfo.Members);#> - public sealed class <#= objInfo.FormatterNameWithoutNameSpace #> : global::MessagePack.Formatters.IMessagePackFormatter<<#= objInfo.FullName #>> <# foreach (var typeArg in objInfo.GenericTypeParameters.Where(x => x.HasConstraints)) { #> where <#= typeArg.Name #> : <#= typeArg.Constraints #> @@ -155,8 +152,8 @@ namespace <#= Namespace #> <# } #> } } -<# } #> -} + +<# } #>} #pragma warning restore 168 #pragma warning restore 414 @@ -164,7 +161,6 @@ namespace <#= Namespace #> #pragma warning restore 612 #pragma warning restore SA1129 // Do not use default value type constructor -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1309 // Field names should not begin with underscore #pragma warning restore SA1312 // Variable names should begin with lower-case letter #pragma warning restore SA1403 // File may only contain a single namespace diff --git a/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.cs b/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.cs index 48e4df6b..58f20711 100644 --- a/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.cs +++ b/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version: 16.0.0.0 +// Runtime Version: 17.0.0.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -17,7 +17,7 @@ namespace MessagePackCompiler.Generator /// <summary> /// Class to produce the template output /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class ResolverTemplate : ResolverTemplateBase { /// <summary> @@ -33,14 +33,14 @@ namespace MessagePackCompiler.Generator #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1649 // File name should match first type name namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - this.Write("\r\n{\r\n using System;\r\n\r\n public class "); + this.Write("\r\n{\r\n public class "); this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); this.Write(" : global::MessagePack.IFormatterResolver\r\n {\r\n public static readonly " + "global::MessagePack.IFormatterResolver Instance = new "); @@ -76,10 +76,10 @@ namespace "); internal static class "); this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); this.Write("GetFormatterHelper\r\n {\r\n private static readonly global::System.Collect" + - "ions.Generic.Dictionary<Type, int> lookup;\r\n\r\n static "); + "ions.Generic.Dictionary<global::System.Type, int> lookup;\r\n\r\n static "); this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); this.Write("GetFormatterHelper()\r\n {\r\n lookup = new global::System.Collecti" + - "ons.Generic.Dictionary<Type, int>("); + "ons.Generic.Dictionary<global::System.Type, int>("); this.Write(this.ToStringHelper.ToStringWithCulture(RegisterInfos.Length)); this.Write(")\r\n {\r\n"); for(var i = 0; i < RegisterInfos.Length; i++) { var x = RegisterInfos[i]; @@ -92,7 +92,7 @@ namespace "); this.Write(@" }; } - internal static object GetFormatter(Type t) + internal static object GetFormatter(global::System.Type t) { int key; if (!lookup.TryGetValue(t, out key)) @@ -122,7 +122,6 @@ namespace "); #pragma warning restore 612 #pragma warning restore SA1312 // Variable names should begin with lower-case letter -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1649 // File name should match first type name "); return this.GenerationEnvironment.ToString(); @@ -132,7 +131,7 @@ namespace "); /// <summary> /// Base class for this transformation /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public class ResolverTemplateBase { #region Fields diff --git a/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.tt b/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.tt index e61688a1..6837185d 100644 --- a/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.tt +++ b/src/MessagePack.GeneratorCore/Generator/ResolverTemplate.tt @@ -11,17 +11,13 @@ #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1649 // File name should match first type name namespace <#= Namespace #> { - using System; - using System.Buffers; - using MessagePack; - public class <#= ResolverName #> : global::MessagePack.IFormatterResolver { public static readonly global::MessagePack.IFormatterResolver Instance = new <#= ResolverName #>(); @@ -52,11 +48,11 @@ namespace <#= Namespace #> internal static class <#= ResolverName #>GetFormatterHelper { - private static readonly global::System.Collections.Generic.Dictionary<Type, int> lookup; + private static readonly global::System.Collections.Generic.Dictionary<global::System.Type, int> lookup; static <#= ResolverName #>GetFormatterHelper() { - lookup = new global::System.Collections.Generic.Dictionary<Type, int>(<#= RegisterInfos.Length #>) + lookup = new global::System.Collections.Generic.Dictionary<global::System.Type, int>(<#= RegisterInfos.Length #>) { <# for(var i = 0; i < RegisterInfos.Length; i++) { var x = RegisterInfos[i]; #> { typeof(<#= x.FullName #>), <#= i #> }, @@ -64,7 +60,7 @@ namespace <#= Namespace #> }; } - internal static object GetFormatter(Type t) + internal static object GetFormatter(global::System.Type t) { int key; if (!lookup.TryGetValue(t, out key)) @@ -75,7 +71,7 @@ namespace <#= Namespace #> switch (key) { <# for(var i = 0; i < RegisterInfos.Length; i++) { var x = RegisterInfos[i]; #> - case <#= i #>: return new <#= x.FormatterName.StartsWith("global::") ? x.FormatterName: (!string.IsNullOrEmpty(FormatterNamespace) ? FormatterNamespace + "." : FormatterNamespace) + x.FormatterName#>(); + case <#= i #>: return new <#= x.FormatterName.StartsWith("global::") ? x.FormatterName: (!string.IsNullOrEmpty(FormatterNamespace) ? FormatterNamespace + "." : FormatterNamespace) + x.FormatterName #>(); <# } #> default: return null; } @@ -89,5 +85,4 @@ namespace <#= Namespace #> #pragma warning restore 612 #pragma warning restore SA1312 // Variable names should begin with lower-case letter -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1649 // File name should match first type name diff --git a/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.cs b/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.cs index a3df9f44..abc89f78 100644 --- a/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.cs +++ b/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version: 16.0.0.0 +// Runtime Version: 17.0.0.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -17,7 +17,7 @@ namespace MessagePackCompiler.Generator /// <summary> /// Class to produce the template output /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class StringKeyFormatterTemplate : StringKeyFormatterTemplateBase { /// <summary> @@ -33,9 +33,9 @@ namespace MessagePackCompiler.Generator #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs #pragma warning disable SA1129 // Do not use default value type constructor -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1309 // Field names should not begin with underscore #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1403 // File may only contain a single namespace @@ -43,7 +43,7 @@ namespace MessagePackCompiler.Generator namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - this.Write("\r\n{\r\n using global::System.Buffers;\r\n using global::MessagePack;\r\n"); + this.Write("\r\n{\r\n"); var list = new List<ValueTuple<MemberSerializationInfo, byte[]>>(); foreach (var objInfo in ObjectSerializationInfos) { list.Clear(); @@ -53,7 +53,7 @@ foreach (var objInfo in ObjectSerializationInfos) { } bool isFormatterResolverNecessary = ShouldUseFormatterResolverHelper.ShouldUseFormatterResolver(objInfo.Members); - this.Write("\r\n public sealed class "); + this.Write(" public sealed class "); this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FormatterNameWithoutNameSpace)); this.Write(" : global::MessagePack.Formatters.IMessagePackFormatter<"); this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName)); @@ -191,9 +191,21 @@ foreach (var objInfo in ObjectSerializationInfos) { if (objInfo.Members.Length != 0) { this.Write(" reader.Depth--;\r\n"); } - this.Write(" return ____result;\r\n }\r\n }\r\n"); + this.Write(" return ____result;\r\n }\r\n }\r\n\r\n"); } - this.Write("}\r\n"); + this.Write(@"} + +#pragma warning restore 168 +#pragma warning restore 414 +#pragma warning restore 618 +#pragma warning restore 612 + +#pragma warning restore SA1129 // Do not use default value type constructor +#pragma warning restore SA1309 // Field names should not begin with underscore +#pragma warning restore SA1312 // Variable names should begin with lower-case letter +#pragma warning restore SA1403 // File may only contain a single namespace +#pragma warning restore SA1649 // File name should match first type name +"); return this.GenerationEnvironment.ToString(); } } @@ -201,7 +213,7 @@ foreach (var objInfo in ObjectSerializationInfos) { /// <summary> /// Base class for this transformation /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public class StringKeyFormatterTemplateBase { #region Fields diff --git a/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.tt b/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.tt index 9bc3e4d8..9f0dac87 100644 --- a/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.tt +++ b/src/MessagePack.GeneratorCore/Generator/StringKey/StringKeyFormatterTemplate.tt @@ -12,9 +12,9 @@ #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs #pragma warning disable SA1129 // Do not use default value type constructor -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1309 // Field names should not begin with underscore #pragma warning disable SA1312 // Variable names should begin with lower-case letter #pragma warning disable SA1403 // File may only contain a single namespace @@ -22,8 +22,6 @@ namespace <#= Namespace #> { - using global::System.Buffers; - using global::MessagePack; <# var list = new List<ValueTuple<MemberSerializationInfo, byte[]>>(); foreach (var objInfo in ObjectSerializationInfos) { list.Clear(); @@ -33,7 +31,6 @@ foreach (var objInfo in ObjectSerializationInfos) { } bool isFormatterResolverNecessary = ShouldUseFormatterResolverHelper.ShouldUseFormatterResolver(objInfo.Members); #> - public sealed class <#= objInfo.FormatterNameWithoutNameSpace #> : global::MessagePack.Formatters.IMessagePackFormatter<<#= objInfo.FullName #>> <# foreach (var typeArg in objInfo.GenericTypeParameters.Where(x => x.HasConstraints)) {#> where <#= typeArg.Name #> : <#= typeArg.Constraints #> @@ -147,5 +144,16 @@ foreach (var objInfo in ObjectSerializationInfos) { return ____result; } } -<# } #> -} + +<# } #>} + +#pragma warning restore 168 +#pragma warning restore 414 +#pragma warning restore 618 +#pragma warning restore 612 + +#pragma warning restore SA1129 // Do not use default value type constructor +#pragma warning restore SA1309 // Field names should not begin with underscore +#pragma warning restore SA1312 // Variable names should begin with lower-case letter +#pragma warning restore SA1403 // File may only contain a single namespace +#pragma warning restore SA1649 // File name should match first type name diff --git a/src/MessagePack.GeneratorCore/Generator/UnionTemplate.cs b/src/MessagePack.GeneratorCore/Generator/UnionTemplate.cs index 1106f1cb..b7a639bf 100644 --- a/src/MessagePack.GeneratorCore/Generator/UnionTemplate.cs +++ b/src/MessagePack.GeneratorCore/Generator/UnionTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version: 16.0.0.0 +// Runtime Version: 17.0.0.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -17,7 +17,7 @@ namespace MessagePackCompiler.Generator /// <summary> /// Class to produce the template output /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public partial class UnionTemplate : UnionTemplateBase { /// <summary> @@ -33,39 +33,43 @@ namespace MessagePackCompiler.Generator #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1649 // File name should match first type name namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - this.Write("\r\n{\r\n using System;\r\n using System.Buffers;\r\n using System.Collections.G" + - "eneric;\r\n using MessagePack;\r\n\r\n"); + this.Write("\r\n{\r\n"); foreach(var info in UnionSerializationInfos) { this.Write(" public sealed class "); this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<"); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - this.Write(">\r\n {\r\n private readonly Dictionary<RuntimeTypeHandle, KeyValuePair<int" + - ", int>> typeToKeyAndJumpMap;\r\n private readonly Dictionary<int, int> keyT" + - "oJumpMap;\r\n\r\n public "); + this.Write(@"> + { + private readonly global::System.Collections.Generic.Dictionary<global::System.RuntimeTypeHandle, global::System.Collections.Generic.KeyValuePair<int, int>> typeToKeyAndJumpMap; + private readonly global::System.Collections.Generic.Dictionary<int, int> keyToJumpMap; + + public "); this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); - this.Write("Formatter()\r\n {\r\n this.typeToKeyAndJumpMap = new Dictionary<Run" + - "timeTypeHandle, KeyValuePair<int, int>>("); + this.Write("Formatter()\r\n {\r\n this.typeToKeyAndJumpMap = new global::System" + + ".Collections.Generic.Dictionary<global::System.RuntimeTypeHandle, global::System" + + ".Collections.Generic.KeyValuePair<int, int>>("); this.Write(this.ToStringHelper.ToStringWithCulture(info.SubTypes.Length)); this.Write(", global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)\r\n " + " {\r\n"); for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; this.Write(" { typeof("); this.Write(this.ToStringHelper.ToStringWithCulture(item.Type)); - this.Write(").TypeHandle, new KeyValuePair<int, int>("); + this.Write(").TypeHandle, new global::System.Collections.Generic.KeyValuePair<int, int>("); this.Write(this.ToStringHelper.ToStringWithCulture(item.Key)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(i)); this.Write(") },\r\n"); } - this.Write(" };\r\n this.keyToJumpMap = new Dictionary<int, int>("); + this.Write(" };\r\n this.keyToJumpMap = new global::System.Collections.Ge" + + "neric.Dictionary<int, int>("); this.Write(this.ToStringHelper.ToStringWithCulture(info.SubTypes.Length)); this.Write(")\r\n {\r\n"); for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; @@ -75,12 +79,12 @@ namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(i)); this.Write(" },\r\n"); } - this.Write(" };\r\n }\r\n\r\n public void Serialize(ref MessagePackWriter " + - "writer, "); + this.Write(" };\r\n }\r\n\r\n public void Serialize(ref global::MessagePac" + + "k.MessagePackWriter writer, "); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); this.Write(@" value, global::MessagePack.MessagePackSerializerOptions options) { - KeyValuePair<int, int> keyValuePair; + global::System.Collections.Generic.KeyValuePair<int, int> keyValuePair; if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair)) { writer.WriteArrayHeader(2); @@ -101,7 +105,7 @@ namespace "); "\r\n return;\r\n }\r\n\r\n writer.WriteNil();\r\n " + " }\r\n\r\n public "); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - this.Write(@" Deserialize(ref MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) + this.Write(@" Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) { if (reader.TryReadNil()) { @@ -110,7 +114,7 @@ namespace "); if (reader.ReadArrayHeader() != 2) { - throw new InvalidOperationException(""Invalid Union data was detected. Type:"); + throw new global::System.InvalidOperationException(""Invalid Union data was detected. Type:"); this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); this.Write("\");\r\n }\r\n\r\n options.Security.DepthStep(ref reader);\r\n " + " var key = reader.ReadInt32();\r\n\r\n if (!this.keyToJumpMap.TryGet" + @@ -139,7 +143,6 @@ namespace "); #pragma warning restore 618 #pragma warning restore 612 -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1403 // File may only contain a single namespace #pragma warning restore SA1649 // File name should match first type name "); @@ -150,7 +153,7 @@ namespace "); /// <summary> /// Base class for this transformation /// </summary> - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] public class UnionTemplateBase { #region Fields diff --git a/src/MessagePack.GeneratorCore/Generator/UnionTemplate.tt b/src/MessagePack.GeneratorCore/Generator/UnionTemplate.tt index 216cf3c3..eb9272d0 100644 --- a/src/MessagePack.GeneratorCore/Generator/UnionTemplate.tt +++ b/src/MessagePack.GeneratorCore/Generator/UnionTemplate.tt @@ -11,33 +11,28 @@ #pragma warning disable 612 #pragma warning disable 414 #pragma warning disable 168 +#pragma warning disable CS1591 // document public APIs -#pragma warning disable SA1200 // Using directives should be placed correctly #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1649 // File name should match first type name namespace <#= Namespace #> { - using System; - using System.Buffers; - using System.Collections.Generic; - using MessagePack; - <# foreach(var info in UnionSerializationInfos) { #> public sealed class <#= info.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= info.FullName #>> { - private readonly Dictionary<RuntimeTypeHandle, KeyValuePair<int, int>> typeToKeyAndJumpMap; - private readonly Dictionary<int, int> keyToJumpMap; + private readonly global::System.Collections.Generic.Dictionary<global::System.RuntimeTypeHandle, global::System.Collections.Generic.KeyValuePair<int, int>> typeToKeyAndJumpMap; + private readonly global::System.Collections.Generic.Dictionary<int, int> keyToJumpMap; public <#= info.Name #>Formatter() { - this.typeToKeyAndJumpMap = new Dictionary<RuntimeTypeHandle, KeyValuePair<int, int>>(<#= info.SubTypes.Length #>, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default) + this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary<global::System.RuntimeTypeHandle, global::System.Collections.Generic.KeyValuePair<int, int>>(<#= info.SubTypes.Length #>, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default) { <# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> - { typeof(<#= item.Type #>).TypeHandle, new KeyValuePair<int, int>(<#= item.Key #>, <#= i #>) }, + { typeof(<#= item.Type #>).TypeHandle, new global::System.Collections.Generic.KeyValuePair<int, int>(<#= item.Key #>, <#= i #>) }, <# } #> }; - this.keyToJumpMap = new Dictionary<int, int>(<#= info.SubTypes.Length #>) + this.keyToJumpMap = new global::System.Collections.Generic.Dictionary<int, int>(<#= info.SubTypes.Length #>) { <# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> { <#= item.Key #>, <#= i #> }, @@ -45,9 +40,9 @@ namespace <#= Namespace #> }; } - public void Serialize(ref MessagePackWriter writer, <#= info.FullName #> value, global::MessagePack.MessagePackSerializerOptions options) + public void Serialize(ref global::MessagePack.MessagePackWriter writer, <#= info.FullName #> value, global::MessagePack.MessagePackSerializerOptions options) { - KeyValuePair<int, int> keyValuePair; + global::System.Collections.Generic.KeyValuePair<int, int> keyValuePair; if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair)) { writer.WriteArrayHeader(2); @@ -69,7 +64,7 @@ namespace <#= Namespace #> writer.WriteNil(); } - public <#= info.FullName #> Deserialize(ref MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) + public <#= info.FullName #> Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) { if (reader.TryReadNil()) { @@ -78,7 +73,7 @@ namespace <#= Namespace #> if (reader.ReadArrayHeader() != 2) { - throw new InvalidOperationException("Invalid Union data was detected. Type:<#= info.FullName #>"); + throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:<#= info.FullName #>"); } options.Security.DepthStep(ref reader); @@ -116,6 +111,5 @@ namespace <#= Namespace #> #pragma warning restore 618 #pragma warning restore 612 -#pragma warning restore SA1200 // Using directives should be placed correctly #pragma warning restore SA1403 // File may only contain a single namespace #pragma warning restore SA1649 // File name should match first type name diff --git a/src/MessagePack.GeneratorCore/MessagePack.GeneratorCore.csproj b/src/MessagePack.GeneratorCore/MessagePack.GeneratorCore.csproj index 526615e5..df4755e2 100644 --- a/src/MessagePack.GeneratorCore/MessagePack.GeneratorCore.csproj +++ b/src/MessagePack.GeneratorCore/MessagePack.GeneratorCore.csproj @@ -11,9 +11,8 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.10.0" /> - <PackageReference Include="Microsoft.Build" Version="15.9.20" /> - <PackageReference Include="System.CodeDom" Version="4.7.0" /> + <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" /> + <PackageReference Include="System.CodeDom" Version="6.0.0" /> </ItemGroup> <ItemGroup> diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/DateTimeFormatters.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/DateTimeFormatters.cs index 06d2ef80..07da2097 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/DateTimeFormatters.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/DateTimeFormatters.cs @@ -70,4 +70,50 @@ namespace MessagePack.Formatters return array; } } + +#if NET6_0_OR_GREATER + /// <summary> + /// Serializes a <see cref="DateOnly"/> value as an ordinary <see cref="int"/> using the <see cref="DateOnly.DayNumber"/>. + /// </summary> + public sealed class DateOnlyFormatter : IMessagePackFormatter<DateOnly> + { + public static readonly DateOnlyFormatter Instance = new DateOnlyFormatter(); + + private DateOnlyFormatter() + { + } + + public void Serialize(ref MessagePackWriter writer, DateOnly value, MessagePackSerializerOptions options) + { + writer.Write(value.DayNumber); + } + + public DateOnly Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + return DateOnly.FromDayNumber(reader.ReadInt32()); + } + } + + /// <summary> + /// Serializes a <see cref="TimeOnly"/> value as an extension, recording either seconds or ticks depending on the resolution required. + /// </summary> + public sealed class TimeOnlyFormatter : IMessagePackFormatter<TimeOnly> + { + public static readonly TimeOnlyFormatter Instance = new TimeOnlyFormatter(); + + private TimeOnlyFormatter() + { + } + + public void Serialize(ref MessagePackWriter writer, TimeOnly value, MessagePackSerializerOptions options) + { + writer.Write(value.Ticks); + } + + public TimeOnly Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + return new TimeOnly(reader.ReadInt64()); + } + } +#endif } diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs new file mode 100644 index 00000000..9e07521b --- /dev/null +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs @@ -0,0 +1,61 @@ +// Copyright (c) All contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Microsoft.NET.StringTools; + +namespace MessagePack.Formatters +{ + /// <summary> + /// A <see cref="string" /> formatter that interns strings on deserialization. + /// </summary> + public sealed class StringInterningFormatter : IMessagePackFormatter<string> + { + /// <inheritdoc/> + public string Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + if (reader.TryReadNil()) + { + return null; + } + + MessagePackReader retryReader = reader; + if (reader.TryReadStringSpan(out ReadOnlySpan<byte> bytes)) + { + if (bytes.Length < 4096) + { + if (bytes.Length == 0) + { + return string.Empty; + } + + Span<char> chars = stackalloc char[bytes.Length]; + int charLength; +#if SPAN_BUILTIN + charLength = StringEncoding.UTF8.GetChars(bytes, chars); +#else + unsafe + { + fixed (byte* pBytes = bytes) + fixed (char* pChars = chars) + { + charLength = StringEncoding.UTF8.GetChars(pBytes, bytes.Length, pChars, chars.Length); + } + } +#endif + return Strings.WeakIntern(chars.Slice(0, charLength)); + } + else + { + // Rewind the reader to the start of the string because we're taking the slow path. + reader = retryReader; + } + } + + return Strings.WeakIntern(reader.ReadString()); + } + + /// <inheritdoc/> + public void Serialize(ref MessagePackWriter writer, string value, MessagePackSerializerOptions options) => writer.Write(value); + } +} diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs.meta b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs.meta new file mode 100644 index 00000000..329667d4 --- /dev/null +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StringInterningFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78f9cfd44a10b334582b112b07143434 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs index 9fe752df..2813b92e 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs @@ -27,7 +27,11 @@ namespace Nerdbank.Streams [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")] internal class Sequence<T> : IBufferWriter<T>, IDisposable { - private static readonly int DefaultLengthFromArrayPool = 1 + (4095 / Marshal.SizeOf<T>()); + private const int MaximumAutoGrowSize = 32 * 1024; + + private static readonly int DefaultLengthFromArrayPool = 1 + (4095 / Unsafe.SizeOf<T>()); + + private static readonly ReadOnlySequence<T> Empty = new ReadOnlySequence<T>(SequenceSegment.Empty, 0, SequenceSegment.Empty, 0); private readonly Stack<SequenceSegment> segmentPool = new Stack<SequenceSegment>(); @@ -87,10 +91,22 @@ namespace Nerdbank.Streams /// The <see cref="MemoryPool{T}"/> in use may itself have a minimum array length as well, /// in which case the higher of the two minimums dictate the minimum array size that will be allocated. /// </para> + /// <para> + /// If <see cref="AutoIncreaseMinimumSpanLength"/> is <c>true</c>, this value may be automatically increased as the length of a sequence grows. + /// </para> /// </remarks> public int MinimumSpanLength { get; set; } = 0; /// <summary> + /// Gets or sets a value indicating whether the <see cref="MinimumSpanLength"/> should be + /// intelligently increased as the length of the sequence grows. + /// </summary> + /// <remarks> + /// This can help prevent long sequences made up of many very small arrays. + /// </remarks> + public bool AutoIncreaseMinimumSpanLength { get; set; } = true; + + /// <summary> /// Gets this sequence expressed as a <see cref="ReadOnlySequence{T}"/>. /// </summary> /// <returns>A read only sequence representing the data in this object.</returns> @@ -112,9 +128,9 @@ namespace Nerdbank.Streams /// <param name="sequence">The sequence to convert.</param> public static implicit operator ReadOnlySequence<T>(Sequence<T> sequence) { - return sequence.first != null + return sequence.first != null && sequence.last != null ? new ReadOnlySequence<T>(sequence.first, sequence.first.Start, sequence.last, sequence.last.End) - : ReadOnlySequence<T>.Empty; + : Empty; } /// <summary> @@ -128,10 +144,22 @@ namespace Nerdbank.Streams public void AdvanceTo(SequencePosition position) { var firstSegment = (SequenceSegment)position.GetObject(); + if (firstSegment == null) + { + // Emulate PipeReader behavior which is to just return for default(SequencePosition) + return; + } + + if (ReferenceEquals(firstSegment, SequenceSegment.Empty) && this.Length == 0) + { + // We were called with our own empty buffer segment. + return; + } + int firstIndex = position.GetInteger(); // Before making any mutations, confirm that the block specified belongs to this sequence. - var current = this.first; + Sequence<T>.SequenceSegment current = this.first; while (current != firstSegment && current != null) { current = current.Next; @@ -151,12 +179,7 @@ namespace Nerdbank.Streams firstSegment.AdvanceTo(firstIndex); - if (firstSegment.Length == 0) - { - firstSegment = this.RecycleAndGetNext(firstSegment); - } - - this.first = firstSegment; + this.first = firstSegment.Length == 0 ? this.RecycleAndGetNext(firstSegment) : firstSegment; if (this.first == null) { @@ -174,6 +197,7 @@ namespace Nerdbank.Streams SequenceSegment last = this.last; Verify.Operation(last != null, "Cannot advance before acquiring memory."); last.Advance(count); + this.ConsiderMinimumSizeIncrease(); } /// <summary> @@ -191,6 +215,24 @@ namespace Nerdbank.Streams public Span<T> GetSpan(int sizeHint) => this.GetSegment(sizeHint).RemainingSpan; /// <summary> + /// Adds an existing memory location to this sequence without copying. + /// </summary> + /// <param name="memory">The memory to add.</param> + /// <remarks> + /// This *may* leave significant slack space in a previously allocated block if calls to <see cref="Append(ReadOnlyMemory{T})"/> + /// follow calls to <see cref="GetMemory(int)"/> or <see cref="GetSpan(int)"/>. + /// </remarks> + public void Append(ReadOnlyMemory<T> memory) + { + if (memory.Length > 0) + { + Sequence<T>.SequenceSegment segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment(); + segment.AssignForeign(memory); + this.Append(segment); + } + } + + /// <summary> /// Clears the entire sequence, recycles associated memory into pools, /// and resets this instance for reuse. /// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance. @@ -204,7 +246,7 @@ namespace Nerdbank.Streams /// </summary> public void Reset() { - var current = this.first; + Sequence<T>.SequenceSegment current = this.first; while (current != null) { current = this.RecycleAndGetNext(current); @@ -236,7 +278,7 @@ namespace Nerdbank.Streams if (minBufferSize.HasValue) { - var segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment(); + Sequence<T>.SequenceSegment segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment(); if (this.arrayPool != null) { segment.Assign(this.arrayPool.Rent(minBufferSize.Value == -1 ? DefaultLengthFromArrayPool : minBufferSize.Value)); @@ -268,7 +310,7 @@ namespace Nerdbank.Streams else { // The last block is completely unused. Replace it instead of appending to it. - var current = this.first; + Sequence<T>.SequenceSegment current = this.first; if (this.first != this.last) { while (current.Next != this.last) @@ -291,24 +333,40 @@ namespace Nerdbank.Streams private SequenceSegment RecycleAndGetNext(SequenceSegment segment) { - var recycledSegment = segment; - segment = segment.Next; + Sequence<T>.SequenceSegment recycledSegment = segment; + Sequence<T>.SequenceSegment nextSegment = segment.Next; recycledSegment.ResetMemory(this.arrayPool); this.segmentPool.Push(recycledSegment); - return segment; + return nextSegment; + } + + private void ConsiderMinimumSizeIncrease() + { + if (this.AutoIncreaseMinimumSpanLength && this.MinimumSpanLength < MaximumAutoGrowSize) + { + int autoSize = Math.Min(MaximumAutoGrowSize, (int)Math.Min(int.MaxValue, this.Length / 2)); + if (this.MinimumSpanLength < autoSize) + { + this.MinimumSpanLength = autoSize; + } + } } private class SequenceSegment : ReadOnlySequenceSegment<T> { + internal static readonly SequenceSegment Empty = new SequenceSegment(); + /// <summary> /// A value indicating whether the element may contain references (and thus must be cleared). /// </summary> private static readonly bool MayContainReferences = !typeof(T).GetTypeInfo().IsPrimitive; +#pragma warning disable SA1011 // Closing square brackets should be spaced correctly /// <summary> /// Gets the backing array, when using an <see cref="ArrayPool{T}"/> instead of a <see cref="MemoryPool{T}"/>. /// </summary> private T[] array; +#pragma warning restore SA1011 // Closing square brackets should be spaced correctly /// <summary> /// Gets the position within <see cref="ReadOnlySequenceSegment{T}.Memory"/> where the data starts. @@ -363,6 +421,11 @@ namespace Nerdbank.Streams } /// <summary> + /// Gets a value indicating whether this segment refers to memory that came from outside and that we cannot write to nor recycle. + /// </summary> + internal bool IsForeignMemory => this.array == null && this.MemoryOwner == null; + + /// <summary> /// Assigns this (recyclable) segment a new area in memory. /// </summary> /// <param name="memoryOwner">The memory and a means to recycle it.</param> @@ -383,11 +446,21 @@ namespace Nerdbank.Streams } /// <summary> + /// Assigns this (recyclable) segment a new area in memory. + /// </summary> + /// <param name="memory">A memory block obtained from outside, that we do not own and should not recycle.</param> + internal void AssignForeign(ReadOnlyMemory<T> memory) + { + this.Memory = memory; + this.End = memory.Length; + } + + /// <summary> /// Clears all fields in preparation to recycle this instance. /// </summary> internal void ResetMemory(ArrayPool<T> arrayPool) { - this.ClearReferences(this.Start, this.End); + this.ClearReferences(this.Start, this.End - this.Start); this.Memory = default; this.Next = null; this.RunningIndex = 0; @@ -411,14 +484,17 @@ namespace Nerdbank.Streams /// <param name="segment">The next segment in the linked list.</param> internal void SetNext(SequenceSegment segment) { - Debug.Assert(segment != null, "Null not allowed."); this.Next = segment; segment.RunningIndex = this.RunningIndex + this.Start + this.Length; - // When setting Memory, we start with index 0 instead of this.Start because - // the first segment has an explicit index set anyway, - // and we don't want to double-count it here. - this.Memory = this.AvailableMemory.Slice(0, this.Start + this.Length); + // Trim any slack on this segment. + if (!this.IsForeignMemory) + { + // When setting Memory, we start with index 0 instead of this.Start because + // the first segment has an explicit index set anyway, + // and we don't want to double-count it here. + this.Memory = this.AvailableMemory.Slice(0, this.Start + this.Length); + } } /// <summary> diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePack.asmdef b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePack.asmdef index f1e851eb..ff7f5b38 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePack.asmdef +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePack.asmdef @@ -13,9 +13,10 @@ "System.Buffers.dll", "System.Threading.Tasks.Extensions.dll", "System.Runtime.CompilerServices.Unsafe.dll", + "Microsoft.NET.StringTools.dll", "System.Runtime.Extensions.dll" ], "autoReferenced": true, "defineConstraints": [], "versionDefines": [] -}
\ No newline at end of file +} diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.Json.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.Json.cs index 1d604957..38e39985 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.Json.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.Json.cs @@ -171,7 +171,7 @@ namespace MessagePack } scratchWriter.Flush(); - ToLZ4BinaryCore(scratchRental.Value, ref writer, options.Compression); + ToLZ4BinaryCore(scratchRental.Value, ref writer, options.Compression, options.CompressionMinLength); } } else diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.cs index a4f902f5..f3773f70 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializer.cs @@ -18,8 +18,7 @@ namespace MessagePack [System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Each overload has sufficiently unique required parameters.")] public static partial class MessagePackSerializer { - private const int LZ4NotCompressionSizeInLz4BlockType = 64; - private const int MaxHintSize = 1024 * 1024; + private static MessagePackSerializerOptions defaultOptions; /// <summary> /// Gets or sets the default set of options to use when not explicitly specified for a method call. @@ -33,7 +32,20 @@ namespace MessagePack /// If you are an app author, realize that setting this property impacts the entire application so it should only be /// set once, and before any use of <see cref="MessagePackSerializer"/> occurs. /// </remarks> - public static MessagePackSerializerOptions DefaultOptions { get; set; } = MessagePackSerializerOptions.Standard; + public static MessagePackSerializerOptions DefaultOptions + { + get + { + if (defaultOptions is null) + { + defaultOptions = MessagePackSerializerOptions.Standard; + } + + return defaultOptions; + } + + set => defaultOptions = value; + } /// <summary> /// A thread-local, recyclable array that may be used for short bursts of code. @@ -92,7 +104,7 @@ namespace MessagePack MessagePackWriter scratchWriter = writer.Clone(scratch); options.Resolver.GetFormatterWithVerify<T>().Serialize(ref scratchWriter, value, options); scratchWriter.Flush(); - ToLZ4BinaryCore(scratch, ref writer, options.Compression); + ToLZ4BinaryCore(scratch, ref writer, options.Compression, options.CompressionMinLength); } } else @@ -348,7 +360,7 @@ namespace MessagePack do { cancellationToken.ThrowIfCancellationRequested(); - Span<byte> span = sequence.GetSpan(stream.CanSeek ? (int)Math.Min(MaxHintSize, stream.Length - stream.Position) : 0); + Span<byte> span = sequence.GetSpan(stream.CanSeek ? (int)Math.Min(options.SuggestedContiguousMemorySize, stream.Length - stream.Position) : 0); bytesRead = stream.Read(span); sequence.Advance(bytesRead); } @@ -396,7 +408,7 @@ namespace MessagePack int bytesRead; do { - Memory<byte> memory = sequence.GetMemory(stream.CanSeek ? (int)Math.Min(MaxHintSize, stream.Length - stream.Position) : 0); + Memory<byte> memory = sequence.GetMemory(stream.CanSeek ? (int)Math.Min(options.SuggestedContiguousMemorySize, stream.Length - stream.Position) : 0); bytesRead = await stream.ReadAsync(memory, cancellationToken).ConfigureAwait(false); sequence.Advance(bytesRead); } @@ -567,16 +579,16 @@ namespace MessagePack return false; } - private static void ToLZ4BinaryCore(in ReadOnlySequence<byte> msgpackUncompressedData, ref MessagePackWriter writer, MessagePackCompression compression) + private static void ToLZ4BinaryCore(in ReadOnlySequence<byte> msgpackUncompressedData, ref MessagePackWriter writer, MessagePackCompression compression, int minCompressionSize) { - if (compression == MessagePackCompression.Lz4Block) + if (msgpackUncompressedData.Length < minCompressionSize) { - if (msgpackUncompressedData.Length < LZ4NotCompressionSizeInLz4BlockType) - { - writer.WriteRaw(msgpackUncompressedData); - return; - } + writer.WriteRaw(msgpackUncompressedData); + return; + } + if (compression == MessagePackCompression.Lz4Block) + { var maxCompressedLength = LZ4Codec.MaximumOutputLength((int)msgpackUncompressedData.Length); var lz4Span = ArrayPool<byte>.Shared.Rent(maxCompressedLength); try diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializerOptions.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializerOptions.cs index bc1557b0..de2bb4b8 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializerOptions.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializerOptions.cs @@ -42,7 +42,7 @@ namespace MessagePack /// <summary> /// Initializes a new instance of the <see cref="MessagePackSerializerOptions"/> class. /// </summary> - protected internal MessagePackSerializerOptions(IFormatterResolver resolver) + public MessagePackSerializerOptions(IFormatterResolver resolver) { this.Resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); } @@ -61,6 +61,8 @@ namespace MessagePack this.Resolver = copyFrom.Resolver; this.Compression = copyFrom.Compression; + this.CompressionMinLength = copyFrom.CompressionMinLength; + this.SuggestedContiguousMemorySize = copyFrom.SuggestedContiguousMemorySize; this.OldSpec = copyFrom.OldSpec; this.OmitAssemblyVersion = copyFrom.OmitAssemblyVersion; this.AllowAssemblyVersionMismatch = copyFrom.AllowAssemblyVersionMismatch; @@ -86,6 +88,26 @@ namespace MessagePack public MessagePackCompression Compression { get; private set; } /// <summary> + /// Gets the length a serialized msgpack result must equal or exceed before <see cref="Compression"/> is applied. + /// </summary> + /// <value>The default value is 64.</value> + /// <remarks> + /// When compression is <em>not</em> applied due to a short serialized result, deserialization will still succeed + /// even if <see cref="Compression"/> is set to something other than <see cref="MessagePackCompression.None"/>. + /// </remarks> + public int CompressionMinLength { get; private set; } = 64; + + /// <summary> + /// Gets the size of contiguous memory blocks in bytes that may be allocated for buffering purposes. + /// </summary> + /// <value>The default value is 1MB.</value> + /// <remarks> + /// Larger values may perform a bit faster, but may result in adding a runtime perf tax due to using the + /// <see href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap">Large Object Heap</see>. + /// </remarks> + public int SuggestedContiguousMemorySize { get; private set; } = 1024 * 1024; + + /// <summary> /// Gets a value indicating whether to serialize with <see cref="MessagePackWriter.OldSpec"/> set to some value /// causing messagepack spec compliance to be explicitly set to the old or new format. /// </summary> @@ -199,6 +221,50 @@ namespace MessagePack } /// <summary> + /// Gets a copy of these options with the <see cref="CompressionMinLength"/> property set to a new value. + /// </summary> + /// <param name="compressionMinLength">The new value for the <see cref="CompressionMinLength"/> property. Must be a positive integer.</param> + /// <returns>The new instance; or the original if the value is unchanged.</returns> + public MessagePackSerializerOptions WithCompressionMinLength(int compressionMinLength) + { + if (this.CompressionMinLength == compressionMinLength) + { + return this; + } + + if (compressionMinLength <= 0) + { + throw new ArgumentOutOfRangeException(nameof(compressionMinLength)); + } + + var result = this.Clone(); + result.CompressionMinLength = compressionMinLength; + return result; + } + + /// <summary> + /// Gets a copy of these options with the <see cref="SuggestedContiguousMemorySize"/> property set to a new value. + /// </summary> + /// <param name="suggestedContiguousMemorySize">The new value for the <see cref="SuggestedContiguousMemorySize"/> property. Must be at least 256.</param> + /// <returns>The new instance; or the original if the value is unchanged.</returns> + public MessagePackSerializerOptions WithSuggestedContiguousMemorySize(int suggestedContiguousMemorySize) + { + if (this.SuggestedContiguousMemorySize == suggestedContiguousMemorySize) + { + return this; + } + + if (suggestedContiguousMemorySize < 256) + { + throw new ArgumentOutOfRangeException(nameof(suggestedContiguousMemorySize), "This should be at least 256"); + } + + var result = this.Clone(); + result.SuggestedContiguousMemorySize = suggestedContiguousMemorySize; + return result; + } + + /// <summary> /// Gets a copy of these options with the <see cref="OldSpec"/> property set to a new value. /// </summary> /// <param name="oldSpec">The new value for the <see cref="OldSpec"/>.</param> diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/BuiltinResolver.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/BuiltinResolver.cs index 000b9fbd..0defd99f 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/BuiltinResolver.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/BuiltinResolver.cs @@ -64,9 +64,13 @@ namespace MessagePack.Internal { typeof(byte), ByteFormatter.Instance }, { typeof(sbyte), SByteFormatter.Instance }, { typeof(DateTime), DateTimeFormatter.Instance }, +#if NET6_0_OR_GREATER + { typeof(DateOnly), DateOnlyFormatter.Instance }, + { typeof(TimeOnly), TimeOnlyFormatter.Instance }, +#endif { typeof(char), CharFormatter.Instance }, - // Nulllable Primitive + // Nullable Primitive { typeof(Int16?), NullableInt16Formatter.Instance }, { typeof(Int32?), NullableInt32Formatter.Instance }, { typeof(Int64?), NullableInt64Formatter.Instance }, diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json index 677cba61..19011e4f 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json @@ -1,7 +1,7 @@ { "name": "com.neuecc.messagepack", "displayName": "MessagePack", - "version": "2.3.74", + "version": "2.4.25", "unity": "2018.4", "description": "Extremely Fast MessagePack Serializer for C#.", "keywords": [ diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackSerializerOptionsTests.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackSerializerOptionsTests.cs index 96bec149..0db5157c 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackSerializerOptionsTests.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackSerializerOptionsTests.cs @@ -1,6 +1,7 @@ // Copyright (c) All contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using MessagePack; using MessagePack.Resolvers; using Xunit; @@ -13,7 +14,8 @@ public class MessagePackSerializerOptionsTests .WithOmitAssemblyVersion(true) .WithResolver(BuiltinResolver.Instance) .WithOldSpec(false) - .WithSecurity(MySecurityOptions.Instance); + .WithSecurity(MySecurityOptions.Instance) + .WithSuggestedContiguousMemorySize(64 * 1024); [Fact] public void AllowAssemblyVersionMismatch() @@ -37,6 +39,26 @@ public class MessagePackSerializerOptionsTests } [Fact] + public void CompressionMinLength() + { + Assert.Equal(64, MessagePackSerializerOptions.Standard.CompressionMinLength); + Assert.Throws<ArgumentOutOfRangeException>(() => MessagePackSerializerOptions.Standard.WithCompressionMinLength(0)); + Assert.Throws<ArgumentOutOfRangeException>(() => MessagePackSerializerOptions.Standard.WithCompressionMinLength(-1)); + MessagePackSerializerOptions options = MessagePackSerializerOptions.Standard.WithCompressionMinLength(128); + Assert.Equal(128, options.CompressionMinLength); + } + + [Fact] + public void SuggestedContiguousMemorySize() + { + Assert.Equal(1024 * 1024, MessagePackSerializerOptions.Standard.SuggestedContiguousMemorySize); + Assert.Throws<ArgumentOutOfRangeException>(() => MessagePackSerializerOptions.Standard.WithSuggestedContiguousMemorySize(0)); + Assert.Throws<ArgumentOutOfRangeException>(() => MessagePackSerializerOptions.Standard.WithSuggestedContiguousMemorySize(4)); + MessagePackSerializerOptions options = MessagePackSerializerOptions.Standard.WithSuggestedContiguousMemorySize(512); + Assert.Equal(512, options.SuggestedContiguousMemorySize); + } + + [Fact] public void OldSpec() { Assert.Null(MessagePackSerializerOptions.Standard.OldSpec); @@ -63,6 +85,7 @@ public class MessagePackSerializerOptionsTests var mutated = NonDefaultOptions.WithOldSpec(true); Assert.True(mutated.OldSpec.Value); Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.SuggestedContiguousMemorySize, mutated.SuggestedContiguousMemorySize); Assert.Equal(NonDefaultOptions.AllowAssemblyVersionMismatch, mutated.AllowAssemblyVersionMismatch); Assert.Equal(NonDefaultOptions.OmitAssemblyVersion, mutated.OmitAssemblyVersion); Assert.Same(NonDefaultOptions.Resolver, mutated.Resolver); @@ -82,11 +105,25 @@ public class MessagePackSerializerOptionsTests } [Fact] + public void WithSuggestedContiguousMemorySize_PreservesOtherProperties() + { + var mutated = NonDefaultOptions.WithSuggestedContiguousMemorySize(612); + Assert.Equal(612, mutated.SuggestedContiguousMemorySize); + Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.OldSpec, mutated.OldSpec); + Assert.Equal(NonDefaultOptions.AllowAssemblyVersionMismatch, mutated.AllowAssemblyVersionMismatch); + Assert.Equal(NonDefaultOptions.OmitAssemblyVersion, mutated.OmitAssemblyVersion); + Assert.Same(NonDefaultOptions.Resolver, mutated.Resolver); + Assert.Same(MySecurityOptions.Instance, mutated.Security); + } + + [Fact] public void WithAllowAssemblyVersionMismatch_PreservesOtherProperties() { var mutated = NonDefaultOptions.WithAllowAssemblyVersionMismatch(false); Assert.False(mutated.AllowAssemblyVersionMismatch); Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.SuggestedContiguousMemorySize, mutated.SuggestedContiguousMemorySize); Assert.Equal(NonDefaultOptions.OldSpec, mutated.OldSpec); Assert.Equal(NonDefaultOptions.OmitAssemblyVersion, mutated.OmitAssemblyVersion); Assert.Same(NonDefaultOptions.Resolver, mutated.Resolver); @@ -99,6 +136,7 @@ public class MessagePackSerializerOptionsTests var mutated = NonDefaultOptions.WithOmitAssemblyVersion(false); Assert.False(mutated.OmitAssemblyVersion); Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.SuggestedContiguousMemorySize, mutated.SuggestedContiguousMemorySize); Assert.Equal(NonDefaultOptions.OldSpec, mutated.OldSpec); Assert.Equal(NonDefaultOptions.AllowAssemblyVersionMismatch, mutated.AllowAssemblyVersionMismatch); Assert.Same(NonDefaultOptions.Resolver, mutated.Resolver); @@ -111,6 +149,7 @@ public class MessagePackSerializerOptionsTests var mutated = NonDefaultOptions.WithResolver(ContractlessStandardResolver.Instance); Assert.Same(ContractlessStandardResolver.Instance, mutated.Resolver); Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.SuggestedContiguousMemorySize, mutated.SuggestedContiguousMemorySize); Assert.Equal(NonDefaultOptions.OldSpec, mutated.OldSpec); Assert.Equal(NonDefaultOptions.AllowAssemblyVersionMismatch, mutated.AllowAssemblyVersionMismatch); Assert.Equal(NonDefaultOptions.OmitAssemblyVersion, mutated.OmitAssemblyVersion); @@ -124,6 +163,7 @@ public class MessagePackSerializerOptionsTests Assert.Same(MessagePackSecurity.TrustedData, mutated.Security); Assert.Same(NonDefaultOptions.Resolver, mutated.Resolver); Assert.Equal(NonDefaultOptions.Compression, mutated.Compression); + Assert.Equal(NonDefaultOptions.SuggestedContiguousMemorySize, mutated.SuggestedContiguousMemorySize); Assert.Equal(NonDefaultOptions.OldSpec, mutated.OldSpec); Assert.Equal(NonDefaultOptions.AllowAssemblyVersionMismatch, mutated.AllowAssemblyVersionMismatch); Assert.Equal(NonDefaultOptions.OmitAssemblyVersion, mutated.OmitAssemblyVersion); diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackWriterTests.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackWriterTests.cs index 5d06e78d..85d29365 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackWriterTests.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackWriterTests.cs @@ -10,6 +10,7 @@ using System.Threading; using Nerdbank.Streams; using Xunit; using Xunit.Abstractions; +using MessagePackWriterCref = MessagePack.MessagePackWriter; namespace MessagePack.Tests { @@ -33,7 +34,7 @@ namespace MessagePack.Tests #endif /// <summary> - /// Verifies that <see cref="MessagePackWriter.WriteRaw(ReadOnlySpan{byte})"/> + /// Verifies that <see cref="MessagePackWriterCref.WriteRaw(ReadOnlySpan{byte})"/> /// accepts a span that came from stackalloc. /// </summary> [Fact] diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StandardClassLibraryFormatterTests.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StandardClassLibraryFormatterTests.cs index 12abda44..35123476 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StandardClassLibraryFormatterTests.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StandardClassLibraryFormatterTests.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Linq; +using Nerdbank.Streams; using Xunit; using Xunit.Abstractions; @@ -77,5 +77,60 @@ namespace MessagePack.Tests byte[] byte_array = MessagePackSerializer.Deserialize<byte[]>(input); Assert.Equal(new byte[] { 1, 2, 3 }, byte_array); } + +#if NET6_0_OR_GREATER + [Fact] + public void DateOnly() + { + var value = new DateOnly(2012, 3, 5); + this.AssertRoundtrip(value); + this.AssertRoundtrip<DateOnly?>(value); + this.AssertRoundtrip(new[] { value }); + } + + [Fact] + public void TimeOnly() + { + TimeOnly lowRes = new TimeOnly(5, 4, 3); + this.AssertRoundtrip(lowRes); + this.AssertRoundtrip<TimeOnly?>(lowRes); + this.AssertRoundtrip(new[] { lowRes }); + + TimeOnly mediumRes = new TimeOnly(5, 4, 3, 2); + this.AssertRoundtrip(mediumRes); + this.AssertRoundtrip<TimeOnly?>(mediumRes); + this.AssertRoundtrip(new[] { mediumRes }); + + TimeOnly highRes = new TimeOnly(lowRes.Ticks + 1); + this.AssertRoundtrip(highRes); + this.AssertRoundtrip(System.TimeOnly.MaxValue); + } +#endif + + private void AssertRoundtrip<T>(T value) + { + Assert.Equal(value, this.Roundtrip(value, breakupBuffer: false)); + Assert.Equal(value, this.Roundtrip(value, breakupBuffer: true)); + } + + private T Roundtrip<T>(T value, bool breakupBuffer = false) + { + byte[] msgpack = MessagePackSerializer.Serialize(value, MessagePackSerializerOptions.Standard); + this.logger.WriteLine("{0} 0x{1}", value, TestUtilities.ToHex(msgpack)); + + if (breakupBuffer) + { + using (Sequence<byte> seq = new Sequence<byte>()) + { + seq.Append(msgpack.AsMemory(0, msgpack.Length - 1)); + seq.Append(msgpack.AsMemory(msgpack.Length - 1, 1)); + return MessagePackSerializer.Deserialize<T>(seq, MessagePackSerializerOptions.Standard); + } + } + else + { + return MessagePackSerializer.Deserialize<T>(msgpack, MessagePackSerializerOptions.Standard); + } + } } } diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs new file mode 100644 index 00000000..d4e98f77 --- /dev/null +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs @@ -0,0 +1,107 @@ +// Copyright (c) All contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using MessagePack.Formatters; +using MessagePack.Resolvers; +using Nerdbank.Streams; +using Xunit; + +namespace MessagePack.Tests +{ + public class StringInterningTests + { + [Fact] + public void NullString() + { + var seq = new Sequence<byte>(); + var writer = new MessagePackWriter(seq); + writer.WriteNil(); + writer.Flush(); + + var reader = new MessagePackReader(seq); + string result = StandardResolver.Instance.GetFormatter<string>().Deserialize(ref reader, MessagePackSerializerOptions.Standard); + Assert.Null(result); + } + + [Fact] + public void EmptyString() + { + var seq = new Sequence<byte>(); + var writer = new MessagePackWriter(seq); + writer.Write(string.Empty); + writer.Flush(); + + var reader = new MessagePackReader(seq); + string result = StandardResolver.Instance.GetFormatter<string>().Deserialize(ref reader, MessagePackSerializerOptions.Standard); + Assert.Same(string.Empty, result); + } + + [Theory] + [InlineData(3)] + [InlineData(1024 * 1024)] + public void EquivalentStringsGetSharedInstance(int length) + { + string originalValue1 = new string('a', length); + string originalValue3 = new string('b', length); + var seq = new Sequence<byte>(); + var writer = new MessagePackWriter(seq); + writer.Write(originalValue1); + writer.Write(originalValue1); + writer.Write(originalValue3); + writer.Flush(); + + var reader = new MessagePackReader(seq); + var formatter = new StringInterningFormatter(); + string value1 = formatter.Deserialize(ref reader, MessagePackSerializerOptions.Standard); + string value2 = formatter.Deserialize(ref reader, MessagePackSerializerOptions.Standard); + string value3 = formatter.Deserialize(ref reader, MessagePackSerializerOptions.Standard); + + Assert.Equal(originalValue1, value1); + Assert.Equal(originalValue3, value3); + + Assert.Same(value1, value2); + } + + [Fact] + public void StringMemberInterning() + { + ClassOfStrings before = new ClassOfStrings { InternedString = "abc", OrdinaryString = "def" }; + ClassOfStrings after1 = MessagePackSerializer.Deserialize<ClassOfStrings>(MessagePackSerializer.Serialize(before, MessagePackSerializerOptions.Standard), MessagePackSerializerOptions.Standard); + ClassOfStrings after2 = MessagePackSerializer.Deserialize<ClassOfStrings>(MessagePackSerializer.Serialize(before, MessagePackSerializerOptions.Standard), MessagePackSerializerOptions.Standard); + Assert.Equal(after1.InternedString, after2.InternedString); + Assert.Equal(after1.OrdinaryString, after2.OrdinaryString); + + Assert.Same(after1.InternedString, after2.InternedString); + Assert.NotSame(after1.OrdinaryString, after2.OrdinaryString); + } + + [Fact] + public void StringMemberInterning_CustomResolver() + { + var options = MessagePackSerializerOptions.Standard.WithResolver( + CompositeResolver.Create( + new IMessagePackFormatter[] { new StringInterningFormatter() }, + new IFormatterResolver[] { StandardResolver.Instance })); + + ClassOfStrings before = new ClassOfStrings { InternedString = "abc", OrdinaryString = "def" }; + ClassOfStrings after1 = MessagePackSerializer.Deserialize<ClassOfStrings>(MessagePackSerializer.Serialize(before, options), options); + ClassOfStrings after2 = MessagePackSerializer.Deserialize<ClassOfStrings>(MessagePackSerializer.Serialize(before, options), options); + Assert.Equal(after1.InternedString, after2.InternedString); + Assert.Equal(after1.OrdinaryString, after2.OrdinaryString); + + Assert.Same(after1.InternedString, after2.InternedString); + Assert.Same(after1.OrdinaryString, after2.OrdinaryString); + } + + [MessagePackObject] + public class ClassOfStrings + { + [Key(0)] + [MessagePackFormatter(typeof(StringInterningFormatter))] + public string InternedString { get; set; } + + [Key(1)] + public string OrdinaryString { get; set; } + } + } +} diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs.meta b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs.meta new file mode 100644 index 00000000..a6117b9c --- /dev/null +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/StringInterningTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 593d09755237d984a95626a65167c3a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/TestUtilities.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/TestUtilities.cs index 0a4bf9fb..abc85b0f 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/TestUtilities.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/TestUtilities.cs @@ -15,6 +15,8 @@ namespace MessagePack.Tests /// Gets a value indicating whether the mono runtime is executing this code. /// </summary> internal static bool IsRunningOnMono => Type.GetType("Mono.Runtime") != null; + + internal static string ToHex(byte[] buffer) => BitConverter.ToString(buffer).Replace("-", string.Empty).ToLowerInvariant(); } public class NullTestOutputHelper : ITestOutputHelper diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs index c83b4d51..f1eee269 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs @@ -130,6 +130,11 @@ namespace Xunit { NUnit.Framework.Assert.AreSame(expected, actual); } + + public static void NotSame(object expected, object actual) + { + NUnit.Framework.Assert.AreNotSame(expected, actual); + } } [Serializable] diff --git a/src/MessagePack.UnityClient/copy_assets.bat b/src/MessagePack.UnityClient/copy_assets.bat index bb7232df..c2b03f0e 100644 --- a/src/MessagePack.UnityClient/copy_assets.bat +++ b/src/MessagePack.UnityClient/copy_assets.bat @@ -11,6 +11,7 @@ echo F | xcopy "..\..\bin\MessagePack\release\netstandard2.0\publish\System.Buffers.dll" ".\Assets\Plugins\System.Buffers.dll" /Y /I echo F | xcopy "..\..\bin\MessagePack\release\netstandard2.0\publish\System.Memory.dll" ".\Assets\Plugins\System.Memory.dll" /Y /I echo F | xcopy "..\..\bin\MessagePack\release\netstandard2.0\publish\System.Runtime.CompilerServices.Unsafe.dll" ".\Assets\Plugins\System.Runtime.CompilerServices.Unsafe.dll" /Y /I +echo F | xcopy "..\..\bin\MessagePack\release\netstandard2.0\publish\Microsoft.NET.StringTools.dll" ".\Assets\Plugins\Microsoft.NET.StringTools.dll" /Y /I echo F | xcopy "..\..\bin\MessagePack\release\netstandard2.0\publish\System.Threading.Tasks.Extensions.dll" ".\Assets\Plugins\System.Threading.Tasks.Extensions.dll" /Y /I @popd diff --git a/src/MessagePack.UnityClient/copy_assets.sh b/src/MessagePack.UnityClient/copy_assets.sh index 9912ab97..7743fd66 100755 --- a/src/MessagePack.UnityClient/copy_assets.sh +++ b/src/MessagePack.UnityClient/copy_assets.sh @@ -21,4 +21,5 @@ fi cp ${SCRIPT_DIR}/../../bin/MessagePack/${BUILDCONFIGURATION}/netstandard2.0/publish/System.Buffers.dll ${SCRIPT_DIR}/Assets/Plugins/System.Buffers.dll cp ${SCRIPT_DIR}/../../bin/MessagePack/${BUILDCONFIGURATION}/netstandard2.0/publish/System.Memory.dll ${SCRIPT_DIR}/Assets/Plugins/System.Memory.dll cp ${SCRIPT_DIR}/../../bin/MessagePack/${BUILDCONFIGURATION}/netstandard2.0/publish/System.Runtime.CompilerServices.Unsafe.dll ${SCRIPT_DIR}/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll +cp ${SCRIPT_DIR}/../../bin/MessagePack/${BUILDCONFIGURATION}/netstandard2.0/publish/Microsoft.NET.StringTools.dll ${SCRIPT_DIR}/Assets/Plugins/Microsoft.NET.StringTools.dll cp ${SCRIPT_DIR}/../../bin/MessagePack/${BUILDCONFIGURATION}/netstandard2.0/publish/System.Threading.Tasks.Extensions.dll ${SCRIPT_DIR}/Assets/Plugins/System.Threading.Tasks.Extensions.dll diff --git a/src/MessagePack/MessagePack.csproj b/src/MessagePack/MessagePack.csproj index bffdded8..801ab7de 100644 --- a/src/MessagePack/MessagePack.csproj +++ b/src/MessagePack/MessagePack.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFrameworks>netstandard2.0;netcoreapp3.1;net5.0</TargetFrameworks> + <TargetFrameworks>netstandard2.0;netcoreapp3.1;net6.0</TargetFrameworks> <NoWarn>$(NoWarn);CS0649</NoWarn> <AllowUnsafeBlocks>True</AllowUnsafeBlocks> <DefineConstants Condition=" '$(TargetFramework)' != 'netstandard2.0' ">$(DefineConstants);SPAN_BUILTIN</DefineConstants> @@ -33,16 +33,15 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.2" PrivateAssets="all" /> + <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.3" PrivateAssets="all" /> + <PackageReference Include="Microsoft.NET.StringTools" Version="1.0.0" /> </ItemGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> - <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0" /> - <PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> - <PackageReference Include="System.Reflection.Emit" Version="4.6.0" /> - <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.6.0" /> - <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" /> - <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" /> - <PackageReference Include="System.Memory" Version="4.5.3" /> + <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" /> + <PackageReference Include="System.Collections.Immutable" Version="1.7.1" /> + <PackageReference Include="System.Reflection.Emit" Version="4.7.0" /> + <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" /> + <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" /> </ItemGroup> <ItemGroup> diff --git a/src/MessagePack/net5.0/PublicAPI.Unshipped.txt b/src/MessagePack/net5.0/PublicAPI.Unshipped.txt index e69de29b..49e84ad1 100644 --- a/src/MessagePack/net5.0/PublicAPI.Unshipped.txt +++ b/src/MessagePack/net5.0/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +MessagePack.Formatters.StringInterningFormatter +MessagePack.Formatters.StringInterningFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> string +MessagePack.Formatters.StringInterningFormatter.Serialize(ref MessagePack.MessagePackWriter writer, string value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.StringInterningFormatter.StringInterningFormatter() -> void +MessagePack.MessagePackSerializerOptions.CompressionMinLength.get -> int +MessagePack.MessagePackSerializerOptions.WithCompressionMinLength(int compressionMinLength) -> MessagePack.MessagePackSerializerOptions
\ No newline at end of file diff --git a/src/MessagePack/netcoreapp2.1/PublicAPI.Shipped.txt b/src/MessagePack/net6.0/PublicAPI.Shipped.txt index c7fc0219..b0a1a3dc 100644 --- a/src/MessagePack/netcoreapp2.1/PublicAPI.Shipped.txt +++ b/src/MessagePack/net6.0/PublicAPI.Shipped.txt @@ -1015,9 +1015,7 @@ MessagePack.MessagePackSerializerOptions.Security.get -> MessagePack.MessagePack MessagePack.MessagePackSerializerOptions.WithSecurity(MessagePack.MessagePackSecurity security) -> MessagePack.MessagePackSerializerOptions MessagePack.MessagePackStreamReader.DiscardBufferedData() -> void MessagePack.MessagePackStreamReader.MessagePackStreamReader(System.IO.Stream stream, bool leaveOpen) -> void -MessagePack.MessagePackStreamReader.ReadArrayHeaderAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int> MessagePack.MessagePackStreamReader.ReadArrayAsync(System.Threading.CancellationToken cancellationToken) -> System.Collections.Generic.IAsyncEnumerable<System.Buffers.ReadOnlySequence<byte>> -MessagePack.MessagePackStreamReader.ReadMapHeaderAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int> MessagePack.MessagePackWriter.WriteBinHeader(int length) -> void MessagePack.MessagePackWriter.WriteStringHeader(int byteCount) -> void static readonly MessagePack.MessagePackSecurity.TrustedData -> MessagePack.MessagePackSecurity @@ -1155,10 +1153,17 @@ virtual MessagePack.Formatters.PrimitiveObjectFormatter.DeserializeMap(ref Messa MessagePack.ExtensionHeader.ExtensionHeader() -> void MessagePack.ExtensionResult.ExtensionResult() -> void MessagePack.FormatterNotRegisteredException.FormatterNotRegisteredException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) -> void +MessagePack.Formatters.HalfFormatter +MessagePack.Formatters.HalfFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> System.Half +MessagePack.Formatters.HalfFormatter.Serialize(ref MessagePack.MessagePackWriter writer, System.Half value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.InterfaceReadOnlySetFormatter<T> +MessagePack.Formatters.InterfaceReadOnlySetFormatter<T>.InterfaceReadOnlySetFormatter() -> void MessagePack.MessagePackReader.MessagePackReader() -> void MessagePack.MessagePackSerializerOptions.SequencePool.get -> MessagePack.SequencePool MessagePack.MessagePackSerializerOptions.WithPool(MessagePack.SequencePool pool) -> MessagePack.MessagePackSerializerOptions MessagePack.MessagePackStreamReader.MessagePackStreamReader(System.IO.Stream stream, bool leaveOpen, MessagePack.SequencePool sequencePool) -> void +MessagePack.MessagePackStreamReader.ReadArrayHeaderAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int> +MessagePack.MessagePackStreamReader.ReadMapHeaderAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int> MessagePack.MessagePackWriter.MessagePackWriter() -> void MessagePack.SequencePool MessagePack.SequencePool.SequencePool() -> void @@ -1167,6 +1172,7 @@ MessagePack.SequencePool.SequencePool(int maxSize, System.Buffers.ArrayPool<byte MessagePack.TinyJsonException.TinyJsonException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) -> void static MessagePack.Nil.operator !=(MessagePack.Nil left, MessagePack.Nil right) -> bool static MessagePack.Nil.operator ==(MessagePack.Nil left, MessagePack.Nil right) -> bool +static readonly MessagePack.Formatters.HalfFormatter.Instance -> MessagePack.Formatters.IMessagePackFormatter<System.Half> virtual MessagePack.MessagePackStreamReader.Dispose(bool disposing) -> void MessagePack.Formatters.GenericEnumerableFormatter<TElement, TCollection> MessagePack.Formatters.GenericEnumerableFormatter<TElement, TCollection>.GenericEnumerableFormatter() -> void diff --git a/src/MessagePack/net6.0/PublicAPI.Unshipped.txt b/src/MessagePack/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 00000000..89697310 --- /dev/null +++ b/src/MessagePack/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,16 @@ +MessagePack.Formatters.DateOnlyFormatter +MessagePack.Formatters.DateOnlyFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> System.DateOnly +MessagePack.Formatters.DateOnlyFormatter.Serialize(ref MessagePack.MessagePackWriter writer, System.DateOnly value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.StringInterningFormatter +MessagePack.Formatters.StringInterningFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> string +MessagePack.Formatters.StringInterningFormatter.Serialize(ref MessagePack.MessagePackWriter writer, string value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.StringInterningFormatter.StringInterningFormatter() -> void +MessagePack.Formatters.TimeOnlyFormatter +MessagePack.Formatters.TimeOnlyFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> System.TimeOnly +MessagePack.Formatters.TimeOnlyFormatter.Serialize(ref MessagePack.MessagePackWriter writer, System.TimeOnly value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.MessagePackSerializerOptions.CompressionMinLength.get -> int +MessagePack.MessagePackSerializerOptions.SuggestedContiguousMemorySize.get -> int +MessagePack.MessagePackSerializerOptions.WithCompressionMinLength(int compressionMinLength) -> MessagePack.MessagePackSerializerOptions +MessagePack.MessagePackSerializerOptions.WithSuggestedContiguousMemorySize(int suggestedContiguousMemorySize) -> MessagePack.MessagePackSerializerOptions +static readonly MessagePack.Formatters.DateOnlyFormatter.Instance -> MessagePack.Formatters.DateOnlyFormatter +static readonly MessagePack.Formatters.TimeOnlyFormatter.Instance -> MessagePack.Formatters.TimeOnlyFormatter diff --git a/src/MessagePack/netcoreapp2.1/PublicAPI.Unshipped.txt b/src/MessagePack/netcoreapp2.1/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29b..00000000 --- a/src/MessagePack/netcoreapp2.1/PublicAPI.Unshipped.txt +++ /dev/null diff --git a/src/MessagePack/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/MessagePack/netcoreapp3.1/PublicAPI.Unshipped.txt index e69de29b..ba449cac 100644 --- a/src/MessagePack/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/src/MessagePack/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +MessagePack.Formatters.StringInterningFormatter +MessagePack.Formatters.StringInterningFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> string +MessagePack.Formatters.StringInterningFormatter.Serialize(ref MessagePack.MessagePackWriter writer, string value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.StringInterningFormatter.StringInterningFormatter() -> void +MessagePack.MessagePackSerializerOptions.CompressionMinLength.get -> int +MessagePack.MessagePackSerializerOptions.SuggestedContiguousMemorySize.get -> int +MessagePack.MessagePackSerializerOptions.WithCompressionMinLength(int compressionMinLength) -> MessagePack.MessagePackSerializerOptions +MessagePack.MessagePackSerializerOptions.WithSuggestedContiguousMemorySize(int suggestedContiguousMemorySize) -> MessagePack.MessagePackSerializerOptions diff --git a/src/MessagePack/netstandard2.0/PublicAPI.Unshipped.txt b/src/MessagePack/netstandard2.0/PublicAPI.Unshipped.txt index e69de29b..2cdd3d32 100644 --- a/src/MessagePack/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/MessagePack/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +MessagePack.Formatters.StringInterningFormatter +MessagePack.Formatters.StringInterningFormatter.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> string +MessagePack.Formatters.StringInterningFormatter.Serialize(ref MessagePack.MessagePackWriter writer, string value, MessagePack.MessagePackSerializerOptions options) -> void +MessagePack.Formatters.StringInterningFormatter.StringInterningFormatter() -> void +MessagePack.MessagePackSerializerOptions.CompressionMinLength.get -> int +MessagePack.MessagePackSerializerOptions.SuggestedContiguousMemorySize.get -> int +MessagePack.MessagePackSerializerOptions.WithCompressionMinLength(int compressionMinLength) -> MessagePack.MessagePackSerializerOptions +MessagePack.MessagePackSerializerOptions.WithSuggestedContiguousMemorySize(int suggestedContiguousMemorySize) -> MessagePack.MessagePackSerializerOptions
\ No newline at end of file |