// Jeffrey Stedfast (fejj@ximian.com)
// Dan Lewis (dihlewis@yahoo.co.uk)
// Sebastien Pouliot <sebastien@ximian.com>
+// Marek Safar (marek.safar@seznam.cz)
//
// (C) 2001 Ximian, Inc. http://www.ximian.com
// Copyright (C) 2004-2005 Novell (http://www.novell.com)
using System.Runtime.CompilerServices;
#if NET_2_0
+using System.Collections.Generic;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
+using Mono.Globalization.Unicode;
#endif
namespace System
[Serializable]
#if NET_2_0
[ComVisible (true)]
- public sealed class String : IConvertible, ICloneable, IEnumerable, IComparable, IComparable<String>, IEquatable <String>
+ public sealed class String : IConvertible, ICloneable, IEnumerable, IComparable, IComparable<String>, IEquatable <String>, IEnumerable<char>
#else
public sealed class String : IConvertible, ICloneable, IEnumerable, IComparable
#endif
if (count == 1)
return new String[1] { ToString() };
- return InternalSplit (separator, count);
+ return InternalSplit (separator, count, 0);
}
#if NET_2_0
[ComVisible (false)]
- [MonoTODO]
+ [MonoDocumentationNote ("code should be moved to managed")]
public String[] Split (char[] separator, int count, StringSplitOptions options)
{
if (separator == null || separator.Length == 0)
if ((options != StringSplitOptions.None) && (options != StringSplitOptions.RemoveEmptyEntries))
throw new ArgumentException ("options must be one of the values in the StringSplitOptions enumeration", "options");
- bool removeEmpty = (options & StringSplitOptions.RemoveEmptyEntries) == StringSplitOptions.RemoveEmptyEntries;
+ if (count == 0)
+ return new string [0];
- if (!removeEmpty)
- return Split (separator, count);
- else {
- /* FIXME: Optimize this */
- String[] res = Split (separator, count);
- int n = 0;
- for (int i = 0; i < res.Length; ++i)
- if (res [i] == String.Empty)
- n ++;
- if (n > 0) {
- String[] arr = new String [res.Length - n];
- int pos = 0;
- for (int i = 0; i < res.Length; ++i)
- if (res [i] != String.Empty)
- arr [pos ++] = res [i];
- return arr;
- }
- else
- return res;
- }
+ return InternalSplit (separator, count, (int)options);
}
[ComVisible (false)]
public unsafe String Substring (int startIndex)
{
+ if (startIndex == 0)
+ return this;
+
if (startIndex < 0 || startIndex > this.length)
throw new ArgumentOutOfRangeException ("startIndex");
return Compare (this, strB, false);
}
- public static int CompareOrdinal (String strA, String strB)
+ public static unsafe int CompareOrdinal (String strA, String strB)
{
- return CompareOrdinal (strA, strB, CompareOptions.Ordinal);
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null) {
+ return 1;
+ }
+ fixed (char* aptr = strA, bptr = strB) {
+ char* ap = aptr;
+ char* end = ap + Math.Min (strA.Length, strB.Length);
+ char* bp = bptr;
+ while (ap < end) {
+ if (*ap != *bp)
+ return *ap - *bp;
+ ap++;
+ bp++;
+ }
+ return strA.Length - strB.Length;
+ }
}
internal static int CompareOrdinal (String strA, String strB, CompareOptions options)
return 0;
else
return -1;
- }
- else if (strB == null) {
+ } else if (strB == null) {
return 1;
}
{
if (anyOf == null)
throw new ArgumentNullException ("anyOf");
+ if (this.length == 0)
+ return -1;
return InternalIndexOfAny (anyOf, 0, this.length);
}
return InternalIndexOfAny (anyOf, startIndex, count);
}
+ unsafe int InternalIndexOfAny (char[] anyOf, int startIndex, int count)
+ {
+ if (anyOf.Length == 0)
+ return -1;
+
+ if (anyOf.Length == 1)
+ return IndexOfImpl(anyOf[0], startIndex, count);
+
+ fixed (char* any = anyOf) {
+ int highest = *any;
+ int lowest = *any;
+
+ char* end_any_ptr = any + anyOf.Length;
+ char* any_ptr = any;
+ while (++any_ptr != end_any_ptr) {
+ if (*any_ptr > highest) {
+ highest = *any_ptr;
+ continue;
+ }
+
+ if (*any_ptr < lowest)
+ lowest = *any_ptr;
+ }
+
+ fixed (char* start = &start_char) {
+ char* ptr = start + startIndex;
+ char* end_ptr = ptr + count;
+
+ while (ptr != end_ptr) {
+ if (*ptr > highest || *ptr < lowest) {
+ ptr++;
+ continue;
+ }
+
+ if (*ptr == *any)
+ return (int)(ptr - start);
+
+ any_ptr = any;
+ while (++any_ptr != end_any_ptr) {
+ if (*ptr == *any_ptr)
+ return (int)(ptr - start);
+ }
+
+ ptr++;
+ }
+ }
+ }
+ return -1;
+ }
+
+
+#if NET_2_0
+ public int IndexOf (string value, StringComparison comparison)
+ {
+ return IndexOf (value, 0, this.Length, comparison);
+ }
+
+ public int IndexOf (string value, int startIndex, StringComparison comparison)
+ {
+ return IndexOf (value, startIndex, this.Length - startIndex, comparison);
+ }
+
+ public int IndexOf (string value, int startIndex, int count, StringComparison comparison)
+ {
+ switch (comparison) {
+ case StringComparison.CurrentCulture:
+ return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.None);
+ case StringComparison.CurrentCultureIgnoreCase:
+ return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.IgnoreCase);
+ case StringComparison.InvariantCulture:
+ return CultureInfo.InvariantCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.None);
+ case StringComparison.InvariantCultureIgnoreCase:
+ return CultureInfo.InvariantCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.IgnoreCase);
+ case StringComparison.Ordinal:
+ return CultureInfo.InvariantCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.Ordinal);
+ case StringComparison.OrdinalIgnoreCase:
+ return CultureInfo.InvariantCulture.CompareInfo.IndexOf (this, value, startIndex, count, CompareOptions.OrdinalIgnoreCase);
+ }
+ throw new SystemException ("INTERNAL ERROR: should not reach here ...");
+ }
+
+ public int LastIndexOf (string value, StringComparison comparison)
+ {
+ return LastIndexOf (value, value.Length - 1, value.Length, comparison);
+ }
+
+ public int LastIndexOf (string value, int startIndex, StringComparison comparison)
+ {
+ return LastIndexOf (value, startIndex, startIndex + 1, comparison);
+ }
+
+ public int LastIndexOf (string value, int startIndex, int count, StringComparison comparison)
+ {
+ switch (comparison) {
+ case StringComparison.CurrentCulture:
+ return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.None);
+ case StringComparison.CurrentCultureIgnoreCase:
+ return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.IgnoreCase);
+ case StringComparison.InvariantCulture:
+ return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.None);
+ case StringComparison.InvariantCultureIgnoreCase:
+ return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.IgnoreCase);
+ case StringComparison.Ordinal:
+ return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.Ordinal);
+ case StringComparison.OrdinalIgnoreCase:
+ return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.OrdinalIgnoreCase);
+ }
+ throw new SystemException ("INTERNAL ERROR: should not reach here ...");
+ }
+#endif
+
public int IndexOf (char value)
{
- return IndexOf (value, 0, this.length);
+ if (this.length == 0)
+ return -1;
+
+ return IndexOfImpl (value, 0, this.length);
}
public int IndexOf (String value)
if ((startIndex == 0 && this.length == 0) || (startIndex == this.length) || (count == 0))
return -1;
- for (int pos = startIndex; pos < startIndex + count; pos++) {
- if (this[pos] == value)
- return(pos);
+ return IndexOfImpl (value, startIndex, count);
+ }
+
+ unsafe int IndexOfImpl (char value, int startIndex, int count)
+ {
+ // It helps JIT compiler to optimize comparison
+ int value_32 = (int)value;
+
+ fixed (char* start = &start_char) {
+ char* ptr = start + startIndex;
+ char* end_ptr = ptr + (count >> 3 << 3);
+
+ while (ptr != end_ptr) {
+ if (*ptr == value_32)
+ return (int)(ptr - start);
+ if (ptr[1] == value_32)
+ return (int)(ptr - start + 1);
+ if (ptr[2] == value_32)
+ return (int)(ptr - start + 2);
+ if (ptr[3] == value_32)
+ return (int)(ptr - start + 3);
+ if (ptr[4] == value_32)
+ return (int)(ptr - start + 4);
+ if (ptr[5] == value_32)
+ return (int)(ptr - start + 5);
+ if (ptr[6] == value_32)
+ return (int)(ptr - start + 6);
+ if (ptr[7] == value_32)
+ return (int)(ptr - start + 7);
+
+ ptr += 8;
+ }
+
+ end_ptr += count & 0x07;
+ while (ptr != end_ptr) {
+ if (*ptr == value_32)
+ return (int)(ptr - start);
+
+ ptr++;
+ }
+ return -1;
}
- return -1;
}
/* But this one is culture-sensitive */
{
if (this.length == 0)
return -1;
- else
- return LastIndexOf (value, this.length - 1, this.length);
+
+ return LastIndexOfImpl (value, this.length - 1, this.length);
}
public int LastIndexOf (String value)
if (startIndex - count + 1 < 0)
throw new ArgumentOutOfRangeException ("startIndex - count + 1 < 0");
- for(int pos = startIndex; pos > startIndex - count; pos--) {
- if (this [pos] == value)
- return pos;
+ return LastIndexOfImpl (value, startIndex, count);
+ }
+
+ /* This method is culture-insensitive */
+ unsafe int LastIndexOfImpl (char value, int startIndex, int count)
+ {
+ // It helps JIT compiler to optimize comparison
+ int value_32 = (int)value;
+
+ fixed (char* start = &start_char) {
+ char* ptr = start + startIndex;
+ char* end_ptr = ptr - (count >> 3 << 3);
+
+ while (ptr != end_ptr) {
+ if (*ptr == value_32)
+ return (int)(ptr - start);
+ if (ptr[-1] == value_32)
+ return (int)(ptr - start) - 1;
+ if (ptr[-2] == value_32)
+ return (int)(ptr - start) - 2;
+ if (ptr[-3] == value_32)
+ return (int)(ptr - start) - 3;
+ if (ptr[-4] == value_32)
+ return (int)(ptr - start) - 4;
+ if (ptr[-5] == value_32)
+ return (int)(ptr - start) - 5;
+ if (ptr[-6] == value_32)
+ return (int)(ptr - start) - 6;
+ if (ptr[-7] == value_32)
+ return (int)(ptr - start) - 7;
+
+ ptr -= 8;
+ }
+
+ end_ptr -= count & 0x07;
+ while (ptr != end_ptr) {
+ if (*ptr == value_32)
+ return (int)(ptr - start);
+
+ ptr--;
+ }
+ return -1;
}
- return -1;
}
/* But this one is culture-sensitive */
throw new ArgumentOutOfRangeException ("startIndex - count + 1 < 0");
if (value.Length == 0)
- return 0;
+ return startIndex;
if (startIndex == 0 && this.length == 0)
return -1;
return (value == null) || (value.Length == 0);
}
+ public string Normalize ()
+ {
+ return Normalize (NormalizationForm.FormC);
+ }
+
+ public string Normalize (NormalizationForm form)
+ {
+ switch (form) {
+ default:
+ return Normalization.Normalize (this, 0);
+ case NormalizationForm.FormD:
+ return Normalization.Normalize (this, 1);
+ case NormalizationForm.FormKC:
+ return Normalization.Normalize (this, 2);
+ case NormalizationForm.FormKD:
+ return Normalization.Normalize (this, 3);
+ }
+ }
+
+ public bool IsNormalized ()
+ {
+ return IsNormalized (NormalizationForm.FormC);
+ }
+
+ public bool IsNormalized (NormalizationForm form)
+ {
+ switch (form) {
+ default:
+ return Normalization.IsNormalized (this, 0);
+ case NormalizationForm.FormD:
+ return Normalization.IsNormalized (this, 1);
+ case NormalizationForm.FormKC:
+ return Normalization.IsNormalized (this, 2);
+ case NormalizationForm.FormKD:
+ return Normalization.IsNormalized (this, 3);
+ }
+ }
+
public string Remove (int startIndex)
{
if (startIndex < 0)
}
#if NET_2_0
+ [ComVisible (false)]
public bool StartsWith (string value, StringComparison comparisonType)
{
switch (comparisonType) {
}
}
+ [ComVisible (false)]
public bool EndsWith (string value, StringComparison comparisonType)
{
switch (comparisonType) {
#endif
bool StartsWith (String value, bool ignoreCase, CultureInfo culture)
{
+ if (culture == null)
+ culture = CultureInfo.CurrentCulture;
+
return (culture.CompareInfo.IsPrefix (this, value,
ignoreCase ? CompareOptions.IgnoreCase :
CompareOptions.None));
}
/* This method is culture insensitive */
- public String Replace (char oldChar, char newChar)
+ public unsafe String Replace (char oldChar, char newChar)
{
- return InternalReplace (oldChar, newChar);
+ if (this.length == 0 || oldChar == newChar)
+ return this;
+
+ int start_pos = IndexOfImpl (oldChar, 0, this.length);
+ if (start_pos == -1)
+ return this;
+
+ if (start_pos < 4)
+ start_pos = 0;
+
+ string tmp = InternalAllocateStr(length);
+ fixed (char* dest = tmp, src = &start_char) {
+ if (start_pos != 0)
+ memcpy((byte*)dest, (byte*)src, start_pos * 2);
+
+ char* end_ptr = dest + length;
+ char* dest_ptr = dest + start_pos;
+ char* src_ptr = src + start_pos;
+
+ while (dest_ptr != end_ptr) {
+ if (*src_ptr == oldChar)
+ *dest_ptr = newChar;
+ else
+ *dest_ptr = *src_ptr;
+
+ ++src_ptr;
+ ++dest_ptr;
+ }
+ }
+ return tmp;
}
/* This method is culture sensitive */
formatter = provider.GetFormat (typeof (ICustomFormatter))
as ICustomFormatter;
if (arg == null)
- str = "";
+ str = String.Empty;
else if (formatter != null)
str = formatter.Format (arg_format, arg, provider);
else if (arg is IFormattable)
public unsafe static String Concat (String s1, String s2)
{
- if (s1 == null) {
- if (s2 == null)
+ if (s1 == null || s1.Length == 0) {
+ if (s2 == null || s2.Length == 0)
return String.Empty;
return s2;
}
- if (s2 == null)
+ if (s2 == null || s2.Length == 0)
return s1;
String tmp = InternalAllocateStr (s1.length + s2.length);
public unsafe static String Concat (String s1, String s2, String s3)
{
- if (s1 == null){
- if (s2 == null){
- if (s3 == null)
+ if (s1 == null || s1.Length == 0){
+ if (s2 == null || s2.Length == 0){
+ if (s3 == null || s3.Length == 0)
return String.Empty;
return s3;
} else {
- if (s3 == null)
+ if (s3 == null || s3.Length == 0)
return s2;
}
s1 = String.Empty;
} else {
- if (s2 == null){
- if (s3 == null)
+ if (s2 == null || s2.Length == 0){
+ if (s3 == null || s3.Length == 0)
return s1;
else
s2 = String.Empty;
} else {
- if (s3 == null)
+ if (s3 == null || s3.Length == 0)
s3 = String.Empty;
}
}
return Convert.ToSingle (this, provider);
}
- string IConvertible.ToString (IFormatProvider format)
- {
- return this;
- }
-
object IConvertible.ToType (Type conversionType, IFormatProvider provider)
{
return Convert.ToType (this, conversionType, provider);
return Convert.ToUInt64 (this, provider);
}
- TypeCode IConvertible.GetTypeCode ()
- {
- return TypeCode.String;
- }
-
public int Length {
get {
return length;
return new CharEnumerator (this);
}
+#if NET_2_0
+ IEnumerator<char> IEnumerable<char>.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+#endif
+
IEnumerator IEnumerable.GetEnumerator ()
{
return new CharEnumerator (this);
else {
width = 0;
left_align = false;
- format = "";
+ format = String.Empty;
}
// F = argument format (string)
if (newLength > length)
throw new ArgumentOutOfRangeException ("newLength", "newLength as to be <= length");
- length = newLength;
-
// zero terminate, we can pass string objects directly via pinvoke
+ // we also zero the rest of the string, since the new GC needs to be
+ // able to handle the changing size (it will skip the 0 bytes).
fixed (char * pStr = &start_char) {
- pStr [length] = '\0';
+ char *p = pStr + newLength;
+ char *end = pStr + length;
+ while (p < end) {
+ p [0] = '\0';
+ p++;
+ }
}
+ length = newLength;
}
#if NET_2_0
[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
+ // When modifying it, GetCaseInsensitiveHashCode() should be modified as well.
public unsafe override int GetHashCode ()
{
fixed (char * c = this) {
}
}
+ internal unsafe int GetCaseInsensitiveHashCode ()
+ {
+ TextInfo ti = CultureInfo.InvariantCulture.TextInfo;
+ fixed (char * c = this) {
+ char * cc = c;
+ char * end = cc + length - 1;
+ int h = 0;
+ for (;cc < end; cc += 2) {
+ h = (h << 5) - h + ti.ToUpper (*cc);
+ h = (h << 5) - h + ti.ToUpper (cc [1]);
+ }
+ ++end;
+ if (cc < end)
+ h = (h << 5) - h + ti.ToUpper (*cc);
+ return h;
+ }
+ }
+
+ // Certain constructors are redirected to CreateString methods with
+ // matching argument list. The this pointer should not be used.
+
+ private unsafe String CreateString (sbyte* value)
+ {
+ if (value == null)
+ return String.Empty;
+
+ byte* bytes = (byte*) value;
+ int length = 0;
+
+ try {
+ while (bytes++ [0] != 0)
+ length++;
+ } catch (NullReferenceException) {
+ throw new ArgumentOutOfRangeException ("value", "Value does not refer to a valid string.");
+#if NET_2_0
+ } catch (AccessViolationException) {
+ throw new ArgumentOutOfRangeException ("value", "Value does not refer to a valid string.");
+#endif
+ }
+
+ return CreateString (value, 0, length, null);
+ }
+
+ private unsafe String CreateString (sbyte* value, int startIndex, int length)
+ {
+ return CreateString (value, startIndex, length, null);
+ }
+
+ private unsafe String CreateString (sbyte* value, int startIndex, int length, Encoding enc)
+ {
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length", "Non-negative number required.");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex", "Non-negative number required.");
+ if (value + startIndex < value)
+ throw new ArgumentOutOfRangeException ("startIndex", "Value, startIndex and length do not refer to a valid string.");
+
+ bool isDefaultEncoding;
+
+ if (isDefaultEncoding = (enc == null)) {
+#if NET_2_0
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ if (length == 0)
+#else
+ if (value == null || length == 0)
+#endif
+ return String.Empty;
+
+ enc = Encoding.Default;
+ }
+
+ byte [] bytes = new byte [length];
+
+ if (length != 0)
+ fixed (byte* bytePtr = bytes)
+ try {
+ memcpy (bytePtr, (byte*) (value + startIndex), length);
+ } catch (NullReferenceException) {
+#if !NET_2_0
+ if (!isDefaultEncoding)
+ throw;
+#endif
+
+ throw new ArgumentOutOfRangeException ("value", "Value, startIndex and length do not refer to a valid string.");
+#if NET_2_0
+ } catch (AccessViolationException) {
+ if (!isDefaultEncoding)
+ throw;
+
+ throw new ArgumentOutOfRangeException ("value", "Value, startIndex and length do not refer to a valid string.");
+#endif
+ }
+
+ // GetString () is called even when length == 0
+ return enc.GetString (bytes);
+ }
+
+ unsafe string CreateString (char *value)
+ {
+ if (value == null)
+ return string.Empty;
+ char *p = value;
+ int i = 0;
+ while (*p != 0) {
+ ++i;
+ ++p;
+ }
+ string result = InternalAllocateStr (i);
+
+ if (i != 0) {
+ fixed (char *dest = result) {
+ memcpy ((byte*)dest, (byte*)value, i * 2);
+ }
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char *value, int startIndex, int length)
+ {
+ if (length == 0)
+ return string.Empty;
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length");
+
+ string result = InternalAllocateStr (length);
+
+ fixed (char *dest = result) {
+ memcpy ((byte*)dest, (byte*)(value + startIndex), length * 2);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char [] val, int startIndex, int length)
+ {
+ if (val == null)
+ throw new ArgumentNullException ("val");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length");
+ if (startIndex > val.Length - length)
+ throw new ArgumentOutOfRangeException ("Out of range");
+ if (length == 0)
+ return string.Empty;
+
+ string result = InternalAllocateStr (length);
+
+ fixed (char *dest = result, src = val) {
+ memcpy ((byte*)dest, (byte*)(src + startIndex), length * 2);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char [] val)
+ {
+ if (val == null)
+ return string.Empty;
+ if (val.Length == 0)
+ return string.Empty;
+ string result = InternalAllocateStr (val.Length);
+
+ fixed (char *dest = result, src = val) {
+ memcpy ((byte*)dest, (byte*)src, val.Length * 2);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char c, int count)
+ {
+ if (count < 0)
+ throw new ArgumentOutOfRangeException ("count");
+ if (count == 0)
+ return string.Empty;
+ string result = InternalAllocateStr (count);
+ fixed (char *dest = result) {
+ char *p = dest;
+ char *end = p + count;
+ while (p < end) {
+ *p = c;
+ p++;
+ }
+ }
+ return result;
+ }
+
/* helpers used by the runtime as well as above or eslewhere in corlib */
internal static unsafe void memset (byte *dest, int val, int len)
{
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern static string InternalJoin (string separator, string[] value, int sIndex, int count);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern String InternalReplace (char oldChar, char newChar);
-
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern String InternalReplace (String oldValue, string newValue, CompareInfo comp);
private extern void InternalCopyTo (int sIndex, char[] dest, int destIndex, int count);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern String[] InternalSplit (char[] separator, int count);
+ private extern String[] InternalSplit (char[] separator, int count, int options);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern String InternalTrim (char[] chars, int typ);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern int InternalIndexOfAny (char [] arr, int sIndex, int count);
-
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern int InternalLastIndexOfAny (char [] anyOf, int sIndex, int count);