6 // Jeffrey Stedfast (fejj@ximian.com)
7 // Dan Lewis (dihlewis@yahoo.co.uk)
9 // (C) 2001 Ximian, Inc. http://www.ximian.com
14 using System.Collections;
15 using System.Globalization;
16 using System.Runtime.CompilerServices;
21 public sealed class String : IConvertible, IComparable, ICloneable, IEnumerable
23 [NonSerialized] private int length;
24 [NonSerialized] private char start_char;
26 private const int COMPARE_CASE = 0;
27 private const int COMPARE_INCASE = 1;
28 private const int COMPARE_ORDINAL = 2;
30 public static readonly String Empty = "";
32 public static unsafe bool Equals (string a, string b)
34 if ((a as object) == (b as object))
37 if (a == null || b == null)
48 fixed (char * s1 = &a.start_char, s2 = &b.start_char) {
49 // it must be one char, because 0 len is done above
54 int * sint1 = (int *) s1, sint2 = (int *) s2;
57 if (*sint1++ != *sint2++)
66 return *(char *) sint1 == *(char *) sint2;
70 public static bool operator == (String a, String b)
75 public static bool operator != (String a, String b)
77 return !Equals (a, b);
80 public override bool Equals (Object obj)
82 return Equals (this, obj as String);
85 public bool Equals (String value)
87 return Equals (this, value);
90 [IndexerName ("Chars")]
91 public extern char this [int index] {
92 [MethodImplAttribute (MethodImplOptions.InternalCall)]
96 public Object Clone ()
101 public TypeCode GetTypeCode ()
103 return TypeCode.String;
106 public void CopyTo (int sourceIndex, char[] destination, int destinationIndex, int count)
108 // LAMESPEC: should I null-terminate?
109 if (destination == null)
110 throw new ArgumentNullException ("destination");
112 if (sourceIndex < 0 || destinationIndex < 0 || count < 0)
113 throw new ArgumentOutOfRangeException ();
115 if (sourceIndex + count > Length)
116 throw new ArgumentOutOfRangeException ();
118 if (destinationIndex + count > destination.Length)
119 throw new ArgumentOutOfRangeException ();
121 InternalCopyTo (sourceIndex, destination, destinationIndex, count);
124 public char[] ToCharArray ()
126 return ToCharArray (0, length);
129 public char[] ToCharArray (int startIndex, int length)
131 if (startIndex < 0 || length < 0 || startIndex + length > this.length)
132 throw new ArgumentOutOfRangeException ();
134 char [] tmp = new char[length];
136 InternalCopyTo (startIndex, tmp, 0, length);
141 public String [] Split (params char [] separator)
143 return Split (separator, Int32.MaxValue);
146 public String[] Split (char[] separator, int count)
148 if (separator == null || separator.Length == 0)
149 separator = WhiteChars;
152 throw new ArgumentOutOfRangeException ();
155 return new String[0];
158 return new String[1] { ToString() };
160 return InternalSplit (separator, count);
163 public String Substring (int startIndex)
165 if (startIndex < 0 || startIndex > this.length)
166 throw new ArgumentOutOfRangeException ("startIndex");
168 string tmp = InternalAllocateStr (this.length - startIndex);
169 InternalStrcpy (tmp, 0, this, startIndex, length - startIndex);
174 public String Substring (int startIndex, int length)
176 if (length < 0 || startIndex < 0 || startIndex + length > this.length)
177 throw new ArgumentOutOfRangeException ();
182 string tmp = InternalAllocateStr (length);
183 InternalStrcpy (tmp, 0, this, startIndex, length);
188 private static readonly char[] WhiteChars = { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD,
189 (char) 0x20, (char) 0xA0, (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004,
190 (char) 0x2005, (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B,
191 (char) 0x3000, (char) 0xFEFF };
193 public String Trim (params char[] trimChars)
195 if (trimChars == null || trimChars.Length == 0)
196 trimChars = WhiteChars;
198 return InternalTrim (trimChars, 0);
201 public String TrimStart (params char[] trimChars)
203 if (trimChars == null || trimChars.Length == 0)
204 trimChars = WhiteChars;
206 return InternalTrim (trimChars, 1);
209 public String TrimEnd (params char[] trimChars)
211 if (trimChars == null || trimChars.Length == 0)
212 trimChars = WhiteChars;
214 return InternalTrim (trimChars, 2);
217 public static int Compare (String strA, String strB)
219 return Compare (strA, strB, false, CultureInfo.CurrentCulture);
222 public static int Compare (String strA, String strB, bool ignoreCase)
224 return Compare (strA, strB, ignoreCase, CultureInfo.CurrentCulture);
227 public static int Compare (String strA, String strB, bool ignoreCase, CultureInfo culture)
230 throw new ArgumentNullException ("culture");
239 else if (strB == null) {
243 CompareOptions compopts;
246 compopts = CompareOptions.IgnoreCase;
248 compopts = CompareOptions.None;
250 return culture.CompareInfo.Compare (strA, strB, compopts);
253 public static int Compare (String strA, int indexA, String strB, int indexB, int length)
255 return Compare (strA, indexA, strB, indexB, length, false, CultureInfo.CurrentCulture);
258 public static int Compare (String strA, int indexA, String strB, int indexB, int length, bool ignoreCase)
260 return Compare (strA, indexA, strB, indexB, length, ignoreCase, CultureInfo.CurrentCulture);
263 public static int Compare (String strA, int indexA, String strB, int indexB, int length, bool ignoreCase, CultureInfo culture)
266 throw new ArgumentNullException ("culture");
268 if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0))
269 throw new ArgumentOutOfRangeException ();
281 else if (strB == null) {
285 CompareOptions compopts;
288 compopts = CompareOptions.IgnoreCase;
290 compopts = CompareOptions.None;
292 /* Need to cap the requested length to the
293 * length of the string, because
294 * CompareInfo.Compare will insist that length
295 * <= (string.Length - offset)
300 if (length > (strA.Length - indexA)) {
301 len1 = strA.Length - indexA;
304 if (length > (strB.Length - indexB)) {
305 len2 = strB.Length - indexB;
308 return culture.CompareInfo.Compare (strA, indexA, len1, strB, indexB, len2, compopts);
311 public int CompareTo (Object value)
316 if (!(value is String))
317 throw new ArgumentException ();
319 return String.Compare (this, (String) value, false);
322 public int CompareTo (String strB)
327 return Compare (this, strB, false);
330 public static int CompareOrdinal (String strA, String strB)
338 else if (strB == null) {
342 /* Invariant, because that is cheaper to
343 * instantiate (and chances are it already has
346 return CultureInfo.InvariantCulture.CompareInfo.Compare (strA, strB, CompareOptions.Ordinal);
349 public static int CompareOrdinal (String strA, int indexA, String strB, int indexB, int length)
351 if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0))
352 throw new ArgumentOutOfRangeException ();
360 else if (strB == null) {
364 /* Need to cap the requested length to the
365 * length of the string, because
366 * CompareInfo.Compare will insist that length
367 * <= (string.Length - offset)
372 if (length > (strA.Length - indexA)) {
373 len1 = strA.Length - indexA;
376 if (length > (strB.Length - indexB)) {
377 len2 = strB.Length - indexB;
380 return CultureInfo.InvariantCulture.CompareInfo.Compare (strA, indexA, len1, strB, indexB, len2, CompareOptions.Ordinal);
383 public bool EndsWith (String value)
386 throw new ArgumentNullException ("value");
388 if (value == String.Empty)
391 if (value.length > this.length)
394 return (0 == Compare (this, length - value.length, value, 0, value.length));
397 public int IndexOfAny (char [] anyOf)
400 throw new ArgumentNullException ("anyOf");
402 return InternalIndexOfAny (anyOf, 0, this.length);
405 public int IndexOfAny (char [] anyOf, int startIndex)
408 throw new ArgumentNullException ("anyOf");
409 if (startIndex < 0 || startIndex >= this.length)
410 throw new ArgumentOutOfRangeException ("sourceIndex");
412 return InternalIndexOfAny (anyOf, startIndex, this.length - startIndex);
415 public int IndexOfAny (char [] anyOf, int startIndex, int count)
418 throw new ArgumentNullException ("anyOf");
419 if (startIndex < 0 || count < 0 || startIndex + count > this.length)
420 throw new ArgumentOutOfRangeException ();
422 return InternalIndexOfAny (anyOf, startIndex, count);
425 public int IndexOf (char value)
427 return IndexOf (value, 0, this.length);
430 public int IndexOf (String value)
432 return IndexOf (value, 0, this.length);
435 public int IndexOf (char value, int startIndex)
437 return IndexOf (value, startIndex, this.length - startIndex);
440 public int IndexOf (String value, int startIndex)
442 return IndexOf (value, startIndex, this.length - startIndex);
445 /* This method is culture-insensitive */
446 public int IndexOf (char value, int startIndex, int count)
448 if (startIndex < 0 || count < 0 || startIndex + count > this.length)
449 throw new ArgumentOutOfRangeException ();
451 if ((startIndex == 0 && this.length == 0) || (startIndex == this.length) || (count == 0))
454 for (int pos = startIndex; pos < startIndex + count; pos++) {
455 if (this[pos] == value)
461 /* But this one is culture-sensitive */
462 public int IndexOf (String value, int startIndex, int count)
465 throw new ArgumentNullException ("value");
467 if (startIndex < 0 || count < 0 || startIndex + count > this.length)
468 throw new ArgumentOutOfRangeException ();
470 if (value.length == 0)
473 if (startIndex == 0 && this.length == 0)
479 return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, startIndex, count);
482 public int LastIndexOfAny (char [] anyOf)
485 throw new ArgumentNullException ("anyOf");
487 return InternalLastIndexOfAny (anyOf, this.length - 1, this.length);
490 public int LastIndexOfAny (char [] anyOf, int startIndex)
493 throw new ArgumentNullException ("anyOf");
495 if (startIndex < 0 || startIndex > this.length)
496 throw new ArgumentOutOfRangeException ();
498 if (this.length == 0)
501 return InternalLastIndexOfAny (anyOf, startIndex, startIndex + 1);
504 public int LastIndexOfAny (char [] anyOf, int startIndex, int count)
507 throw new ArgumentNullException ("anyOf");
509 if (startIndex < 0 || count < 0 || startIndex > this.length || startIndex - count < -1)
510 throw new ArgumentOutOfRangeException ();
512 if (this.length == 0)
515 return InternalLastIndexOfAny (anyOf, startIndex, count);
518 public int LastIndexOf (char value)
520 if (this.length == 0)
523 return LastIndexOf (value, this.length - 1, this.length);
526 public int LastIndexOf (String value)
528 if (this.length == 0)
529 /* This overload does additional checking */
530 return LastIndexOf (value, 0, 0);
532 return LastIndexOf (value, this.length - 1, this.length);
535 public int LastIndexOf (char value, int startIndex)
537 return LastIndexOf (value, startIndex, startIndex + 1);
540 public int LastIndexOf (String value, int startIndex)
542 return LastIndexOf (value, startIndex, startIndex + 1);
545 /* This method is culture-insensitive */
546 public int LastIndexOf (char value, int startIndex, int count)
548 if (startIndex == 0 && this.length == 0)
551 if (startIndex < 0 || count < 0)
552 throw new ArgumentOutOfRangeException ();
554 if (startIndex >= this.length || startIndex - count + 1 < 0)
555 throw new ArgumentOutOfRangeException ();
557 for(int pos = startIndex; pos > startIndex - count; pos--) {
558 if (this [pos] == value)
564 /* But this one is culture-sensitive */
565 public int LastIndexOf (String value, int startIndex, int count)
568 throw new ArgumentNullException ("value");
570 if (value == String.Empty)
573 if (startIndex == 0 && this.length == 0)
576 // This check is needed to match undocumented MS behaviour
577 if (this.length == 0 && value.length > 0)
580 if (value.length > startIndex)
586 if (startIndex < 0 || startIndex > this.length)
587 throw new ArgumentOutOfRangeException ();
589 if (count < 0 || startIndex - count + 1 < 0)
590 throw new ArgumentOutOfRangeException ();
592 return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, startIndex, count);
595 public String PadLeft (int totalWidth)
597 return PadLeft (totalWidth, ' ');
600 public String PadLeft (int totalWidth, char paddingChar)
603 throw new ArgumentException ();
605 if (totalWidth < this.length)
606 return String.Copy (this);
608 return InternalPad (totalWidth, paddingChar, false);
611 public String PadRight (int totalWidth)
613 return PadRight (totalWidth, ' ');
616 public String PadRight (int totalWidth, char paddingChar)
619 throw new ArgumentException ();
621 if (totalWidth < this.length)
622 return String.Copy (this);
624 return InternalPad (totalWidth, paddingChar, true);
627 public bool StartsWith (String value)
630 throw new ArgumentNullException ("value");
632 if (value == String.Empty)
635 if (this.length < value.length)
638 return (0 == Compare (this, 0, value, 0 , value.length));
641 /* This method is culture insensitive */
642 public String Replace (char oldChar, char newChar)
644 return InternalReplace (oldChar, newChar);
647 /* This method is culture sensitive */
648 public String Replace (String oldValue, String newValue)
650 if (oldValue == null)
651 throw new ArgumentNullException ("oldValue");
653 if (oldValue == String.Empty)
654 throw new ArgumentException ("oldValue is the empty string.");
656 if (this == String.Empty)
659 if (oldValue.Length == 0 || oldValue[0] == '\0') {
663 if (newValue == null)
664 newValue = String.Empty;
666 return InternalReplace (oldValue, newValue, CultureInfo.CurrentCulture.CompareInfo);
669 public String Remove (int startIndex, int count)
671 if (startIndex < 0 || count < 0 || startIndex + count > this.length)
672 throw new ArgumentOutOfRangeException ();
674 return InternalRemove (startIndex, count);
677 public String ToLower ()
679 return InternalToLower (CultureInfo.CurrentCulture);
682 public String ToLower (CultureInfo culture)
684 return InternalToLower (culture);
687 public String ToUpper ()
689 return InternalToUpper (CultureInfo.CurrentCulture);
692 public String ToUpper (CultureInfo culture)
694 return InternalToUpper (culture);
697 public override String ToString ()
702 public String ToString (IFormatProvider provider)
707 public String Trim ()
712 public static String Format (String format, Object arg0)
714 return Format (null, format, new Object[] {arg0});
717 public static String Format (String format, Object arg0, Object arg1)
719 return Format (null, format, new Object[] {arg0, arg1});
722 public static String Format (String format, Object arg0, Object arg1, Object arg2)
724 return Format (null, format, new Object[] {arg0, arg1, arg2});
727 public static string Format (string format, params object[] args)
729 return Format (null, format, args);
732 public static string Format (IFormatProvider provider, string format, params object[] args)
734 StringBuilder b = new StringBuilder ();
735 FormatHelper (b, provider, format, args);
736 return b.ToString ();
739 internal static void FormatHelper (StringBuilder result, IFormatProvider provider, string format, params object[] args)
741 if (format == null || args == null)
742 throw new ArgumentNullException ();
746 while (ptr < format.length) {
747 char c = format[ptr ++];
750 result.Append (format, start, ptr - start - 1);
752 // check for escaped open bracket
754 if (format[ptr] == '{') {
765 ParseFormatSpecifier (format, ref ptr, out n, out width, out left_align, out arg_format);
766 if (n >= args.Length)
767 throw new FormatException ("Index (zero based) must be greater than or equal to zero and less than the size of the argument list.");
771 object arg = args[n];
776 else if (arg is IFormattable)
777 str = ((IFormattable)arg).ToString (arg_format, provider);
779 str = arg.ToString ();
781 // pad formatted string and append to result
783 if (width > str.length) {
784 string pad = new String (' ', width - str.length);
800 else if (c == '}' && ptr < format.length && format[ptr] == '}') {
801 result.Append (format, start, ptr - start - 1);
805 throw new FormatException ("Input string was not in a correct format.");
809 if (start < format.length)
810 result.Append (format.Substring (start));
813 public static String Copy (String str)
816 throw new ArgumentNullException ("str");
818 int length = str.length;
820 String tmp = InternalAllocateStr (length);
821 InternalStrcpy (tmp, 0, str);
825 public static String Concat (Object obj)
830 return obj.ToString ();
833 public static String Concat (Object obj1, Object obj2)
837 s1 = (obj1 != null) ? obj1.ToString () : null;
838 s2 = (obj2 != null) ? obj2.ToString () : null;
845 } else if (s2 == null)
848 String tmp = InternalAllocateStr (s1.Length + s2.Length);
849 InternalStrcpy (tmp, 0, s1);
850 InternalStrcpy (tmp, s1.length, s2);
855 public static String Concat (Object obj1, Object obj2, Object obj3)
861 s1 = obj1.ToString ();
866 s2 = obj2.ToString ();
871 s3 = obj3.ToString ();
873 return Concat (s1, s2, s3);
876 public static String Concat (Object obj1, Object obj2, Object obj3, Object obj4)
878 string s1, s2, s3, s4;
883 s1 = obj1.ToString ();
888 s2 = obj2.ToString ();
893 s3 = obj3.ToString ();
898 s4 = obj4.ToString ();
900 return Concat (s1, s2, s3, s4);
904 public static String Concat (String s1, String s2)
915 String tmp = InternalAllocateStr (s1.length + s2.length);
917 InternalStrcpy (tmp, 0, s1);
918 InternalStrcpy (tmp, s1.length, s2);
923 public static String Concat (String s1, String s2, String s3)
947 //return InternalConcat (s1, s2, s3);
948 String tmp = InternalAllocateStr (s1.length + s2.length + s3.length);
950 InternalStrcpy (tmp, 0, s1);
951 InternalStrcpy (tmp, s1.length, s2);
952 InternalStrcpy (tmp, s1.length + s2.length, s3);
957 public static String Concat (String s1, String s2, String s3, String s4)
959 if (s1 == null && s2 == null && s3 == null && s4 == null)
971 String tmp = InternalAllocateStr (s1.length + s2.length + s3.length + s4.length);
973 InternalStrcpy (tmp, 0, s1);
974 InternalStrcpy (tmp, s1.length, s2);
975 InternalStrcpy (tmp, s1.length + s2.length, s3);
976 InternalStrcpy (tmp, s1.length + s2.length + s3.length, s4);
981 public static String Concat (params Object[] args)
984 int len, i, currentpos;
987 throw new ArgumentNullException ("args");
989 strings = new string [args.Length];
992 foreach (object arg in args) {
993 /* use Empty for each null argument */
995 strings[i] = String.Empty;
997 strings[i] = arg.ToString ();
998 len += strings[i].length;
1003 return String.Empty;
1007 String tmp = InternalAllocateStr (len);
1008 for (i = 0; i < strings.Length; i++) {
1009 InternalStrcpy (tmp, currentpos, strings[i]);
1010 currentpos += strings[i].length;
1016 public static String Concat (params String[] values)
1018 int len, i, currentpos;
1021 throw new ArgumentNullException ("values");
1024 foreach (string value in values)
1025 len += value != null ? value.length : 0;
1028 return String.Empty;
1032 String tmp = InternalAllocateStr (len);
1033 for (i = 0; i < values.Length; i++) {
1034 if (values[i] == null)
1037 InternalStrcpy (tmp, currentpos, values[i]);
1038 currentpos += values[i].length;
1044 public String Insert (int startIndex, String value)
1047 throw new ArgumentNullException ("value");
1049 if (startIndex < 0 || startIndex > this.length)
1050 throw new ArgumentOutOfRangeException ();
1052 return InternalInsert (startIndex, value);
1056 public static string Intern (string str)
1059 throw new ArgumentNullException ("str");
1061 return InternalIntern (str);
1064 public static string IsInterned (string str)
1067 throw new ArgumentNullException ("str");
1069 return InternalIsInterned (str);
1072 public static string Join (string separator, string [] value)
1075 throw new ArgumentNullException ("value");
1077 return Join (separator, value, 0, value.Length);
1080 public static string Join (string separator, string[] value, int startIndex, int count)
1083 throw new ArgumentNullException ("value");
1085 if (startIndex + count > value.Length)
1086 throw new ArgumentOutOfRangeException ();
1088 if (startIndex == value.Length)
1089 return String.Empty;
1091 return InternalJoin (separator, value, startIndex, count);
1094 bool IConvertible.ToBoolean (IFormatProvider provider)
1096 return Convert.ToBoolean (this, provider);
1099 byte IConvertible.ToByte (IFormatProvider provider)
1101 return Convert.ToByte (this, provider);
1104 char IConvertible.ToChar (IFormatProvider provider)
1106 return Convert.ToChar (this, provider);
1109 DateTime IConvertible.ToDateTime (IFormatProvider provider)
1111 return Convert.ToDateTime (this, provider);
1114 decimal IConvertible.ToDecimal (IFormatProvider provider)
1116 return Convert.ToDecimal (this, provider);
1119 double IConvertible.ToDouble (IFormatProvider provider)
1121 return Convert.ToDouble (this, provider);
1124 short IConvertible.ToInt16 (IFormatProvider provider)
1126 return Convert.ToInt16 (this, provider);
1129 int IConvertible.ToInt32 (IFormatProvider provider)
1131 return Convert.ToInt32 (this, provider);
1134 long IConvertible.ToInt64 (IFormatProvider provider)
1136 return Convert.ToInt64 (this, provider);
1139 [CLSCompliant (false)]
1140 sbyte IConvertible.ToSByte (IFormatProvider provider)
1142 return Convert.ToSByte (this, provider);
1145 float IConvertible.ToSingle (IFormatProvider provider)
1147 return Convert.ToSingle (this, provider);
1150 string IConvertible.ToString (IFormatProvider format)
1155 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
1157 return Convert.ToType (this, conversionType, provider);
1160 [CLSCompliant (false)]
1161 ushort IConvertible.ToUInt16 (IFormatProvider provider)
1163 return Convert.ToUInt16 (this, provider);
1166 [CLSCompliant (false)]
1167 uint IConvertible.ToUInt32 (IFormatProvider provider)
1169 return Convert.ToUInt32 (this, provider);
1172 [CLSCompliant (false)]
1173 ulong IConvertible.ToUInt64 (IFormatProvider provider)
1175 return Convert.ToUInt64 (this, provider);
1178 TypeCode IConvertible.GetTypeCode ()
1180 return TypeCode.String;
1189 public CharEnumerator GetEnumerator ()
1191 return new CharEnumerator (this);
1194 IEnumerator IEnumerable.GetEnumerator ()
1196 return new CharEnumerator (this);
1199 private static void ParseFormatSpecifier (string str, ref int ptr, out int n, out int width,
1200 out bool left_align, out string format)
1202 // parses format specifier of form:
1208 // N = argument number (non-negative integer)
1210 n = ParseDecimal (str, ref ptr);
1212 throw new FormatException ("Input string was not in a correct format.");
1214 // M = width (non-negative integer)
1216 if (str[ptr] == ',') {
1217 // White space between ',' and number or sign.
1219 while (Char.IsWhiteSpace (str [ptr]))
1222 format = str.Substring (start, ptr - start);
1224 left_align = (str [ptr] == '-');
1228 width = ParseDecimal (str, ref ptr);
1230 throw new FormatException ("Input string was not in a correct format.");
1238 // F = argument format (string)
1240 if (str[ptr] == ':') {
1242 while (str[ptr] != '}')
1245 format += str.Substring (start, ptr - start);
1250 if (str[ptr ++] != '}')
1251 throw new FormatException ("Input string was not in a correct format.");
1253 catch (IndexOutOfRangeException) {
1254 throw new FormatException ("Input string was not in a correct format.");
1258 private static int ParseDecimal (string str, ref int ptr)
1264 if (c < '0' || '9' < c)
1267 n = n * 10 + c - '0';
1278 internal unsafe void InternalSetChar (int idx, char val)
1280 if ((uint) idx >= (uint) Length)
1281 throw new ArgumentOutOfRangeException ("idx");
1283 fixed (char * pStr = &start_char)
1289 internal unsafe void InternalSetLength (int newLength)
1291 if (newLength > length)
1292 throw new ArgumentOutOfRangeException ("newLength", "newLength as to be <= length");
1296 // zero terminate, we can pass string objects directly via pinvoke
1297 fixed (char * pStr = &start_char) {
1298 pStr [length] = '\0';
1302 [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
1303 unsafe public extern String (char *value);
1305 [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
1306 unsafe public extern String (char *value, int startIndex, int length);
1308 [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
1309 unsafe public extern String (sbyte *value);
1311 [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
1312 unsafe public extern String (sbyte *value, int startIndex, int length);
1314 [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
1315 unsafe public extern String (sbyte *value, int startIndex, int length, Encoding enc);
1317 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1318 public extern String (char [] val, int startIndex, int length);
1320 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1321 public extern String (char [] val);
1323 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1324 public extern String (char c, int count);
1326 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1327 public extern override int GetHashCode ();
1329 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1330 private extern static string InternalJoin (string separator, string[] value, int sIndex, int count);
1332 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1333 private extern String InternalInsert (int sourceIndex, String value);
1335 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1336 private extern String InternalReplace (char oldChar, char newChar);
1338 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1339 private extern String InternalReplace (String oldValue, string newValue, CompareInfo comp);
1341 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1342 private extern String InternalRemove (int sIndex, int count);
1344 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1345 private extern void InternalCopyTo (int sIndex, char[] dest, int destIndex, int count);
1347 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1348 private extern String[] InternalSplit (char[] separator, int count);
1350 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1351 private extern String InternalTrim (char[] chars, int typ);
1353 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1354 private extern int InternalIndexOfAny (char [] arr, int sIndex, int count);
1356 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1357 private extern int InternalLastIndexOfAny (char [] anyOf, int sIndex, int count);
1359 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1360 private extern String InternalPad (int width, char chr, bool right);
1362 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1363 private extern String InternalToLower (CultureInfo culture);
1365 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1366 private extern String InternalToUpper (CultureInfo culture);
1368 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1369 internal extern static String InternalAllocateStr (int length);
1371 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1372 internal extern static void InternalStrcpy (String dest, int destPos, String src);
1374 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1375 internal extern static void InternalStrcpy (String dest, int destPos, String src, int sPos, int count);
1377 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1378 private extern static string InternalIntern (string str);
1380 [MethodImplAttribute (MethodImplOptions.InternalCall)]
1381 private extern static string InternalIsInterned (string str);