diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props
index 6c4c13243e129..a205c2d280dd1 100644
--- a/src/coreclr/clr.featuredefines.props
+++ b/src/coreclr/clr.featuredefines.props
@@ -36,12 +36,6 @@
true
-
-
- true
-
-
-
$(DefineConstants);FEATURE_ARRAYSTUB_AS_IL
$(DefineConstants);FEATURE_MULTICASTSTUB_AS_IL
@@ -60,7 +54,6 @@
$(DefineConstants);FEATURE_TYPEEQUIVALENCE
$(DefineConstants);FEATURE_BASICFREEZE
$(DefineConstants);FEATURE_PORTABLE_SHUFFLE_THUNKS
- $(DefineConstants);FEATURE_UTF8STRING
$(DefineConstants);PROFILING_SUPPORTED
$(DefineConstants);FEATURE_PROFAPI_ATTACH_DETACH
diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake
index eafe212786d85..d22738910023c 100644
--- a/src/coreclr/clrdefinitions.cmake
+++ b/src/coreclr/clrdefinitions.cmake
@@ -1,11 +1,5 @@
include(clrfeatures.cmake)
-# Features we're currently flighting, but don't intend to ship in officially supported releases
-if (PRERELEASE)
- add_definitions(-DFEATURE_UTF8STRING)
- # add_definitions(-DFEATURE_XXX)
-endif (PRERELEASE)
-
add_compile_definitions($<$>:DACCESS_COMPILE>)
add_compile_definitions($<$>:CROSSGEN_COMPILE>)
add_compile_definitions($<$>:CROSS_COMPILE>)
diff --git a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
index 304b50f06676d..1b0204588a2f8 100644
--- a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -253,9 +253,6 @@
-
-
-
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Utf8String.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Utf8String.CoreCLR.cs
deleted file mode 100644
index 015f89ee16a01..0000000000000
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Utf8String.CoreCLR.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text.Unicode;
-using Internal.Runtime.CompilerServices;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- /*
- * INSTANCE FIELDS
- * Do not reorder these fields. They must match the layout of Utf8StringObject in object.h.
- */
-
- private readonly int _length;
- private readonly byte _firstByte;
-
- /*
- * INSTANCE PROPERTIES
- */
-
- ///
- /// Returns the length (in UTF-8 code units, or s) of this instance.
- ///
- public int Length => _length;
-
- /*
- * CONSTRUCTORS
- *
- * Defining a new constructor for string-like types (like Utf8String) requires changes both
- * to the managed code below and to the native VM code. See the comment at the top of
- * src/vm/ecall.cpp for instructions on how to add new overloads.
- *
- * These ctors validate their input, throwing ArgumentException if the input does not represent
- * well-formed UTF-8 data. (In the case of transcoding ctors, the ctors throw if the input does
- * not represent well-formed UTF-16 data.) There are Create* factory methods which allow the caller
- * to control this behavior with finer granularity, including performing U+FFFD replacement instead
- * of throwing, or even suppressing validation altogether if the caller knows the input to be well-
- * formed.
- *
- * The reason a throwing behavior was chosen by default is that we don't want to surprise developers
- * if ill-formed data loses fidelity while being round-tripped through this type. Developers should
- * perform an explicit gesture to opt-in to lossy behavior, such as calling the factories explicitly
- * documented as performing such replacement.
- */
-
- ///
- /// Creates a instance from existing UTF-8 data.
- ///
- /// The existing UTF-8 data from which to create a new .
- ///
- /// Thrown if does not represent well-formed UTF-8 data.
- ///
- ///
- /// The UTF-8 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- public extern Utf8String(ReadOnlySpan value);
-
-#pragma warning disable CA1822 // Mark members as static
-
-#if !CORECLR
- static
-#endif
- private Utf8String Ctor(ReadOnlySpan value)
- {
- if (value.IsEmpty)
- {
- return Empty;
- }
-
- // Create and populate the Utf8String instance.
-
- Utf8String newString = FastAllocateSkipZeroInit(value.Length);
- Buffer.Memmove(ref newString.DangerousGetMutableReference(), ref MemoryMarshal.GetReference(value), (uint)value.Length);
-
- // Now perform validation.
- // Reminder: Perform validation over the copy, not over the source.
-
- if (!Utf8Utility.IsWellFormedUtf8(newString.AsBytes()))
- {
- throw new ArgumentException(
- message: SR.Utf8String_InputContainedMalformedUtf8,
- paramName: nameof(value));
- }
-
- return newString;
- }
-
- ///
- /// Creates a instance from existing UTF-8 data.
- ///
- ///
- /// Thrown if does not represent well-formed UTF-8 data.
- ///
- ///
- /// The UTF-8 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- public extern Utf8String(byte[] value, int startIndex, int length);
-
-#if !CORECLR
- static
-#endif
- private Utf8String Ctor(byte[] value, int startIndex, int length)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return Ctor(new ReadOnlySpan(value, startIndex, length));
- }
-
- ///
- /// Creates a instance from existing null-terminated UTF-8 data.
- ///
- ///
- /// Thrown if does not represent well-formed UTF-8 data.
- ///
- ///
- /// The UTF-8 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- [CLSCompliant(false)]
- public extern unsafe Utf8String(byte* value);
-
-#if !CORECLR
- static
-#endif
- private unsafe Utf8String Ctor(byte* value)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return Ctor(new ReadOnlySpan(value, string.strlen(value)));
- }
-
- ///
- /// Creates a instance from existing UTF-16 data, transcoding the
- /// existing data to UTF-8 upon creation.
- ///
- /// The existing UTF-16 data from which to create a new .
- ///
- /// Thrown if does not represent well-formed UTF-16 data.
- ///
- ///
- /// The UTF-16 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- public extern Utf8String(ReadOnlySpan value);
-
-#if !CORECLR
- static
-#endif
- private Utf8String Ctor(ReadOnlySpan value)
- {
- Utf8String? newString = CreateFromUtf16Common(value, replaceInvalidSequences: false);
-
- if (newString is null)
- {
- // Input buffer contained invalid UTF-16 data.
-
- throw new ArgumentException(
- message: SR.Utf8String_InputContainedMalformedUtf16,
- paramName: nameof(value));
- }
-
- return newString;
- }
-
- ///
- /// Creates a instance from existing UTF-16 data.
- ///
- ///
- /// Thrown if does not represent well-formed UTF-16 data.
- ///
- ///
- /// The UTF-16 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- public extern Utf8String(char[] value, int startIndex, int length);
-
-#if !CORECLR
- static
-#endif
- private Utf8String Ctor(char[] value, int startIndex, int length)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return Ctor(new ReadOnlySpan(value, startIndex, length));
- }
-
- ///
- /// Creates a instance from existing null-terminated UTF-16 data.
- ///
- ///
- /// Thrown if does not represent well-formed UTF-16 data.
- ///
- ///
- /// The UTF-16 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- [CLSCompliant(false)]
- public extern unsafe Utf8String(char* value);
-
-#if !CORECLR
- static
-#endif
- private unsafe Utf8String Ctor(char* value)
- {
- if (value == null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return Ctor(new ReadOnlySpan(value, string.wcslen(value)));
- }
-
- ///
- /// Creates a instance from existing UTF-16 data.
- ///
- ///
- /// The UTF-16 data in is validated for well-formedness upon construction,
- /// and an exception is thrown if the input is ill-formed. To avoid this exception, consider using
- /// or .
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- public extern Utf8String(string value);
-
-#if !CORECLR
- static
-#endif
- private Utf8String Ctor(string value)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return Ctor(value.AsSpan());
- }
-
-#pragma warning restore CA1822
-
- /*
- * METHODS
- */
-
- ///
- /// Similar to , but skips the null check on the input.
- /// Throws a if the input is null.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ReadOnlySpan AsBytesSkipNullCheck()
- {
- // By dereferencing Length first, the JIT will skip the null check that normally precedes
- // most instance method calls, and it'll use the field dereference as the null check.
-
- int length = Length;
- return new ReadOnlySpan(ref DangerousGetMutableReference(), length);
- }
-
- ///
- /// Returns a mutable that can be used to populate this
- /// instance. Only to be used during construction.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal Span DangerousGetMutableSpan()
- {
- // By dereferencing Length first, the JIT will skip the null check that normally precedes
- // most instance method calls, and it'll use the field dereference as the null check.
-
- int length = Length;
- return new Span(ref DangerousGetMutableReference(), length);
- }
-
- ///
- /// Returns a mutable reference to the first byte of this
- /// (or the null terminator if the string is empty).
- ///
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference() => ref Unsafe.AsRef(in _firstByte);
-
- ///
- /// Gets an immutable reference that can be used in a statement. The resulting
- /// reference can be pinned and used as a null-terminated LPCUTF8STR.
- ///
- ///
- /// If this instance is empty, returns a reference to the null terminator.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)] // for compiler use only
- public ref readonly byte GetPinnableReference() => ref _firstByte;
-
- /*
- * HELPER METHODS
- */
-
- ///
- /// Creates a new zero-initialized instance of the specified length. Actual storage allocated is "length + 1" bytes
- /// because instances are null-terminated.
- ///
- ///
- /// The implementation of this method checks its input argument for overflow.
- ///
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Utf8String FastAllocate(int length);
- }
-}
diff --git a/src/coreclr/src/classlibnative/bcltype/objectnative.cpp b/src/coreclr/src/classlibnative/bcltype/objectnative.cpp
index 7af628a04e5cb..80023e27a9d81 100644
--- a/src/coreclr/src/classlibnative/bcltype/objectnative.cpp
+++ b/src/coreclr/src/classlibnative/bcltype/objectnative.cpp
@@ -236,9 +236,6 @@ FCIMPL1(Object*, ObjectNative::AllocateUninitializedClone, Object* pObjUNSAFE)
// assert that String has overloaded the Clone() method
_ASSERTE(pMT != g_pStringClass);
-#ifdef FEATURE_UTF8STRING
- _ASSERTE(pMT != g_pUtf8StringClass);
-#endif // FEATURE_UTF8STRING
if (pMT->IsArray()) {
refClone = DupArrayForCloning((BASEARRAYREF)refClone);
diff --git a/src/coreclr/src/inc/dacvars.h b/src/coreclr/src/inc/dacvars.h
index 92f3edf77855b..9f2b5c96fae44 100644
--- a/src/coreclr/src/inc/dacvars.h
+++ b/src/coreclr/src/inc/dacvars.h
@@ -162,9 +162,6 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pObjectClass, ::g_pObjectClass
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pRuntimeTypeClass, ::g_pRuntimeTypeClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pCanonMethodTableClass, ::g_pCanonMethodTableClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pStringClass, ::g_pStringClass)
-#ifdef FEATURE_UTF8STRING
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pUtf8StringClass, ::g_pUtf8StringClass)
-#endif // FEATURE_UTF8STRING
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pArrayClass, ::g_pArrayClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pSZArrayHelperClass, ::g_pSZArrayHelperClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pNullableClass, ::g_pNullableClass)
diff --git a/src/coreclr/src/vm/appdomain.cpp b/src/coreclr/src/vm/appdomain.cpp
index 1ba7c47cd50a1..f703b4214cea6 100644
--- a/src/coreclr/src/vm/appdomain.cpp
+++ b/src/coreclr/src/vm/appdomain.cpp
@@ -1517,11 +1517,6 @@ void SystemDomain::LoadBaseSystemClasses()
// Load String
g_pStringClass = CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_STRING);
-#ifdef FEATURE_UTF8STRING
- // Load Utf8String
- g_pUtf8StringClass = CoreLibBinder::GetClass(CLASS__UTF8_STRING);
-#endif // FEATURE_UTF8STRING
-
#ifndef CROSSGEN_COMPILE
ECall::PopulateManagedStringConstructors();
#endif // CROSSGEN_COMPILE
diff --git a/src/coreclr/src/vm/classnames.h b/src/coreclr/src/vm/classnames.h
index e2af51817f168..59e516d3e3a42 100644
--- a/src/coreclr/src/vm/classnames.h
+++ b/src/coreclr/src/vm/classnames.h
@@ -94,10 +94,6 @@
#define g_ThreadClassName "System.Threading.Thread"
#define g_TypeClassName "System.Type"
-#ifdef FEATURE_UTF8STRING
-#define g_Utf8StringName "Utf8String"
-#endif // FEATURE_UTF8STRING
-
#define g_VariantClassName "System.Variant"
#define g_GuidClassName "System.Guid"
diff --git a/src/coreclr/src/vm/common.h b/src/coreclr/src/vm/common.h
index f01ec501bb67e..6694e74d8b485 100644
--- a/src/coreclr/src/vm/common.h
+++ b/src/coreclr/src/vm/common.h
@@ -162,9 +162,6 @@ typedef DPTR(class ReJitManager) PTR_ReJitManager;
typedef DPTR(struct ReJitInfo) PTR_ReJitInfo;
typedef DPTR(struct SharedReJitInfo) PTR_SharedReJitInfo;
typedef DPTR(class StringObject) PTR_StringObject;
-#ifdef FEATURE_UTF8STRING
-typedef DPTR(class Utf8StringObject) PTR_Utf8StringObject;
-#endif // FEATURE_UTF8STRING
typedef DPTR(class TypeHandle) PTR_TypeHandle;
typedef VPTR(class VirtualCallStubManager) PTR_VirtualCallStubManager;
typedef VPTR(class VirtualCallStubManagerManager) PTR_VirtualCallStubManagerManager;
diff --git a/src/coreclr/src/vm/corelib.h b/src/coreclr/src/vm/corelib.h
index 21c8a6c4332ff..dbf514748420a 100644
--- a/src/coreclr/src/vm/corelib.h
+++ b/src/coreclr/src/vm/corelib.h
@@ -318,10 +318,6 @@ DEFINE_CLASS(ENCODING, Text, Encoding)
DEFINE_CLASS(RUNE, Text, Rune)
-#ifdef FEATURE_UTF8STRING
-DEFINE_CLASS(CHAR8, System, Char8)
-#endif // FEATURE_UTF8STRING
-
DEFINE_CLASS(ENUM, System, Enum)
DEFINE_CLASS(ENVIRONMENT, System, Environment)
@@ -847,17 +843,6 @@ DEFINE_METHOD(STRING, WCSLEN, wcslen,
DEFINE_METHOD(STRING, STRLEN, strlen, SM_PtrByte_RetInt)
DEFINE_PROPERTY(STRING, LENGTH, Length, Int)
-#ifdef FEATURE_UTF8STRING
-DEFINE_CLASS(UTF8_STRING, System, Utf8String)
-DEFINE_METHOD(UTF8_STRING, CTORF_READONLYSPANOFBYTE,Ctor, IM_ReadOnlySpanOfByte_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_READONLYSPANOFCHAR,Ctor, IM_ReadOnlySpanOfChar_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_BYTEARRAY_START_LEN,Ctor, IM_ArrByte_Int_Int_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_BYTEPTR, Ctor, IM_PtrByte_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_CHARARRAY_START_LEN,Ctor, IM_ArrChar_Int_Int_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_CHARPTR, Ctor, IM_PtrChar_RetUtf8Str)
-DEFINE_METHOD(UTF8_STRING, CTORF_STRING, Ctor, IM_String_RetUtf8Str)
-#endif // FEATURE_UTF8STRING
-
DEFINE_CLASS(STRING_BUILDER, Text, StringBuilder)
DEFINE_PROPERTY(STRING_BUILDER, LENGTH, Length, Int)
DEFINE_PROPERTY(STRING_BUILDER, CAPACITY, Capacity, Int)
diff --git a/src/coreclr/src/vm/ecall.cpp b/src/coreclr/src/vm/ecall.cpp
index a86d12c4b434a..5daa657f33a4d 100644
--- a/src/coreclr/src/vm/ecall.cpp
+++ b/src/coreclr/src/vm/ecall.cpp
@@ -84,30 +84,6 @@ static_assert_no_msg(ECallCtor_First + 8 == ECall::CtorSBytePtrStartLengthEncodi
#define NumberOfStringConstructors 9
-#ifdef FEATURE_UTF8STRING
-// METHOD__UTF8STRING__CTORF_XXX has to be in same order as ECall::Utf8StringCtorCharXxx
-#define METHOD__UTF8STRING__CTORF_FIRST METHOD__UTF8_STRING__CTORF_READONLYSPANOFBYTE
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 0 == METHOD__UTF8_STRING__CTORF_READONLYSPANOFBYTE);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 1 == METHOD__UTF8_STRING__CTORF_READONLYSPANOFCHAR);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 2 == METHOD__UTF8_STRING__CTORF_BYTEARRAY_START_LEN);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 3 == METHOD__UTF8_STRING__CTORF_BYTEPTR);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 4 == METHOD__UTF8_STRING__CTORF_CHARARRAY_START_LEN);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 5 == METHOD__UTF8_STRING__CTORF_CHARPTR);
-static_assert_no_msg(METHOD__UTF8STRING__CTORF_FIRST + 6 == METHOD__UTF8_STRING__CTORF_STRING);
-
-// ECall::Utf8StringCtorCharXxx has to be in same order as METHOD__UTF8STRING__CTORF_XXX
-#define ECallUtf8String_Ctor_First ECall::Utf8StringCtorReadOnlySpanOfByteManaged
-static_assert_no_msg(ECallUtf8String_Ctor_First + 0 == ECall::Utf8StringCtorReadOnlySpanOfByteManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 1 == ECall::Utf8StringCtorReadOnlySpanOfCharManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 2 == ECall::Utf8StringCtorByteArrayStartLengthManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 3 == ECall::Utf8StringCtorBytePtrManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 4 == ECall::Utf8StringCtorCharArrayStartLengthManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 5 == ECall::Utf8StringCtorCharPtrManaged);
-static_assert_no_msg(ECallUtf8String_Ctor_First + 6 == ECall::Utf8StringCtorStringManaged);
-
-#define NumberOfUtf8StringConstructors 7
-#endif // FEATURE_UTF8STRING
-
void ECall::PopulateManagedStringConstructors()
{
STANDARD_VM_CONTRACT;
@@ -126,19 +102,6 @@ void ECall::PopulateManagedStringConstructors()
ECall::DynamicallyAssignFCallImpl(pDest, ECallCtor_First + i);
}
-#ifdef FEATURE_UTF8STRING
- _ASSERTE(g_pUtf8StringClass != NULL);
- for (int i = 0; i < NumberOfUtf8StringConstructors; i++)
- {
- MethodDesc* pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__UTF8STRING__CTORF_FIRST + i));
- _ASSERTE(pMD != NULL);
-
- PCODE pDest = pMD->GetMultiCallableAddrOfCode();
-
- ECall::DynamicallyAssignFCallImpl(pDest, ECallUtf8String_Ctor_First + i);
- }
-#endif // FEATURE_UTF8STRING
-
INDEBUG(fInitialized = true);
}
diff --git a/src/coreclr/src/vm/ecall.h b/src/coreclr/src/vm/ecall.h
index 19b8753828709..f1fedf2cbeb4e 100644
--- a/src/coreclr/src/vm/ecall.h
+++ b/src/coreclr/src/vm/ecall.h
@@ -118,21 +118,7 @@ class ECall
DYNAMICALLY_ASSIGNED_FCALL_IMPL(CtorSBytePtrStartLengthEncodingManaged, NULL) \
DYNAMICALLY_ASSIGNED_FCALL_IMPL(InternalGetCurrentThread, NULL) \
-#define _DYNAMICALLY_ASSIGNED_FCALLS_UTF8STRING() \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(FastAllocateUtf8String, FramedAllocateUtf8String) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorReadOnlySpanOfByteManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorReadOnlySpanOfCharManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorByteArrayStartLengthManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorBytePtrManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorCharArrayStartLengthManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorCharPtrManaged, NULL) \
- DYNAMICALLY_ASSIGNED_FCALL_IMPL(Utf8StringCtorStringManaged, NULL) \
-
-#ifdef FEATURE_UTF8STRING
-#define DYNAMICALLY_ASSIGNED_FCALLS() _DYNAMICALLY_ASSIGNED_FCALLS_BASE() _DYNAMICALLY_ASSIGNED_FCALLS_UTF8STRING()
-#else
#define DYNAMICALLY_ASSIGNED_FCALLS() _DYNAMICALLY_ASSIGNED_FCALLS_BASE()
-#endif // FEATURE_UTF8STRING
enum
{
diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h
index 2c8e41ac831e7..87389732f8d2e 100644
--- a/src/coreclr/src/vm/ecalllist.h
+++ b/src/coreclr/src/vm/ecalllist.h
@@ -111,19 +111,6 @@ FCFuncStart(gStringFuncs)
FCFuncElement("Intern", AppDomainNative::GetOrInternString)
FCFuncEnd()
-#ifdef FEATURE_UTF8STRING
-FCFuncStart(gUtf8StringFuncs)
- FCDynamic("FastAllocate", CORINFO_INTRINSIC_Illegal, ECall::FastAllocateUtf8String)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ReadOnlySpanOfByte_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorReadOnlySpanOfByteManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ReadOnlySpanOfChar_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorReadOnlySpanOfCharManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ArrByte_Int_Int_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorByteArrayStartLengthManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_PtrByte_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorBytePtrManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ArrChar_Int_Int_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorCharArrayStartLengthManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_PtrChar_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorCharPtrManaged)
- FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_Str_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::Utf8StringCtorStringManaged)
-FCFuncEnd()
-#endif // FEATURE_UTF8STRING
-
FCFuncStart(gValueTypeFuncs)
FCFuncElement("CanCompareBits", ValueTypeHelper::CanCompareBits)
FCFuncElement("FastEqualsCheck", ValueTypeHelper::FastEqualsCheck)
@@ -1219,9 +1206,6 @@ FCClassElement("TypeLoadException", "System", gTypeLoadExceptionFuncs)
FCClassElement("TypeNameParser", "System", gTypeNameParser)
FCClassElement("TypedReference", "System", gTypedReferenceFuncs)
FCClassElement("UnmanagedThreadPoolWorkItem", "System.Threading", gUnmanagedThreadPoolWorkItemFuncs)
-#ifdef FEATURE_UTF8STRING
-FCClassElement("Utf8String", "System", gUtf8StringFuncs)
-#endif // FEATURE_UTF8STRING
FCClassElement("ValueType", "System", gValueTypeFuncs)
#ifdef FEATURE_COMINTEROP
FCClassElement("Variant", "System", gVariantFuncs)
diff --git a/src/coreclr/src/vm/gchelpers.cpp b/src/coreclr/src/vm/gchelpers.cpp
index d08a747839204..028e17b020d9b 100644
--- a/src/coreclr/src/vm/gchelpers.cpp
+++ b/src/coreclr/src/vm/gchelpers.cpp
@@ -869,55 +869,6 @@ STRINGREF AllocateString( DWORD cchStringLength )
return ObjectToSTRINGREF(orString);
}
-#ifdef FEATURE_UTF8STRING
-UTF8STRINGREF AllocateUtf8String(DWORD cchStringLength)
-{
- CONTRACTL{
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE; // returns an objref without pinning it => cooperative
- } CONTRACTL_END;
-
-#ifdef _DEBUG
- if (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP))
- {
- char *a = new char;
- delete a;
- }
-#endif
-
- // Limit the maximum string size to <2GB to mitigate risk of security issues caused by 32-bit integer
- // overflows in buffer size calculations.
- //
- // 0x7FFFFFBF is derived from the const 0x3FFFFFDF in SlowAllocateString.
- // Adding +1 (for null terminator) and multiplying by sizeof(WCHAR) means that
- // SlowAllocateString allows a maximum of 0x7FFFFFC0 bytes to be used for the
- // string data itself, with some additional buffer for object headers and other
- // data. Since we don't have the sizeof(WCHAR) multiplication here, we only need
- // -1 to account for the null terminator, leading to a max size of 0x7FFFFFBF.
- if (cchStringLength > 0x7FFFFFBF)
- ThrowOutOfMemory();
-
- SIZE_T totalSize = PtrAlign(Utf8StringObject::GetSize(cchStringLength));
- _ASSERTE(totalSize > cchStringLength);
-
- SetTypeHandleOnThreadForAlloc(TypeHandle(g_pUtf8StringClass));
-
- GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS;
- if (totalSize >= g_pConfig->GetGCLOHThreshold())
- flags |= GC_ALLOC_LARGE_OBJECT_HEAP;
-
- Utf8StringObject* orString = (Utf8StringObject*)Alloc(totalSize, flags);
-
- // Initialize Object
- orString->SetMethodTable(g_pUtf8StringClass);
- orString->SetLength(cchStringLength);
-
- PublishObjectAndNotify(orString, flags);
- return ObjectToUTF8STRINGREF(orString);
-}
-#endif // FEATURE_UTF8STRING
-
#ifdef FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
// OBJECTREF AllocateComClassObject(ComClassFactory* pComClsFac)
void AllocateComClassObject(ComClassFactory* pComClsFac, OBJECTREF* ppRefClass)
diff --git a/src/coreclr/src/vm/gchelpers.h b/src/coreclr/src/vm/gchelpers.h
index f9a9ac5320e29..794706c222674 100644
--- a/src/coreclr/src/vm/gchelpers.h
+++ b/src/coreclr/src/vm/gchelpers.h
@@ -36,10 +36,6 @@ OBJECTREF AllocateObjectArray(DWORD cElements, TypeHandle ElementType, BOOL bAll
// Allocate a string
STRINGREF AllocateString( DWORD cchStringLength );
-#ifdef FEATURE_UTF8STRING
-UTF8STRINGREF AllocateUtf8String( DWORD cchStringLength );
-#endif // FEATURE_UTF8STRING
-
OBJECTREF DupArrayForCloning(BASEARRAYREF pRef);
// The JIT requests the EE to specify an allocation helper to use at each new-site.
diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp
index 0df65b9e6b8cf..c101e43575a72 100644
--- a/src/coreclr/src/vm/jithelpers.cpp
+++ b/src/coreclr/src/vm/jithelpers.cpp
@@ -2389,61 +2389,6 @@ HCIMPL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength)
}
HCIMPLEND
-#ifdef FEATURE_UTF8STRING
-HCIMPL1(Utf8StringObject*, AllocateUtf8String_MP_FastPortable, DWORD stringLength)
-{
- FCALL_CONTRACT;
-
- do
- {
- _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
-
- // Instead of doing elaborate overflow checks, we just limit the number of elements. This will avoid all overflow
- // problems, as well as making sure big string objects are correctly allocated in the big object heap.
- if (stringLength >= LARGE_OBJECT_SIZE - 256)
- {
- break;
- }
-
- // This is typically the only call in the fast path. Making the call early seems to be better, as it allows the compiler
- // to use volatile registers for intermediate values. This reduces the number of push/pop instructions and eliminates
- // some reshuffling of intermediate values into nonvolatile registers around the call.
- Thread *thread = GetThread();
-
- SIZE_T totalSize = Utf8StringObject::GetSize(stringLength);
-
- // The method table's base size includes space for a terminating null character
- _ASSERTE(totalSize >= g_pUtf8StringClass->GetBaseSize());
- _ASSERTE(totalSize - g_pUtf8StringClass->GetBaseSize() == stringLength);
-
- SIZE_T alignedTotalSize = ALIGN_UP(totalSize, DATA_ALIGNMENT);
- _ASSERTE(alignedTotalSize >= totalSize);
- totalSize = alignedTotalSize;
-
- gc_alloc_context *allocContext = thread->GetAllocContext();
- BYTE *allocPtr = allocContext->alloc_ptr;
- _ASSERTE(allocPtr <= allocContext->alloc_limit);
- if (totalSize > static_cast(allocContext->alloc_limit - allocPtr))
- {
- break;
- }
- allocContext->alloc_ptr = allocPtr + totalSize;
-
- _ASSERTE(allocPtr != nullptr);
- Utf8StringObject *stringObject = reinterpret_cast(allocPtr);
- stringObject->SetMethodTable(g_pUtf8StringClass);
- stringObject->SetLength(stringLength);
-
- return stringObject;
- } while (false);
-
- // Tail call to the slow helper
- ENDFORBIDGC();
- return HCCALL1(FramedAllocateUtf8String, stringLength);
-}
-HCIMPLEND
-#endif // FEATURE_UTF8STRING
-
#include
/*********************************************************************/
@@ -2482,22 +2427,6 @@ HCIMPL1(StringObject*, FramedAllocateString, DWORD stringLength)
}
HCIMPLEND
-#ifdef FEATURE_UTF8STRING
-HCIMPL1(Utf8StringObject*, FramedAllocateUtf8String, DWORD stringLength)
-{
- FCALL_CONTRACT;
-
- UTF8STRINGREF result = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
-
- result = AllocateUtf8String(stringLength);
-
- HELPER_METHOD_FRAME_END();
- return((Utf8StringObject*) OBJECTREFToObject(result));
-}
-HCIMPLEND
-#endif // FEATURE_UTF8STRING
-
/*********************************************************************/
OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok)
{
diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp
index b8274eb3344e7..ad5f9b12c1819 100644
--- a/src/coreclr/src/vm/jitinterface.cpp
+++ b/src/coreclr/src/vm/jitinterface.cpp
@@ -7399,9 +7399,6 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn,
if (methodTable == CoreLibBinder::GetClass(CLASS__BOOLEAN)
|| methodTable == CoreLibBinder::GetClass(CLASS__BYTE)
|| methodTable == CoreLibBinder::GetClass(CLASS__SBYTE)
-#ifdef FEATURE_UTF8STRING
- || methodTable == CoreLibBinder::GetClass(CLASS__CHAR8)
-#endif // FEATURE_UTF8STRING
|| methodTable == CoreLibBinder::GetClass(CLASS__CHAR)
|| methodTable == CoreLibBinder::GetClass(CLASS__INT16)
|| methodTable == CoreLibBinder::GetClass(CLASS__UINT16)
diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h
index 0d2a720299a4f..ccdafd03e8726 100644
--- a/src/coreclr/src/vm/jitinterface.h
+++ b/src/coreclr/src/vm/jitinterface.h
@@ -203,11 +203,6 @@ extern FCDECL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength
extern FCDECL1(StringObject*, UnframedAllocateString, DWORD stringLength);
extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength);
-#ifdef FEATURE_UTF8STRING
-extern FCDECL1(Utf8StringObject*, AllocateUtf8String_MP_FastPortable, DWORD stringLength);
-extern FCDECL1(Utf8StringObject*, FramedAllocateUtf8String, DWORD stringLength);
-#endif // FEATURE_UTF8STRING
-
extern FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
extern FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
extern FCDECL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
diff --git a/src/coreclr/src/vm/jitinterfacegen.cpp b/src/coreclr/src/vm/jitinterfacegen.cpp
index 661d68fa7d8d1..68ab56aeb96ef 100644
--- a/src/coreclr/src/vm/jitinterfacegen.cpp
+++ b/src/coreclr/src/vm/jitinterfacegen.cpp
@@ -79,9 +79,6 @@ void InitJITHelpers1()
SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_MP_FastPortable);
ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateString_MP_FastPortable), ECall::FastAllocateString);
-#ifdef FEATURE_UTF8STRING
- ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateUtf8String_MP_FastPortable), ECall::FastAllocateUtf8String);
-#endif // FEATURE_UTF8STRING
#else // TARGET_UNIX
// if (multi-proc || server GC)
if (GCHeapUtilities::UseThreadAllocationContexts())
@@ -93,9 +90,6 @@ void InitJITHelpers1()
SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_MP_InlineGetThread);
ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastMP_InlineGetThread), ECall::FastAllocateString);
-#ifdef FEATURE_UTF8STRING
- ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateUtf8String_MP_FastPortable), ECall::FastAllocateUtf8String);
-#endif // FEATURE_UTF8STRING
}
else
{
@@ -110,9 +104,6 @@ void InitJITHelpers1()
SetJitHelperFunction(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1OBJ_UP);
ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateStringFastUP), ECall::FastAllocateString);
-#ifdef FEATURE_UTF8STRING
- ECall::DynamicallyAssignFCallImpl(GetEEFuncEntryPoint(AllocateUtf8String_MP_FastPortable), ECall::FastAllocateUtf8String);
-#endif // FEATURE_UTF8STRING
}
#endif // TARGET_UNIX
}
diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp
index a2e2295cf7fca..56d874c2ed780 100644
--- a/src/coreclr/src/vm/marshalnative.cpp
+++ b/src/coreclr/src/vm/marshalnative.cpp
@@ -236,11 +236,6 @@ FCIMPL1(FC_BOOL_RET, MarshalNative::IsPinnable, Object* obj)
if (obj->GetMethodTable() == g_pStringClass)
FC_RETURN_BOOL(TRUE);
-#ifdef FEATURE_UTF8STRING
- if (obj->GetMethodTable() == g_pUtf8StringClass)
- FC_RETURN_BOOL(TRUE);
-#endif // FEATURE_UTF8STRING
-
if (obj->GetMethodTable()->IsArray())
{
BASEARRAYREF asArray = (BASEARRAYREF)ObjectToOBJECTREF(obj);
@@ -456,11 +451,6 @@ void ValidatePinnedObject(OBJECTREF obj)
if (obj->GetMethodTable() == g_pStringClass)
return;
-#ifdef FEATURE_UTF8STRING
- if (obj->GetMethodTable() == g_pUtf8StringClass)
- return;
-#endif // FEATURE_UTF8STRING
-
if (obj->GetMethodTable()->IsArray())
{
BASEARRAYREF asArray = (BASEARRAYREF) obj;
diff --git a/src/coreclr/src/vm/metasig.h b/src/coreclr/src/vm/metasig.h
index 03b2e457271b5..0714e0c50e209 100644
--- a/src/coreclr/src/vm/metasig.h
+++ b/src/coreclr/src/vm/metasig.h
@@ -414,16 +414,6 @@ DEFINE_METASIG(IM(Obj_Int_RetIntPtr, j i, I))
DEFINE_METASIG(IM(ArrByte_Int_Int_RetVoid, a(b) i i, v))
DEFINE_METASIG(IM(PtrByte_RetVoid, P(b), v))
-#ifdef FEATURE_UTF8STRING
-DEFINE_METASIG_T(IM(ReadOnlySpanOfByte_RetUtf8Str, GI(g(READONLY_SPAN), 1, b), C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(ReadOnlySpanOfChar_RetUtf8Str, GI(g(READONLY_SPAN), 1, u), C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(ArrByte_Int_Int_RetUtf8Str, a(b) i i, C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(PtrByte_RetUtf8Str, P(b), C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(ArrChar_Int_Int_RetUtf8Str, a(u) i i, C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(PtrChar_RetUtf8Str, P(u), C(UTF8_STRING)))
-DEFINE_METASIG_T(IM(String_RetUtf8Str, s, C(UTF8_STRING)))
-#endif // FEATURE_UTF8STRING
-
DEFINE_METASIG(IM(Char_Char_RetStr, u u, s))
DEFINE_METASIG(IM(Char_Int_RetVoid, u i, v))
DEFINE_METASIG_T(SM(RetCultureInfo, _, C(CULTURE_INFO)))
diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp
index ec07edc2b557b..5e09e619b9e8b 100644
--- a/src/coreclr/src/vm/methodtablebuilder.cpp
+++ b/src/coreclr/src/vm/methodtablebuilder.cpp
@@ -9770,19 +9770,6 @@ void MethodTableBuilder::CheckForSystemTypes()
pMT->SetComponentSize(2);
}
-#ifdef FEATURE_UTF8STRING
- else if (strcmp(name, g_Utf8StringName) == 0 && strcmp(nameSpace, g_SystemNS) == 0)
- {
- // Utf8Strings are not "normal" objects, so we need to mess with their method table a bit
- // so that the GC can figure out how big each string is...
- DWORD baseSize = Utf8StringObject::GetBaseSize();
- pMT->SetBaseSize(baseSize); // NULL character included
-
- GetHalfBakedClass()->SetBaseSizePadding(baseSize - bmtFP->NumInstanceFieldBytes);
-
- pMT->SetComponentSize(1);
- }
-#endif // FEATURE_UTF8STRING
else if (strcmp(name, g_CriticalFinalizerObjectName) == 0 && strcmp(nameSpace, g_ConstrainedExecutionNS) == 0)
{
// To introduce a class with a critical finalizer,
diff --git a/src/coreclr/src/vm/object.h b/src/coreclr/src/vm/object.h
index 0604d6583401c..9f6bdf8562ad9 100644
--- a/src/coreclr/src/vm/object.h
+++ b/src/coreclr/src/vm/object.h
@@ -783,9 +783,6 @@ typedef DPTR(UPTRArray) PTR_UPTRArray;
typedef DPTR(PTRArray) PTR_PTRArray;
class StringObject;
-#ifdef FEATURE_UTF8STRING
-class Utf8StringObject;
-#endif // FEATURE_UTF8STRING
#ifdef USE_CHECKED_OBJECTREFS
typedef REF BASEARRAYREF;
@@ -804,9 +801,6 @@ typedef REF UPTRARRAYREF;
typedef REF CHARARRAYREF;
typedef REF PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays.
typedef REF STRINGREF;
-#ifdef FEATURE_UTF8STRING
-typedef REF UTF8STRINGREF;
-#endif // FEATURE_UTF8STRING
#else // USE_CHECKED_OBJECTREFS
@@ -826,9 +820,6 @@ typedef PTR_UPTRArray UPTRARRAYREF;
typedef PTR_CHARArray CHARARRAYREF;
typedef PTR_PTRArray PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays.
typedef PTR_StringObject STRINGREF;
-#ifdef FEATURE_UTF8STRING
-typedef PTR_Utf8StringObject UTF8STRINGREF;
-#endif // FEATURE_UTF8STRING
#endif // USE_CHECKED_OBJECTREFS
@@ -1067,56 +1058,6 @@ class ReflectClassBaseObject : public BaseObjectWithCachedData
};
-#ifdef FEATURE_UTF8STRING
-class Utf8StringObject : public Object
-{
-#ifdef DACCESS_COMPILE
- friend class ClrDataAccess;
-#endif
-
-private:
- DWORD m_StringLength;
- BYTE m_FirstChar;
-
-public:
- VOID SetLength(DWORD len) { LIMITED_METHOD_CONTRACT; _ASSERTE(len >= 0); m_StringLength = len; }
-
-protected:
- Utf8StringObject() { LIMITED_METHOD_CONTRACT; }
- ~Utf8StringObject() { LIMITED_METHOD_CONTRACT; }
-
-public:
-
- /*=================RefInterpretGetStringValuesDangerousForGC======================
- **N.B.: This perfoms no range checking and relies on the caller to have done this.
- **Args: (IN)ref -- the Utf8String to be interpretted.
- ** (OUT)chars -- a pointer to the characters in the buffer.
- ** (OUT)length -- a pointer to the length of the buffer.
- **Returns: void.
- **Exceptions: None.
- ==============================================================================*/
- // !!!! If you use this function, you have to be careful because chars is a pointer
- // !!!! to the data buffer of ref. If GC happens after this call, you need to make
- // !!!! sure that you have a pin handle on ref, or use GCPROTECT_BEGINPINNING on ref.
- void RefInterpretGetStringValuesDangerousForGC(__deref_out_ecount(*length + 1) CHAR **chars, int *length) {
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE(GetGCSafeMethodTable() == g_pUtf8StringClass);
- *length = GetStringLength();
- *chars = GetBuffer();
-#ifdef _DEBUG
- EnableStressHeapHelper();
-#endif
- }
-
- DWORD GetStringLength() { LIMITED_METHOD_DAC_CONTRACT; return( m_StringLength );}
- CHAR* GetBuffer() { LIMITED_METHOD_CONTRACT; return (CHAR*)( dac_cast(this) + offsetof(Utf8StringObject, m_FirstChar) ); }
-
- static DWORD GetBaseSize();
- static SIZE_T GetSize(DWORD stringLength);
-};
-#endif // FEATURE_UTF8STRING
-
// This is the Method version of the Reflection object.
// A Method has adddition information.
// m_pMD - A pointer to the actual MethodDesc of the method.
diff --git a/src/coreclr/src/vm/object.inl b/src/coreclr/src/vm/object.inl
index e82fdebfbeb50..e61f2eb443bab 100644
--- a/src/coreclr/src/vm/object.inl
+++ b/src/coreclr/src/vm/object.inl
@@ -60,22 +60,6 @@ __forceinline /*static*/ SIZE_T StringObject::GetSize(DWORD strLen)
return GetBaseSize() + strLen * sizeof(WCHAR);
}
-#ifdef FEATURE_UTF8STRING
-__forceinline /*static*/ DWORD Utf8StringObject::GetBaseSize()
-{
- LIMITED_METHOD_DAC_CONTRACT;
-
- return OBJECT_BASESIZE + sizeof(DWORD) /* length */ + sizeof(BYTE) /* null terminator */;
-}
-
-__forceinline /*static*/ SIZE_T Utf8StringObject::GetSize(DWORD strLen)
-{
- LIMITED_METHOD_DAC_CONTRACT;
-
- return GetBaseSize() + strLen;
-}
-#endif // FEATURE_UTF8STRING
-
#ifdef DACCESS_COMPILE
inline void Object::EnumMemoryRegions(void)
diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp
index 0051a9345c892..3dfa8ca727739 100644
--- a/src/coreclr/src/vm/reflectioninvocation.cpp
+++ b/src/coreclr/src/vm/reflectioninvocation.cpp
@@ -2201,11 +2201,7 @@ FCIMPL1(Object*, ReflectionSerialization::GetUninitializedObject, ReflectClassBa
PREFIX_ASSUME(pMT != NULL);
//We don't allow unitialized Strings or Utf8Strings.
- if (pMT == g_pStringClass
-#ifdef FEATURE_UTF8STRING
- || pMT == g_pUtf8StringClass
-#endif // FEATURE_UTF8STRING
- ) {
+ if (pMT == g_pStringClass) {
COMPlusThrow(kArgumentException, W("Argument_NoUninitializedStrings"));
}
diff --git a/src/coreclr/src/vm/vars.cpp b/src/coreclr/src/vm/vars.cpp
index b684583c7d970..152027b02032c 100644
--- a/src/coreclr/src/vm/vars.cpp
+++ b/src/coreclr/src/vm/vars.cpp
@@ -59,9 +59,6 @@ GPTR_IMPL(MethodTable, g_pObjectClass);
GPTR_IMPL(MethodTable, g_pRuntimeTypeClass);
GPTR_IMPL(MethodTable, g_pCanonMethodTableClass); // System.__Canon
GPTR_IMPL(MethodTable, g_pStringClass);
-#ifdef FEATURE_UTF8STRING
-GPTR_IMPL(MethodTable, g_pUtf8StringClass);
-#endif // FEATURE_UTF8STRING
GPTR_IMPL(MethodTable, g_pArrayClass);
GPTR_IMPL(MethodTable, g_pSZArrayHelperClass);
GPTR_IMPL(MethodTable, g_pNullableClass);
diff --git a/src/coreclr/src/vm/vars.hpp b/src/coreclr/src/vm/vars.hpp
index 3b85c93adc5e1..88140bdc48635 100644
--- a/src/coreclr/src/vm/vars.hpp
+++ b/src/coreclr/src/vm/vars.hpp
@@ -73,9 +73,6 @@ class LoaderHeap;
class IGCHeap;
class Object;
class StringObject;
-#ifdef FEATURE_UTF8STRING
-class Utf8StringObject;
-#endif // FEATURE_UTF8STRING
class ArrayClass;
class MethodTable;
class MethodDesc;
@@ -309,10 +306,6 @@ class REF : public OBJECTREF
#define OBJECTREFToObject(objref) ((objref).operator-> ())
#define ObjectToSTRINGREF(obj) (STRINGREF(obj))
#define STRINGREFToObject(objref) (*( (StringObject**) &(objref) ))
-#ifdef FEATURE_UTF8STRING
-#define ObjectToUTF8STRINGREF(obj) (UTF8STRINGREF(obj))
-#define UTF8STRINGREFToObject(objref) (*( (Utf8StringObject**) &(objref) ))
-#endif // FEATURE_UTF8STRING
#else // _DEBUG_IMPL
@@ -323,10 +316,6 @@ class REF : public OBJECTREF
#define OBJECTREFToObject(objref) ((PTR_Object) (objref))
#define ObjectToSTRINGREF(obj) ((PTR_StringObject) (obj))
#define STRINGREFToObject(objref) ((PTR_StringObject) (objref))
-#ifdef FEATURE_UTF8STRING
-#define ObjectToUTF8STRINGREF(obj) ((PTR_Utf8StringObject) (obj))
-#define UTF8STRINGREFToObject(objref) ((PTR_Utf8StringObject) (objref))
-#endif // FEATURE_UTF8STRING
#endif // _DEBUG_IMPL
@@ -365,9 +354,6 @@ GPTR_DECL(MethodTable, g_pObjectClass);
GPTR_DECL(MethodTable, g_pRuntimeTypeClass);
GPTR_DECL(MethodTable, g_pCanonMethodTableClass); // System.__Canon
GPTR_DECL(MethodTable, g_pStringClass);
-#ifdef FEATURE_UTF8STRING
-GPTR_DECL(MethodTable, g_pUtf8StringClass);
-#endif // FEATURE_UTF8STRING
GPTR_DECL(MethodTable, g_pArrayClass);
GPTR_DECL(MethodTable, g_pSZArrayHelperClass);
GPTR_DECL(MethodTable, g_pNullableClass);
diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props
index b48551a1fba5b..1b5162d941c82 100644
--- a/src/libraries/Directory.Build.props
+++ b/src/libraries/Directory.Build.props
@@ -90,8 +90,6 @@
-
-
diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 159721414fde2..53d63d973da1d 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -1954,24 +1954,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/libraries/System.Private.CoreLib/src/System/Char8.cs b/src/libraries/System.Private.CoreLib/src/System/Char8.cs
deleted file mode 100644
index 9dfdbc81215a1..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Char8.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System
-{
- ///
- /// Represents a UTF-8 code unit, the elemental type of .
- ///
- public readonly struct Char8 : IComparable, IEquatable
- {
- private readonly byte _value;
-
- private Char8(byte value)
- {
- _value = value;
- }
-
- public static bool operator ==(Char8 left, Char8 right) => left._value == right._value;
- public static bool operator !=(Char8 left, Char8 right) => left._value != right._value;
- public static bool operator <(Char8 left, Char8 right) => left._value < right._value;
- public static bool operator <=(Char8 left, Char8 right) => left._value <= right._value;
- public static bool operator >(Char8 left, Char8 right) => left._value > right._value;
- public static bool operator >=(Char8 left, Char8 right) => left._value >= right._value;
-
- // Operators from Utf8Char to
- // TODO: Once C# gets support for checked operators, we should add those here.
-
- public static implicit operator byte(Char8 value) => value._value;
- [CLSCompliant(false)]
- public static explicit operator sbyte(Char8 value) => (sbyte)value._value; // explicit because can integer overflow
- public static explicit operator char(Char8 value) => (char)value._value; // explicit because don't want to encourage char conversion
- public static implicit operator short(Char8 value) => value._value;
- [CLSCompliant(false)]
- public static implicit operator ushort(Char8 value) => value._value;
- public static implicit operator int(Char8 value) => value._value;
- [CLSCompliant(false)]
- public static implicit operator uint(Char8 value) => value._value;
- public static implicit operator long(Char8 value) => value._value;
- [CLSCompliant(false)]
- public static implicit operator ulong(Char8 value) => value._value;
-
- // Operators from to Char8; most are explicit because narrowing conversions could be lossy
- // TODO: Once C# gets support for checked operators, we should add those here.
-
- public static implicit operator Char8(byte value) => new Char8(value);
- [CLSCompliant(false)]
- public static explicit operator Char8(sbyte value) => new Char8((byte)value);
- public static explicit operator Char8(char value) => new Char8((byte)value);
- public static explicit operator Char8(short value) => new Char8((byte)value);
- [CLSCompliant(false)]
- public static explicit operator Char8(ushort value) => new Char8((byte)value);
- public static explicit operator Char8(int value) => new Char8((byte)value);
- [CLSCompliant(false)]
- public static explicit operator Char8(uint value) => new Char8((byte)value);
- public static explicit operator Char8(long value) => new Char8((byte)value);
- [CLSCompliant(false)]
- public static explicit operator Char8(ulong value) => new Char8((byte)value);
-
- public int CompareTo(Char8 other) => this._value.CompareTo(other._value);
-
- public override bool Equals(object? obj) => (obj is Char8 other) && (this == other);
- public bool Equals(Char8 other) => this == other;
-
- public override int GetHashCode() => _value;
-
- public override string ToString() => _value.ToString("X2");
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Memory.cs b/src/libraries/System.Private.CoreLib/src/System/Memory.cs
index c93dfc4baed17..531ec481e0446 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Memory.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Memory.cs
@@ -166,9 +166,6 @@ internal Memory(object? obj, int start, int length)
// 'obj is T[]' below also handles things like int[] <-> uint[] being convertible
Debug.Assert((obj == null)
|| (typeof(T) == typeof(char) && obj is string)
-#if FEATURE_UTF8STRING
- || ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && obj is Utf8String)
-#endif // FEATURE_UTF8STRING
|| (obj is T[])
|| (obj is MemoryManager));
@@ -218,14 +215,6 @@ public override string ToString()
{
return (_object is string str) ? str.Substring(_index, _length) : Span.ToString();
}
-#if FEATURE_UTF8STRING
- else if (typeof(T) == typeof(Char8))
- {
- // TODO_UTF8STRING: Call into optimized transcoding routine when it's available.
- Span span = Span;
- return Encoding.UTF8.GetString(new ReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length));
- }
-#endif // FEATURE_UTF8STRING
return string.Format("System.Memory<{0}>[{1}]", typeof(T).Name, _length);
}
@@ -302,13 +291,6 @@ public unsafe Span Span
refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).GetRawStringData());
lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length;
}
-#if FEATURE_UTF8STRING
- else if ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && tmpObject.GetType() == typeof(Utf8String))
- {
- refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).DangerousGetMutableReference());
- lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length;
- }
-#endif // FEATURE_UTF8STRING
else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject))
{
// We know the object is not null, it's not a string, and it is variable-length. The only
@@ -423,14 +405,6 @@ public unsafe MemoryHandle Pin()
ref char stringData = ref Unsafe.Add(ref s.GetRawStringData(), _index);
return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle);
}
-#if FEATURE_UTF8STRING
- else if ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && tmpObject is Utf8String utf8String)
- {
- GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned);
- ref byte stringData = ref utf8String.DangerousGetMutableReference(_index);
- return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle);
- }
-#endif // FEATURE_UTF8STRING
else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject))
{
// 'tmpObject is T[]' below also handles things like int[] <-> uint[] being convertible
diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs
index e26612c07ef67..105273a664921 100644
--- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs
@@ -101,9 +101,6 @@ internal ReadOnlyMemory(object? obj, int start, int length)
// 'obj is T[]' below also handles things like int[] <-> uint[] being convertible
Debug.Assert((obj == null)
|| (typeof(T) == typeof(char) && obj is string)
-#if FEATURE_UTF8STRING
- || ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && obj is Utf8String)
-#endif // FEATURE_UTF8STRING
|| (obj is T[])
|| (obj is MemoryManager));
@@ -147,14 +144,6 @@ public override string ToString()
{
return (_object is string str) ? str.Substring(_index, _length) : Span.ToString();
}
-#if FEATURE_UTF8STRING
- else if (typeof(T) == typeof(Char8))
- {
- // TODO_UTF8STRING: Call into optimized transcoding routine when it's available.
- ReadOnlySpan span = Span;
- return Encoding.UTF8.GetString(new ReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length));
- }
-#endif // FEATURE_UTF8STRING
return string.Format("System.ReadOnlyMemory<{0}>[{1}]", typeof(T).Name, _length);
}
@@ -224,13 +213,6 @@ public unsafe ReadOnlySpan Span
refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).GetRawStringData());
lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length;
}
-#if FEATURE_UTF8STRING
- else if ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && tmpObject.GetType() == typeof(Utf8String))
- {
- refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).DangerousGetMutableReference());
- lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length;
- }
-#endif // FEATURE_UTF8STRING
else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject))
{
// We know the object is not null, it's not a string, and it is variable-length. The only
@@ -338,14 +320,6 @@ public unsafe MemoryHandle Pin()
ref char stringData = ref Unsafe.Add(ref s.GetRawStringData(), _index);
return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle);
}
-#if FEATURE_UTF8STRING
- else if ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && tmpObject is Utf8String utf8String)
- {
- GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned);
- ref byte stringData = ref utf8String.DangerousGetMutableReference(_index);
- return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle);
- }
-#endif // FEATURE_UTF8STRING
else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject))
{
// 'tmpObject is T[]' below also handles things like int[] <-> uint[] being convertible
diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs
index 465fc78674df5..38fea0090ca9a 100644
--- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs
@@ -319,13 +319,6 @@ public override string ToString()
{
return new string(new ReadOnlySpan(ref Unsafe.As(ref _pointer.Value), _length));
}
-#if FEATURE_UTF8STRING
- else if (typeof(T) == typeof(Char8))
- {
- // TODO_UTF8STRING: Call into optimized transcoding routine when it's available.
- return Encoding.UTF8.GetString(new ReadOnlySpan(ref Unsafe.As(ref _pointer.Value), _length));
- }
-#endif // FEATURE_UTF8STRING
return string.Format("System.ReadOnlySpan<{0}>[{1}]", typeof(T).Name, _length);
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs
index 83e0d7db3b33b..3a76f44da15fb 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs
@@ -245,9 +245,6 @@ public static bool TryGetArray(ReadOnlyMemory memory, out ArraySegment
if (obj != null && !(
(typeof(T) == typeof(char) && obj.GetType() == typeof(string))
-#if FEATURE_UTF8STRING
- || ((typeof(T) == typeof(byte) || typeof(T) == typeof(Char8)) && obj.GetType() == typeof(Utf8String))
-#endif // FEATURE_UTF8STRING
))
{
if (RuntimeHelpers.ObjectHasComponentSize(obj))
diff --git a/src/libraries/System.Private.CoreLib/src/System/Span.cs b/src/libraries/System.Private.CoreLib/src/System/Span.cs
index 735380233d9a3..e82ca80a44a54 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Span.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Span.cs
@@ -399,13 +399,6 @@ public override string ToString()
{
return new string(new ReadOnlySpan(ref Unsafe.As(ref _pointer.Value), _length));
}
-#if FEATURE_UTF8STRING
- else if (typeof(T) == typeof(Char8))
- {
- // TODO_UTF8STRING: Call into optimized transcoding routine when it's available.
- return Encoding.UTF8.GetString(new ReadOnlySpan(ref Unsafe.As(ref _pointer.Value), _length));
- }
-#endif // FEATURE_UTF8STRING
return string.Format("System.Span<{0}>[{1}]", typeof(T).Name, _length);
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.cs
index 2ecb58c3782b2..91db035d8ef53 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.cs
@@ -49,102 +49,5 @@ public static unsafe int GetIndexOfFirstInvalidUtf8Sequence(ReadOnlySpan u
}
}
-#if FEATURE_UTF8STRING
- ///
- /// Returns a value stating whether contains only well-formed UTF-8 data.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe bool IsWellFormedUtf8(ReadOnlySpan utf8Data)
- {
- fixed (byte* pUtf8Data = &MemoryMarshal.GetReference(utf8Data))
- {
- // The return value here will point to the end of the span if the data is well-formed.
- byte* pFirstInvalidByte = GetPointerToFirstInvalidByte(pUtf8Data, utf8Data.Length, out int _, out _);
- return (pFirstInvalidByte == (pUtf8Data + (uint)utf8Data.Length));
- }
- }
-
- ///
- /// Returns if it is null or contains only well-formed UTF-8 data;
- /// otherwises allocates a new instance containing the same data as
- /// but where all invalid UTF-8 sequences have been replaced
- /// with U+FFFD.
- ///
- public static Utf8String ValidateAndFixupUtf8String(Utf8String value)
- {
- if (value.Length == 0)
- {
- return value;
- }
-
- ReadOnlySpan valueAsBytes = value.AsBytes();
-
- int idxOfFirstInvalidData = GetIndexOfFirstInvalidUtf8Sequence(valueAsBytes, out _);
- if (idxOfFirstInvalidData < 0)
- {
- return value;
- }
-
- // TODO_UTF8STRING: Replace this with the faster implementation once it's available.
- // (The faster implementation is in the dev/utf8string_bak branch currently.)
-
- MemoryStream memStream = new MemoryStream();
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- memStream.Write(valueAsBytes.Slice(0, idxOfFirstInvalidData));
-
- valueAsBytes = valueAsBytes.Slice(idxOfFirstInvalidData);
- do
- {
- if (Rune.DecodeFromUtf8(valueAsBytes, out _, out int bytesConsumed) == OperationStatus.Done)
- {
- // Valid scalar value - copy data as-is to MemoryStream
- memStream.Write(valueAsBytes.Slice(0, bytesConsumed));
- }
- else
- {
- // Invalid scalar value - copy U+FFFD to MemoryStream
- memStream.Write(ReplacementCharSequence);
- }
-
- valueAsBytes = valueAsBytes.Slice(bytesConsumed);
- } while (!valueAsBytes.IsEmpty);
-#else
- if (!MemoryMarshal.TryGetArray(value.AsMemoryBytes(), out ArraySegment valueArraySegment))
- {
- Debug.Fail("Utf8String on netstandard should always be backed by an array.");
- }
-
- memStream.Write(valueArraySegment.Array, valueArraySegment.Offset, idxOfFirstInvalidData);
-
- valueArraySegment = new ArraySegment(
- valueArraySegment.Array,
- idxOfFirstInvalidData,
- valueArraySegment.Count - idxOfFirstInvalidData);
- do
- {
- if (Rune.DecodeFromUtf8(valueArraySegment, out _, out int bytesConsumed) == OperationStatus.Done)
- {
- // Valid scalar value - copy data as-is to MemoryStream
- memStream.Write(valueArraySegment.Array, valueArraySegment.Offset, bytesConsumed);
- }
- else
- {
- // Invalid scalar value - copy U+FFFD to MemoryStream
- memStream.Write(ReplacementCharSequence, 0, ReplacementCharSequence.Length);
- }
-
- valueArraySegment = new ArraySegment(
- valueArraySegment.Array,
- valueArraySegment.Offset + bytesConsumed,
- valueArraySegment.Count - bytesConsumed);
- } while (valueArraySegment.Count > 0);
-#endif
-
- bool success = memStream.TryGetBuffer(out ArraySegment memStreamBuffer);
- Debug.Assert(success, "Couldn't get underlying MemoryStream buffer.");
-
- return Utf8String.UnsafeCreateWithoutValidation(memStreamBuffer);
- }
-#endif // FEATURE_UTF8STRING
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Comparison.cs
deleted file mode 100644
index ed42f474ee8a4..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Comparison.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Text.Unicode;
-
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- public static bool operator ==(Utf8Span left, Utf8Span right) => Equals(left, right);
- public static bool operator !=(Utf8Span left, Utf8Span right) => !Equals(left, right);
-
- public int CompareTo(Utf8Span other)
- {
- // TODO_UTF8STRING: This is ordinal, but String.CompareTo uses CurrentCulture.
- // Is this acceptable?
-
- return Utf8StringComparer.Ordinal.Compare(this, other);
- }
-
- public int CompareTo(Utf8Span other, StringComparison comparison)
- {
- // TODO_UTF8STRING: We can avoid the virtual dispatch by moving the switch into this method.
-
- return Utf8StringComparer.FromComparison(comparison).Compare(this, other);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// . An ordinal comparison is used.
- ///
- public bool Contains(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && Contains(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// . The specified comparison is used.
- ///
- public bool Contains(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && Contains(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// the specified . An ordinal comparison is used.
- ///
- public bool Contains(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
- return (this.Bytes.IndexOf(runeBytes.Slice(0, runeBytesWritten)) >= 0);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// the specified . The specified comparison is used.
- ///
- public bool Contains(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return this.ToString().Contains(value.ToString(), comparison);
-#else
- return this.ToString().IndexOf(value.ToString(), comparison) >= 0;
-#endif
- }
-
- ///
- /// Returns a value stating whether the current instance contains .
- /// An ordinal comparison is used.
- ///
- public bool Contains(Utf8Span value)
- {
- return (this.Bytes.IndexOf(value.Bytes) >= 0);
- }
-
- ///
- /// Returns a value stating whether the current instance contains .
- /// The specified comparison is used.
- ///
- public bool Contains(Utf8Span value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return this.ToString().Contains(value.ToString(), comparison);
-#else
- return this.ToString().IndexOf(value.ToString(), comparison) >= 0;
-#endif
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// . An ordinal comparison is used.
- ///
- public bool EndsWith(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && EndsWith(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// . The specified comparison is used.
- ///
- public bool EndsWith(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && EndsWith(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// the specified . An ordinal comparison is used.
- ///
- public bool EndsWith(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
- return this.Bytes.EndsWith(runeBytes.Slice(0, runeBytesWritten));
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// the specified . The specified comparison is used.
- ///
- public bool EndsWith(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return this.ToString().EndsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with .
- /// An ordinal comparison is used.
- ///
- public bool EndsWith(Utf8Span value)
- {
- return this.Bytes.EndsWith(value.Bytes);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with .
- /// The specified comparison is used.
- ///
- public bool EndsWith(Utf8Span value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return this.ToString().EndsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// . An ordinal comparison is used.
- ///
- public bool StartsWith(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && StartsWith(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// . The specified comparison is used.
- ///
- public bool StartsWith(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && StartsWith(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// the specified . An ordinal comparison is used.
- ///
- public bool StartsWith(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
- return this.Bytes.StartsWith(runeBytes.Slice(0, runeBytesWritten));
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// the specified . The specified comparison is used.
- ///
- public bool StartsWith(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return this.ToString().StartsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with .
- /// An ordinal comparison is used.
- ///
- public bool StartsWith(Utf8Span value)
- {
- return this.Bytes.StartsWith(value.Bytes);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with .
- /// The specified comparison is used.
- ///
- public bool StartsWith(Utf8Span value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return this.ToString().StartsWith(value.ToString(), comparison);
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Conversion.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Conversion.cs
deleted file mode 100644
index 23535043af544..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Conversion.cs
+++ /dev/null
@@ -1,325 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Text.Unicode;
-
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- ///
- /// Returns a new instance which represents this instance
- /// normalized using the specified Unicode normalization form.
- ///
- ///
- /// The original is left unchanged by this operation.
- ///
- public Utf8String Normalize(NormalizationForm normalizationForm = NormalizationForm.FormC)
- {
- // TODO_UTF8STRING: Reduce allocations in this code path.
-
- return new Utf8String(this.ToString().Normalize(normalizationForm));
- }
-
- ///
- /// Converts this to the desired Unicode normalization form, writing the
- /// UTF-8 result to the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the normalization operation.
- ///
- ///
- /// The original is left unchanged by this operation. Note that the the required
- /// length of may be longer or shorter (in terms of UTF-8 byte count)
- /// than the input .
- ///
- public int Normalize(Span destination, NormalizationForm normalizationForm = NormalizationForm.FormC)
- {
- // TODO_UTF8STRING: Reduce allocations in this code path.
-
- ReadOnlySpan normalized = this.ToString().Normalize(normalizationForm).AsSpan();
- OperationStatus status = Utf8.FromUtf16(normalized, destination, out int _, out int bytesWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "Normalize shouldn't have produced malformed Unicode string.");
-
- if (status != OperationStatus.Done)
- {
- bytesWritten = -1; // "destination too small"
- }
-
- return bytesWritten;
- }
-
- ///
- /// Returns the entire as an array of UTF-8 bytes.
- ///
- public byte[] ToByteArray() => Bytes.ToArray();
-
- ///
- /// Converts this to a .
- ///
- public unsafe char[] ToCharArray()
- {
- if (IsEmpty)
- {
- return Array.Empty();
- }
-
- // TODO_UTF8STRING: Since we know the underlying data is immutable, well-formed UTF-8,
- // we can perform transcoding using an optimized code path that skips all safety checks.
- // We should also consider skipping the two-pass if possible.
-
- fixed (byte* pbUtf8 = &DangerousGetMutableReference())
- {
- byte* pbUtf8Invalid = Utf8Utility.GetPointerToFirstInvalidByte(pbUtf8, this.Length, out int utf16CodeUnitCountAdjustment, out _);
- Debug.Assert(pbUtf8Invalid == pbUtf8 + this.Length, "Invalid UTF-8 data seen in buffer.");
-
- char[] asUtf16 = new char[this.Length + utf16CodeUnitCountAdjustment];
- fixed (char* pbUtf16 = asUtf16)
- {
- OperationStatus status = Utf8Utility.TranscodeToUtf16(pbUtf8, this.Length, pbUtf16, asUtf16.Length, out byte* pbUtf8End, out char* pchUtf16End);
- Debug.Assert(status == OperationStatus.Done, "The buffer changed out from under us unexpectedly?");
- Debug.Assert(pbUtf8End == pbUtf8 + this.Length, "The buffer changed out from under us unexpectedly?");
- Debug.Assert(pchUtf16End == pbUtf16 + asUtf16.Length, "The buffer changed out from under us unexpectedly?");
-
- return asUtf16;
- }
- }
- }
-
- ///
- /// Converts this instance to its UTF-16 equivalent, writing the result into
- /// the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the transcoding operation.
- ///
- public int ToChars(Span destination)
- {
- OperationStatus status = Utf8.ToUtf16(Bytes, destination, out int _, out int charsWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "Utf8Spans shouldn't contain ill-formed UTF-8 data.");
-
- if (status != OperationStatus.Done)
- {
- charsWritten = -1; // "destination too small"
- }
-
- return charsWritten;
- }
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to lowercase using .
- ///
- ///
- /// The original is left unchanged by this operation. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToLower(CultureInfo culture)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- if (culture is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.culture);
- }
-
- return new Utf8String(this.ToString().ToLower(culture));
- }
-
- ///
- /// Converts this to lowercase using , writing the
- /// UTF-8 result to the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the case conversion operation.
- ///
- ///
- /// The original is left unchanged by this operation. Note that the the required
- /// length of may be longer or shorter (in terms of UTF-8 byte count)
- /// than the input .
- ///
- public int ToLower(Span destination, CultureInfo culture)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- if (culture is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.culture);
- }
-
- ReadOnlySpan asLower = this.ToString().ToLower(culture).AsSpan();
- OperationStatus status = Utf8.FromUtf16(asLower, destination, out int _, out int bytesWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "ToLower shouldn't have produced malformed Unicode string.");
-
- if (status != OperationStatus.Done)
- {
- bytesWritten = -1; // "destination too small"
- }
-
- return bytesWritten;
- }
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to lowercase using the invariant culture.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToLowerInvariant()
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- return new Utf8String(this.ToString().ToLowerInvariant());
- }
-
- ///
- /// Converts this to lowercase using the invariant culture, writing the
- /// UTF-8 result to the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the case conversion operation.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the the required
- /// length of may be longer or shorter (in terms of UTF-8 byte count)
- /// than the input .
- ///
- public int ToLowerInvariant(Span destination)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- ReadOnlySpan asLowerInvariant = this.ToString().ToLowerInvariant().AsSpan();
- OperationStatus status = Utf8.FromUtf16(asLowerInvariant, destination, out int _, out int bytesWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "ToLowerInvariant shouldn't have produced malformed Unicode string.");
-
- if (status != OperationStatus.Done)
- {
- bytesWritten = -1; // "destination too small"
- }
-
- return bytesWritten;
- }
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to uppercase using .
- ///
- ///
- /// The original is left unchanged by this operation. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToUpper(CultureInfo culture)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- if (culture is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.culture);
- }
-
- return new Utf8String(this.ToString().ToUpper(culture));
- }
-
- ///
- /// Converts this to uppercase using , writing the
- /// UTF-8 result to the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the case conversion operation.
- ///
- ///
- /// The original is left unchanged by this operation. Note that the the required
- /// length of may be longer or shorter (in terms of UTF-8 byte count)
- /// than the input .
- ///
- public int ToUpper(Span destination, CultureInfo culture)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- if (culture is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.culture);
- }
-
- ReadOnlySpan asUpper = this.ToString().ToUpper(culture).AsSpan();
- OperationStatus status = Utf8.FromUtf16(asUpper, destination, out int _, out int bytesWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "ToUpper shouldn't have produced malformed Unicode string.");
-
- if (status != OperationStatus.Done)
- {
- bytesWritten = -1; // "destination too small"
- }
-
- return bytesWritten;
- }
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to uppercase using the invariant culture.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToUpperInvariant()
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- return new Utf8String(this.ToString().ToUpperInvariant());
- }
-
- ///
- /// Converts this to uppercase using the invariant culture, writing the
- /// UTF-8 result to the buffer .
- ///
- ///
- /// The number of bytes written to , or -1 if
- /// is not large enough to hold the result of the case conversion operation.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the the required
- /// length of may be longer or shorter (in terms of UTF-8 byte count)
- /// than the input .
- ///
- public int ToUpperInvariant(Span destination)
- {
- // TODO_UTF8STRING: Avoid intermediate allocations.
-
- ReadOnlySpan asUpperInvariant = this.ToString().ToUpperInvariant().AsSpan();
- OperationStatus status = Utf8.FromUtf16(asUpperInvariant, destination, out int _, out int bytesWritten, replaceInvalidSequences: false, isFinalBlock: true);
-
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.DestinationTooSmall, "ToUpperInvariant shouldn't have produced malformed Unicode string.");
-
- if (status != OperationStatus.Done)
- {
- bytesWritten = -1; // "destination too small"
- }
-
- return bytesWritten;
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Enumeration.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Enumeration.cs
deleted file mode 100644
index 422a12ed109f7..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Enumeration.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- public CharEnumerable Chars => new CharEnumerable(this);
- public RuneEnumerable Runes => new RuneEnumerable(this);
-
- public readonly ref struct CharEnumerable
- {
- private readonly Utf8Span _span;
-
- internal CharEnumerable(Utf8Span span)
- {
- _span = span;
- }
-
- public Enumerator GetEnumerator() => new Enumerator(_span);
-
- public ref struct Enumerator
- {
- private uint _currentCharPair;
- private ReadOnlySpan _remainingUtf8Bytes;
-
- internal Enumerator(Utf8Span span)
- {
- _currentCharPair = default;
- _remainingUtf8Bytes = span.Bytes;
- }
-
- public char Current => (char)_currentCharPair;
-
- public bool MoveNext()
- {
- // We don't need to worry about tearing since this enumerator is a ref struct.
-
- if (_currentCharPair > char.MaxValue)
- {
- // There was a surrogate pair smuggled in here from a previous operation.
- // Shift out the high surrogate value and return immediately.
-
- _currentCharPair >>= 16;
- return true;
- }
-
- if (_remainingUtf8Bytes.IsEmpty)
- {
- return false;
- }
-
- // TODO_UTF8STRING: Since we assume Utf8String instances are well-formed, we may instead
- // call an optimized version of the "decode" routine below which skips well-formedness checks.
-
- OperationStatus status = Rune.DecodeFromUtf8(_remainingUtf8Bytes, out Rune currentRune, out int bytesConsumed);
- Debug.Assert(status == OperationStatus.Done, "Somebody fed us invalid data?");
-
- if (currentRune.IsBmp)
- {
- // Common case - BMP scalar value.
-
- _currentCharPair = (uint)currentRune.Value;
- }
- else
- {
- // Uncommon case - supplementary plane (astral) scalar value.
- // We'll smuggle the two UTF-16 code units into a single 32-bit value,
- // with the leading surrogate packed into the low 16 bits of the value,
- // and the trailing surrogate packed into the high 16 bits of the value.
-
- UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)currentRune.Value, out char leadingCodeUnit, out char trailingCodeUnit);
- _currentCharPair = (uint)leadingCodeUnit + ((uint)trailingCodeUnit << 16);
- }
-
- // TODO_UTF8STRING: We can consider unsafe slicing below if we wish since we know we're
- // not going to overrun the end of the span.
-
- _remainingUtf8Bytes = _remainingUtf8Bytes.Slice(bytesConsumed);
- return true;
- }
- }
- }
-
- public readonly ref struct RuneEnumerable
- {
- private readonly Utf8Span _span;
-
- internal RuneEnumerable(Utf8Span span)
- {
- _span = span;
- }
-
- public Enumerator GetEnumerator() => new Enumerator(_span);
-
- public ref struct Enumerator
- {
- private Rune _currentRune;
- private ReadOnlySpan _remainingUtf8Bytes;
-
- internal Enumerator(Utf8Span span)
- {
- _currentRune = default;
- _remainingUtf8Bytes = span.Bytes;
- }
-
- public Rune Current => _currentRune;
-
- public bool MoveNext()
- {
- // We don't need to worry about tearing since this enumerator is a ref struct.
-
- if (_remainingUtf8Bytes.IsEmpty)
- {
- return false;
- }
-
- // TODO_UTF8STRING: Since we assume Utf8Span instances are well-formed, we may instead
- // call an optimized version of the "decode" routine below which skips well-formedness checks.
-
- OperationStatus status = Rune.DecodeFromUtf8(_remainingUtf8Bytes, out _currentRune, out int bytesConsumed);
- Debug.Assert(status == OperationStatus.Done, "Somebody fed us invalid data?");
-
- // TODO_UTF8STRING: We can consider unsafe slicing below if we wish since we know we're
- // not going to overrun the end of the span.
-
- _remainingUtf8Bytes = _remainingUtf8Bytes.Slice(bytesConsumed);
- return true;
- }
- }
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Manipulation.cs
deleted file mode 100644
index a0b874af5ea66..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Manipulation.cs
+++ /dev/null
@@ -1,521 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text.Unicode;
-
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- public SplitResult Split(char separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- if (!Rune.TryCreate(separator, out Rune rune))
- {
- throw new ArgumentOutOfRangeException(
- paramName: nameof(separator),
- message: SR.ArgumentOutOfRange_Utf16SurrogatesDisallowed);
- }
-
- Utf8String.CheckSplitOptions(options);
-
- return new SplitResult(this, rune, options);
- }
-
- public SplitResult Split(Rune separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- Utf8String.CheckSplitOptions(options);
-
- return new SplitResult(this, separator, options);
- }
-
- public SplitResult Split(Utf8Span separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- if (separator.IsEmpty)
- {
- throw new ArgumentException(
- paramName: nameof(separator),
- message: SR.Argument_CannotBeEmptySpan);
- }
-
- Utf8String.CheckSplitOptions(options);
-
- return new SplitResult(this, separator, options);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(char separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(char separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(Rune separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(Rune separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(Utf8Span separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(Utf8Span separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(char separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(char separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(Rune separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(Rune separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(Utf8Span separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, Empty)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(Utf8Span separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Trims whitespace from the beginning and the end of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8Span Trim() => TrimHelper(TrimType.Both);
-
- ///
- /// Trims whitespace from only the end of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8Span TrimEnd() => TrimHelper(TrimType.Tail);
-
- internal Utf8Span TrimHelper(TrimType trimType)
- {
- ReadOnlySpan retSpan = Bytes;
-
- if ((trimType & TrimType.Head) != 0)
- {
- int indexOfFirstNonWhiteSpaceChar = Utf8Utility.GetIndexOfFirstNonWhiteSpaceChar(retSpan);
- Debug.Assert((uint)indexOfFirstNonWhiteSpaceChar <= (uint)retSpan.Length);
-
- // TODO_UTF8STRING: Can use an unsafe slicing routine below if we need a perf boost.
-
- retSpan = retSpan.Slice(indexOfFirstNonWhiteSpaceChar);
- }
-
- if ((trimType & TrimType.Tail) != 0)
- {
- int indexOfTrailingWhiteSpaceSequence = Utf8Utility.GetIndexOfTrailingWhiteSpaceSequence(retSpan);
- Debug.Assert((uint)indexOfTrailingWhiteSpaceSequence <= (uint)retSpan.Length);
-
- // TODO_UTF8STRING: Can use an unsafe slicing routine below if we need a perf boost.
-
- retSpan = retSpan.Slice(0, indexOfTrailingWhiteSpaceSequence);
- }
-
- return UnsafeCreateWithoutValidation(retSpan);
- }
-
- ///
- /// Trims whitespace from only the beginning of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8Span TrimStart() => TrimHelper(TrimType.Head);
-
- [StructLayout(LayoutKind.Auto)]
- public readonly ref struct SplitResult
- {
- private readonly State _state;
-
- internal SplitResult(Utf8Span source, Rune searchRune, Utf8StringSplitOptions splitOptions)
- {
- _state = new State
- {
- RemainingSearchSpace = source,
- SearchRune = searchRune.Value,
- SearchTerm = default,
- SplitOptions = splitOptions
- };
- }
-
- internal SplitResult(Utf8Span source, Utf8Span searchTerm, Utf8StringSplitOptions splitOptions)
- {
- _state = new State
- {
- RemainingSearchSpace = source,
- SearchRune = -1,
- SearchTerm = searchTerm,
- SplitOptions = splitOptions
- };
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out item2);
- TrimIfNeeded(ref item2);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out item3);
- TrimIfNeeded(ref item3);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3, out Utf8Span item4)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out remainder);
- _state.DeconstructHelper(in remainder, out item3, out item4);
- TrimIfNeeded(ref item4);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3, out Utf8Span item4, out Utf8Span item5)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out remainder);
- _state.DeconstructHelper(in remainder, out item3, out remainder);
- _state.DeconstructHelper(in remainder, out item4, out item5);
- TrimIfNeeded(ref item5);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3, out Utf8Span item4, out Utf8Span item5, out Utf8Span item6)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out remainder);
- _state.DeconstructHelper(in remainder, out item3, out remainder);
- _state.DeconstructHelper(in remainder, out item4, out remainder);
- _state.DeconstructHelper(in remainder, out item5, out item6);
- TrimIfNeeded(ref item6);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3, out Utf8Span item4, out Utf8Span item5, out Utf8Span item6, out Utf8Span item7)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out remainder);
- _state.DeconstructHelper(in remainder, out item3, out remainder);
- _state.DeconstructHelper(in remainder, out item4, out remainder);
- _state.DeconstructHelper(in remainder, out item5, out remainder);
- _state.DeconstructHelper(in remainder, out item6, out item7);
- TrimIfNeeded(ref item7);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span item1, out Utf8Span item2, out Utf8Span item3, out Utf8Span item4, out Utf8Span item5, out Utf8Span item6, out Utf8Span item7, out Utf8Span item8)
- {
- _state.DeconstructHelper(in _state.RemainingSearchSpace, out item1, out Utf8Span remainder);
- _state.DeconstructHelper(in remainder, out item2, out remainder);
- _state.DeconstructHelper(in remainder, out item3, out remainder);
- _state.DeconstructHelper(in remainder, out item4, out remainder);
- _state.DeconstructHelper(in remainder, out item5, out remainder);
- _state.DeconstructHelper(in remainder, out item6, out remainder);
- _state.DeconstructHelper(in remainder, out item7, out item8);
- TrimIfNeeded(ref item8);
- }
-
- public Enumerator GetEnumerator() => new Enumerator(this);
-
- private void TrimIfNeeded(ref Utf8Span span)
- {
- if ((_state.SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- span = span.Trim();
- }
- }
-
- [StructLayout(LayoutKind.Auto)]
- public ref struct Enumerator
- {
- private const Utf8StringSplitOptions HALT_ENUMERATION = (Utf8StringSplitOptions)int.MinValue;
-
- private Utf8Span _current;
- private State _state;
-
- internal Enumerator(SplitResult result)
- {
- _current = default;
- _state = result._state; // copy by value
- }
-
- public Utf8Span Current => _current;
-
- public bool MoveNext()
- {
- // Happy path: if the search term was found, then the two 'out' fields below are overwritten with
- // the contents of the (before, after) tuple, and we can return right away.
-
- if (_state.DeconstructHelper(in _state.RemainingSearchSpace, out _current, out _state.RemainingSearchSpace))
- {
- return true;
- }
-
- // At this point, the search term was not found within the search space. '_current' contains the last
- // bit of data after the final occurrence of the search term. We'll also set a flag saying that we've
- // completed enumeration.
-
- if (_current.IsEmpty && (_state.SplitOptions & Utf8StringSplitOptions.RemoveEmptyEntries) != 0)
- {
- return false;
- }
-
- if ((_state.SplitOptions & HALT_ENUMERATION) != 0)
- {
- return false;
- }
-
- _state.SplitOptions |= HALT_ENUMERATION; // prevents yielding forever at end of split
-
- return true;
- }
- }
-
- [StructLayout(LayoutKind.Auto)]
- private ref struct State // fully mutable
- {
- internal Utf8Span RemainingSearchSpace;
- internal int SearchRune; // -1 if not specified, takes less space than "Rune?"
- internal Utf8Span SearchTerm;
- internal Utf8StringSplitOptions SplitOptions;
-
- // Returns 'true' if a match was found, 'false' otherwise.
- internal readonly bool DeconstructHelper(in Utf8Span source, out Utf8Span firstItem, out Utf8Span remainder)
- {
- // n.b. Our callers might pass the same reference for 'source' and 'remainder'.
- // We need to take care not to read 'source' after writing 'remainder'.
-
- bool wasMatchFound;
- ref readonly Utf8Span searchSpan = ref source;
-
- while (true)
- {
- if (searchSpan.IsEmpty)
- {
- firstItem = searchSpan;
- remainder = default;
- wasMatchFound = false;
- break;
- }
-
- Range matchRange;
-
- if (SearchRune >= 0)
- {
-#if NETCOREAPP3_0
- wasMatchFound = searchSpan.TryFind(new Rune((uint)SearchRune), out matchRange);
-#else
- wasMatchFound = searchSpan.TryFind(Rune.UnsafeCreate((uint)SearchRune), out matchRange);
-#endif
- }
- else
- {
- wasMatchFound = searchSpan.TryFind(SearchTerm, out matchRange);
- }
-
- if (!wasMatchFound)
- {
- // If no match was found, we move 'source' to 'firstItem', trim if necessary, and return right away.
-
- firstItem = searchSpan;
-
- if ((SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- firstItem = firstItem.Trim();
- }
-
- remainder = default;
- }
- else
- {
- // Otherwise, if a match was found, split the result across 'firstItem' and 'remainder',
- // applying trimming if necessary.
-
- firstItem = searchSpan[..matchRange.Start]; // TODO_UTF8STRING: Could use unsafe slicing as optimization
- remainder = searchSpan[matchRange.End..]; // TODO_UTF8STRING: Could use unsafe slicing as optimization
-
- if ((SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- firstItem = firstItem.Trim();
- }
-
- // If we're asked to remove empty entries, loop until there's a real value in 'firstItem'.
-
- if ((SplitOptions & Utf8StringSplitOptions.RemoveEmptyEntries) != 0 && firstItem.IsEmpty)
- {
- searchSpan = ref remainder;
- continue;
- }
- }
-
- break; // loop only if explicit 'continue' statement was hit
- }
-
- return wasMatchFound;
- }
- }
- }
-
- [StructLayout(LayoutKind.Auto)]
- public readonly ref struct SplitOnResult
- {
- // Used when there is no match.
- internal SplitOnResult(Utf8Span originalSearchSpace)
- {
- Before = originalSearchSpace;
- After = Empty;
- }
-
- // Used when a match is found.
- internal SplitOnResult(Utf8Span originalSearchSpace, Range searchTermMatchRange)
- {
- (int startIndex, int length) = searchTermMatchRange.GetOffsetAndLength(originalSearchSpace.Length);
-
- // TODO_UTF8STRING: The below indexer performs correctness checks. We can skip these checks (and even the
- // bounds checks more generally) since we know the inputs are all valid and the containing struct is not
- // subject to tearing.
-
- Before = originalSearchSpace[..startIndex];
- After = originalSearchSpace[(startIndex + length)..];
- }
-
- public Utf8Span After { get; }
- public Utf8Span Before { get; }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8Span before, out Utf8Span after)
- {
- before = Before;
- after = After;
- }
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs
deleted file mode 100644
index a004812e61a5a..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.Searching.cs
+++ /dev/null
@@ -1,577 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Globalization;
-using System.Text.Unicode;
-
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(char value, out Range range)
- {
- if (Rune.TryCreate(value, out Rune rune))
- {
- return TryFind(rune, out range);
- }
- else
- {
- // Surrogate chars can't exist in well-formed UTF-8 data - bail immediately.
-
- range = default;
- return false;
- }
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(char value, StringComparison comparisonType, out Range range)
- {
- if (Rune.TryCreate(value, out Rune rune))
- {
- return TryFind(rune, comparisonType, out range);
- }
- else
- {
- CheckStringComparison(comparisonType);
-
- // Surrogate chars can't exist in well-formed UTF-8 data - bail immediately.
-
- range = default;
- return false;
- }
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(Rune value, out Range range)
- {
- if (value.IsAscii)
- {
- // Special-case ASCII since it's a simple single byte search.
-
- int idx = Bytes.IndexOf((byte)value.Value);
- if (idx < 0)
- {
- range = default;
- return false;
- }
- else
- {
- range = idx..(idx + 1);
- return true;
- }
- }
- else
- {
- // Slower path: need to search a multi-byte sequence.
- // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
- // know Rune instances are well-formed and slicing is safe.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);
-
- return TryFind(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), out range);
- }
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(Rune value, StringComparison comparisonType, out Range range)
- {
- if (comparisonType == StringComparison.Ordinal)
- {
- return TryFind(value, out range);
- }
- else
- {
- // Slower path: not an ordinal comparison.
- // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
- // know Rune instances are well-formed and slicing is safe.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);
-
- return TryFind(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), comparisonType, out range);
- }
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(Utf8Span value, out Range range)
- {
- int idx;
-
- if (value.Bytes.Length == 1)
- {
- // Special-case ASCII since it's a simple single byte search.
-
- idx = this.Bytes.IndexOf(value.Bytes[0]);
- }
- else
- {
- // Slower path: need to search a multi-byte sequence.
-
- idx = this.Bytes.IndexOf(value.Bytes);
- }
-
- if (idx < 0)
- {
- range = default;
- return false;
- }
- else
- {
- range = idx..(idx + value.Bytes.Length);
- return true;
- }
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(Utf8Span value, StringComparison comparisonType, out Range range) => TryFind(value, comparisonType, out range, fromBeginning: true);
-
- private unsafe bool TryFind(Utf8Span value, StringComparison comparisonType, out Range range, bool fromBeginning)
- {
- CheckStringComparison(comparisonType);
-
- if (value.IsEmpty)
- {
- // sourceString.IndexOf/LastIndexOf(term, comparer) should return the minimum/maximum value index
- // for which the expression "sourceString.Substring(index).StartsWith(term, comparer)" is true.
- // The range we return to the caller should reflect this so that they can pull out the correct index.
-
- if (fromBeginning)
- {
- range = Index.Start..Index.Start;
- }
- else
- {
- range = Index.End..Index.End;
- }
- return true;
- }
-
- if (this.IsEmpty)
- {
- range = default;
- return false;
- }
-
- CompareInfo compareInfo = default!; // will be overwritten if it matters
- CompareOptions compareOptions = GetCaseCompareOfComparisonCulture(comparisonType);
-
- if (GlobalizationMode.Invariant)
- {
- // In the Invariant globalization mode, all comparisons are normalized to Ordinal or OrdinalIgnoreCase,
- // and even in "ignore case" we only map [a-z] <-> [A-Z]. All other code points remain unmapped.
-
- // TODO_UTF8STRING: We should take advantage of the property described above to avoid the UTF-16
- // transcoding step entirely.
-
- if (compareOptions == CompareOptions.None)
- {
- return (fromBeginning)
- ? TryFind(value, out range)
- : TryFindLast(value, out range); // call the ordinal search routine
- }
- }
- else
- {
- switch (comparisonType)
- {
- case StringComparison.Ordinal:
- return (fromBeginning)
- ? TryFind(value, out range)
- : TryFindLast(value, out range);
-
- case StringComparison.OrdinalIgnoreCase:
- // TODO_UTF8STRING: Can probably optimize this case.
-#if SYSTEM_PRIVATE_CORELIB
- compareInfo = CompareInfo.Invariant;
-#else
- compareInfo = CultureInfo.InvariantCulture.CompareInfo;
-#endif
- break;
-
- case StringComparison.CurrentCulture:
- case StringComparison.CurrentCultureIgnoreCase:
- compareInfo = CultureInfo.CurrentCulture.CompareInfo;
- break;
-
- default:
- Debug.Assert(comparisonType == StringComparison.InvariantCulture || comparisonType == StringComparison.InvariantCultureIgnoreCase);
-#if SYSTEM_PRIVATE_CORELIB
- compareInfo = CompareInfo.Invariant;
-#else
- compareInfo = CultureInfo.InvariantCulture.CompareInfo;
-#endif
- break;
- }
- }
-
- // TODO_UTF8STRING: Remove allocations below, and try to avoid the transcoding step if possible.
-
- string thisTranscodedToUtf16 = this.ToStringNoReplacement();
- string otherTranscodedToUtf16 = value.ToStringNoReplacement();
-
- int idx, matchLength;
-
-#if SYSTEM_PRIVATE_CORELIB
- if (GlobalizationMode.Invariant)
- {
- // If we got here, it meant we're doing an OrdinalIgnoreCase comparison.
-
- Debug.Assert(compareOptions == CompareOptions.IgnoreCase);
-
- idx = CompareInfo.InvariantIndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, ignoreCase: true, fromBeginning);
- matchLength = otherTranscodedToUtf16.Length; // If there was a match, it involved only simple case folding.
- }
- else
- {
- idx = (fromBeginning)
- ? compareInfo.IndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, compareOptions, out matchLength)
- : compareInfo.LastIndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, compareOptions, out matchLength);
- }
-#else
- Debug.Assert(comparisonType == StringComparison.OrdinalIgnoreCase);
-
- if (fromBeginning)
- {
- idx = compareInfo.IndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, 0, thisTranscodedToUtf16.Length, compareOptions);
- }
- else
- {
- idx = compareInfo.LastIndexOf(thisTranscodedToUtf16, otherTranscodedToUtf16, thisTranscodedToUtf16.Length, thisTranscodedToUtf16.Length, compareOptions);
- }
- matchLength = otherTranscodedToUtf16.Length;
-#endif
-
- if (idx < 0)
- {
- // No match found. Bail out now.
-
- range = default;
- return false;
- }
-
- // If we reached this point, we found a match. The 'idx' local is the index in the source
- // string (indexed by UTF-16 code units) where the match was found, and the 'matchLength'
- // local is the number of chars in the source string which constitute the match. This length
- // can be different than the length of the search string, as non-ordinal IndexOf operations
- // follow Unicode full case folding semantics and might also normalize characters like
- // digraphs.
-
-#if SYSTEM_PRIVATE_CORELIB
- fixed (char* pThisTranscodedToUtf16 = &thisTranscodedToUtf16.GetRawStringData())
-#else
- fixed (char* pThisTranscodedToUtf16 = thisTranscodedToUtf16)
-#endif
- {
- // First, we need to convert the UTF-16 'idx' to its UTF-8 equivalent.
-
- char* pStoppedCounting = Utf16Utility.GetPointerToFirstInvalidChar(pThisTranscodedToUtf16, idx, out long utf8CodeUnitCountAdjustment, out _);
- Debug.Assert(pStoppedCounting == pThisTranscodedToUtf16 + idx, "We shouldn't have generated an ill-formed UTF-16 temp string.");
- Debug.Assert((ulong)(idx + utf8CodeUnitCountAdjustment) <= (uint)this.Bytes.Length, "Start index should be within the source UTF-8 data.");
-
- // Normally when we produce a UTF-8 code unit count from a UTF-16 source we
- // need to perform 64-bit arithmetic so we don't overflow. But in this case
- // we know the true original source was UTF-8, so its length is known already
- // to fit into a signed 32-bit integer. So we'll perform an unchecked cast.
-
- int utf8StartIdx = idx + (int)utf8CodeUnitCountAdjustment;
-
- // Now we need to convert the UTF-16 'matchLength' to its UTF-8 equivalent.
-
- pStoppedCounting = Utf16Utility.GetPointerToFirstInvalidChar(pThisTranscodedToUtf16 + idx, matchLength, out utf8CodeUnitCountAdjustment, out _);
- Debug.Assert(pStoppedCounting == pThisTranscodedToUtf16 + idx + matchLength, "We shouldn't have generated an ill-formed UTF-16 temp string.");
- Debug.Assert((ulong)(utf8StartIdx + matchLength + utf8CodeUnitCountAdjustment) <= (uint)this.Bytes.Length, "End index should be within the source UTF-8 data.");
-
- int utf8EndIdx = utf8StartIdx + matchLength + (int)utf8CodeUnitCountAdjustment;
-
- // Some quick sanity checks on the return value before we return.
-
- Debug.Assert(0 <= utf8StartIdx);
- Debug.Assert(utf8StartIdx <= utf8EndIdx);
- Debug.Assert(utf8EndIdx <= this.Bytes.Length);
-
- range = utf8StartIdx..utf8EndIdx;
- return true;
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(char value, out Range range)
- {
- if (Rune.TryCreate(value, out Rune rune))
- {
- return TryFindLast(rune, out range);
- }
- else
- {
- // Surrogate chars can't exist in well-formed UTF-8 data - bail immediately.
-
- range = default;
- return false;
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(char value, StringComparison comparisonType, out Range range)
- {
- if (Rune.TryCreate(value, out Rune rune))
- {
- return TryFindLast(rune, comparisonType, out range);
- }
- else
- {
- CheckStringComparison(comparisonType);
-
- // Surrogate chars can't exist in well-formed UTF-8 data - bail immediately.
-
- range = default;
- return false;
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(Rune value, out Range range)
- {
- if (value.IsAscii)
- {
- // Special-case ASCII since it's a simple single byte search.
-
- int idx = Bytes.LastIndexOf((byte)value.Value);
- if (idx < 0)
- {
- range = default;
- return false;
- }
- else
- {
- range = idx..(idx + 1);
- return true;
- }
- }
- else
- {
- // Slower path: need to search a multi-byte sequence.
- // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
- // know Rune instances are well-formed and slicing is safe.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);
-
- return TryFindLast(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), out range);
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(Rune value, StringComparison comparisonType, out Range range)
- {
- if (comparisonType == StringComparison.Ordinal)
- {
- return TryFindLast(value, out range);
- }
- else
- {
- // Slower path: not an ordinal comparison.
- // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
- // know Rune instances are well-formed and slicing is safe.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);
-
- return TryFindLast(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), comparisonType, out range);
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(Utf8Span value, out Range range)
- {
- int idx;
-
- if (value.Bytes.Length <= 1)
- {
- if (value.Bytes.Length == 1)
- {
- idx = this.Bytes.LastIndexOf(value.Bytes[0]); // special-case ASCII since it's a single byte search
- }
- else
- {
- idx = this.Length; // the last empty substring always occurs at the end of the buffer
- }
- }
- else
- {
- // Slower path: need to search a multi-byte sequence.
-
- idx = this.Bytes.LastIndexOf(value.Bytes);
- }
-
- if (idx < 0)
- {
- range = default;
- return false;
- }
- else
- {
- range = idx..(idx + value.Bytes.Length);
- return true;
- }
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(Utf8Span value, StringComparison comparisonType, out Range range) => TryFind(value, comparisonType, out range, fromBeginning: false);
-
- private static void CheckStringComparison(StringComparison comparisonType)
- {
-#if SYSTEM_PRIVATE_CORELIB
- string.CheckStringComparison(comparisonType);
-#else
- // Single comparison to check if comparisonType is within [CurrentCulture .. OrdinalIgnoreCase]
- if ((uint)comparisonType > (uint)StringComparison.OrdinalIgnoreCase)
- {
- ThrowHelper.ThrowArgumentException(SR.NotSupported_StringComparison, ExceptionArgument.comparisonType);
- }
-
- // There's no API that would allow getting the correct match length
- // for other StringComparisons.
- if (comparisonType != StringComparison.Ordinal &&
- comparisonType != StringComparison.OrdinalIgnoreCase)
- {
- ThrowHelper.ThrowNotSupportedException(SR.Utf8Span_TryFindOnlySupportsOrdinal);
- }
-#endif
- }
-
- private static CompareOptions GetCaseCompareOfComparisonCulture(StringComparison comparisonType)
- {
-#if SYSTEM_PRIVATE_CORELIB
- return string.GetCaseCompareOfComparisonCulture(comparisonType);
-#else
- Debug.Assert((uint)comparisonType <= (uint)StringComparison.OrdinalIgnoreCase);
-
- // Culture enums can be & with CompareOptions.IgnoreCase 0x01 to extract if IgnoreCase or CompareOptions.None 0x00
- //
- // CompareOptions.None 0x00
- // CompareOptions.IgnoreCase 0x01
- //
- // StringComparison.CurrentCulture: 0x00
- // StringComparison.InvariantCulture: 0x02
- // StringComparison.Ordinal 0x04
- //
- // StringComparison.CurrentCultureIgnoreCase: 0x01
- // StringComparison.InvariantCultureIgnoreCase: 0x03
- // StringComparison.OrdinalIgnoreCase 0x05
-
- return (CompareOptions)((int)comparisonType & (int)CompareOptions.IgnoreCase);
-#endif
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs
deleted file mode 100644
index fcd6d4f92cb23..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs
+++ /dev/null
@@ -1,329 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text.Unicode;
-
-#if SYSTEM_PRIVATE_CORELIB
-using Internal.Runtime.CompilerServices;
-#endif
-
-#pragma warning disable 0809 //warning CS0809: Obsolete member 'Utf8Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)'
-
-namespace System.Text
-{
- [StructLayout(LayoutKind.Auto)]
- public readonly ref partial struct Utf8Span
- {
- ///
- /// Creates a from an existing instance.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Utf8Span(Utf8String? value)
- {
- Bytes = Utf8Extensions.AsBytes(value);
- }
-
- ///
- /// Ctor for internal use only. Caller _must_ validate both invariants hold:
- /// (a) the buffer represents well-formed UTF-8 data, and
- /// (b) the buffer is immutable.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private Utf8Span(ReadOnlySpan rawData)
- {
- // In debug builds, we want to ensure that the callers really did validate
- // the buffer for well-formedness. The entire line below is removed when
- // compiling release builds.
-
- Debug.Assert(Utf8Utility.GetIndexOfFirstInvalidUtf8Sequence(rawData, out _) == -1);
-
- Bytes = rawData;
- }
-
- public ReadOnlySpan Bytes { get; }
-
- public static Utf8Span Empty => default;
-
- public bool IsEmpty => Bytes.IsEmpty;
-
- ///
- /// Returns the length (in UTF-8 code units, or s) of this instance.
- ///
- public int Length => Bytes.Length;
-
- public Utf8Span this[Range range]
- {
- get
- {
- (int offset, int length) = range.GetOffsetAndLength(Length);
-
- // Check for a split across a multi-byte subsequence on the way out.
- // Reminder: Unlike Utf8String, we can't safely dereference past the end of the span.
-
- ref byte newRef = ref DangerousGetMutableReference(offset);
- if (length > 0 && Utf8Utility.IsUtf8ContinuationByte(newRef))
- {
- Utf8String.ThrowImproperStringSplit();
- }
-
- int endIdx = offset + length;
- if (endIdx < Length && Utf8Utility.IsUtf8ContinuationByte(DangerousGetMutableReference(endIdx)))
- {
- Utf8String.ThrowImproperStringSplit();
- }
-
-#if SYSTEM_PRIVATE_CORELIB
- return UnsafeCreateWithoutValidation(new ReadOnlySpan(ref newRef, length));
-#else
- return UnsafeCreateWithoutValidation(Bytes.Slice(offset, length));
-#endif
- }
- }
-
- ///
- /// Returns a mutable reference to the first byte of this
- /// (or, if this is empty, to where the first byte would be).
- ///
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference() => ref MemoryMarshal.GetReference(Bytes);
-
- ///
- /// Returns a mutable reference to the element at index
- /// of this instance. The index is not bounds-checked.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference(int index)
- {
- Debug.Assert(index >= 0, "Caller should've performed bounds checking.");
- return ref DangerousGetMutableReference((uint)index);
- }
-
- ///
- /// Returns a mutable reference to the element at index
- /// of this instance. The index is not bounds-checked.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference(nuint index)
- {
- // Allow retrieving references to just past the end of the span (but shouldn't dereference this).
-
- Debug.Assert(index <= (uint)Length, "Caller should've performed bounds checking.");
-#if SYSTEM_PRIVATE_CORELIB
- return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), index);
-#else
- return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (nint)index);
-#endif
- }
-
- public bool IsEmptyOrWhiteSpace() => (Utf8Utility.GetIndexOfFirstNonWhiteSpaceChar(Bytes) == Length);
-
- ///
- /// This method is not supported as spans cannot be boxed. To compare two spans, use operator==.
- ///
- /// Always thrown by this method.
- ///
- ///
- [Obsolete("Equals(object) on Utf8Span will always throw an exception. Use Equals(Utf8Span) or operator == instead.")]
- [EditorBrowsable(EditorBrowsableState.Never)]
- public override bool Equals(object? obj)
- {
- throw new NotSupportedException(SR.Utf8Span_CannotCallEqualsObject);
- }
-
- public bool Equals(Utf8Span other) => Equals(this, other);
-
- public bool Equals(Utf8Span other, StringComparison comparison) => Equals(this, other, comparison);
-
- public static bool Equals(Utf8Span left, Utf8Span right) => left.Bytes.SequenceEqual(right.Bytes);
-
- public static bool Equals(Utf8Span left, Utf8Span right, StringComparison comparison)
- {
- // TODO_UTF8STRING: This perf can be improved, including removing
- // the virtual dispatch by putting the switch directly in this method.
-
- return Utf8StringComparer.FromComparison(comparison).Equals(left, right);
- }
-
- public override int GetHashCode()
- {
- // TODO_UTF8STRING: Consider whether this should use a different seed than String.GetHashCode.
- // This method should only be called to calculate the hash code over spans that represent
- // UTF-8 textual data, not over arbitrary binary sequences.
-
- ulong seed = Marvin.DefaultSeed;
-#if SYSTEM_PRIVATE_CORELIB
- return Marvin.ComputeHash32(ref MemoryMarshal.GetReference(Bytes), (uint)Length /* in bytes */, (uint)seed, (uint)(seed >> 32));
-#else
- return Marvin.ComputeHash32(Bytes, seed);
-#endif
- }
-
- public int GetHashCode(StringComparison comparison)
- {
- // TODO_UTF8STRING: This perf can be improved, including removing
- // the virtual dispatch by putting the switch directly in this method.
-
- return Utf8StringComparer.FromComparison(comparison).GetHashCode(this);
- }
-
- ///
- /// Returns if this UTF-8 text consists of all-ASCII data,
- /// if there is any non-ASCII data within this UTF-8 text.
- ///
- ///
- /// ASCII text is defined as text consisting only of scalar values in the range [ U+0000..U+007F ].
- /// Empty spans are considered to be all-ASCII. The runtime of this method is O(n).
- ///
- public bool IsAscii()
- {
- // TODO_UTF8STRING: Use an API that takes 'ref byte' instead of a 'byte*' as a parameter.
-
- unsafe
- {
- fixed (byte* pData = &MemoryMarshal.GetReference(Bytes))
- {
- return (ASCIIUtility.GetIndexOfFirstNonAsciiByte(pData, (uint)Length) == (uint)Length);
- }
- }
- }
-
- ///
- /// Returns a value stating whether this instance is normalized
- /// using the specified Unicode normalization form.
- ///
- /// The to check.
- /// if this instance represents text
- /// normalized under , otherwise .
- public bool IsNormalized(NormalizationForm normalizationForm = NormalizationForm.FormC)
- {
- // TODO_UTF8STRING: Avoid allocations in this code path.
-
- return ToString().IsNormalized(normalizationForm);
- }
-
- ///
- /// Gets an immutable reference that can be used in a statement. Unlike
- /// , the resulting reference is not guaranteed to be null-terminated.
- ///
- ///
- /// If this instance is empty, returns . Dereferencing
- /// such a reference will result in a being generated.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ref readonly byte GetPinnableReference()
- {
- // This returns null if the underlying span is empty. The reason for this is that unlike
- // Utf8String, these buffers are not guaranteed to be null-terminated, so it's not always
- // safe or meaningful to dereference the element just past the end of the buffer.
-
- return ref Bytes.GetPinnableReference();
- }
-
- public override string ToString()
- {
- // TODO_UTF8STRING: Since we know the underlying data is immutable, well-formed UTF-8,
- // we can perform transcoding using an optimized code path that skips all safety checks.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return Encoding.UTF8.GetString(Bytes);
-#else
- if (IsEmpty)
- {
- return string.Empty;
- }
-
- unsafe
- {
- fixed (byte* pBytes = Bytes)
- {
- return Encoding.UTF8.GetString(pBytes, Length);
- }
- }
-#endif
- }
-
- ///
- /// Converts this instance to a .
- ///
- ///
- /// This routine throws if the underlying instance
- /// contains invalid UTF-8 data.
- ///
- internal unsafe string ToStringNoReplacement()
- {
- // TODO_UTF8STRING: Optimize the call below, potentially by avoiding the two-pass.
-
- fixed (byte* pData = &MemoryMarshal.GetReference(Bytes))
- {
- byte* pFirstInvalidByte = Utf8Utility.GetPointerToFirstInvalidByte(pData, Length, out int utf16CodeUnitCountAdjustment, out _);
- if (pFirstInvalidByte != pData + (uint)Length)
- {
- // Saw bad UTF-8 data.
- // TODO_UTF8STRING: Throw a better exception below?
-
- ThrowHelper.ThrowInvalidOperationException();
- }
-
- int utf16CharCount = Length + utf16CodeUnitCountAdjustment;
- Debug.Assert(utf16CharCount <= Length && utf16CharCount >= 0);
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- // TODO_UTF8STRING: Can we call string.FastAllocate directly?
- return string.Create(utf16CharCount, (pbData: (IntPtr)pData, cbData: Length), static (chars, state) =>
- {
- OperationStatus status = Utf8.ToUtf16(new ReadOnlySpan((byte*)state.pbData, state.cbData), chars, out _, out _, replaceInvalidSequences: false);
- Debug.Assert(status == OperationStatus.Done, "Did somebody mutate this Utf8String instance unexpectedly?");
- });
-#else
- char[] buffer = ArrayPool.Shared.Rent(utf16CharCount);
- try
- {
- fixed (char* pBuffer = buffer)
- {
- Encoding.UTF8.GetChars(pData, Length, pBuffer, utf16CharCount);
- return new string(pBuffer, 0, utf16CharCount);
- }
- }
- finally
- {
- ArrayPool.Shared.Return(buffer);
- }
-#endif
- }
- }
-
- public Utf8String ToUtf8String()
- {
- // TODO_UTF8STRING: Since we know the underlying data is immutable, well-formed UTF-8,
- // we can perform transcoding using an optimized code path that skips all safety checks.
-
- return Utf8String.UnsafeCreateWithoutValidation(Bytes);
- }
-
- ///
- /// Wraps a instance around the provided ,
- /// skipping validation of the input data.
- ///
- ///
- /// Callers must uphold the following two invariants:
- ///
- /// (a) consists only of well-formed UTF-8 data and does
- /// not contain invalid or incomplete UTF-8 subsequences; and
- /// (b) the contents of will not change for the duration
- /// of the returned 's existence.
- ///
- /// If these invariants are not maintained, the runtime may exhibit undefined behavior.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Utf8Span UnsafeCreateWithoutValidation(ReadOnlySpan buffer)
- {
- return new Utf8Span(buffer);
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8StringComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8StringComparer.cs
deleted file mode 100644
index 8e56da7442594..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8StringComparer.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace System.Text
-{
- internal abstract class Utf8StringComparer : IComparer, IEqualityComparer
- {
- // Nobody except for nested classes can create instances of this type.
- private Utf8StringComparer() { }
-
- public static Utf8StringComparer CurrentCulture => new CultureAwareComparer(CultureInfo.CurrentCulture.CompareInfo, CompareOptions.None);
- public static Utf8StringComparer CurrentCultureIgnoreCase => new CultureAwareComparer(CultureInfo.CurrentCulture.CompareInfo, CompareOptions.IgnoreCase);
- public static Utf8StringComparer InvariantCulture => CultureAwareComparer.Invariant;
- public static Utf8StringComparer InvariantCultureIgnoreCase => CultureAwareComparer.InvariantIgnoreCase;
- public static Utf8StringComparer Ordinal => OrdinalComparer.Instance;
- public static Utf8StringComparer OrdinalIgnoreCase => OrdinalIgnoreCaseComparer.Instance;
-
- public static Utf8StringComparer Create(CultureInfo culture, bool ignoreCase) => Create(culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
-
- public static Utf8StringComparer Create(CultureInfo culture, CompareOptions options)
- {
- if (culture is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.culture);
- }
-
- return new CultureAwareComparer(culture.CompareInfo, options);
- }
-
- public static Utf8StringComparer FromComparison(StringComparison comparisonType)
- {
- return comparisonType switch
- {
- StringComparison.CurrentCulture => CurrentCulture,
- StringComparison.CurrentCultureIgnoreCase => CurrentCultureIgnoreCase,
- StringComparison.InvariantCulture => InvariantCulture,
- StringComparison.InvariantCultureIgnoreCase => InvariantCultureIgnoreCase,
- StringComparison.Ordinal => Ordinal,
- StringComparison.OrdinalIgnoreCase => OrdinalIgnoreCase,
- _ => throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)),
- };
- }
-
- public abstract int Compare(Utf8String? x, Utf8String? y);
- public abstract int Compare(Utf8Span x, Utf8Span y);
- public abstract bool Equals(Utf8String? x, Utf8String? y);
- public abstract bool Equals(Utf8Span x, Utf8Span y);
-#pragma warning disable CS8614 // Remove warning disable when nullable attributes are respected
- public abstract int GetHashCode(Utf8String obj);
-#pragma warning restore CS8614
- public abstract int GetHashCode(Utf8Span obj);
-
- private sealed class CultureAwareComparer : Utf8StringComparer
- {
-#if SYSTEM_PRIVATE_CORELIB
- internal static readonly CultureAwareComparer Invariant = new CultureAwareComparer(CompareInfo.Invariant, CompareOptions.None);
- internal static readonly CultureAwareComparer InvariantIgnoreCase = new CultureAwareComparer(CompareInfo.Invariant, CompareOptions.IgnoreCase);
-#else
- internal static readonly CultureAwareComparer Invariant = new CultureAwareComparer(CultureInfo.InvariantCulture.CompareInfo, CompareOptions.None);
- internal static readonly CultureAwareComparer InvariantIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture.CompareInfo, CompareOptions.IgnoreCase);
-#endif
-
- private readonly CompareInfo _compareInfo;
- private readonly CompareOptions _options;
-
- internal CultureAwareComparer(CompareInfo compareInfo, CompareOptions options)
- {
- Debug.Assert(compareInfo != null);
-
- _compareInfo = compareInfo;
- _options = options;
- }
-
- public override int Compare(Utf8String? x, Utf8String? y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return _compareInfo.Compare(x?.ToString(), y?.ToString(), _options);
- }
-
- public override int Compare(Utf8Span x, Utf8Span y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return _compareInfo.Compare(x.ToString(), y.ToString(), _options);
- }
-
- public override bool Equals(Utf8String? x, Utf8String? y) => Compare(x, y) == 0;
- public override bool Equals(Utf8Span x, Utf8Span y) => Compare(x, y) == 0;
-
- public override int GetHashCode(Utf8String? obj)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return (obj is null) ? 0 : _compareInfo.GetHashCode(obj.ToString(), _options);
- }
-
- public override int GetHashCode(Utf8Span obj)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return _compareInfo.GetHashCode(obj.ToString(), _options);
- }
- }
-
- private sealed class OrdinalComparer : Utf8StringComparer
- {
- public static readonly OrdinalComparer Instance = new OrdinalComparer();
-
- // All accesses must be through the static factory.
- private OrdinalComparer() { }
-
- public override int Compare(Utf8String? x, Utf8String? y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return string.CompareOrdinal(x?.ToString(), y?.ToString());
- }
-
- public override int Compare(Utf8Span x, Utf8Span y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return string.CompareOrdinal(x.ToString(), y.ToString());
- }
-
- public override bool Equals(Utf8String? x, Utf8String? y) => Utf8String.Equals(x, y);
- public override bool Equals(Utf8Span x, Utf8Span y) => Utf8Span.Equals(x, y);
- public override int GetHashCode(Utf8String obj) => obj.GetHashCode();
- public override int GetHashCode(Utf8Span obj) => obj.GetHashCode();
- }
-
- private sealed class OrdinalIgnoreCaseComparer : Utf8StringComparer
- {
- public static readonly OrdinalIgnoreCaseComparer Instance = new OrdinalIgnoreCaseComparer();
-
- // All accesses must be through the static factory.
- private OrdinalIgnoreCaseComparer() { }
-
- public override int Compare(Utf8String? x, Utf8String? y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.Compare(x?.ToString(), y?.ToString());
- }
-
- public override int Compare(Utf8Span x, Utf8Span y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.Compare(x.ToString(), y.ToString());
- }
-
- public override bool Equals(Utf8String? x, Utf8String? y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.Equals(x?.ToString(), y?.ToString());
- }
-
- public override bool Equals(Utf8Span x, Utf8Span y)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.Equals(x.ToString(), y.ToString());
- }
-
- public override int GetHashCode(Utf8String obj)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.ToString());
- }
-
- public override int GetHashCode(Utf8Span obj)
- {
- // TODO_UTF8STRING: Avoid the allocations below.
-
- return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.ToString());
- }
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Comparison.cs
deleted file mode 100644
index df4f9fb32a0be..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Comparison.cs
+++ /dev/null
@@ -1,383 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Text.Unicode;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- /*
- * COMPARISON OF UTF-8 AGAINST UTF-16
- */
-
- ///
- /// Returns a value stating whether and
- /// represent the same data. An ordinal comparison is performed scalar-by-scalar.
- ///
- ///
- /// This method returns if both and
- /// are null, or if both are empty. This method returns
- /// if either input contains an ill-formed subsequence. Otherwise, this method returns
- /// if and only if both arguments decode to the same Unicode scalar value sequence.
- ///
- public static bool AreEquivalent(Utf8String? utf8Text, string? utf16Text)
- {
- if (ReferenceEquals(utf8Text, utf16Text))
- {
- return true; // both are null
- }
-
- if (utf8Text is null || utf16Text is null)
- {
- return false; // null is never equivalent to non-null
- }
-
- if (utf8Text.Length == 0 && utf16Text.Length == 0)
- {
- return true; // empty is equivalent to empty
- }
-
- // Short-circuit: are the texts of sufficiently different lengths that
- // they could never be equivalent? This check allows us to skip the
- // normal decoding walk, which is O(n).
- //
- // The maximum length of a 'System.String' is around 1 billion elements,
- // so we can perform the multiplication within an unsigned 32-bit domain.
-
- Debug.Assert((ulong)utf16Text.Length * MAX_UTF8_BYTES_PER_UTF16_CHAR <= uint.MaxValue, "Did somebody change the max. allowed string length?");
-
- if (utf8Text.Length < utf16Text.Length
- || ((uint)utf16Text.Length * MAX_UTF8_BYTES_PER_UTF16_CHAR < (uint)utf8Text.Length))
- {
- return false;
- }
-
- return AreEquivalentOrdinalSkipShortCircuitingChecks(utf8Text.AsBytes(), utf16Text.AsSpan());
- }
-
- ///
- /// Returns a value stating whether and
- /// represent the same data. An ordinal comparison is performed scalar-by-scalar.
- ///
- ///
- /// This method returns if both and
- /// are empty. This method returns
- /// if either input contains an ill-formed subsequence. Otherwise, this method returns
- /// if and only if both arguments decode to the same Unicode scalar value sequence.
- ///
- public static bool AreEquivalent(Utf8Span utf8Text, ReadOnlySpan utf16Text) => AreEquivalent(utf8Text.Bytes, utf16Text);
-
- ///
- /// Returns a value stating whether and
- /// represent the same data. An ordinal comparison is performed scalar-by-scalar.
- ///
- ///
- /// This method returns if both and
- /// are empty. This method returns
- /// if either input contains an ill-formed subsequence. Otherwise, this method returns
- /// if and only if both arguments decode to the same Unicode scalar value sequence.
- ///
- public static bool AreEquivalent(ReadOnlySpan utf8Text, ReadOnlySpan utf16Text)
- {
- if (utf8Text.Length == 0 && utf16Text.Length == 0)
- {
- // Don't use IsEmpty for this check; JIT can optimize "Length == 0" better
- // for this particular scenario.
-
- return true;
- }
-
- // Same check as the (Utf8String, string) overload. The primary difference is that
- // since spans can be up to 2 billion elements in length, we need to perform
- // the multiplication step in the unsigned 64-bit domain to avoid integer overflow.
-
- if (utf8Text.Length < utf16Text.Length
- || ((ulong)(uint)utf16Text.Length * MAX_UTF8_BYTES_PER_UTF16_CHAR < (uint)utf8Text.Length))
- {
- return false;
- }
-
- return AreEquivalentOrdinalSkipShortCircuitingChecks(utf8Text, utf16Text);
- }
-
- private static bool AreEquivalentOrdinalSkipShortCircuitingChecks(ReadOnlySpan utf8Text, ReadOnlySpan utf16Text)
- {
- while (!utf16Text.IsEmpty)
- {
- // If the next UTF-16 subsequence is malformed or incomplete, or if the next
- // UTF-8 subsequence is malformed or incomplete, or if they don't decode to
- // the exact same Unicode scalar value, fail.
- //
- // The Rune.DecodeFrom* APIs handle empty inputs just fine and return "Incomplete".
-
- // TODO_UTF8STRING: If we assume Utf8String contains well-formed UTF-8, we could
- // create a version of this method that calls a faster implementation of DecodeFromUtf8.
- // We'd need to be careful not to call that optimized routine if the user passed
- // us a normal ROS that didn't originate from a Utf8String or similar.
-
- if (Rune.DecodeFromUtf16(utf16Text, out Rune scalarFromUtf16, out int charsConsumedJustNow) != OperationStatus.Done
- || Rune.DecodeFromUtf8(utf8Text, out Rune scalarFromUtf8, out int bytesConsumedJustNow) != OperationStatus.Done
- || scalarFromUtf16 != scalarFromUtf8)
- {
- return false;
- }
-
- // TODO_UTF8STRING: As an optimization, we could perform unsafe slices below.
-
- utf16Text = utf16Text.Slice(charsConsumedJustNow);
- utf8Text = utf8Text.Slice(bytesConsumedJustNow);
- }
-
- // We decoded the entire UTF-16 input, and so far it has matched the decoded form
- // of the UTF-8 input. Now just make sure we've also decoded the entirety of the
- // UTF-8 data, otherwise the input strings aren't equivalent.
-
- return utf8Text.IsEmpty;
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// . An ordinal comparison is used.
- ///
- public bool Contains(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && Contains(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// . The specified comparison is used.
- ///
- public bool Contains(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && Contains(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// the specified . An ordinal comparison is used.
- ///
- public bool Contains(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
-#if SYSTEM_PRIVATE_CORELIB
- return SpanHelpers.IndexOf(
- ref DangerousGetMutableReference(), Length,
- ref MemoryMarshal.GetReference(runeBytes), runeBytesWritten) >= 0;
-#else
- return GetSpan()
- .IndexOf(runeBytes.Slice(0, runeBytesWritten)) >= 0;
-#endif
- }
-
- ///
- /// Returns a value stating whether the current instance contains
- /// the specified . The specified comparison is used.
- ///
- public bool Contains(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return ToString().Contains(value.ToString(), comparison);
-#else
- return ToString().IndexOf(value.ToString(), comparison) >= 0;
-#endif
- }
-
- ///
- /// Returns a value stating whether the current instance contains .
- /// An ordinal comparison is used.
- ///
- public bool Contains(Utf8String value)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsBytes().IndexOf(value.AsBytes()) >= 0;
- }
-
- ///
- /// Returns a value stating whether the current instance contains .
- /// The specified comparison is used.
- ///
- public bool Contains(Utf8String value, StringComparison comparison)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return ToString().Contains(value.ToString(), comparison);
-#else
- return ToString().IndexOf(value.ToString(), comparison) >= 0;
-#endif
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// . An ordinal comparison is used.
- ///
- public bool EndsWith(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && EndsWith(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// . The specified comparison is used.
- ///
- public bool EndsWith(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && EndsWith(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// the specified . An ordinal comparison is used.
- ///
- public bool EndsWith(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
- return this.AsBytes().EndsWith(runeBytes.Slice(0, runeBytesWritten));
- }
-
- ///
- /// Returns a value stating whether the current instance ends with
- /// the specified . The specified comparison is used.
- ///
- public bool EndsWith(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return ToString().EndsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance ends with .
- /// An ordinal comparison is used.
- ///
- public bool EndsWith(Utf8String value)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsBytes().EndsWith(value.AsBytes());
- }
-
- ///
- /// Returns a value stating whether the current instance ends with .
- /// The specified comparison is used.
- ///
- public bool EndsWith(Utf8String value, StringComparison comparison)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return ToString().EndsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// . An ordinal comparison is used.
- ///
- public bool StartsWith(char value)
- {
- return Rune.TryCreate(value, out Rune rune) && StartsWith(rune);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// . The specified comparison is used.
- ///
- public bool StartsWith(char value, StringComparison comparison)
- {
- return Rune.TryCreate(value, out Rune rune) && StartsWith(rune, comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// the specified . An ordinal comparison is used.
- ///
- public bool StartsWith(Rune value)
- {
- // TODO_UTF8STRING: This should be split into two methods:
- // One which operates on a single-byte (ASCII) search value,
- // the other which operates on a multi-byte (non-ASCII) search value.
-
- Span runeBytes = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
- int runeBytesWritten = value.EncodeToUtf8(runeBytes);
-
- return this.AsBytes().StartsWith(runeBytes.Slice(0, runeBytesWritten));
- }
-
- ///
- /// Returns a value stating whether the current instance begins with
- /// the specified . The specified comparison is used.
- ///
- public bool StartsWith(Rune value, StringComparison comparison)
- {
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return ToString().StartsWith(value.ToString(), comparison);
- }
-
- ///
- /// Returns a value stating whether the current instance begins with .
- /// An ordinal comparison is used.
- ///
- public bool StartsWith(Utf8String value)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsBytes().StartsWith(value.AsBytes());
- }
-
- ///
- /// Returns a value stating whether the current instance begins with .
- /// The specified comparison is used.
- ///
- public bool StartsWith(Utf8String value, StringComparison comparison)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- // TODO_UTF8STRING: Optimize me to avoid allocations.
-
- return ToString().StartsWith(value.ToString(), comparison);
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Construction.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Construction.cs
deleted file mode 100644
index 7508458d73bad..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Construction.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Text.Unicode;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- private const int MAX_STACK_TRANSCODE_CHAR_COUNT = 128;
-
- // For values beyond U+FFFF, it's 4 UTF-8 bytes per 2 UTF-16 chars (2:1 ratio)
- private const int MAX_UTF8_BYTES_PER_UTF16_CHAR = 3;
-
- /*
- * STATIC FACTORIES
- */
-
- ///
- /// Creates a instance from existing UTF-8 data.
- ///
- /// The existing data from which to create the new .
- ///
- /// When this method returns, contains a with the same contents as
- /// if consists of well-formed UTF-8 data. Otherwise, .
- ///
- ///
- /// if contains well-formed UTF-8 data and
- /// contains the encapsulating a copy of that data. Otherwise, .
- ///
- ///
- /// This method is a non-throwing equivalent of the constructor .
- ///
- public static bool TryCreateFrom(ReadOnlySpan buffer, [NotNullWhen(true)] out Utf8String? value)
- {
- if (buffer.IsEmpty)
- {
- value = Empty; // it's valid to create a Utf8String instance from an empty buffer; we'll return the Empty singleton
- return true;
- }
-
- // Create and populate the Utf8String instance.
-
- Utf8String newString = FastAllocateSkipZeroInit(buffer.Length);
-#if SYSTEM_PRIVATE_CORELIB
- Buffer.Memmove(ref newString.DangerousGetMutableReference(), ref MemoryMarshal.GetReference(buffer), (uint)buffer.Length);
-#else
- buffer.CopyTo(newString.DangerousGetMutableSpan());
-#endif
-
- // Now perform validation.
- // Reminder: Perform validation over the copy, not over the source.
-
- if (Utf8Utility.IsWellFormedUtf8(newString.AsBytes()))
- {
- value = newString;
- return true;
- }
- else
- {
- value = default;
- return false;
- }
- }
-
- ///
- /// Creates a instance from existing UTF-16 data, transcoding the
- /// existing data to UTF-8 upon creation.
- ///
- /// The existing UTF-16 data from which to create a new .
- ///
- /// When this method returns, contains a with equivalent contents as
- /// if consists of well-formed UTF-16 data. Otherwise, .
- ///
- ///
- /// if contains well-formed UTF-16 data and
- /// contains the encapsulating equivalent data (as UTF-8). Otherwise, .
- ///
- ///
- /// This method is a non-throwing equivalent of the constructor .
- ///
- public static bool TryCreateFrom(ReadOnlySpan buffer, [NotNullWhen(true)] out Utf8String? value)
- {
- // Returning "false" from this method means only that the original input buffer didn't
- // contain well-formed UTF-16 data. This method could fail in other ways, such as
- // throwing an OutOfMemoryException if allocation of the output parameter fails.
-
- value = CreateFromUtf16Common(buffer, replaceInvalidSequences: false);
- return !(value is null);
- }
-
- ///
- /// Creates a instance from existing UTF-8 data.
- ///
- /// The existing data from which to create the new .
- ///
- /// If contains any ill-formed UTF-8 subsequences, those subsequences will
- /// be replaced with in the returned instance.
- /// This may result in the returned having different contents (and thus a different
- /// total byte length) than the source parameter .
- ///
- public static Utf8String CreateFromRelaxed(ReadOnlySpan buffer)
- {
- if (buffer.IsEmpty)
- {
- return Empty;
- }
-
- // Create and populate the Utf8String instance.
-
- Utf8String newString = FastAllocateSkipZeroInit(buffer.Length);
-#if SYSTEM_PRIVATE_CORELIB
- Buffer.Memmove(ref newString.DangerousGetMutableReference(), ref MemoryMarshal.GetReference(buffer), (uint)buffer.Length);
-#else
- buffer.CopyTo(newString.DangerousGetMutableSpan());
-#endif
-
- // Now perform validation & fixup.
-
- return Utf8Utility.ValidateAndFixupUtf8String(newString);
- }
-
- ///
- /// Creates a instance from existing UTF-16 data.
- ///
- /// The existing data from which to create the new .
- ///
- /// If contains any ill-formed UTF-16 subsequences, those subsequences will
- /// be replaced with in the returned instance.
- /// This may result in the original string data not round-tripping properly; that is, calling
- /// on the returned instance may produce a
- /// whose contents differ from .
- ///
- public static Utf8String CreateFromRelaxed(ReadOnlySpan buffer)
- {
- Utf8String? newString = CreateFromUtf16Common(buffer, replaceInvalidSequences: true);
-
- if (newString is null)
- {
- // This shouldn't happen unless somebody mutated the input buffer in the middle
- // of data processing. We just fail in this scenario rather than retrying.
-
- throw new ArgumentException(
- message: SR.Utf8String_InputContainedMalformedUtf16,
- paramName: nameof(buffer));
- }
-
- return newString;
- }
-
- internal static Utf8String CreateFromRune(Rune value)
- {
- // Can skip zero-init since we're going to populate the entire buffer.
-
- Utf8String newString = FastAllocateSkipZeroInit(value.Utf8SequenceLength);
-
- if (value.IsAscii)
- {
- // Fast path: If an ASCII value, just allocate the one-byte string and fill in the single byte contents.
-
- newString.DangerousGetMutableReference() = (byte)value.Value;
- return newString;
- }
- else
- {
- // Slow path: If not ASCII, allocate a string of the appropriate length and fill in the multi-byte contents.
-
- int bytesWritten = value.EncodeToUtf8(newString.DangerousGetMutableSpan());
- Debug.Assert(newString.Length == bytesWritten);
- return newString;
- }
- }
-
- // Returns 'null' if the input buffer does not represent well-formed UTF-16 data and 'replaceInvalidSequences' is false.
- private static Utf8String? CreateFromUtf16Common(ReadOnlySpan value, bool replaceInvalidSequences)
- {
- // Shortcut: Since we expect most strings to be small-ish, first try a one-pass
- // operation where we transcode directly on to the stack and then copy the validated
- // data into the new Utf8String instance. It's still O(n), but it should have a smaller
- // constant factor than a typical "count + transcode" combo.
-
- OperationStatus status;
- Utf8String newString;
-
- if (value.Length <= MAX_STACK_TRANSCODE_CHAR_COUNT /* in chars */)
- {
- if (value.IsEmpty)
- {
- return Empty;
- }
-
- Span scratch = stackalloc byte[MAX_STACK_TRANSCODE_CHAR_COUNT * MAX_UTF8_BYTES_PER_UTF16_CHAR]; // largest possible expansion, as explained below
- status = Utf8.FromUtf16(value, scratch, out _, out int scratchBytesWritten, replaceInvalidSequences);
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.InvalidData);
-
- if (status == OperationStatus.InvalidData)
- {
- return null;
- }
-
- // At this point we know transcoding succeeded, so the original input data was well-formed.
- // We'll memcpy the scratch buffer into the new Utf8String instance, which is very fast.
-
- newString = FastAllocateSkipZeroInit(scratchBytesWritten);
- scratch.Slice(0, scratchBytesWritten).CopyTo(newString.DangerousGetMutableSpan());
- return newString;
- }
-
- // First, determine how many UTF-8 bytes we'll need in order to represent this data.
- // This also checks the input data for well-formedness.
-
- long utf8CodeUnitCountAdjustment;
-
- unsafe
- {
- fixed (char* pChars = &MemoryMarshal.GetReference(value))
- {
- if (Utf16Utility.GetPointerToFirstInvalidChar(pChars, value.Length, out utf8CodeUnitCountAdjustment, out int _) != (pChars + (uint)value.Length))
- {
- return null;
- }
- }
- }
-
- // The max possible expansion transcoding UTF-16 to UTF-8 is that each input char corresponds
- // to 3 UTF-8 bytes. This is most common in CJK languages. Since the input buffer could be
- // up to int.MaxValue elements in length, we need to use a 64-bit value to hold the total
- // required UTF-8 byte length. However, the VM places restrictions on how large a Utf8String
- // instance can be, and the maximum allowed element count is just under int.MaxValue. (This
- // mirrors the restrictions already in place for System.String.) The VM will throw an
- // OutOfMemoryException if anybody tries to create a Utf8String instance larger than that,
- // so if we detect any sort of overflow we'll end up passing int.MaxValue down to the allocation
- // routine. This normalizes the OutOfMemoryException the caller sees.
-
- long totalUtf8BytesRequired = (uint)value.Length + utf8CodeUnitCountAdjustment;
- if (totalUtf8BytesRequired > int.MaxValue)
- {
- totalUtf8BytesRequired = int.MaxValue;
- }
-
- // We can get away with FastAllocateSkipZeroInit here because we're not going to return the
- // new Utf8String instance to the caller if we don't overwrite every byte of the buffer.
-
- newString = FastAllocateSkipZeroInit((int)totalUtf8BytesRequired);
-
- // Now transcode the UTF-16 input into the newly allocated Utf8String's buffer. We can't call the
- // "skip validation" transcoder because the caller could've mutated the input buffer between the
- // initial counting step and the transcoding step below.
-
- status = Utf8.FromUtf16(value, newString.DangerousGetMutableSpan(), out _, out int bytesWritten, replaceInvalidSequences: false);
- if (status != OperationStatus.Done || bytesWritten != newString.Length)
- {
- // Did somebody mutate our input buffer? Shouldn't be any other way this could happen.
-
- return null;
- }
-
- return newString;
- }
-
-#if !SYSTEM_PRIVATE_CORELIB
- // Returns 'null' if the input buffer does not represent well-formed UTF-16 data and 'replaceInvalidSequences' is false.
- private static byte[]? CreateBufferFromUtf16Common(ReadOnlySpan value, bool replaceInvalidSequences)
- {
- // Shortcut: Since we expect most strings to be small-ish, first try a one-pass
- // operation where we transcode directly on to the stack and then copy the validated
- // data into the new Utf8String instance. It's still O(n), but it should have a smaller
- // constant factor than a typical "count + transcode" combo.
-
- OperationStatus status;
- byte[] newBuffer;
-
- if (value.Length <= MAX_STACK_TRANSCODE_CHAR_COUNT /* in chars */)
- {
- if (value.IsEmpty)
- {
- return Utf8String.Empty._bytes;
- }
-
- Span scratch = stackalloc byte[MAX_STACK_TRANSCODE_CHAR_COUNT * MAX_UTF8_BYTES_PER_UTF16_CHAR]; // largest possible expansion, as explained below
- status = Utf8.FromUtf16(value, scratch, out _, out int scratchBytesWritten, replaceInvalidSequences);
- Debug.Assert(status == OperationStatus.Done || status == OperationStatus.InvalidData);
-
- if (status == OperationStatus.InvalidData)
- {
- return null;
- }
-
- // At this point we know transcoding succeeded, so the original input data was well-formed.
- // We'll memcpy the scratch buffer into the new Utf8String instance, which is very fast.
-
- newBuffer = new byte[scratchBytesWritten + 1]; // null-terminated
- scratch.Slice(0, scratchBytesWritten).CopyTo(newBuffer);
- return newBuffer;
- }
-
- // First, determine how many UTF-8 bytes we'll need in order to represent this data.
- // This also checks the input data for well-formedness.
-
- long utf8CodeUnitCountAdjustment;
-
- unsafe
- {
- fixed (char* pChars = &MemoryMarshal.GetReference(value))
- {
- if (Utf16Utility.GetPointerToFirstInvalidChar(pChars, value.Length, out utf8CodeUnitCountAdjustment, out int _) != (pChars + (uint)value.Length))
- {
- return null;
- }
- }
- }
-
- // The max possible expansion transcoding UTF-16 to UTF-8 is that each input char corresponds
- // to 3 UTF-8 bytes. This is most common in CJK languages. Since the input buffer could be
- // up to int.MaxValue elements in length, we need to use a 64-bit value to hold the total
- // required UTF-8 byte length. However, the VM places restrictions on how large a Utf8String
- // instance can be, and the maximum allowed element count is just under int.MaxValue. (This
- // mirrors the restrictions already in place for System.String.) The VM will throw an
- // OutOfMemoryException if anybody tries to create a Utf8String instance larger than that,
- // so if we detect any sort of overflow we'll end up passing int.MaxValue down to the allocation
- // routine. This normalizes the OutOfMemoryException the caller sees.
-
- long totalUtf8BytesRequired = (uint)value.Length + utf8CodeUnitCountAdjustment;
- if (totalUtf8BytesRequired >= int.MaxValue)
- {
- totalUtf8BytesRequired = int.MaxValue - 1;
- }
-
- // We can get away with FastAllocateSkipZeroInit here because we're not going to return the
- // new Utf8String instance to the caller if we don't overwrite every byte of the buffer.
-
- newBuffer = new byte[(int)totalUtf8BytesRequired + 1]; // null-terminated
-
- // Now transcode the UTF-16 input into the newly allocated Utf8String's buffer. We can't call the
- // "skip validation" transcoder because the caller could've mutated the input buffer between the
- // initial counting step and the transcoding step below.
-
- status = Utf8.FromUtf16(value, newBuffer.AsSpan(0, newBuffer.Length - 1), out _, out int bytesWritten, replaceInvalidSequences: false);
- if (status != OperationStatus.Done || bytesWritten != newBuffer.Length - 1)
- {
- // Did somebody mutate our input buffer? Shouldn't be any other way this could happen.
-
- return null;
- }
-
- return newBuffer;
- }
-#endif // !SYSTEM_PRIVATE_CORELIB
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- ///
- /// Creates a new instance, allowing the provided delegate to populate the
- /// instance data of the returned object.
- ///
- /// Type of the state object provided to .
- /// The length, in bytes, of the instance to create.
- /// The state object to provide to .
- /// The callback which will be invoked to populate the returned .
- ///
- /// Thrown if populates the buffer with ill-formed UTF-8 data.
- ///
- ///
- /// The runtime will perform UTF-8 validation over the contents provided by the delegate.
- /// If an invalid UTF-8 subsequence is detected, an exception is thrown.
- ///
- public static Utf8String Create(int length, TState state, SpanAction action)
- {
- if (length < 0)
- {
- ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
- }
-
- if (action is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
- }
-
- if (length == 0)
- {
- return Empty; // special-case empty input
- }
-
- // Create and populate the Utf8String instance.
- // Can't use FastAllocateSkipZeroInit here because we're handing the raw buffer to user code.
-
- Utf8String newString = FastAllocate(length);
- action(newString.DangerousGetMutableSpan(), state);
-
- // Now perform validation.
-
- if (!Utf8Utility.IsWellFormedUtf8(newString.AsBytes()))
- {
- throw new ArgumentException(
- message: SR.Utf8String_CallbackProvidedMalformedData,
- paramName: nameof(action));
- }
-
- return newString;
- }
-
- ///
- /// Creates a new instance, allowing the provided delegate to populate the
- /// instance data of the returned object.
- ///
- /// Type of the state object provided to .
- /// The length, in bytes, of the instance to create.
- /// The state object to provide to .
- /// The callback which will be invoked to populate the returned .
- ///
- /// The runtime will perform UTF-8 validation over the contents provided by the delegate.
- /// If an invalid UTF-8 subsequence is detected, the invalid subsequence is replaced with
- /// in the returned instance. This could result in the returned instance
- /// having a different byte length than specified by the parameter.
- ///
- public static Utf8String CreateRelaxed(int length, TState state, SpanAction action)
- {
- if (length < 0)
- {
- ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
- }
-
- if (action is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
- }
-
- if (length == 0)
- {
- return Empty; // special-case empty input
- }
-
- // Create and populate the Utf8String instance.
- // Can't use FastAllocateSkipZeroInit here because we're handing the raw buffer to user code.
-
- Utf8String newString = FastAllocate(length);
- action(newString.DangerousGetMutableSpan(), state);
-
- // Now perform validation and fixup.
-
- return Utf8Utility.ValidateAndFixupUtf8String(newString);
- }
-
- ///
- /// Creates a new instance, allowing the provided delegate to populate the
- /// instance data of the returned object. Please see remarks for important safety information about
- /// this method.
- ///
- /// Type of the state object provided to .
- /// The length, in bytes, of the instance to create.
- /// The state object to provide to .
- /// The callback which will be invoked to populate the returned .
- ///
- /// This factory method can be used as an optimization to skip the validation step that
- /// normally performs. The contract
- /// of this method requires that populate the buffer with well-formed UTF-8
- /// data, as contractually guarantees that it contains only well-formed UTF-8 data,
- /// and runtime instability could occur if a caller violates this guarantee.
- ///
- public static Utf8String UnsafeCreateWithoutValidation(int length, TState state, SpanAction action)
- {
- if (length < 0)
- {
- ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
- }
-
- if (action is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
- }
-
- if (length == 0)
- {
- return Empty; // special-case empty input
- }
-
- // Create and populate the Utf8String instance.
- // Can't use FastAllocateSkipZeroInit here because we're handing the raw buffer to user code.
-
- Utf8String newString = FastAllocate(length);
- action(newString.DangerousGetMutableSpan(), state);
-
- // The line below is removed entirely in release builds.
-
- Debug.Assert(Utf8Utility.IsWellFormedUtf8(newString.AsBytes()), "Callback populated the buffer with ill-formed UTF-8 data.");
-
- return newString;
- }
-#endif // !NETSTANDARD2_0
-
- ///
- /// Creates a new instance populated with a copy of the provided contents.
- /// Please see remarks for important safety information about this method.
- ///
- /// The contents to copy to the new .
- ///
- /// This factory method can be used as an optimization to skip the validation step that the
- /// constructors normally perform. The contract of this method requires that
- /// contain only well-formed UTF-8 data, as
- /// contractually guarantees that it contains only well-formed UTF-8 data, and runtime instability
- /// could occur if a caller violates this guarantee.
- ///
- public static Utf8String UnsafeCreateWithoutValidation(ReadOnlySpan utf8Contents)
- {
- if (utf8Contents.IsEmpty)
- {
- return Empty; // special-case empty input
- }
-
- // Create and populate the Utf8String instance.
-
- Utf8String newString = FastAllocateSkipZeroInit(utf8Contents.Length);
- utf8Contents.CopyTo(newString.DangerousGetMutableSpan());
- // TODO_UTF8STRING: Zero-init was skipped above, but we didn't null-terminate the string
-
- // The line below is removed entirely in release builds.
-
- Debug.Assert(Utf8Utility.IsWellFormedUtf8(newString.AsBytes()), "Buffer contained ill-formed UTF-8 data.");
-
- return newString;
- }
-
- /*
- * HELPER METHODS
- */
-
- ///
- /// Creates a new instance of the specified length. Actual storage allocated is "length + 1" bytes
- /// because instances are null-terminated. Aside from the null terminator, the contents of the new
- /// instance are not zero-inited. Use only with first-party APIs which we know for a fact will
- /// initialize the entire contents of the Utf8String instance.
- ///
- ///
- /// The implementation of this method checks its input argument for overflow.
- ///
- private static Utf8String FastAllocateSkipZeroInit(int length)
- {
- // TODO_UTF8STRING: Actually skip zero-init.
-
- return FastAllocate(length);
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Conversion.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Conversion.cs
deleted file mode 100644
index 2e304e1a08b9e..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Conversion.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Globalization;
-using System.Text;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- ///
- /// Returns a value stating whether this instance is normalized
- /// using the specified Unicode normalization form.
- ///
- /// The to check.
- /// if this instance represents text
- /// normalized under , otherwise .
- public bool IsNormalized(NormalizationForm normalizationForm = NormalizationForm.FormC)
- {
- // TODO_UTF8STRING: Avoid allocations in this code path.
-
- return ToString().IsNormalized(normalizationForm);
- }
-
- ///
- /// Returns a new instance which represents this instance
- /// normalized using the specified Unicode normalization form.
- ///
- ///
- /// The original is left unchanged by this operation.
- ///
- public Utf8String Normalize(NormalizationForm normalizationForm = NormalizationForm.FormC) => this.AsSpanSkipNullCheck().Normalize(normalizationForm);
-
- ///
- /// Converts this to a .
- ///
- public char[] ToCharArray() => this.AsSpanSkipNullCheck().ToCharArray();
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to lowercase using .
- ///
- ///
- /// The original is left unchanged by this operation. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToLower(CultureInfo culture) => this.AsSpanSkipNullCheck().ToLower(culture);
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to lowercase using the invariant culture.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToLowerInvariant() => this.AsSpanSkipNullCheck().ToLowerInvariant();
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to uppercase using .
- ///
- ///
- /// The original is left unchanged by this operation. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToUpper(CultureInfo culture) => this.AsSpanSkipNullCheck().ToUpper(culture);
-
- ///
- /// Returns a new instance which represents this instance
- /// converted to uppercase using the invariant culture.
- ///
- ///
- /// The original is left unchanged by this operation. For more information on the
- /// invariant culture, see the property. Note that the returned
- /// instance may be longer or shorter (in terms of UTF-8 byte count) than the
- /// input .
- ///
- public Utf8String ToUpperInvariant() => this.AsSpanSkipNullCheck().ToUpperInvariant();
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Enumeration.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Enumeration.cs
deleted file mode 100644
index b52f2799d52b1..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Enumeration.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- /*
- * ENUMERABLE PROPERTY ACCESSORS
- */
-
- ///
- /// Allows enumeration over the individual UTF-8 bytes of this instance.
- ///
- public ByteEnumerable Bytes => new ByteEnumerable(this);
-
- ///
- /// Allows enumeration over the UTF-16 code units (see ) which would result
- /// from transcoding this instance to a UTF-16 .
- ///
- public CharEnumerable Chars => new CharEnumerable(this);
-
- ///
- /// Allows enumeration over the Unicode scalar values (see ) which are
- /// encoded by this instance.
- ///
- public RuneEnumerable Runes => new RuneEnumerable(this);
-
- /*
- * ENUMERATORS
- */
-
- public readonly struct ByteEnumerable : IEnumerable
- {
- private readonly Utf8String _obj;
-
- internal ByteEnumerable(Utf8String obj)
- {
- _obj = obj;
- }
-
- public Enumerator GetEnumerator() => new Enumerator(_obj);
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- public struct Enumerator : IEnumerator
- {
- private readonly Utf8String _obj;
- private int _nextByteIdx;
-
- internal Enumerator(Utf8String obj)
- {
- _obj = obj;
- _nextByteIdx = 0;
- Current = default;
- }
-
- public byte Current { get; private set; }
-
- public bool MoveNext()
- {
- int nextByteIdx = _nextByteIdx;
- ReadOnlySpan objAsBytes = _obj.AsBytesSkipNullCheck();
-
- if ((uint)nextByteIdx < (uint)objAsBytes.Length)
- {
- Current = objAsBytes[nextByteIdx];
- _nextByteIdx = nextByteIdx + 1;
- return true;
- }
- else
- {
- return false;
- }
- }
-
- void IDisposable.Dispose()
- {
- // intentionally no-op
- }
-
- object IEnumerator.Current => Current;
-
- void IEnumerator.Reset() => throw NotImplemented.ByDesign;
- }
- }
-
- public readonly struct CharEnumerable : IEnumerable
- {
- private readonly Utf8String _obj;
-
- internal CharEnumerable(Utf8String obj)
- {
- _obj = obj;
- }
-
- public Enumerator GetEnumerator() => new Enumerator(_obj);
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- public struct Enumerator : IEnumerator
- {
- private readonly Utf8String _obj;
- private uint _currentCharPair;
- private int _nextByteIdx;
-
- internal Enumerator(Utf8String obj)
- {
- _obj = obj;
- _currentCharPair = default;
- _nextByteIdx = 0;
- }
-
- public char Current => (char)_currentCharPair;
-
- public bool MoveNext()
- {
- // Make copies of fields to avoid tearing issues since we're
- // about to perform unsafe accesses.
-
- uint currentCharPair = _currentCharPair;
- if (currentCharPair > char.MaxValue)
- {
- // There was a surrogate pair smuggled in here from a previous operation.
- // Shift out the high surrogate value and return immediately.
-
- _currentCharPair = currentCharPair >> 16;
- return true;
- }
-
- ReadOnlySpan bytes = _obj.AsBytesSkipNullCheck();
- int nextByteIdx = _nextByteIdx;
-
- if ((uint)nextByteIdx >= (uint)bytes.Length)
- {
- return false; // no more data
- }
-
- // TODO_UTF8STRING: Can we skip correctness checks below?
- // Perhaps not, this enumerator struct is potentially tearable.
-
- OperationStatus status = Rune.DecodeFromUtf8(bytes.Slice(nextByteIdx), out Rune currentRune, out int bytesConsumedJustNow);
- Debug.Assert(status == OperationStatus.Done);
-
- _nextByteIdx = nextByteIdx + bytesConsumedJustNow;
-
- if (currentRune.IsBmp)
- {
- // Common case - BMP scalar value.
-
- _currentCharPair = (uint)currentRune.Value;
- }
- else
- {
- // Uncommon case - supplementary (astral) plane scalar value.
- // We'll smuggle the two UTF-16 code units into a single 32-bit value,
- // with the leading surrogate packed into the low 16 bits of the value,
- // and the trailing surrogate packed into the high 16 bits of the value.
-
- UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)currentRune.Value, out char leadingCodeUnit, out char trailingCodeUnit);
- _currentCharPair = (uint)leadingCodeUnit + ((uint)trailingCodeUnit << 16);
- }
-
- return true;
- }
-
- void IDisposable.Dispose()
- {
- // intentionally no-op
- }
-
- object IEnumerator.Current => Current;
-
- void IEnumerator.Reset() => throw NotImplemented.ByDesign;
- }
- }
-
- public readonly struct RuneEnumerable : IEnumerable
- {
- private readonly Utf8String _obj;
-
- internal RuneEnumerable(Utf8String obj)
- {
- _obj = obj;
- }
-
- public Enumerator GetEnumerator() => new Enumerator(_obj);
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- public struct Enumerator : IEnumerator
- {
- private readonly Utf8String _obj;
- private Rune _currentRune;
- private int _nextByteIdx;
-
- internal Enumerator(Utf8String obj)
- {
- _obj = obj;
- _currentRune = default;
- _nextByteIdx = 0;
- }
-
- public Rune Current => _currentRune;
-
- public bool MoveNext()
- {
- // Make copies of fields to avoid tearing issues since we're
- // about to perform unsafe accesses.
-
- ReadOnlySpan bytes = _obj.AsBytesSkipNullCheck();
- int nextByteIdx = _nextByteIdx;
-
- if ((uint)nextByteIdx >= (uint)bytes.Length)
- {
- return false; // no more data
- }
-
- bytes = bytes.Slice(nextByteIdx);
-
- // TODO_UTF8STRING: Can we skip correctness checks below?
- // Perhaps not, this enumerator struct is potentially tearable.
-
- OperationStatus status = Rune.DecodeFromUtf8(bytes, out _currentRune, out int bytesConsumedJustNow);
- Debug.Assert(status == OperationStatus.Done);
-
- _nextByteIdx = nextByteIdx + bytesConsumedJustNow;
- return true;
- }
-
- void IDisposable.Dispose()
- {
- // intentionally no-op
- }
-
- object IEnumerator.Current => Current;
-
- void IEnumerator.Reset() => throw NotImplemented.ByDesign;
- }
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Manipulation.cs
deleted file mode 100644
index affdaf7d2e040..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Manipulation.cs
+++ /dev/null
@@ -1,767 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Text.Unicode;
-
-#if SYSTEM_PRIVATE_CORELIB
-using Internal.Runtime.CompilerServices;
-#endif
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- [StackTraceHidden]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void CheckSplitOptions(Utf8StringSplitOptions options)
- {
- if ((uint)options > (uint)(Utf8StringSplitOptions.RemoveEmptyEntries | Utf8StringSplitOptions.TrimEntries))
- {
- CheckSplitOptions_Throw(options);
- }
- }
-
- [StackTraceHidden]
- private static void CheckSplitOptions_Throw(Utf8StringSplitOptions options)
- {
- throw new ArgumentOutOfRangeException(
- paramName: nameof(options),
- message: SR.Format(SR.Arg_EnumIllegalVal, (int)options));
- }
-
- ///
- /// Substrings this without bounds checking.
- ///
- private Utf8String InternalSubstring(int startIndex, int length)
- {
- Debug.Assert(startIndex >= 0, "StartIndex cannot be negative.");
- Debug.Assert(startIndex <= this.Length, "StartIndex cannot point beyond the end of the string (except to the null terminator).");
- Debug.Assert(length >= 0, "Length cannot be negative.");
- Debug.Assert(startIndex + length <= this.Length, "StartIndex and Length cannot point beyond the end of the string.");
-
- Debug.Assert(length != 0 && length != this.Length, "Caller should handle Length boundary conditions.");
-
- // Since Utf8String instances must contain well-formed UTF-8 data, we cannot allow a substring such that
- // either boundary of the new substring splits a multi-byte UTF-8 subsequence. Fortunately this is a very
- // easy check: since we assume the original buffer consisted entirely of well-formed UTF-8 data, all we
- // need to do is check that neither the substring we're about to create nor the substring that would
- // follow immediately thereafter begins with a UTF-8 continuation byte. Should this occur, it means that
- // the UTF-8 lead byte is in a prior substring, which would indicate a multi-byte sequence has been split.
- // It's ok for us to dereference the element immediately after the end of the Utf8String instance since
- // we know it's a null terminator.
-
- if (Utf8Utility.IsUtf8ContinuationByte(DangerousGetMutableReference(startIndex))
- || Utf8Utility.IsUtf8ContinuationByte(DangerousGetMutableReference(startIndex + length)))
- {
- ThrowImproperStringSplit();
- }
-
- Utf8String newString = FastAllocateSkipZeroInit(length);
-#if SYSTEM_PRIVATE_CORELIB
- Buffer.Memmove(ref newString.DangerousGetMutableReference(), ref this.DangerousGetMutableReference(startIndex), (uint)length);
-#else
- this.GetSpan().Slice(startIndex, length).CopyTo(newString.DangerousGetMutableSpan());
-#endif
-
- return newString;
- }
-
- private Utf8String InternalSubstringWithoutCorrectnessChecks(int startIndex, int length)
- {
- Debug.Assert(startIndex >= 0, "StartIndex cannot be negative.");
- Debug.Assert(startIndex <= this.Length, "StartIndex cannot point beyond the end of the string (except to the null terminator).");
- Debug.Assert(length >= 0, "Length cannot be negative.");
- Debug.Assert(startIndex + length <= this.Length, "StartIndex and Length cannot point beyond the end of the string.");
-
- // In debug mode, perform the checks anyway. It's ok if we read just past the end of the
- // Utf8String instance, since we'll just be reading the null terminator (which is safe).
-
- Debug.Assert(!Utf8Utility.IsUtf8ContinuationByte(DangerousGetMutableReference(startIndex)), "Somebody is trying to split this Utf8String improperly.");
- Debug.Assert(!Utf8Utility.IsUtf8ContinuationByte(DangerousGetMutableReference(startIndex + length)), "Somebody is trying to split this Utf8String improperly.");
-
- if (length == 0)
- {
- return Empty;
- }
- else if (length == this.Length)
- {
- return this;
- }
- else
- {
- Utf8String newString = FastAllocateSkipZeroInit(length);
-#if SYSTEM_PRIVATE_CORELIB
- Buffer.Memmove(ref newString.DangerousGetMutableReference(), ref this.DangerousGetMutableReference(startIndex), (uint)length);
-#else
- this.GetSpan().Slice(startIndex, length).CopyTo(newString.DangerousGetMutableSpan());
-#endif
- return newString;
- }
- }
-
- [StackTraceHidden]
- internal static void ThrowImproperStringSplit()
- {
- throw new InvalidOperationException(
- message: SR.Utf8String_CannotSplitMultibyteSubsequence);
- }
-
- internal Utf8String Substring(int startIndex, int length)
- {
- ValidateStartIndexAndLength(startIndex, length);
-
- // Optimizations: since instances are immutable, we can return 'this' or the known
- // Empty instance if the caller passed us a startIndex at the string boundary.
-
- if (length == 0)
- {
- return Empty;
- }
-
- if (length == this.Length)
- {
- return this;
- }
-
- return InternalSubstring(startIndex, length);
- }
-
- public SplitResult Split(char separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- if (!Rune.TryCreate(separator, out Rune rune))
- {
- throw new ArgumentOutOfRangeException(
- paramName: nameof(separator),
- message: SR.ArgumentOutOfRange_Utf16SurrogatesDisallowed);
- }
-
- CheckSplitOptions(options);
-
- return new SplitResult(this, rune, options);
- }
-
- public SplitResult Split(Rune separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- CheckSplitOptions(options);
-
- return new SplitResult(this, separator, options);
- }
-
- public SplitResult Split(Utf8String separator, Utf8StringSplitOptions options = Utf8StringSplitOptions.None)
- {
- if (IsNullOrEmpty(separator))
- {
- throw new ArgumentException(
- paramName: nameof(separator),
- message: SR.Argument_CannotBeNullOrEmpty);
- }
-
- CheckSplitOptions(options);
-
- return new SplitResult(this, separator, options);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(char separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(char separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(Rune separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(Rune separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOn(Utf8String separator)
- {
- return TryFind(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOn(Utf8String separator, StringComparison comparisonType)
- {
- return TryFind(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(char separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(char separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(Rune separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(Rune separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// An ordinal search is performed.
- ///
- public SplitOnResult SplitOnLast(Utf8String separator)
- {
- return TryFindLast(separator, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Locates the last occurrence of within this instance, creating
- /// instances which represent the data on either side of the separator. If is not found
- /// within this instance, returns the tuple "(this, null)".
- ///
- ///
- /// The search is performed using the specified .
- ///
- public SplitOnResult SplitOnLast(Utf8String separator, StringComparison comparisonType)
- {
- return TryFindLast(separator, comparisonType, out Range range) ? new SplitOnResult(this, range) : new SplitOnResult(this);
- }
-
- ///
- /// Trims whitespace from the beginning and the end of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8String Trim() => TrimHelper(TrimType.Both);
-
- ///
- /// Trims whitespace from only the end of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8String TrimEnd() => TrimHelper(TrimType.Tail);
-
- private Utf8String TrimHelper(TrimType trimType)
- {
- Utf8Span trimmedSpan = this.AsSpan().TrimHelper(trimType);
-
- // Try to avoid allocating a new Utf8String instance if possible.
- // Otherwise, allocate a new substring wrapped around the resulting slice.
-
- return (trimmedSpan.Length == this.Length) ? this : trimmedSpan.ToUtf8String();
- }
-
- ///
- /// Trims whitespace from only the beginning of this ,
- /// returning a new containing the resulting slice.
- ///
- public Utf8String TrimStart() => TrimHelper(TrimType.Head);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [StackTraceHidden]
- private void ValidateStartIndexAndLength(int startIndex, int length)
- {
-#if TARGET_64BIT
- // See comment in Span.Slice for how this works.
- if ((ulong)(uint)startIndex + (ulong)(uint)length > (ulong)(uint)this.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException();
-#else
- if ((uint)startIndex > (uint)this.Length || (uint)length > (uint)(this.Length - startIndex))
- ThrowHelper.ThrowArgumentOutOfRangeException();
-#endif
- }
-
- [StructLayout(LayoutKind.Auto)]
- public readonly struct SplitResult : IEnumerable
- {
- private readonly State _state;
-
- internal SplitResult(Utf8String source, Rune searchRune, Utf8StringSplitOptions splitOptions)
- {
- _state = new State
- {
- FullSearchSpace = source,
- OffsetAtWhichToContinueSearch = 0,
- SearchRune = searchRune.Value,
- SearchTerm = default,
- SplitOptions = splitOptions
- };
- }
-
- internal SplitResult(Utf8String source, Utf8String searchTerm, Utf8StringSplitOptions splitOptions)
- {
- _state = new State
- {
- FullSearchSpace = source,
- OffsetAtWhichToContinueSearch = 0,
- SearchRune = -1,
- SearchTerm = searchTerm,
- SplitOptions = splitOptions
- };
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- item2 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- item3 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3, out Utf8String? item4)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item3 = TrimIfNeeded(nextItem);
-
- item4 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3, out Utf8String? item4, out Utf8String? item5)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item3 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item4 = TrimIfNeeded(nextItem);
-
- item5 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3, out Utf8String? item4, out Utf8String? item5, out Utf8String? item6)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item3 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item4 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item5 = TrimIfNeeded(nextItem);
-
- item6 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3, out Utf8String? item4, out Utf8String? item5, out Utf8String? item6, out Utf8String? item7)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item3 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item4 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item5 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item6 = TrimIfNeeded(nextItem);
-
- item7 = TrimIfNeeded(remainder);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String? item1, out Utf8String? item2, out Utf8String? item3, out Utf8String? item4, out Utf8String? item5, out Utf8String? item6, out Utf8String? item7, out Utf8String? item8)
- {
- _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span nextItem, out Utf8Span remainder);
- item1 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item2 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item3 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item4 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item5 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item6 = TrimIfNeeded(nextItem);
-
- _state.DeconstructHelper(in remainder, out nextItem, out remainder);
- item7 = TrimIfNeeded(nextItem);
-
- item8 = TrimIfNeeded(remainder);
- }
-
- public Enumerator GetEnumerator() => new Enumerator(this);
-
- private unsafe Utf8String? TrimIfNeeded(Utf8Span span)
- {
- if ((_state.SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- span = span.Trim();
- }
-
- if (span.Length < _state.FullSearchSpace.Length)
- {
- if (!span.IsEmpty)
- {
- return span.ToUtf8String();
- }
- else
- {
- // normalize empty spans to null if needed, otherwise normalize to Utf8String.Empty
-
- if ((_state.SplitOptions & Utf8StringSplitOptions.RemoveEmptyEntries) != 0
- || Unsafe.AreSame(ref span.DangerousGetMutableReference(), ref Unsafe.AsRef(null)))
- {
- return null;
- }
-
- return Empty;
- }
- }
- else
- {
- // Don't bother making a copy of the entire Utf8String instance;
- // just return the original value.
-
- return _state.FullSearchSpace;
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- [StructLayout(LayoutKind.Auto)]
- public struct Enumerator : IEnumerator
- {
- private const Utf8StringSplitOptions HALT_ENUMERATION = (Utf8StringSplitOptions)int.MinValue;
-
- private Utf8String? _current;
- private State _state;
-
- internal Enumerator(SplitResult result)
- {
- _current = null;
- _state = result._state; // copy by value
- }
-
- public Utf8String? Current => _current;
-
- public bool MoveNext()
- {
- bool wasMatchFound = _state.DeconstructHelper(_state.GetRemainingSearchSpace(), out Utf8Span firstItem, out Utf8Span remainder);
-
- _current = (firstItem.IsEmpty) ? Empty : (firstItem.Length == _state.FullSearchSpace.Length) ? _state.FullSearchSpace : firstItem.ToUtf8String();
- _state.OffsetAtWhichToContinueSearch = _state.FullSearchSpace.Length - remainder.Length;
-
- if (wasMatchFound)
- {
- return true;
- }
-
- // At this point, the search term was not found within the search space. '_current' contains the last
- // bit of data after the final occurrence of the search term. We'll also set a flag saying that we've
- // completed enumeration.
-
- if (firstItem.IsEmpty && (_state.SplitOptions & Utf8StringSplitOptions.RemoveEmptyEntries) != 0)
- {
- return false;
- }
-
- if ((_state.SplitOptions & HALT_ENUMERATION) != 0)
- {
- return false;
- }
-
- _state.SplitOptions |= HALT_ENUMERATION; // prevents yielding forever at end of split
-
- return true;
- }
-
- void IDisposable.Dispose()
- {
- // no-op
- }
-
- object? IEnumerator.Current => Current;
-
- void IEnumerator.Reset()
- {
- throw new NotSupportedException();
- }
- }
-
- [StructLayout(LayoutKind.Auto)]
- private struct State // fully mutable
- {
- internal Utf8String FullSearchSpace;
- internal int OffsetAtWhichToContinueSearch;
- internal int SearchRune; // -1 if not specified, takes less space than "Rune?"
- internal Utf8String? SearchTerm;
- internal Utf8StringSplitOptions SplitOptions;
-
- // Returns 'true' if a match was found, 'false' otherwise.
- internal readonly bool DeconstructHelper(in Utf8Span source, out Utf8Span firstItem, out Utf8Span remainder)
- {
- // n.b. Our callers might pass the same reference for 'source' and 'remainder'.
- // We need to take care not to read 'source' after writing 'remainder'.
-
- bool wasMatchFound;
- ref readonly Utf8Span searchSpan = ref source;
-
- while (true)
- {
- if (searchSpan.IsEmpty)
- {
- firstItem = searchSpan;
- remainder = default;
- wasMatchFound = false;
- break;
- }
-
- Range matchRange;
-
- int searchRune = SearchRune; // local copy so as to avoid struct tearing
- if (searchRune >= 0)
- {
-#if NETCOREAPP3_0
- wasMatchFound = searchSpan.TryFind(new Rune((uint)searchRune), out matchRange);
-#else
- wasMatchFound = searchSpan.TryFind(Rune.UnsafeCreate((uint)searchRune), out matchRange);
-#endif
- }
- else
- {
- wasMatchFound = searchSpan.TryFind(SearchTerm, out matchRange);
- }
-
- if (!wasMatchFound)
- {
- // If no match was found, we move 'source' to 'firstItem', trim if necessary, and return right away.
-
- firstItem = searchSpan;
-
- if ((SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- firstItem = firstItem.Trim();
- }
-
- remainder = default;
- }
- else
- {
- // Otherwise, if a match was found, split the result across 'firstItem' and 'remainder',
- // applying trimming if necessary.
-
- firstItem = searchSpan[..matchRange.Start]; // TODO_UTF8STRING: Could use unsafe slicing as optimization
- remainder = searchSpan[matchRange.End..]; // TODO_UTF8STRING: Could use unsafe slicing as optimization
-
- if ((SplitOptions & Utf8StringSplitOptions.TrimEntries) != 0)
- {
- firstItem = firstItem.Trim();
- }
-
- // If we're asked to remove empty entries, loop until there's a real value in 'firstItem'.
-
- if ((SplitOptions & Utf8StringSplitOptions.RemoveEmptyEntries) != 0 && firstItem.IsEmpty)
- {
- searchSpan = ref remainder;
- continue;
- }
- }
-
- break; // loop only if explicit 'continue' statement was hit
- }
-
- return wasMatchFound;
- }
-
- internal Utf8Span GetRemainingSearchSpace()
- {
- // TODO_UTF8STRING: The slice below can be optimized by performing a specialized bounds check
- // and multi-byte subsequence check, since we don't need to check the end of the span.
- // If we do optimize this we need to remember to make local copies of the fields we're reading
- // to guard against torn structs.
-
- return FullSearchSpace.AsSpanSkipNullCheck()[OffsetAtWhichToContinueSearch..];
- }
- }
- }
-
- [StructLayout(LayoutKind.Auto)]
- public readonly struct SplitOnResult
- {
- // Used when there is no match.
- internal SplitOnResult(Utf8String originalSearchSpace)
- {
- Before = originalSearchSpace;
- After = null;
- }
-
- // Used when a match is found.
- internal SplitOnResult(Utf8String originalSearchSpace, Range searchTermMatchRange)
- {
- (int startIndex, int length) = searchTermMatchRange.GetOffsetAndLength(originalSearchSpace.Length);
-
- // TODO_UTF8STRING: The below indexer performs correctness checks. We can skip these checks (and even the
- // bounds checks more generally) since we know the inputs are all valid and the containing struct is not
- // subject to tearing.
-
- Before = originalSearchSpace[..startIndex];
- After = originalSearchSpace[(startIndex + length)..];
- }
-
- public Utf8String? After { get; }
- public Utf8String Before { get; }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out Utf8String before, out Utf8String? after)
- {
- before = Before;
- after = After;
- }
- }
- }
-}
-
-#if !SYSTEM_PRIVATE_CORELIB
-namespace System.Diagnostics
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Struct, Inherited = false)]
- internal sealed class StackTraceHiddenAttribute : Attribute
- {
- public StackTraceHiddenAttribute() { }
- }
-}
-#endif
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Searching.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.Searching.cs
deleted file mode 100644
index 166d87d73f726..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.Searching.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Text;
-
-namespace System
-{
- public sealed partial class Utf8String
- {
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(char value, out Range range) => this.AsSpanSkipNullCheck().TryFind(value, out range);
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(char value, StringComparison comparisonType, out Range range) => this.AsSpanSkipNullCheck().TryFind(value, comparisonType, out range);
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(Rune value, out Range range) => this.AsSpanSkipNullCheck().TryFind(value, out range);
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(Rune value, StringComparison comparisonType, out Range range) => this.AsSpanSkipNullCheck().TryFind(value, comparisonType, out range);
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFind(Utf8String value, out Range range)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsSpanSkipNullCheck().TryFind(value, out range);
- }
-
- ///
- /// Attempts to locate the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFind(Utf8String value, StringComparison comparisonType, out Range range)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsSpanSkipNullCheck().TryFind(value, comparisonType, out range);
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(char value, out Range range) => this.AsSpanSkipNullCheck().TryFindLast(value, out range);
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(char value, StringComparison comparisonType, out Range range) => this.AsSpanSkipNullCheck().TryFindLast(value, comparisonType, out range);
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(Rune value, out Range range) => this.AsSpanSkipNullCheck().TryFindLast(value, out range);
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(Rune value, StringComparison comparisonType, out Range range) => this.AsSpanSkipNullCheck().TryFindLast(value, comparisonType, out range);
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// An ordinal search is performed.
- ///
- public bool TryFindLast(Utf8String value, out Range range)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsSpanSkipNullCheck().TryFindLast(value, out range);
- }
-
- ///
- /// Attempts to locate the last occurrence of the target within this instance.
- /// If is found, returns and sets to
- /// the location where occurs within this instance.
- /// If is not found, returns and sets
- /// to .
- ///
- ///
- /// The search is performed using the specified .
- ///
- public bool TryFindLast(Utf8String value, StringComparison comparisonType, out Range range)
- {
- if (value is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- return this.AsSpanSkipNullCheck().TryFindLast(value, comparisonType, out range);
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs
deleted file mode 100644
index 30b4cbd93dc6d..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs
+++ /dev/null
@@ -1,280 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Unicode;
-
-#if SYSTEM_PRIVATE_CORELIB
-using Internal.Runtime.CompilerServices;
-#endif
-
-namespace System
-{
- ///
- /// Represents an immutable string of UTF-8 code units.
- ///
- public sealed partial class Utf8String : IComparable, IEquatable
- {
- /*
- * STATIC FIELDS
- */
-
- public static readonly Utf8String Empty = FastAllocate(0);
-
- /*
- * OPERATORS
- */
-
- ///
- /// Compares two instances for equality using a comparer.
- ///
- public static bool operator ==(Utf8String? left, Utf8String? right) => Equals(left, right);
-
- ///
- /// Compares two instances for inequality using a comparer.
- ///
- public static bool operator !=(Utf8String? left, Utf8String? right) => !Equals(left, right);
-
- ///
- /// Projects a instance as a .
- ///
- ///
- public static implicit operator Utf8Span(Utf8String? value) => new Utf8Span(value);
-
- /*
- * INDEXERS
- */
-
- public Utf8String this[Range range]
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- // The two lines immediately below provide no bounds checking.
- // The Substring method we call will both perform a bounds check
- // and check for an improper split across a multi-byte subsequence.
-
- int startIdx = range.Start.GetOffset(Length);
- int endIdx = range.End.GetOffset(Length);
-
- return Substring(startIdx, endIdx - startIdx);
- }
- }
-
- /*
- * METHODS
- */
-
- ///
- /// Similar to , but skips the null check on the input.
- /// Throws a if the input is null.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal Utf8Span AsSpanSkipNullCheck()
- {
- return Utf8Span.UnsafeCreateWithoutValidation(this.AsBytesSkipNullCheck());
- }
-
- public int CompareTo(Utf8String? other)
- {
- // TODO_UTF8STRING: This is ordinal, but String.CompareTo uses CurrentCulture.
- // Is this acceptable? Should we perhaps just remove the interface?
-
- return Utf8StringComparer.Ordinal.Compare(this, other);
- }
-
- public int CompareTo(Utf8String? other, StringComparison comparison)
- {
- // TODO_UTF8STRING: We can avoid the virtual dispatch by moving the switch into this method.
-
- return Utf8StringComparer.FromComparison(comparison).Compare(this, other);
- }
-
- ///
- /// Returns a mutable reference to the element at index
- /// of this instance. The index is not bounds-checked.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference(int index)
- {
- Debug.Assert(index >= 0, "Caller should've performed bounds checking.");
- return ref DangerousGetMutableReference((uint)index);
- }
-
- ///
- /// Returns a mutable reference to the element at index
- /// of this instance. The index is not bounds-checked.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref byte DangerousGetMutableReference(nuint index)
- {
- // Allow retrieving references to the null terminator.
-
- Debug.Assert(index <= (uint)Length, "Caller should've performed bounds checking.");
-#if SYSTEM_PRIVATE_CORELIB
- return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), index);
-#else
- return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (nint)index);
-#endif
- }
-
- ///
- /// Performs an equality comparison using a comparer.
- ///
- public override bool Equals(object? obj)
- {
- return (obj is Utf8String other) && this.Equals(other);
- }
-
- ///
- /// Performs an equality comparison using a comparer.
- ///
- public bool Equals(Utf8String? value)
- {
- // First, a very quick check for referential equality.
-
- if (ReferenceEquals(this, value))
- {
- return true;
- }
-
- // Otherwise, perform a simple bitwise equality check.
-
- return !(value is null)
- && this.Length == value.Length
-#if SYSTEM_PRIVATE_CORELIB
- && SpanHelpers.SequenceEqual(ref this.DangerousGetMutableReference(), ref value.DangerousGetMutableReference(), (uint)Length);
-#else
- && this.GetSpan().SequenceEqual(value.GetSpan());
-#endif
- }
-
- ///
- /// Performs an equality comparison using the specified .
- ///
- public bool Equals(Utf8String? value, StringComparison comparison) => Equals(this, value, comparison);
-
- ///
- /// Compares two instances using a comparer.
- ///
- public static bool Equals(Utf8String? left, Utf8String? right)
- {
- // First, a very quick check for referential equality.
-
- if (ReferenceEquals(left, right))
- {
- return true;
- }
-
- // Otherwise, perform a simple bitwise equality check.
-
- return !(left is null)
- && !(right is null)
- && left.Length == right.Length
-#if SYSTEM_PRIVATE_CORELIB
- && SpanHelpers.SequenceEqual(ref left.DangerousGetMutableReference(), ref right.DangerousGetMutableReference(), (uint)left.Length);
-#else
- && left.GetSpan().SequenceEqual(right.GetSpan());
-#endif
- }
-
- ///
- /// Performs an equality comparison using the specified .
- ///
- public static bool Equals(Utf8String? a, Utf8String? b, StringComparison comparison)
- {
- // TODO_UTF8STRING: This perf can be improved, including removing
- // the virtual dispatch by putting the switch directly in this method.
-
- return Utf8StringComparer.FromComparison(comparison).Equals(a, b);
- }
-
- ///
- /// Returns a hash code using a comparison.
- ///
- public override int GetHashCode()
- {
- // TODO_UTF8STRING: Consider whether this should use a different seed than String.GetHashCode.
-
- ulong seed = Marvin.DefaultSeed;
-#if SYSTEM_PRIVATE_CORELIB
- return Marvin.ComputeHash32(ref DangerousGetMutableReference(), (uint)_length /* in bytes */, (uint)seed, (uint)(seed >> 32));
-#else
- return Marvin.ComputeHash32(_bytes, seed);
-#endif
- }
-
- ///
- /// Returns a hash code using the specified .
- ///
- public int GetHashCode(StringComparison comparison)
- {
- // TODO_UTF8STRING: This perf can be improved, including removing
- // the virtual dispatch by putting the switch directly in this method.
-
- return Utf8StringComparer.FromComparison(comparison).GetHashCode(this);
- }
-
- ///
- /// Returns if this UTF-8 text consists of all-ASCII data,
- /// if there is any non-ASCII data within this UTF-8 text.
- ///
- ///
- /// ASCII text is defined as text consisting only of scalar values in the range [ U+0000..U+007F ].
- /// Empty strings are considered to be all-ASCII. The runtime of this method is O(n).
- ///
- public bool IsAscii()
- {
- return this.AsSpan().IsAscii();
- }
-
- ///
- /// Returns if is or zero length;
- /// otherwise.
- ///
- public static bool IsNullOrEmpty([NotNullWhen(false)] Utf8String? value)
- {
- // Copied from String.IsNullOrEmpty. See that method for detailed comments on why this pattern is used.
- return (value is null || 0u >= (uint)value.Length) ? true : false;
- }
-
- public static bool IsNullOrWhiteSpace([NotNullWhen(false)] Utf8String? value)
- {
- return (value is null) || value.AsSpan().IsEmptyOrWhiteSpace();
- }
-
- ///
- /// Returns the entire as an array of UTF-8 bytes.
- ///
- public byte[] ToByteArray() => this.AsSpanSkipNullCheck().ToByteArray();
-
- ///
- /// Converts this instance to a .
- ///
- public override string ToString()
- {
- // TODO_UTF8STRING: Optimize the call below, potentially by avoiding the two-pass.
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- return Encoding.UTF8.GetString(this.AsBytesSkipNullCheck());
-#else
- if (Length == 0)
- {
- return string.Empty;
- }
-
- unsafe
- {
- fixed (byte* pBytes = this.AsBytesSkipNullCheck())
- {
- return Encoding.UTF8.GetString(pBytes, Length);
- }
- }
-#endif
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8StringSplitOptions.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8StringSplitOptions.cs
deleted file mode 100644
index 0a1426cfbaba4..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Utf8StringSplitOptions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System
-{
- // TODO_UTF8STRING: This should be removed and we should use regular StringSplitOptions
- // once a 'TrimEntries' flag gets added to the type.
-
- [Flags]
- public enum Utf8StringSplitOptions
- {
- None = 0,
- RemoveEmptyEntries = 1,
- TrimEntries = 2
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/Directory.Build.props b/src/libraries/System.Utf8String.Experimental/Directory.Build.props
deleted file mode 100644
index 1dce756f3e082..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/Directory.Build.props
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
- Open
-
-
\ No newline at end of file
diff --git a/src/libraries/System.Utf8String.Experimental/README.md b/src/libraries/System.Utf8String.Experimental/README.md
deleted file mode 100644
index c4e05f915d6d8..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-The `Utf8String` and `Char8` types are now available for experimentation. They currently exist in the package __System.Utf8String.Experimental__. Because this is an experimental package, it is unsupported for use in production workloads.
-
-To install:
-
-```ps
-install-package System.Utf8String.Experimental -prerelease -source https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
-```
-
-This package can only be installed into a project targeting a __nightly__ build of coreclr or libraries. Anything under the _master_ column of https://github.com/dotnet/core-sdk would work, as would any coreclr + libraries built from your own dev box (as long as you're building from _master_ instead of _release/..._). Installing this onto a project targeting an official Preview build would not work, as official Preview builds come from the _release_ branch.
-
-It's possible that installing the package might fail with an error similar to that seen below.
-
-```txt
-install-package : NU1605: Detected package downgrade: Microsoft.NETCore.Platforms from 3.0.0-preview6.19251.6 to 3.0.0-preview6.19223.2. Reference the package directly from the project to select a different version.
-```
-
-This can occur if the NuGet client attempts to install a newer version of the package than allowed by the .NET Runtime version your application is targeting. For now you can work around this error by specifying the explicit package version in the install command. Match the version passed to the NuGet client (shown below) to the version specified in the error message (shown above).
-
-```ps
-install-package System.Utf8String.Experimental -prerelease -source https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json -version 3.0.0-preview6.19223.2
-```
-
-Not all of the APIs are hooked up yet, but we have some preliminary APIs that allow experimentation with the feature, including basic creation and inspection of `Utf8String` instances, wrapping a `ReadOnlySpan` or a `ReadOnlyMemory` around a `Utf8String` instance, and passing a `Utf8String` instance through `HttpClient`. Full list of APIs available at https://github.com/dotnet/runtime/blob/master/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs.
-
-Certain language features also work as expected.
-
-```cs
-Utf8String s1 = new Utf8String(/* ... */);
-
-// range indexers work
-Utf8String s2 = s1[2..5];
-
-// as does pinning
-fixed (byte* pUtf8 = s1) { /* use 'pUtf8' here */ }
-
-// and allocating a GCHandle
-GCHandle handle = GCHandle.Alloc(s1, GCHandleType.Pinned);
-```
-
-For more information on the feature and API usage, see https://github.com/dotnet/corefxlab/issues/2350 and https://github.com/dotnet/runtime/issues/933.
diff --git a/src/libraries/System.Utf8String.Experimental/System.Utf8String.Experimental.sln b/src/libraries/System.Utf8String.Experimental/System.Utf8String.Experimental.sln
deleted file mode 100644
index 9a92feba4d1c6..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/System.Utf8String.Experimental.sln
+++ /dev/null
@@ -1,60 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27213.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Utf8String.Experimental.Tests", "tests\System.Utf8String.Experimental.Tests.csproj", "{72E9FB32-4692-4692-A10B-9F053F8F1A88}"
- ProjectSection(ProjectDependencies) = postProject
- {D4266847-6692-481B-9459-6141DB7DA339} = {D4266847-6692-481B-9459-6141DB7DA339}
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Utf8String.Experimental", "src\System.Utf8String.Experimental.csproj", "{D4266847-6692-481B-9459-6141DB7DA339}"
- ProjectSection(ProjectDependencies) = postProject
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0} = {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Utf8String.Experimental", "ref\System.Utf8String.Experimental.csproj", "{7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1A2F9F4A-A032-433E-B914-ADD5992BB178}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{911886E1-C0A6-4830-AAAE-BF320F644704}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {72E9FB32-4692-4692-A10B-9F053F8F1A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {72E9FB32-4692-4692-A10B-9F053F8F1A88}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {72E9FB32-4692-4692-A10B-9F053F8F1A88}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {72E9FB32-4692-4692-A10B-9F053F8F1A88}.Release|Any CPU.Build.0 = Release|Any CPU
- {D4266847-6692-481B-9459-6141DB7DA339}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D4266847-6692-481B-9459-6141DB7DA339}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D4266847-6692-481B-9459-6141DB7DA339}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D4266847-6692-481B-9459-6141DB7DA339}.Release|Any CPU.Build.0 = Release|Any CPU
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0}.Release|Any CPU.Build.0 = Release|Any CPU
- {911886E1-C0A6-4830-AAAE-BF320F644704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {911886E1-C0A6-4830-AAAE-BF320F644704}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {911886E1-C0A6-4830-AAAE-BF320F644704}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {911886E1-C0A6-4830-AAAE-BF320F644704}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {72E9FB32-4692-4692-A10B-9F053F8F1A88} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
- {D4266847-6692-481B-9459-6141DB7DA339} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
- {7AF57E6B-2CED-45C9-8BCA-5BBA60D018E0} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
- {911886E1-C0A6-4830-AAAE-BF320F644704} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {7196F6AB-8F22-4E4D-B6D1-3C2CFF86229C}
- EndGlobalSection
-EndGlobal
diff --git a/src/libraries/System.Utf8String.Experimental/pkg/System.Utf8String.Experimental.pkgproj b/src/libraries/System.Utf8String.Experimental/pkg/System.Utf8String.Experimental.pkgproj
deleted file mode 100644
index 5de0422cf63b3..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/pkg/System.Utf8String.Experimental.pkgproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
- net461;netcoreapp2.0;uap10.0.16299;$(AllXamarinFrameworks)
-
-
-
-
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs
deleted file mode 100644
index 5f1d14ec279de..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Forwards.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#if !NETSTANDARD2_0 && !NETFRAMEWORK
-[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Index))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Range))]
-
-#if !NETSTANDARD2_1
-[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Text.Rune))]
-#endif // !NETSTANDARD2_1
-
-#endif // !NETSTANDARD2_0
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Range.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Range.cs
deleted file mode 100644
index 7c4116944f7c4..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Range.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the https://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace System
-{
- public readonly partial struct Index : System.IEquatable
- {
- private readonly int _dummyPrimitive;
- public Index(int value, bool fromEnd = false) { throw null; }
- public static System.Index End { get { throw null; } }
- public bool IsFromEnd { get { throw null; } }
- public static System.Index Start { get { throw null; } }
- public int Value { get { throw null; } }
- public bool Equals(System.Index other) { throw null; }
- public override bool Equals(object? value) { throw null; }
- public static System.Index FromEnd(int value) { throw null; }
- public static System.Index FromStart(int value) { throw null; }
- public override int GetHashCode() { throw null; }
- public int GetOffset(int length) { throw null; }
- public static implicit operator System.Index(int value) { throw null; }
- public override string ToString() { throw null; }
- }
- public readonly partial struct Range : System.IEquatable
- {
- private readonly int _dummyPrimitive;
- public Range(System.Index start, System.Index end) { throw null; }
- public static System.Range All { get { throw null; } }
- public System.Index End { get { throw null; } }
- public System.Index Start { get { throw null; } }
- public static System.Range EndAt(System.Index end) { throw null; }
- public override bool Equals(object? value) { throw null; }
- public bool Equals(System.Range other) { throw null; }
- public override int GetHashCode() { throw null; }
- public (int Offset, int Length) GetOffsetAndLength(int length) { throw null; }
- public static System.Range StartAt(System.Index start) { throw null; }
- public override string ToString() { throw null; }
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs
deleted file mode 100644
index da7e4be0f2340..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the https://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace System.Text
-{
- public readonly partial struct Rune : System.IComparable, System.IComparable, System.IEquatable
- {
- private readonly int _dummyPrimitive;
- public Rune(char ch) { throw null; }
- public Rune(char highSurrogate, char lowSurrogate) { throw null; }
- public Rune(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public Rune(uint value) { throw null; }
- public bool IsAscii { get { throw null; } }
- public bool IsBmp { get { throw null; } }
- public int Plane { get { throw null; } }
- public static System.Text.Rune ReplacementChar { get { throw null; } }
- public int Utf16SequenceLength { get { throw null; } }
- public int Utf8SequenceLength { get { throw null; } }
- public int Value { get { throw null; } }
- public int CompareTo(System.Text.Rune other) { throw null; }
- public static System.Buffers.OperationStatus DecodeFromUtf16(System.ReadOnlySpan source, out System.Text.Rune result, out int charsConsumed) { throw null; }
- public static System.Buffers.OperationStatus DecodeFromUtf8(System.ReadOnlySpan source, out System.Text.Rune result, out int bytesConsumed) { throw null; }
- public static System.Buffers.OperationStatus DecodeLastFromUtf16(System.ReadOnlySpan source, out System.Text.Rune result, out int charsConsumed) { throw null; }
- public static System.Buffers.OperationStatus DecodeLastFromUtf8(System.ReadOnlySpan source, out System.Text.Rune value, out int bytesConsumed) { throw null; }
- public int EncodeToUtf16(System.Span destination) { throw null; }
- public int EncodeToUtf8(System.Span destination) { throw null; }
- public override bool Equals(object? obj) { throw null; }
- public bool Equals(System.Text.Rune other) { throw null; }
- public override int GetHashCode() { throw null; }
- public static double GetNumericValue(System.Text.Rune value) { throw null; }
- public static System.Text.Rune GetRuneAt(string input, int index) { throw null; }
- public static System.Globalization.UnicodeCategory GetUnicodeCategory(System.Text.Rune value) { throw null; }
- public static bool IsControl(System.Text.Rune value) { throw null; }
- public static bool IsDigit(System.Text.Rune value) { throw null; }
- public static bool IsLetter(System.Text.Rune value) { throw null; }
- public static bool IsLetterOrDigit(System.Text.Rune value) { throw null; }
- public static bool IsLower(System.Text.Rune value) { throw null; }
- public static bool IsNumber(System.Text.Rune value) { throw null; }
- public static bool IsPunctuation(System.Text.Rune value) { throw null; }
- public static bool IsSeparator(System.Text.Rune value) { throw null; }
- public static bool IsSymbol(System.Text.Rune value) { throw null; }
- public static bool IsUpper(System.Text.Rune value) { throw null; }
- public static bool IsValid(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool IsValid(uint value) { throw null; }
- public static bool IsWhiteSpace(System.Text.Rune value) { throw null; }
- public static bool operator ==(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static explicit operator System.Text.Rune(char ch) { throw null; }
- public static explicit operator System.Text.Rune(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator System.Text.Rune(uint value) { throw null; }
- public static bool operator >(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static bool operator >=(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static bool operator !=(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static bool operator <(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static bool operator <=(System.Text.Rune left, System.Text.Rune right) { throw null; }
- public static System.Text.Rune ToLower(System.Text.Rune value, System.Globalization.CultureInfo culture) { throw null; }
- public static System.Text.Rune ToLowerInvariant(System.Text.Rune value) { throw null; }
- public override string ToString() { throw null; }
- public static System.Text.Rune ToUpper(System.Text.Rune value, System.Globalization.CultureInfo culture) { throw null; }
- public static System.Text.Rune ToUpperInvariant(System.Text.Rune value) { throw null; }
- public static bool TryCreate(char highSurrogate, char lowSurrogate, out System.Text.Rune result) { throw null; }
- public static bool TryCreate(char ch, out System.Text.Rune result) { throw null; }
- public static bool TryCreate(int value, out System.Text.Rune result) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryCreate(uint value, out System.Text.Rune result) { throw null; }
- public bool TryEncodeToUtf16(System.Span destination, out int charsWritten) { throw null; }
- public bool TryEncodeToUtf8(System.Span destination, out int bytesWritten) { throw null; }
- public static bool TryGetRuneAt(string input, int index, out System.Text.Rune value) { throw null; }
- int IComparable.CompareTo(object? obj) { throw null; }
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs
deleted file mode 100644
index a72e76090dead..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.cs
+++ /dev/null
@@ -1,442 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the https://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace System
-{
- public readonly partial struct Char8 : System.IComparable, System.IEquatable
- {
- private readonly int _dummyPrimitive;
- public int CompareTo(System.Char8 other) { throw null; }
- public bool Equals(System.Char8 other) { throw null; }
- public override bool Equals(object? obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Char8 left, System.Char8 right) { throw null; }
- public static explicit operator System.Char8(char value) { throw null; }
- public static explicit operator char(System.Char8 value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator sbyte(System.Char8 value) { throw null; }
- public static explicit operator System.Char8(short value) { throw null; }
- public static explicit operator System.Char8(int value) { throw null; }
- public static explicit operator System.Char8(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator System.Char8(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator System.Char8(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator System.Char8(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator System.Char8(ulong value) { throw null; }
- public static bool operator >(System.Char8 left, System.Char8 right) { throw null; }
- public static bool operator >=(System.Char8 left, System.Char8 right) { throw null; }
- public static implicit operator System.Char8(byte value) { throw null; }
- public static implicit operator byte(System.Char8 value) { throw null; }
- public static implicit operator short(System.Char8 value) { throw null; }
- public static implicit operator int(System.Char8 value) { throw null; }
- public static implicit operator long(System.Char8 value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator ushort(System.Char8 value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator uint(System.Char8 value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator ulong(System.Char8 value) { throw null; }
- public static bool operator !=(System.Char8 left, System.Char8 right) { throw null; }
- public static bool operator <(System.Char8 left, System.Char8 right) { throw null; }
- public static bool operator <=(System.Char8 left, System.Char8 right) { throw null; }
- public override string ToString() { throw null; }
- }
- public static partial class Utf8Extensions
- {
- public static System.ReadOnlySpan AsBytes(this System.ReadOnlySpan text) { throw null; }
- public static System.ReadOnlySpan AsBytes(this System.Utf8String? text) { throw null; }
- public static System.ReadOnlySpan AsBytes(this System.Utf8String? text, int start) { throw null; }
- public static System.ReadOnlySpan AsBytes(this System.Utf8String? text, int start, int length) { throw null; }
- public static System.ReadOnlyMemory AsMemoryBytes(this System.Utf8String? text) { throw null; }
- public static System.ReadOnlyMemory AsMemoryBytes(this System.Utf8String? text, System.Index startIndex) { throw null; }
- public static System.ReadOnlyMemory AsMemoryBytes(this System.Utf8String? text, int start) { throw null; }
- public static System.ReadOnlyMemory AsMemoryBytes(this System.Utf8String? text, int start, int length) { throw null; }
- public static System.ReadOnlyMemory AsMemoryBytes(this System.Utf8String? text, System.Range range) { throw null; }
- public static System.Text.Utf8Span AsSpan(this System.Utf8String? text) { throw null; }
- public static System.Text.Utf8Span AsSpan(this System.Utf8String? text, int start) { throw null; }
- public static System.Text.Utf8Span AsSpan(this System.Utf8String? text, int start, int length) { throw null; }
- public static System.Utf8String ToUtf8String(this System.Text.Rune rune) { throw null; }
- }
- public sealed partial class Utf8String : System.IComparable, System.IEquatable
- {
- public static readonly System.Utf8String Empty;
- [System.CLSCompliantAttribute(false)]
- public unsafe Utf8String(byte* value) { }
- public Utf8String(byte[] value, int startIndex, int length) { }
- [System.CLSCompliantAttribute(false)]
- public unsafe Utf8String(char* value) { }
- public Utf8String(char[] value, int startIndex, int length) { }
- public Utf8String(System.ReadOnlySpan value) { }
- public Utf8String(System.ReadOnlySpan value) { }
- public Utf8String(string value) { }
- public ByteEnumerable Bytes { get { throw null; } }
- public CharEnumerable Chars { get { throw null; } }
- public int Length { get { throw null; } }
- public RuneEnumerable Runes { get { throw null; } }
- public static bool AreEquivalent(System.Utf8String? utf8Text, string? utf16Text) { throw null; }
- public static bool AreEquivalent(System.Text.Utf8Span utf8Text, System.ReadOnlySpan utf16Text) { throw null; }
- public static bool AreEquivalent(System.ReadOnlySpan utf8Text, System.ReadOnlySpan utf16Text) { throw null; }
- public int CompareTo(System.Utf8String? other) { throw null; }
- public int CompareTo(System.Utf8String? other, System.StringComparison comparison) { throw null; }
- public bool Contains(char value) { throw null; }
- public bool Contains(char value, System.StringComparison comparison) { throw null; }
- public bool Contains(System.Text.Rune value) { throw null; }
- public bool Contains(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool Contains(System.Utf8String value) { throw null; }
- public bool Contains(System.Utf8String value, System.StringComparison comparison) { throw null; }
-#if !NETSTANDARD2_0 && !NETFRAMEWORK
- public static System.Utf8String Create(int length, TState state, System.Buffers.SpanAction action) { throw null; }
-#endif
- public static System.Utf8String CreateFromRelaxed(System.ReadOnlySpan buffer) { throw null; }
- public static System.Utf8String CreateFromRelaxed(System.ReadOnlySpan buffer) { throw null; }
-#if !NETSTANDARD2_0 && !NETFRAMEWORK
- public static System.Utf8String CreateRelaxed(int length, TState state, System.Buffers.SpanAction action) { throw null; }
-#endif
- public bool EndsWith(char value) { throw null; }
- public bool EndsWith(char value, System.StringComparison comparison) { throw null; }
- public bool EndsWith(System.Text.Rune value) { throw null; }
- public bool EndsWith(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool EndsWith(System.Utf8String value) { throw null; }
- public bool EndsWith(System.Utf8String value, System.StringComparison comparison) { throw null; }
- public override bool Equals(object? obj) { throw null; }
- public static bool Equals(System.Utf8String? a, System.Utf8String? b, System.StringComparison comparison) { throw null; }
- public static bool Equals(System.Utf8String? left, System.Utf8String? right) { throw null; }
- public bool Equals(System.Utf8String? value) { throw null; }
- public bool Equals(System.Utf8String? value, System.StringComparison comparison) { throw null; }
- public override int GetHashCode() { throw null; }
- public int GetHashCode(System.StringComparison comparison) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public ref readonly byte GetPinnableReference() { throw null; }
- public static implicit operator System.Text.Utf8Span(System.Utf8String? value) { throw null; }
- public bool IsAscii() { throw null; }
- public bool IsNormalized(System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
- public static bool IsNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] System.Utf8String? value) { throw null; }
- public static bool IsNullOrWhiteSpace([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] System.Utf8String? value) { throw null; }
- public System.Utf8String Normalize(System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
- public static bool operator !=(System.Utf8String? left, System.Utf8String? right) { throw null; }
- public static bool operator ==(System.Utf8String? left, System.Utf8String? right) { throw null; }
- public SplitResult Split(char separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitResult Split(System.Text.Rune separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitResult Split(System.Utf8String separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitOnResult SplitOn(char separator) { throw null; }
- public SplitOnResult SplitOn(char separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOn(System.Text.Rune separator) { throw null; }
- public SplitOnResult SplitOn(System.Text.Rune separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOn(System.Utf8String separator) { throw null; }
- public SplitOnResult SplitOn(System.Utf8String separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(char separator) { throw null; }
- public SplitOnResult SplitOnLast(char separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Rune separator) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Rune separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(System.Utf8String separator) { throw null; }
- public SplitOnResult SplitOnLast(System.Utf8String separator, System.StringComparison comparisonType) { throw null; }
- public bool StartsWith(char value) { throw null; }
- public bool StartsWith(char value, System.StringComparison comparison) { throw null; }
- public bool StartsWith(System.Text.Rune value) { throw null; }
- public bool StartsWith(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool StartsWith(System.Utf8String value) { throw null; }
- public bool StartsWith(System.Utf8String value, System.StringComparison comparison) { throw null; }
- public System.Utf8String this[System.Range range] { get { throw null; } }
- public byte[] ToByteArray() { throw null; }
- public char[] ToCharArray() { throw null; }
- public System.Utf8String ToLower(System.Globalization.CultureInfo culture) { throw null; }
- public System.Utf8String ToLowerInvariant() { throw null; }
- public override string ToString() { throw null; }
- public System.Utf8String ToUpper(System.Globalization.CultureInfo culture) { throw null; }
- public System.Utf8String ToUpperInvariant() { throw null; }
- public System.Utf8String Trim() { throw null; }
- public System.Utf8String TrimEnd() { throw null; }
- public System.Utf8String TrimStart() { throw null; }
- public static bool TryCreateFrom(System.ReadOnlySpan buffer, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Utf8String? value) { throw null; }
- public static bool TryCreateFrom(System.ReadOnlySpan buffer, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Utf8String? value) { throw null; }
- public bool TryFind(char value, out System.Range range) { throw null; }
- public bool TryFind(char value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Rune value, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Rune value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFind(System.Utf8String value, out System.Range range) { throw null; }
- public bool TryFind(System.Utf8String value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(char value, out System.Range range) { throw null; }
- public bool TryFindLast(char value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Rune value, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Rune value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(System.Utf8String value, out System.Range range) { throw null; }
- public bool TryFindLast(System.Utf8String value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public static System.Utf8String UnsafeCreateWithoutValidation(System.ReadOnlySpan utf8Contents) { throw null; }
-#if !NETSTANDARD2_0 && !NETFRAMEWORK
- public static System.Utf8String UnsafeCreateWithoutValidation(int length, TState state, System.Buffers.SpanAction action) { throw null; }
-#endif
- public readonly partial struct ByteEnumerable : System.Collections.Generic.IEnumerable
- {
- private readonly object _dummy;
- public Enumerator GetEnumerator() { throw null; }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; }
- public struct Enumerator : System.Collections.Generic.IEnumerator
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public readonly byte Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- void System.IDisposable.Dispose() { }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
- public readonly partial struct CharEnumerable : System.Collections.Generic.IEnumerable
- {
- private readonly object _dummy;
- public Enumerator GetEnumerator() { throw null; }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; }
- public struct Enumerator : System.Collections.Generic.IEnumerator
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public char Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- void System.IDisposable.Dispose() { }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
- public readonly partial struct RuneEnumerable : System.Collections.Generic.IEnumerable
- {
- private readonly object _dummy;
- public Enumerator GetEnumerator() { throw null; }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; }
- public struct Enumerator : System.Collections.Generic.IEnumerator
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public System.Text.Rune Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- void System.IDisposable.Dispose() { }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
- public readonly struct SplitResult : System.Collections.Generic.IEnumerable
- {
- private readonly object _dummy;
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3, out System.Utf8String? item4) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3, out System.Utf8String? item4, out System.Utf8String? item5) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3, out System.Utf8String? item4, out System.Utf8String? item5, out System.Utf8String? item6) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3, out System.Utf8String? item4, out System.Utf8String? item5, out System.Utf8String? item6, out System.Utf8String? item7) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String? item1, out System.Utf8String? item2, out System.Utf8String? item3, out System.Utf8String? item4, out System.Utf8String? item5, out System.Utf8String? item6, out System.Utf8String? item7, out System.Utf8String? item8) { throw null; }
- public Enumerator GetEnumerator() { throw null; }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; }
- public struct Enumerator : System.Collections.Generic.IEnumerator
- {
- private readonly object _dummy;
- public System.Utf8String? Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- void System.IDisposable.Dispose() { }
- object? System.Collections.IEnumerator.Current { get { throw null; } }
- void System.Collections.IEnumerator.Reset() { throw null; }
- }
- }
- public readonly struct SplitOnResult
- {
- private readonly object _dummy;
- public System.Utf8String? After { get { throw null; } }
- public System.Utf8String Before { get { throw null; } }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Utf8String before, out System.Utf8String? after) { throw null; }
- }
- }
- [System.FlagsAttribute]
- public enum Utf8StringSplitOptions
- {
- None = 0,
- RemoveEmptyEntries = 1,
- TrimEntries = 2
- }
-}
-namespace System.Net.Http
-{
- public sealed partial class Utf8StringContent : System.Net.Http.HttpContent
- {
- public Utf8StringContent(System.Utf8String content) { }
- public Utf8StringContent(System.Utf8String content, string? mediaType) { }
- protected override System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; }
- protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; }
- protected override bool TryComputeLength(out long length) { throw null; }
- }
-}
-namespace System.Text
-{
- public readonly ref partial struct Utf8Span
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public Utf8Span(System.Utf8String? value) { throw null; }
- public System.ReadOnlySpan Bytes { get { throw null; } }
- public CharEnumerable Chars { get { throw null; } }
- public static System.Text.Utf8Span Empty { get { throw null; } }
- public bool IsEmpty { get { throw null; } }
- public int Length { get { throw null; } }
- public RuneEnumerable Runes { get { throw null; } }
- public int CompareTo(System.Text.Utf8Span other) { throw null; }
- public int CompareTo(System.Text.Utf8Span other, System.StringComparison comparison) { throw null; }
- public bool Contains(char value) { throw null; }
- public bool Contains(char value, System.StringComparison comparison) { throw null; }
- public bool Contains(System.Text.Rune value) { throw null; }
- public bool Contains(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool Contains(System.Text.Utf8Span value) { throw null; }
- public bool Contains(System.Text.Utf8Span value, System.StringComparison comparison) { throw null; }
- public bool EndsWith(char value) { throw null; }
- public bool EndsWith(char value, System.StringComparison comparison) { throw null; }
- public bool EndsWith(System.Text.Rune value) { throw null; }
- public bool EndsWith(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool EndsWith(System.Text.Utf8Span value) { throw null; }
- public bool EndsWith(System.Text.Utf8Span value, System.StringComparison comparison) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- [System.ObsoleteAttribute("Equals(object) on Utf8Span will always throw an exception. Use Equals(Utf8Span) or == instead.")]
- public override bool Equals(object? obj) { throw null; }
- public bool Equals(System.Text.Utf8Span other) { throw null; }
- public bool Equals(System.Text.Utf8Span other, System.StringComparison comparison) { throw null; }
- public static bool Equals(System.Text.Utf8Span left, System.Text.Utf8Span right) { throw null; }
- public static bool Equals(System.Text.Utf8Span left, System.Text.Utf8Span right, System.StringComparison comparison) { throw null; }
- public override int GetHashCode() { throw null; }
- public int GetHashCode(System.StringComparison comparison) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public ref readonly byte GetPinnableReference() { throw null; }
- public bool IsAscii() { throw null; }
- public bool IsEmptyOrWhiteSpace() { throw null; }
- public bool IsNormalized(System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
- public System.Utf8String Normalize(System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
- public int Normalize(System.Span destination, System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
- public static bool operator !=(System.Text.Utf8Span left, System.Text.Utf8Span right) { throw null; }
- public static bool operator ==(System.Text.Utf8Span left, System.Text.Utf8Span right) { throw null; }
- public System.Text.Utf8Span this[System.Range range] { get { throw null; } }
- public SplitResult Split(char separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitResult Split(System.Text.Rune separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitResult Split(System.Text.Utf8Span separator, System.Utf8StringSplitOptions options = System.Utf8StringSplitOptions.None) { throw null; }
- public SplitOnResult SplitOn(char separator) { throw null; }
- public SplitOnResult SplitOn(char separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOn(System.Text.Rune separator) { throw null; }
- public SplitOnResult SplitOn(System.Text.Rune separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOn(System.Text.Utf8Span separator) { throw null; }
- public SplitOnResult SplitOn(System.Text.Utf8Span separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(char separator) { throw null; }
- public SplitOnResult SplitOnLast(char separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Rune separator) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Rune separator, System.StringComparison comparisonType) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Utf8Span separator) { throw null; }
- public SplitOnResult SplitOnLast(System.Text.Utf8Span separator, System.StringComparison comparisonType) { throw null; }
- public bool StartsWith(char value) { throw null; }
- public bool StartsWith(char value, System.StringComparison comparison) { throw null; }
- public bool StartsWith(System.Text.Rune value) { throw null; }
- public bool StartsWith(System.Text.Rune value, System.StringComparison comparison) { throw null; }
- public bool StartsWith(System.Text.Utf8Span value) { throw null; }
- public bool StartsWith(System.Text.Utf8Span value, System.StringComparison comparison) { throw null; }
- public System.Text.Utf8Span Trim() { throw null; }
- public System.Text.Utf8Span TrimEnd() { throw null; }
- public System.Text.Utf8Span TrimStart() { throw null; }
- public byte[] ToByteArray() { throw null; }
- public char[] ToCharArray() { throw null; }
- public int ToChars(System.Span destination) { throw null; }
- public System.Utf8String ToLower(System.Globalization.CultureInfo culture) { throw null; }
- public int ToLower(System.Span destination, System.Globalization.CultureInfo culture) { throw null; }
- public System.Utf8String ToLowerInvariant() { throw null; }
- public int ToLowerInvariant(System.Span destination) { throw null; }
- public override string ToString() { throw null; }
- public System.Utf8String ToUpper(System.Globalization.CultureInfo culture) { throw null; }
- public int ToUpper(System.Span destination, System.Globalization.CultureInfo culture) { throw null; }
- public System.Utf8String ToUpperInvariant() { throw null; }
- public int ToUpperInvariant(System.Span destination) { throw null; }
- public System.Utf8String ToUtf8String() { throw null; }
- public bool TryFind(char value, out System.Range range) { throw null; }
- public bool TryFind(char value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Rune value, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Rune value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Utf8Span value, out System.Range range) { throw null; }
- public bool TryFind(System.Text.Utf8Span value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(char value, out System.Range range) { throw null; }
- public bool TryFindLast(char value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Rune value, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Rune value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Utf8Span value, out System.Range range) { throw null; }
- public bool TryFindLast(System.Text.Utf8Span value, System.StringComparison comparisonType, out System.Range range) { throw null; }
- public static System.Text.Utf8Span UnsafeCreateWithoutValidation(System.ReadOnlySpan buffer) { throw null; }
- public readonly ref struct CharEnumerable
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public Enumerator GetEnumerator() { throw null; }
- public ref struct Enumerator
- {
- private object _dummy;
- private int _dummyPrimitive;
- public char Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- }
- }
- public readonly ref struct RuneEnumerable
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public Enumerator GetEnumerator() { throw null; }
- public ref struct Enumerator
- {
- private object _dummy;
- private int _dummyPrimitive;
- public System.Text.Rune Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- }
- }
- public readonly ref struct SplitResult
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3, out System.Text.Utf8Span item4) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3, out System.Text.Utf8Span item4, out System.Text.Utf8Span item5) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3, out System.Text.Utf8Span item4, out System.Text.Utf8Span item5, out System.Text.Utf8Span item6) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3, out System.Text.Utf8Span item4, out System.Text.Utf8Span item5, out System.Text.Utf8Span item6, out System.Text.Utf8Span item7) { throw null; }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span item1, out System.Text.Utf8Span item2, out System.Text.Utf8Span item3, out System.Text.Utf8Span item4, out System.Text.Utf8Span item5, out System.Text.Utf8Span item6, out System.Text.Utf8Span item7, out System.Text.Utf8Span item8) { throw null; }
- public Enumerator GetEnumerator() { throw null; }
- public ref struct Enumerator
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public System.Text.Utf8Span Current { get { throw null; } }
- public bool MoveNext() { throw null; }
- }
- }
- public readonly ref struct SplitOnResult
- {
- private readonly object _dummy;
- private readonly int _dummyPrimitive;
- public Utf8Span After { get { throw null; } }
- public Utf8Span Before { get { throw null; } }
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- public void Deconstruct(out System.Text.Utf8Span before, out System.Text.Utf8Span after) { throw null; }
- }
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj
deleted file mode 100644
index eb5a1414f8cdf..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- true
-
- $(NoWarn);0809;0618
- netstandard2.0;netstandard2.1;netcoreapp3.0;$(NetCoreAppCurrent);net461
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.net5.0.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.net5.0.cs
deleted file mode 100644
index 85f2598f8de55..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.net5.0.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the https://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace System
-{
- public static partial class Utf8Extensions
- {
- public static System.ReadOnlyMemory AsMemory(this System.Utf8String? text) { throw null; }
- public static System.ReadOnlyMemory AsMemory(this System.Utf8String? text, System.Index startIndex) { throw null; }
- public static System.ReadOnlyMemory AsMemory(this System.Utf8String? text, int start) { throw null; }
- public static System.ReadOnlyMemory AsMemory(this System.Utf8String? text, int start, int length) { throw null; }
- public static System.ReadOnlyMemory AsMemory(this System.Utf8String? text, System.Range range) { throw null; }
- }
-}
-namespace System.Net.Http
-{
- public sealed partial class Utf8StringContent : System.Net.Http.HttpContent
- {
- protected override System.IO.Stream CreateContentReadStream(System.Threading.CancellationToken cancellationToken) { throw null; }
- protected override void SerializeToStream(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { }
- protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; }
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx b/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx
deleted file mode 100644
index 3d5159021118a..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Index was out of range. Must be non-negative and less than the size of the collection.
-
-
- Non-negative number required.
-
-
- UTF-16 surrogate code points (U+D800..U+DFFF) are disallowed.
-
-
- Argument cannot be an empty span.
-
-
- Argument cannot be null or empty.
-
-
- Cannot extract a Unicode scalar value from the specified index in the input.
-
-
- Destination is too short.
-
-
- Illegal enum value: {0}.
-
-
- The string must be null-terminated.
-
-
- The string comparison type passed in is currently not supported.
-
-
- Cannot call Utf8Span.Equals(object). Use Equals(Utf8Span) or operator == instead.
-
-
- UTF-8 searching only supports StringComparison Ordinal and OrdinalIgnoreCase on this platform.
-
-
- The callback populated its buffer with ill-formed UTF-8 data. Callbacks are required to populate the buffer only with well-formed UTF-8 data.
-
-
- Cannot create the desired substring because it would split a multi-byte UTF-8 subsequence.
-
-
- The input buffer contained ill-formed UTF-16 data.
-
-
- The input buffer contained ill-formed UTF-8 data.
-
-
- Object must be of type Rune.
-
-
\ No newline at end of file
diff --git a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj b/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj
deleted file mode 100644
index 8b72b9161c557..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj
+++ /dev/null
@@ -1,154 +0,0 @@
-
-
- true
- $(NetCoreAppCurrent);netstandard2.0;netstandard2.1;netcoreapp3.0;net461
- enable
- $(DefineContants);FEATURE_UTF8STRING
-
-
-
-
-
- $(NoWarn);CS3019;CS0162
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Utf8String.Experimental/src/System/Globalization/GlobalizationMode.cs
deleted file mode 100644
index a59114c85bff0..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System/Globalization/GlobalizationMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Globalization
-{
- internal static partial class GlobalizationMode
- {
- internal static bool Invariant { get; } // TODO: should we enable this?
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/src/System/IO/Utf8StringStream.cs b/src/libraries/System.Utf8String.Experimental/src/System/IO/Utf8StringStream.cs
deleted file mode 100644
index d448a7cc1b909..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System/IO/Utf8StringStream.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.IO
-{
- internal sealed class Utf8StringStream : Stream
- {
- private readonly Utf8String _content;
- private int _position;
-
- public Utf8StringStream(Utf8String content)
- {
- _content = content ?? Utf8String.Empty;
- }
-
- public override bool CanRead => true;
-
- public override bool CanSeek => true;
-
- public override bool CanTimeout => true;
-
- public override bool CanWrite => false;
-
- public override long Length => _content.Length;
-
- public override long Position
- {
- get => _position;
- set
- {
- if ((ulong)value > (uint)_content.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(value));
- }
-
- _position = (int)value;
- }
- }
-
- public override void Flush()
- {
- /* no-op */
- }
-
- public override Task FlushAsync(CancellationToken cancellationToken)
- {
- /* no-op */
- return Task.CompletedTask;
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return Read(new Span(buffer, offset, count));
- }
-
- public
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- override
-#endif
- int Read(Span buffer)
- {
- ReadOnlySpan contentToWrite = _content.AsBytes(_position);
- if (buffer.Length < contentToWrite.Length)
- {
- contentToWrite = contentToWrite.Slice(buffer.Length);
- }
-
- contentToWrite.CopyTo(buffer);
- _position += contentToWrite.Length;
-
- return contentToWrite.Length;
- }
-
- public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- return Task.FromResult(Read(new Span(buffer, offset, count)));
- }
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default)
- {
- return new ValueTask(Read(buffer.Span));
- }
-#endif
-
- public override int ReadByte()
- {
- int position = _position;
- if ((uint)position >= (uint)_content.Length)
- {
- return -1;
- }
-
- _position++;
- return _content.AsBytes()[position];
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- switch (origin)
- {
- case SeekOrigin.Begin:
- break;
- case SeekOrigin.Current:
- offset += _position;
- break;
- case SeekOrigin.End:
- offset += _content.Length;
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(origin));
- }
-
- if ((ulong)offset > (uint)_content.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(offset));
- }
-
- _position = (int)offset;
- return offset;
- }
-
- public override void SetLength(long value) => throw new NotSupportedException();
-
- public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- public override void Write(ReadOnlySpan buffer) => throw new NotSupportedException();
-#endif
-
- public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => throw new NotSupportedException();
-
-#if (!NETSTANDARD2_0 && !NETFRAMEWORK)
- public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => throw new NotSupportedException();
-#endif
- public override void WriteByte(byte value) => throw new NotSupportedException();
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.cs b/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.cs
deleted file mode 100644
index f5fc6a1f843b4..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.IO;
-using System.Net.Http.Headers;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.Http
-{
- public sealed partial class Utf8StringContent : HttpContent
- {
- private const string DefaultMediaType = "text/plain";
-
- private readonly Utf8String _content;
-
- public Utf8StringContent(Utf8String content)
- : this(content, mediaType: null)
- {
- }
-
- public Utf8StringContent(Utf8String content, string? mediaType)
- {
- if (content is null)
- {
- throw new ArgumentNullException(nameof(content));
- }
-
- _content = content;
-
- // Initialize the 'Content-Type' header with information provided by parameters.
-
- Headers.ContentType = new MediaTypeHeaderValue(mediaType ?? DefaultMediaType)
- {
- CharSet = "utf-8" // Encoding.UTF8.WebName
- };
- }
-
- protected override Task CreateContentReadStreamAsync() =>
- Task.FromResult(new Utf8StringStream(_content));
-
-#if (NETSTANDARD2_0 || NETFRAMEWORK)
- protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context)
- {
- ReadOnlyMemory buffer = _content.AsMemoryBytes();
- if (MemoryMarshal.TryGetArray(buffer, out ArraySegment array))
- {
- await stream.WriteAsync(array.Array, array.Offset, array.Count).ConfigureAwait(false);
- }
- else
- {
- byte[] localBuffer = ArrayPool.Shared.Rent(buffer.Length);
- buffer.Span.CopyTo(localBuffer);
-
- await stream.WriteAsync(localBuffer, 0, buffer.Length).ConfigureAwait(false);
-
- ArrayPool.Shared.Return(localBuffer);
- }
- }
-#elif NETSTANDARD2_1 || NETCOREAPP3_0
- protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) =>
- stream.WriteAsync(_content.AsMemoryBytes()).AsTask();
-#else
- protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) =>
- SerializeToStreamAsync(stream, context, default);
-
- protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) =>
- stream.WriteAsync(_content.AsMemoryBytes(), cancellationToken).AsTask();
-#endif
-
- protected override bool TryComputeLength(out long length)
- {
- length = _content.Length;
- return true;
- }
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.netcoreapp.cs b/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.netcoreapp.cs
deleted file mode 100644
index 15eba26150941..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System/Net/Http/Utf8StringContent.netcoreapp.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.IO;
-using System.Net.Http.Headers;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.Http
-{
- public sealed partial class Utf8StringContent
- {
- protected override Stream CreateContentReadStream(CancellationToken cancellationToken) =>
- new Utf8StringStream(_content);
-
- protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) =>
- stream.Write(_content.AsBytes());
- }
-}
diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs
deleted file mode 100644
index ff020e0259cfd..0000000000000
--- a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Runtime.Intrinsics
-{
- internal static class Vector64
- {
- public static Vector64 Create(ulong value) => throw new PlatformNotSupportedException();
- public static Vector64 CreateScalar(uint value) => throw new PlatformNotSupportedException();
- public static Vector64 AsByte(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException();
- public static Vector64 AsUInt32(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException();
- public static Vector64 GetLower(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException();
- public static Vector64 AsUInt64(this Vector64