From 376818187936984c0d89fc242497b049350488c8 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 30 Sep 2019 17:07:02 +0300 Subject: [PATCH] Update NETStandard2.1 APIs (#17080) Contributes to #17064 * Add System.Data.DataSetExtensions to mobile profiles --- bcl.sln | 54 +- external/api-snapshot | 2 +- external/corefx | 2 +- mcs/class/Facades/Makefile | 2 +- .../Facades/netstandard/Facades_netstandard.csproj | 1 + mcs/class/Facades/netstandard/Makefile | 8 +- mcs/class/Facades/netstandard/TypeForwarders.cs | 22 + mcs/class/Makefile | 3 + .../System.Data.DataSetExtensions.csproj | 97 ++- mcs/class/corlib/corefx/ArrayBufferWriter.cs | 185 +++++ mcs/class/corlib/corefx/NullableAttributes.cs | 128 ++++ mcs/class/corlib/corefx/SR.missing.cs | 1 + mcs/class/corlib/corefx/SequenceReader.Search.cs | 778 +++++++++++++++++++++ mcs/class/corlib/corefx/SequenceReader.cs | 449 ++++++++++++ .../corefx/SequenceReaderExtensions.Binary.cs | 187 +++++ mcs/class/corlib/corlib.csproj | 5 + mcs/class/corlib/corlib.dll.sources | 5 + 17 files changed, 1902 insertions(+), 27 deletions(-) create mode 100644 mcs/class/corlib/corefx/ArrayBufferWriter.cs create mode 100644 mcs/class/corlib/corefx/NullableAttributes.cs create mode 100644 mcs/class/corlib/corefx/SequenceReader.Search.cs create mode 100644 mcs/class/corlib/corefx/SequenceReader.cs create mode 100644 mcs/class/corlib/corefx/SequenceReaderExtensions.Binary.cs diff --git a/bcl.sln b/bcl.sln index d1dc7ba739e..2b8beba9ace 100644 --- a/bcl.sln +++ b/bcl.sln @@ -4014,24 +4014,42 @@ Global {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|net_4_x.Build.0 = Debug|net_4_x {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|net_4_x.ActiveCfg = Release|net_4_x {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|net_4_x.Build.0 = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monodroid.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monodroid.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_tv.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_tv.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_watch.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_watch.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|orbis.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|orbis.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|unreal.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|unreal.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|wasm.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|wasm.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|winaot.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|winaot.ActiveCfg = Release|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|xammac.ActiveCfg = Debug|net_4_x - {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|xammac.ActiveCfg = Release|net_4_x + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monodroid.ActiveCfg = Debug|monodroid + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monodroid.Build.0 = Debug|monodroid + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monodroid.ActiveCfg = Release|monodroid + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monodroid.Build.0 = Release|monodroid + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch.ActiveCfg = Debug|monotouch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch.Build.0 = Debug|monotouch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch.ActiveCfg = Release|monotouch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch.Build.0 = Release|monotouch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_tv.ActiveCfg = Debug|monotouch_tv + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_tv.Build.0 = Debug|monotouch_tv + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_tv.ActiveCfg = Release|monotouch_tv + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_tv.Build.0 = Release|monotouch_tv + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_watch.ActiveCfg = Debug|monotouch_watch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|monotouch_watch.Build.0 = Debug|monotouch_watch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_watch.ActiveCfg = Release|monotouch_watch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|monotouch_watch.Build.0 = Release|monotouch_watch + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|orbis.ActiveCfg = Debug|orbis + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|orbis.Build.0 = Debug|orbis + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|orbis.ActiveCfg = Release|orbis + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|orbis.Build.0 = Release|orbis + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|unreal.ActiveCfg = Debug|unreal + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|unreal.Build.0 = Debug|unreal + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|unreal.ActiveCfg = Release|unreal + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|unreal.Build.0 = Release|unreal + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|wasm.ActiveCfg = Debug|wasm + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|wasm.Build.0 = Debug|wasm + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|wasm.ActiveCfg = Release|wasm + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|wasm.Build.0 = Release|wasm + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|winaot.ActiveCfg = Debug|winaot + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|winaot.Build.0 = Debug|winaot + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|winaot.ActiveCfg = Release|winaot + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|winaot.Build.0 = Release|winaot + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|xammac.ActiveCfg = Debug|xammac + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Debug|xammac.Build.0 = Debug|xammac + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|xammac.ActiveCfg = Release|xammac + {AC3AC4DA-7C10-4AE9-A131-6DBBE61432E3}.Release|xammac.Build.0 = Release|xammac {7C660E7A-C89B-4ACA-9458-492B6D14B168}.Debug|net_4_x.ActiveCfg = Debug|net_4_x {7C660E7A-C89B-4ACA-9458-492B6D14B168}.Debug|net_4_x.Build.0 = Debug|net_4_x {7C660E7A-C89B-4ACA-9458-492B6D14B168}.Release|net_4_x.ActiveCfg = Release|net_4_x diff --git a/external/api-snapshot b/external/api-snapshot index 258eb4aaf4a..6f14e433d28 160000 --- a/external/api-snapshot +++ b/external/api-snapshot @@ -1 +1 @@ -Subproject commit 258eb4aaf4ab516204263c80a3004da4da779752 +Subproject commit 6f14e433d28249f07ccbbee3b28fa737253a4163 diff --git a/external/corefx b/external/corefx index 65712075da8..10a41e9f982 160000 --- a/external/corefx +++ b/external/corefx @@ -1 +1 @@ -Subproject commit 65712075da8062eb2d9304104c110185001f8541 +Subproject commit 10a41e9f9828b3e299215406eadfde2ee4c9b29f diff --git a/mcs/class/Facades/Makefile b/mcs/class/Facades/Makefile index da7f8f9b5b0..a709ef2db82 100644 --- a/mcs/class/Facades/Makefile +++ b/mcs/class/Facades/Makefile @@ -38,7 +38,7 @@ doc-update-recursive: @echo "do not recurse the Facades folder" System System.Core System.ComponentModel.DataAnnotations System.Numerics System.Numerics.Vectors System.Runtime.Serialization System.Transactions System.Xml \ -System.ComponentModel.Composition System.ServiceModel System.Xml.Linq System.Data System.IO.Compression.FileSystem System.Runtime.InteropServices.RuntimeInformation \ +System.ComponentModel.Composition System.ServiceModel System.Xml.Linq System.Data System.Data.DataSetExtensions System.IO.Compression.FileSystem System.Runtime.InteropServices.RuntimeInformation \ System.ServiceProcess System.Security System.Net.Http.WebRequest System.Net.Http System.ServiceProcess System.IO.Compression System.IdentityModel System.Web \ Facades/System.Drawing.Primitives Facades/System.Drawing.Common System.Drawing System.Web.Services: diff --git a/mcs/class/Facades/netstandard/Facades_netstandard.csproj b/mcs/class/Facades/netstandard/Facades_netstandard.csproj index b07732fa11e..a11d13df5ba 100644 --- a/mcs/class/Facades/netstandard/Facades_netstandard.csproj +++ b/mcs/class/Facades/netstandard/Facades_netstandard.csproj @@ -175,6 +175,7 @@ + diff --git a/mcs/class/Facades/netstandard/Makefile b/mcs/class/Facades/netstandard/Makefile index 5cd4c43ddd5..91a8cdc57f1 100644 --- a/mcs/class/Facades/netstandard/Makefile +++ b/mcs/class/Facades/netstandard/Makefile @@ -22,13 +22,13 @@ ifeq ($(PROFILE),build) LIB_MCS_FLAGS += -d:SYSTEM_WEB_IMPLEMENTATION else ifeq ($(PROFILE),wasm) LIB_MCS_FLAGS += -d:SYSTEM_WEB_IMPLEMENTATION -unsafe -LIB_REFS += System.Transactions System.Runtime.Serialization System.Data +LIB_REFS += System.Transactions System.Runtime.Serialization System.Data System.Data.DataSetExtensions else ifeq ($(PROFILE),xammac_net_4_5) -LIB_REFS += System.Web.Services System.Transactions System.Runtime.Serialization System.Data +LIB_REFS += System.Web.Services System.Transactions System.Runtime.Serialization System.Data System.Data.DataSetExtensions else ifeq (2.1, $(FRAMEWORK_VERSION)) -LIB_REFS += System.Web.Services System.Transactions System.Runtime.Serialization System.Data +LIB_REFS += System.Web.Services System.Transactions System.Runtime.Serialization System.Data System.Data.DataSetExtensions else -LIB_REFS += System.Web System.Transactions System.Runtime.Serialization System.Data +LIB_REFS += System.Web System.Transactions System.Runtime.Serialization System.Data System.Data.DataSetExtensions endif ifneq (,$(filter build net_4_x, $(PROFILE))) diff --git a/mcs/class/Facades/netstandard/TypeForwarders.cs b/mcs/class/Facades/netstandard/TypeForwarders.cs index 31961398889..fb4d2c7be36 100644 --- a/mcs/class/Facades/netstandard/TypeForwarders.cs +++ b/mcs/class/Facades/netstandard/TypeForwarders.cs @@ -764,6 +764,16 @@ [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.SqlTypes.SqlTypeException))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.SqlTypes.SqlXml))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.SqlTypes.StorageState))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.DataRowComparer))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.DataRowComparer<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.DataRowExtensions))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.DataTableExtensions))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.EnumerableRowCollection))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.EnumerableRowCollection<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.EnumerableRowCollectionExtensions))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.OrderedEnumerableRowCollection<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.TypedTableBase<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Data.TypedTableBaseExtensions))] #endif [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.BooleanSwitch))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.ConditionalAttribute))] @@ -821,6 +831,15 @@ [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.TraceSwitch))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.SuppressMessageAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.AllowNullAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.MaybeNullAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.NotNullAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.NotNullWhenAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.Contracts.Contract))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.Contracts.ContractAbbreviatorAttribute))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Diagnostics.Contracts.ContractArgumentValidatorAttribute))] @@ -2443,6 +2462,9 @@ [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.ReadOnlySpanAction<,>))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.ReadOnlySequence<>))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.ReadOnlySequenceSegment<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.ArrayBufferWriter<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.SequenceReader<>))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.SequenceReaderExtensions))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.SpanAction<,>))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.StandardFormat))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Buffers.Binary.BinaryPrimitives))] diff --git a/mcs/class/Makefile b/mcs/class/Makefile index eb39ac8c2d3..1ab7f8b5c0b 100644 --- a/mcs/class/Makefile +++ b/mcs/class/Makefile @@ -77,6 +77,7 @@ mobile_common_dirs_parallel := \ System.Numerics \ System.Numerics.Vectors \ System.Data \ + System.Data.DataSetExtensions \ Mono.Data.Sqlite \ System.Data.Services.Client \ System.IO.Compression \ @@ -179,6 +180,7 @@ wasm_dirs_parallel := \ System.ServiceModel.Internals \ System.Runtime.Serialization \ System.Data \ + System.Data.DataSetExtensions \ System.Xml.Linq \ System.Numerics \ System.Numerics.Vectors \ @@ -213,6 +215,7 @@ xammac_4_5_dirs_parallel := \ System.Transactions \ System.EnterpriseServices \ System.Data \ + System.Data.DataSetExtensions \ System.Runtime.Serialization \ System.Xml.Linq \ Mono.Data.Sqlite \ diff --git a/mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions.csproj b/mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions.csproj index 89bc8d4cfe5..0edda300262 100644 --- a/mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions.csproj +++ b/mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions.csproj @@ -30,6 +30,76 @@ ./../../class/obj/$(AssemblyName)-net_4_x-$(HostPlatform) NET_4_0;NET_4_5;NET_4_6;MONO;WIN_PLATFORM;COREFX + + ./../../class/lib/monodroid + ./../../class/obj/$(AssemblyName)-monodroid + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;MOBILE_DYNAMIC;MONODROID;ANDROID;COREFX + + + ./../../class/lib/monotouch + ./../../class/obj/$(AssemblyName)-monotouch + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;COREFX + + + ./../../class/lib/monotouch_watch + ./../../class/obj/$(AssemblyName)-monotouch_watch + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;FEATURE_NO_BSD_SOCKETS;MONOTOUCH_WATCH;COREFX + + + ./../../class/lib/monotouch_tv + ./../../class/obj/$(AssemblyName)-monotouch_tv + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;MONOTOUCH_TV;COREFX + + + ./../../class/lib/testing_aot_full_interp + ./../../class/obj/$(AssemblyName)-testing_aot_full_interp + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;DISABLE_REMOTING;DISABLE_SECURITY;FULL_AOT_INTERP;DISABLE_COM;COREFX + + + ./../../class/lib/testing_aot_hybrid + ./../../class/obj/$(AssemblyName)-testing_aot_hybrid + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;DISABLE_REMOTING;DISABLE_SECURITY;MOBILE_DYNAMIC;COREFX + + + ./../../class/lib/testing_aot_full + ./../../class/obj/$(AssemblyName)-testing_aot_full + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;DISABLE_REMOTING;DISABLE_SECURITY;FULL_AOT_DESKTOP;FULL_AOT_RUNTIME;DISABLE_COM;COREFX + + + ./../../class/lib/winaot + ./../../class/obj/$(AssemblyName)-winaot + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;DISABLE_COM;WIN_PLATFORM;WINAOT;FULL_AOT_DESKTOP;FULL_AOT_RUNTIME;COREFX + + + ./../../class/lib/testing_winaot_interp + ./../../class/obj/$(AssemblyName)-testing_winaot_interp + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;DISABLE_COM;WIN_PLATFORM;WINAOT;FULL_AOT_INTERP;DISABLE_SECURITY;DISABLE_REMOTING;COREFX + + + ./../../class/lib/xammac + ./../../class/obj/$(AssemblyName)-xammac + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_DYNAMIC;XAMMAC;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;XAMARIN_MODERN;COREFX + + + ./../../class/lib/xammac_net_4_5 + ./../../class/obj/$(AssemblyName)-xammac_net_4_5 + NET_4_0;NET_4_5;NET_4_6;MONO;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;NO_SYSTEM_DRAWING_DEPENDENCY;NO_WINFORMS_DEPENDENCY;NO_SYSTEM_WEB_DEPENDENCY;XAMMAC_4_5;XAMARIN_MODERN;COREFX + + + ./../../class/lib/orbis + ./../../class/obj/$(AssemblyName)-orbis + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;FULL_AOT_DESKTOP;FULL_AOT_RUNTIME;ORBIS;DISABLE_COM;COREFX + + + ./../../class/lib/unreal + ./../../class/obj/$(AssemblyName)-unreal + NET_1_1;NET_2_0;NET_2_1;MOBILE;MOBILE_DYNAMIC;NET_3_5;NET_4_0;NET_4_5;MONO;COREFX + + + ./../../class/lib/wasm + ./../../class/obj/$(AssemblyName)-wasm + NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_LEGACY;FULL_AOT_DESKTOP;FULL_AOT_RUNTIME;WASM;DISABLE_COM;FEATURE_NO_BSD_SOCKETS;DISABLE_REMOTING;DISABLE_SECURITY;COREFX + true @@ -69,14 +139,37 @@ - - + + + + ..\lib\testing_aot_full_interp\nunitlite.dll + False + + + + + ..\lib\testing_aot_hybrid\nunitlite.dll + False + + + + + ..\lib\testing_aot_full\nunitlite.dll + False + + + + + ..\lib\testing_winaot_interp\nunitlite.dll + False + + diff --git a/mcs/class/corlib/corefx/ArrayBufferWriter.cs b/mcs/class/corlib/corefx/ArrayBufferWriter.cs new file mode 100644 index 00000000000..9a6736bf235 --- /dev/null +++ b/mcs/class/corlib/corefx/ArrayBufferWriter.cs @@ -0,0 +1,185 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; + +namespace System.Buffers +{ + /// + /// Represents a heap-based, array-backed output sink into which data can be written. + /// + public sealed class ArrayBufferWriter : IBufferWriter + { + private T[] _buffer; + private int _index; + + private const int DefaultInitialBufferSize = 256; + + /// + /// Creates an instance of an , in which data can be written to, + /// with the default initial capacity. + /// + public ArrayBufferWriter() + { + _buffer = Array.Empty(); + _index = 0; + } + + /// + /// Creates an instance of an , in which data can be written to, + /// with an initial capacity specified. + /// + /// The minimum capacity with which to initialize the underlying buffer. + /// + /// Thrown when is not positive (i.e. less than or equal to 0). + /// + public ArrayBufferWriter(int initialCapacity) + { + if (initialCapacity <= 0) + throw new ArgumentException(nameof(initialCapacity)); + + _buffer = new T[initialCapacity]; + _index = 0; + } + + /// + /// Returns the data written to the underlying buffer so far, as a . + /// + public ReadOnlyMemory WrittenMemory => _buffer.AsMemory(0, _index); + + /// + /// Returns the data written to the underlying buffer so far, as a . + /// + public ReadOnlySpan WrittenSpan => _buffer.AsSpan(0, _index); + + /// + /// Returns the amount of data written to the underlying buffer so far. + /// + public int WrittenCount => _index; + + /// + /// Returns the total amount of space within the underlying buffer. + /// + public int Capacity => _buffer.Length; + + /// + /// Returns the amount of space available that can still be written into without forcing the underlying buffer to grow. + /// + public int FreeCapacity => _buffer.Length - _index; + + /// + /// Clears the data written to the underlying buffer. + /// + /// + /// You must clear the before trying to re-use it. + /// + public void Clear() + { + Debug.Assert(_buffer.Length >= _index); + _buffer.AsSpan(0, _index).Clear(); + _index = 0; + } + + /// + /// Notifies that amount of data was written to the output / + /// + /// + /// Thrown when is negative. + /// + /// + /// Thrown when attempting to advance past the end of the underlying buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public void Advance(int count) + { + if (count < 0) + throw new ArgumentException(nameof(count)); + + if (_index > _buffer.Length - count) + ThrowInvalidOperationException_AdvancedTooFar(_buffer.Length); + + _index += count; + } + + /// + /// Returns a to write to that is at least the requested length (specified by ). + /// If no is provided (or it's equal to 0), some non-empty buffer is returned. + /// + /// + /// Thrown when is negative. + /// + /// + /// This will never return an empty . + /// + /// + /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public Memory GetMemory(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + Debug.Assert(_buffer.Length > _index); + return _buffer.AsMemory(_index); + } + + /// + /// Returns a to write to that is at least the requested length (specified by ). + /// If no is provided (or it's equal to 0), some non-empty buffer is returned. + /// + /// + /// Thrown when is negative. + /// + /// + /// This will never return an empty . + /// + /// + /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public Span GetSpan(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + Debug.Assert(_buffer.Length > _index); + return _buffer.AsSpan(_index); + } + + private void CheckAndResizeBuffer(int sizeHint) + { + if (sizeHint < 0) + throw new ArgumentException(nameof(sizeHint)); + + if (sizeHint == 0) + { + sizeHint = 1; + } + + if (sizeHint > FreeCapacity) + { + int growBy = Math.Max(sizeHint, _buffer.Length); + + if (_buffer.Length == 0) + { + growBy = Math.Max(growBy, DefaultInitialBufferSize); + } + + int newSize = checked(_buffer.Length + growBy); + + Array.Resize(ref _buffer, newSize); + } + + Debug.Assert(FreeCapacity > 0 && FreeCapacity >= sizeHint); + } + + private static void ThrowInvalidOperationException_AdvancedTooFar(int capacity) + { + throw new InvalidOperationException(SR.Format(SR.BufferWriterAdvancedTooFar, capacity)); + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/corefx/NullableAttributes.cs b/mcs/class/corlib/corefx/NullableAttributes.cs new file mode 100644 index 00000000000..c6276a997ae --- /dev/null +++ b/mcs/class/corlib/corefx/NullableAttributes.cs @@ -0,0 +1,128 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Diagnostics.CodeAnalysis +{ + /// Specifies that null is allowed as an input even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class AllowNullAttribute : Attribute { } + + /// Specifies that null is disallowed as an input even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DisallowNullAttribute : Attribute { } + + /// Specifies that an output may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class MaybeNullAttribute : Attribute { } + + /// Specifies that an output will not be null even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullAttribute : Attribute { } + + /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class MaybeNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that the output will be non-null if the named parameter is non-null. + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullIfNotNullAttribute : Attribute + { + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } + } + + /// Applied to a method that will never return under any circumstance. + [AttributeUsage(AttributeTargets.Method, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DoesNotReturnAttribute : Attribute { } + + /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DoesNotReturnIfAttribute : Attribute + { + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/corefx/SR.missing.cs b/mcs/class/corlib/corefx/SR.missing.cs index 282c0125054..746b71892cb 100644 --- a/mcs/class/corlib/corefx/SR.missing.cs +++ b/mcs/class/corlib/corefx/SR.missing.cs @@ -26,4 +26,5 @@ partial class SR public const string Arg_SwitchExpressionException = "Non-exhaustive switch expression failed to match its input."; public const string SwitchExpressionException_UnmatchedValue = "Unmatched value was {0}."; public const string Argument_InvalidRandomRange = "Range of random number does not contain at least one possibility."; + public const string BufferWriterAdvancedTooFar = "Cannot advance past the end of the buffer, which has a size of {0}."; } \ No newline at end of file diff --git a/mcs/class/corlib/corefx/SequenceReader.Search.cs b/mcs/class/corlib/corefx/SequenceReader.Search.cs new file mode 100644 index 00000000000..aaa3d1d51fd --- /dev/null +++ b/mcs/class/corlib/corefx/SequenceReader.Search.cs @@ -0,0 +1,778 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Buffers +{ +#if __MonoCS__ + public ref partial struct SequenceReader where T : IEquatable +#else + public ref partial struct SequenceReader where T : unmanaged, IEquatable +#endif + { + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiter to look for. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySpan span, T delimiter, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + + if (index != -1) + { + span = index == 0 ? default : remaining.Slice(0, index); + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToSlow(out span, delimiter, advancePastDelimiter); + } + + private bool TryReadToSlow(out ReadOnlySpan span, T delimiter, bool advancePastDelimiter) + { + if (!TryReadToInternal(out ReadOnlySequence sequence, delimiter, advancePastDelimiter, CurrentSpan.Length - CurrentSpanIndex)) + { + span = default; + return false; + } + + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + /// + /// Try to read everything up to the given , ignoring delimiters that are + /// preceded by . + /// + /// The read data, if any. + /// The delimiter to look for. + /// If found prior to it will skip that occurrence. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySpan span, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + + if ((index > 0 && !remaining[index - 1].Equals(delimiterEscape)) || index == 0) + { + span = remaining.Slice(0, index); + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + // This delimiter might be skipped, go down the slow path + return TryReadToSlow(out span, delimiter, delimiterEscape, index, advancePastDelimiter); + } + + private bool TryReadToSlow(out ReadOnlySpan span, T delimiter, T delimiterEscape, int index, bool advancePastDelimiter) + { + if (!TryReadToSlow(out ReadOnlySequence sequence, delimiter, delimiterEscape, index, advancePastDelimiter)) + { + span = default; + return false; + } + + Debug.Assert(sequence.Length > 0); + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + private bool TryReadToSlow(out ReadOnlySequence sequence, T delimiter, T delimiterEscape, int index, bool advancePastDelimiter) + { + SequenceReader copy = this; + + ReadOnlySpan remaining = UnreadSpan; + bool priorEscape = false; + + do + { + if (index >= 0) + { + if (index == 0 && priorEscape) + { + // We were in the escaped state, so skip this delimiter + priorEscape = false; + Advance(index + 1); + remaining = UnreadSpan; + goto Continue; + } + else if (index > 0 && remaining[index - 1].Equals(delimiterEscape)) + { + // This delimiter might be skipped + + // Count our escapes + int escapeCount = 1; + int i = index - 2; + for (; i >= 0; i--) + { + if (!remaining[i].Equals(delimiterEscape)) + break; + } + if (i < 0 && priorEscape) + { + // Started and ended with escape, increment once more + escapeCount++; + } + escapeCount += index - 2 - i; + + if ((escapeCount & 1) != 0) + { + // An odd escape count means we're currently escaped, + // skip the delimiter and reset escaped state. + Advance(index + 1); + priorEscape = false; + remaining = UnreadSpan; + goto Continue; + } + } + + // Found the delimiter. Move to it, slice, then move past it. + AdvanceCurrentSpan(index); + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + else + { + // No delimiter, need to check the end of the span for odd number of escapes then advance + if (remaining.Length > 0 && remaining[remaining.Length - 1].Equals(delimiterEscape)) + { + int escapeCount = 1; + int i = remaining.Length - 2; + for (; i >= 0; i--) + { + if (!remaining[i].Equals(delimiterEscape)) + break; + } + + escapeCount += remaining.Length - 2 - i; + if (i < 0 && priorEscape) + priorEscape = (escapeCount & 1) == 0; // equivalent to incrementing escapeCount before setting priorEscape + else + priorEscape = (escapeCount & 1) != 0; + } + else + { + priorEscape = false; + } + } + + // Nothing in the current span, move to the end, checking for the skip delimiter + AdvanceCurrentSpan(remaining.Length); + remaining = CurrentSpan; + + Continue: + index = remaining.IndexOf(delimiter); + } while (!End); + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiter to look for. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, T delimiter, bool advancePastDelimiter = true) + { + return TryReadToInternal(out sequence, delimiter, advancePastDelimiter); + } + + private bool TryReadToInternal(out ReadOnlySequence sequence, T delimiter, bool advancePastDelimiter, int skip = 0) + { + Debug.Assert(skip >= 0); + SequenceReader copy = this; + if (skip > 0) + Advance(skip); + ReadOnlySpan remaining = UnreadSpan; + + while (_moreData) + { + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + // Found the delimiter. Move to it, slice, then move past it. + if (index > 0) + { + AdvanceCurrentSpan(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + AdvanceCurrentSpan(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given , ignoring delimiters that are + /// preceded by . + /// + /// The read data, if any. + /// The delimiter to look for. + /// If found prior to it will skip that occurrence. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) + { + SequenceReader copy = this; + + ReadOnlySpan remaining = UnreadSpan; + bool priorEscape = false; + + while (_moreData) + { + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + if (index == 0 && priorEscape) + { + // We were in the escaped state, so skip this delimiter + priorEscape = false; + Advance(index + 1); + remaining = UnreadSpan; + continue; + } + else if (index > 0 && remaining[index - 1].Equals(delimiterEscape)) + { + // This delimiter might be skipped + + // Count our escapes + int escapeCount = 0; + for (int i = index; i > 0 && remaining[i - 1].Equals(delimiterEscape); i--, escapeCount++) + ; + if (escapeCount == index && priorEscape) + { + // Started and ended with escape, increment once more + escapeCount++; + } + + priorEscape = false; + if ((escapeCount & 1) != 0) + { + // Odd escape count means we're in the escaped state, so skip this delimiter + Advance(index + 1); + remaining = UnreadSpan; + continue; + } + } + + // Found the delimiter. Move to it, slice, then move past it. + if (index > 0) + { + Advance(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + // No delimiter, need to check the end of the span for odd number of escapes then advance + { + int escapeCount = 0; + for (int i = remaining.Length; i > 0 && remaining[i - 1].Equals(delimiterEscape); i--, escapeCount++) + ; + if (priorEscape && escapeCount == remaining.Length) + { + escapeCount++; + } + priorEscape = escapeCount % 2 != 0; + } + + // Nothing in the current span, move to the end, checking for the skip delimiter + Advance(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiters to look for. + /// True to move past the first found instance of any of the given . + /// True if any of the were found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryReadToAny(out ReadOnlySpan span, ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = delimiters.Length == 2 + ? remaining.IndexOfAny(delimiters[0], delimiters[1]) + : remaining.IndexOfAny(delimiters); + + if (index != -1) + { + span = remaining.Slice(0, index); + Advance(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToAnySlow(out span, delimiters, advancePastDelimiter); + } + + private bool TryReadToAnySlow(out ReadOnlySpan span, ReadOnlySpan delimiters, bool advancePastDelimiter) + { + if (!TryReadToAnyInternal(out ReadOnlySequence sequence, delimiters, advancePastDelimiter, CurrentSpan.Length - CurrentSpanIndex)) + { + span = default; + return false; + } + + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiters to look for. + /// True to move past the first found instance of any of the given . + /// True if any of the were found. + public bool TryReadToAny(out ReadOnlySequence sequence, ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + return TryReadToAnyInternal(out sequence, delimiters, advancePastDelimiter); + } + + private bool TryReadToAnyInternal(out ReadOnlySequence sequence, ReadOnlySpan delimiters, bool advancePastDelimiter, int skip = 0) + { + SequenceReader copy = this; + if (skip > 0) + Advance(skip); + ReadOnlySpan remaining = UnreadSpan; + + while (!End) + { + int index = delimiters.Length == 2 + ? remaining.IndexOfAny(delimiters[0], delimiters[1]) + : remaining.IndexOfAny(delimiters); + + if (index != -1) + { + // Found one of the delimiters. Move to it, slice, then move past it. + if (index > 0) + { + AdvanceCurrentSpan(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + Advance(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read data until the entire given matches. + /// + /// The read data, if any. + /// The multi (T) delimiter. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, ReadOnlySpan delimiter, bool advancePastDelimiter = true) + { + if (delimiter.Length == 0) + { + sequence = default; + return true; + } + + SequenceReader copy = this; + + bool advanced = false; + while (!End) + { + if (!TryReadTo(out sequence, delimiter[0], advancePastDelimiter: false)) + { + this = copy; + return false; + } + + if (delimiter.Length == 1) + { + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + if (IsNext(delimiter)) + { + // Probably a faster way to do this, potentially by avoiding the Advance in the previous TryReadTo call + if (advanced) + { + sequence = copy.Sequence.Slice(copy.Consumed, Consumed - copy.Consumed); + } + + if (advancePastDelimiter) + { + Advance(delimiter.Length); + } + return true; + } + else + { + Advance(1); + advanced = true; + } + } + + this = copy; + sequence = default; + return false; + } + + /// + /// Advance until the given , if found. + /// + /// The delimiter to search for. + /// True to move past the if found. + /// True if the given was found. + public bool TryAdvanceTo(T delimiter, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + Advance(advancePastDelimiter ? index + 1 : index); + return true; + } + + return TryReadToInternal(out _, delimiter, advancePastDelimiter); + } + + /// + /// Advance until any of the given , if found. + /// + /// The delimiters to search for. + /// True to move past the first found instance of any of the given . + /// True if any of the given were found. + public bool TryAdvanceToAny(ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOfAny(delimiters); + if (index != -1) + { + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToAnyInternal(out _, delimiters, advancePastDelimiter); + } + + /// + /// Advance past consecutive instances of the given . + /// + /// How many positions the reader has been advanced. + public long AdvancePast(T value) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length && CurrentSpan[i].Equals(value); i++) + { + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at postion 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Skip consecutive instances of any of the given . + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(ReadOnlySpan values) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length && values.IndexOf(CurrentSpan[i]) != -1; i++) + { + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at postion 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1, T value2, T value3) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1) && !value.Equals(value2) && !value.Equals(value3)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at postion 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1, T value2) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1) && !value.Equals(value2)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at postion 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at postion 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Check to see if the given value is next. + /// + /// The value to compare the next items to. + /// Move past the value if found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNext(T next, bool advancePast = false) + { + if (End) + return false; + + if (CurrentSpan[CurrentSpanIndex].Equals(next)) + { + if (advancePast) + { + AdvanceCurrentSpan(1); + } + return true; + } + return false; + } + + /// + /// Check to see if the given values are next. + /// + /// The span to compare the next items to. + /// Move past the values if found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNext(ReadOnlySpan next, bool advancePast = false) + { + ReadOnlySpan unread = UnreadSpan; + if (unread.StartsWith(next)) + { + if (advancePast) + { + AdvanceCurrentSpan(next.Length); + } + return true; + } + + // Only check the slow path if there wasn't enough to satisfy next + return unread.Length < next.Length && IsNextSlow(next, advancePast); + } + + private unsafe bool IsNextSlow(ReadOnlySpan next, bool advancePast) + { + ReadOnlySpan currentSpan = UnreadSpan; + + // We should only come in here if we need more data than we have in our current span + Debug.Assert(currentSpan.Length < next.Length); + + int fullLength = next.Length; + SequencePosition nextPosition = _nextPosition; + + while (next.StartsWith(currentSpan)) + { + if (next.Length == currentSpan.Length) + { + // Fully matched + if (advancePast) + { + Advance(fullLength); + } + return true; + } + + // Need to check the next segment + while (true) + { + if (!Sequence.TryGet(ref nextPosition, out ReadOnlyMemory nextSegment, advance: true)) + { + // Nothing left + return false; + } + + if (nextSegment.Length > 0) + { + next = next.Slice(currentSpan.Length); + currentSpan = nextSegment.Span; + if (currentSpan.Length > next.Length) + { + currentSpan = currentSpan.Slice(0, next.Length); + } + break; + } + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/corefx/SequenceReader.cs b/mcs/class/corlib/corefx/SequenceReader.cs new file mode 100644 index 00000000000..e199f192432 --- /dev/null +++ b/mcs/class/corlib/corefx/SequenceReader.cs @@ -0,0 +1,449 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; +using Internal.Runtime.CompilerServices; + +namespace System.Buffers +{ +#if __MonoCS__ + public ref partial struct SequenceReader where T : IEquatable +#else + public ref partial struct SequenceReader where T : unmanaged, IEquatable +#endif + { + private SequencePosition _currentPosition; + private SequencePosition _nextPosition; + private bool _moreData; +#if __MonoCS__ + private long _length; +#else + private readonly long _length; +#endif + + /// + /// Create a over the given . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SequenceReader(ReadOnlySequence sequence) + { + CurrentSpanIndex = 0; + Consumed = 0; + Sequence = sequence; + _currentPosition = sequence.Start; + _length = -1; + + sequence.GetFirstSpan(out ReadOnlySpan first, out _nextPosition); + CurrentSpan = first; + _moreData = first.Length > 0; + + if (!_moreData && !sequence.IsSingleSegment) + { + _moreData = true; + GetNextSpan(); + } + } + + /// + /// True when there is no more data in the . + /// +#if __MonoCS__ + public bool End => !_moreData; +#else + public readonly bool End => !_moreData; +#endif + + /// + /// The underlying for the reader. + /// +#if __MonoCS__ + public ReadOnlySequence Sequence { get; } +#else + public readonly ReadOnlySequence Sequence { get; } +#endif + + /// + /// The current position in the . + /// +#if __MonoCS__ + public SequencePosition Position + => Sequence.GetPosition(CurrentSpanIndex, _currentPosition); +#else + public readonly SequencePosition Position + => Sequence.GetPosition(CurrentSpanIndex, _currentPosition); +#endif + + /// + /// The current segment in the as a span. + /// +#if __MonoCS__ + public ReadOnlySpan CurrentSpan { get; private set; } +#else + public ReadOnlySpan CurrentSpan { readonly get; private set; } +#endif + + /// + /// The index in the . + /// +#if __MonoCS__ + public int CurrentSpanIndex { get; private set; } +#else + public int CurrentSpanIndex { readonly get; private set; } +#endif + + /// + /// The unread portion of the . + /// +#if __MonoCS__ + public ReadOnlySpan UnreadSpan +#else + public readonly ReadOnlySpan UnreadSpan +#endif + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => CurrentSpan.Slice(CurrentSpanIndex); + } + + /// + /// The total number of 's processed by the reader. + /// +#if __MonoCS__ + public long Consumed { get; private set; } +#else + public long Consumed { readonly get; private set; } +#endif + + /// + /// Remaining 's in the reader's . + /// +#if __MonoCS__ + public long Remaining => Length - Consumed; +#else + public readonly long Remaining => Length - Consumed; +#endif + + /// + /// Count of in the reader's . + /// +#if __MonoCS__ + public long Length +#else + public readonly long Length +#endif + { + get + { + if (_length < 0) + { + unsafe { + fixed (long* lenPtr = &_length) + // Cast-away readonly to initialize lazy field + Volatile.Write(ref Unsafe.AsRef(lenPtr), Sequence.Length); + } + } + return _length; + } + } + + /// + /// Peeks at the next value without advancing the reader. + /// + /// The next value or default if at the end. + /// False if at the end of the reader. + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if __MonoCS__ + public bool TryPeek(out T value) +#else + public readonly bool TryPeek(out T value) +#endif + { + if (_moreData) + { + value = CurrentSpan[CurrentSpanIndex]; + return true; + } + else + { + value = default; + return false; + } + } + + /// + /// Read the next value and advance the reader. + /// + /// The next value or default if at the end. + /// False if at the end of the reader. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryRead(out T value) + { + if (End) + { + value = default; + return false; + } + + value = CurrentSpan[CurrentSpanIndex]; + CurrentSpanIndex++; + Consumed++; + + if (CurrentSpanIndex >= CurrentSpan.Length) + { + GetNextSpan(); + } + + return true; + } + + /// + /// Move the reader back the specified number of items. + /// + /// + /// Thrown if trying to rewind a negative amount or more than . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Rewind(long count) + { + if ((ulong)count > (ulong)Consumed) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); + } + + Consumed -= count; + + if (CurrentSpanIndex >= count) + { + CurrentSpanIndex -= (int)count; + _moreData = true; + } + else + { + // Current segment doesn't have enough data, scan backward through segments + RetreatToPreviousSpan(Consumed); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void RetreatToPreviousSpan(long consumed) + { + ResetReader(); + Advance(consumed); + } + + private void ResetReader() + { + CurrentSpanIndex = 0; + Consumed = 0; + _currentPosition = Sequence.Start; + _nextPosition = _currentPosition; + + if (Sequence.TryGet(ref _nextPosition, out ReadOnlyMemory memory, advance: true)) + { + _moreData = true; + + if (memory.Length == 0) + { + CurrentSpan = default; + // No data in the first span, move to one with data + GetNextSpan(); + } + else + { + CurrentSpan = memory.Span; + } + } + else + { + // No data in any spans and at end of sequence + _moreData = false; + CurrentSpan = default; + } + } + + /// + /// Get the next segment with available data, if any. + /// + private void GetNextSpan() + { + if (!Sequence.IsSingleSegment) + { + SequencePosition previousNextPosition = _nextPosition; + while (Sequence.TryGet(ref _nextPosition, out ReadOnlyMemory memory, advance: true)) + { + _currentPosition = previousNextPosition; + if (memory.Length > 0) + { + CurrentSpan = memory.Span; + CurrentSpanIndex = 0; + return; + } + else + { + CurrentSpan = default; + CurrentSpanIndex = 0; + previousNextPosition = _nextPosition; + } + } + } + _moreData = false; + } + + /// + /// Move the reader ahead the specified number of items. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(long count) + { + const long TooBigOrNegative = unchecked((long)0xFFFFFFFF80000000); + if ((count & TooBigOrNegative) == 0 && CurrentSpan.Length - CurrentSpanIndex > (int)count) + { + CurrentSpanIndex += (int)count; + Consumed += count; + } + else + { + // Can't satisfy from the current span + AdvanceToNextSpan(count); + } + } + + /// + /// Unchecked helper to avoid unnecessary checks where you know count is valid. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AdvanceCurrentSpan(long count) + { + Debug.Assert(count >= 0); + + Consumed += count; + CurrentSpanIndex += (int)count; + if (CurrentSpanIndex >= CurrentSpan.Length) + GetNextSpan(); + } + + /// + /// Only call this helper if you know that you are advancing in the current span + /// with valid count and there is no need to fetch the next one. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AdvanceWithinSpan(long count) + { + Debug.Assert(count >= 0); + + Consumed += count; + CurrentSpanIndex += (int)count; + + Debug.Assert(CurrentSpanIndex < CurrentSpan.Length); + } + + private void AdvanceToNextSpan(long count) + { + if (count < 0) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); + } + + Consumed += count; + while (_moreData) + { + int remaining = CurrentSpan.Length - CurrentSpanIndex; + + if (remaining > count) + { + CurrentSpanIndex += (int)count; + count = 0; + break; + } + + // As there may not be any further segments we need to + // push the current index to the end of the span. + CurrentSpanIndex += remaining; + count -= remaining; + Debug.Assert(count >= 0); + + GetNextSpan(); + + if (count == 0) + { + break; + } + } + + if (count != 0) + { + // Not enough data left- adjust for where we actually ended and throw + Consumed -= count; + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); + } + } + + /// + /// Copies data from the current to the given span if there + /// is enough data to fill it. + /// + /// + /// This API is used to copy a fixed amount of data out of the sequence if possible. It does not advance + /// the reader. To look ahead for a specific stream of data can be used. + /// + /// Destination span to copy to. + /// True if there is enough data to completely fill the span. + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if __MonoCS__ + public bool TryCopyTo(Span destination) +#else + public readonly bool TryCopyTo(Span destination) +#endif + { + // This API doesn't advance to facilitate conditional advancement based on the data returned. + // We don't provide an advance option to allow easier utilizing of stack allocated destination spans. + // (Because we can make this method readonly we can guarantee that we won't capture the span.) + + ReadOnlySpan firstSpan = UnreadSpan; + if (firstSpan.Length >= destination.Length) + { + firstSpan.Slice(0, destination.Length).CopyTo(destination); + return true; + } + + // Not enough in the current span to satisfy the request, fall through to the slow path + return TryCopyMultisegment(destination); + } + +#if __MonoCS__ + internal bool TryCopyMultisegment(Span destination) +#else + internal readonly bool TryCopyMultisegment(Span destination) +#endif + { + // If we don't have enough to fill the requested buffer, return false + if (Remaining < destination.Length) + return false; + + ReadOnlySpan firstSpan = UnreadSpan; + Debug.Assert(firstSpan.Length < destination.Length); + firstSpan.CopyTo(destination); + int copied = firstSpan.Length; + + SequencePosition next = _nextPosition; + while (Sequence.TryGet(ref next, out ReadOnlyMemory nextSegment, true)) + { + if (nextSegment.Length > 0) + { + ReadOnlySpan nextSpan = nextSegment.Span; + int toCopy = Math.Min(nextSpan.Length, destination.Length - copied); + nextSpan.Slice(0, toCopy).CopyTo(destination.Slice(copied)); + copied += toCopy; + if (copied >= destination.Length) + { + break; + } + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/corefx/SequenceReaderExtensions.Binary.cs b/mcs/class/corlib/corefx/SequenceReaderExtensions.Binary.cs new file mode 100644 index 00000000000..81777fa747b --- /dev/null +++ b/mcs/class/corlib/corefx/SequenceReaderExtensions.Binary.cs @@ -0,0 +1,187 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers.Binary; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Internal.Runtime.CompilerServices; + +namespace System.Buffers +{ +#if !__MonoCS__ + public static partial class SequenceReaderExtensions + { + /// + /// Try to read the given type out of the buffer if possible. Warning: this is dangerous to use with arbitrary + /// structs- see remarks for full details. + /// + /// + /// IMPORTANT: The read is a straight copy of bits. If a struct depends on specific state of it's members to + /// behave correctly this can lead to exceptions, etc. If reading endian specific integers, use the explicit + /// overloads such as + /// + /// + /// True if successful. will be default if failed (due to lack of space). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static unsafe bool TryRead(ref this SequenceReader reader, out T value) where T : unmanaged + { + ReadOnlySpan span = reader.UnreadSpan; + if (span.Length < sizeof(T)) + return TryReadMultisegment(ref reader, out value); + + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); + reader.Advance(sizeof(T)); + return true; + } + + private static unsafe bool TryReadMultisegment(ref SequenceReader reader, out T value) where T : unmanaged + { + Debug.Assert(reader.UnreadSpan.Length < sizeof(T)); + + // Not enough data in the current segment, try to peek for the data we need. + T buffer = default; + Span tempSpan = new Span(&buffer, sizeof(T)); + + if (!reader.TryCopyTo(tempSpan)) + { + value = default; + return false; + } + + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(tempSpan)); + reader.Advance(sizeof(T)); + return true; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadLittleEndian(ref this SequenceReader reader, out short value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out short value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + private static bool TryReadReverseEndianness(ref SequenceReader reader, out short value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadLittleEndian(ref this SequenceReader reader, out int value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out int value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + private static bool TryReadReverseEndianness(ref SequenceReader reader, out int value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadLittleEndian(ref this SequenceReader reader, out long value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out long value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + + private static bool TryReadReverseEndianness(ref SequenceReader reader, out long value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + } +#else + public static partial class SequenceReaderExtensions + { + public static bool TryReadBigEndian(this System.Buffers.SequenceReader reader, out short value) => throw new PlatformNotSupportedException(); + public static bool TryReadBigEndian(this System.Buffers.SequenceReader reader, out int value) => throw new PlatformNotSupportedException(); + public static bool TryReadBigEndian(this System.Buffers.SequenceReader reader, out long value) => throw new PlatformNotSupportedException(); + public static bool TryReadLittleEndian(this System.Buffers.SequenceReader reader, out short value) => throw new PlatformNotSupportedException(); + public static bool TryReadLittleEndian(this System.Buffers.SequenceReader reader, out int value) => throw new PlatformNotSupportedException(); + public static bool TryReadLittleEndian(this System.Buffers.SequenceReader reader, out long value) => throw new PlatformNotSupportedException(); + } +#endif +} diff --git a/mcs/class/corlib/corlib.csproj b/mcs/class/corlib/corlib.csproj index dc2a29a7750..e6e8189646a 100644 --- a/mcs/class/corlib/corlib.csproj +++ b/mcs/class/corlib/corlib.csproj @@ -1862,6 +1862,7 @@ + @@ -1879,6 +1880,7 @@ + @@ -1887,6 +1889,9 @@ + + + diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index 2cda1110ec4..d8d8021a5ca 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -1631,6 +1631,11 @@ corefx/AesGcm.cs corefx/IncrementingEventCounter.cs corefx/IncrementingPollingCounter.cs corefx/PollingCounter.cs +corefx/NullableAttributes.cs +corefx/ArrayBufferWriter.cs +corefx/SequenceReader.cs +corefx/SequenceReader.Search.cs +corefx/SequenceReaderExtensions.Binary.cs corert/DependencyReductionRootAttribute.cs corert/AddrofIntrinsics.cs -- 2.11.4.GIT