5 // Patrik Torstensson (patrik.torstensson@labs2.com)
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;
20 public sealed class String : IConvertible, IComparable, ICloneable, IEnumerable {
23 public static readonly String Empty = "";
25 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
26 unsafe public extern String(char *value);
28 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
29 unsafe public extern String(char *value, int sindex, int length);
31 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
32 unsafe public extern String(sbyte *value);
34 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
35 unsafe public extern String(sbyte *value, int sindex, int length);
37 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
38 unsafe public extern String(sbyte *value, int sindex, int length, Encoding enc);
40 [MethodImplAttribute(MethodImplOptions.InternalCall)]
41 public extern String(char [] val, int sindex, int length);
43 [MethodImplAttribute(MethodImplOptions.InternalCall)]
44 public extern String(char [] val);
46 [MethodImplAttribute(MethodImplOptions.InternalCall)]
47 public extern String(char c, int count);
49 [MethodImplAttribute(MethodImplOptions.InternalCall)]
50 public extern override int GetHashCode();
52 public static bool Equals(String str1, String str2) {
53 if ((str1 as object) == (str2 as object))
56 if (null == str1 || null == str2)
59 if (str1.length != str2.length)
62 return InternalEquals(str1, str2);
65 public static bool operator == (String str1, String str2) {
66 return Equals(str1, str2);
69 public static bool operator != (String str1, String str2) {
70 return !Equals(str1, str2);
73 public override bool Equals(Object obj) {
80 string other = (string) obj;
81 if (length != other.length)
84 return InternalEquals(this, other);
87 public bool Equals(String value) {
91 if (length != value.length)
94 return InternalEquals(this, value);
97 [IndexerName("Chars")]
98 public extern char this[int index] {
99 [MethodImplAttribute(MethodImplOptions.InternalCall)]
103 public Object Clone() {
107 public TypeCode GetTypeCode () {
108 return TypeCode.String;
111 public void CopyTo(int sindex, char[] dest, int dindex, int count) {
112 // LAMESPEC: should I null-terminate?
115 throw new ArgumentNullException();
117 if (sindex < 0 || dindex < 0 || count < 0)
118 throw new ArgumentOutOfRangeException ();
120 if (sindex + count > Length)
121 throw new ArgumentOutOfRangeException ();
123 if (dindex + count > dest.Length)
124 throw new ArgumentOutOfRangeException ();
126 InternalCopyTo(sindex, dest, dindex, count);
129 public char[] ToCharArray() {
130 return ToCharArray(0, length);
133 public char[] ToCharArray(int sindex, int length) {
134 if (sindex < 0 || length < 0 || sindex + length > this.length)
135 throw new ArgumentOutOfRangeException ();
137 char [] tmp = new char[length];
139 InternalCopyTo(sindex, tmp, 0, length);
144 public String [] Split(params char [] separator) {
145 return Split(separator, Int32.MaxValue);
148 public String[] Split(char[] separator, int count) {
149 if (null == separator) {
150 separator = WhiteChars;
154 throw new ArgumentOutOfRangeException ();
157 return new String[0];
160 return new String[1] { ToString() };
162 return InternalSplit(separator, count);
165 public String Substring (int sindex) {
166 if (sindex < 0 || sindex > this.length) {
167 throw new ArgumentOutOfRangeException();
170 string tmp = InternalAllocateStr(this.length - sindex);
171 InternalStrcpy(tmp, 0, this, sindex, length - sindex);
176 public String Substring (int sindex, int length) {
177 if (length < 0 || sindex < 0 || sindex + length > this.length) {
178 throw new ArgumentOutOfRangeException();
184 string tmp = InternalAllocateStr(length);
185 InternalStrcpy(tmp, 0, this, sindex, length);
190 private static readonly char[] WhiteChars = { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20, (char) 0xA0, (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004, (char) 0x2005,
191 (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B, (char) 0x3000, (char) 0xFEFF };
193 public String Trim(params char[] chars) {
194 if (null == chars || chars.Length == 0)
197 return InternalTrim(chars, 0);
200 public String TrimStart(params char[] chars) {
201 if (null == chars || chars.Length == 0)
204 return InternalTrim(chars, 1);
207 public String TrimEnd(params char[] chars) {
208 if (null == chars || chars.Length == 0)
211 return InternalTrim(chars, 2);
214 public static int Compare(String s1, String s2) {
215 return Compare(s1, s2, false);
218 public static int Compare(String s1, String s2, bool inCase) {
224 } else if (null == s2)
227 return InternalCompare(s1, 0, s2, 0, Math.Max(s1.length, s2.length), inCase);
231 public static int Compare(String s1, String s2, bool inCase, CultureInfo culture) {
232 return Compare(s1, s2, inCase);
235 public static int Compare(String s1, int i1, String s2, int i2, int length) {
236 return Compare(s1, i1, s2, i2, length, false);
239 public static int Compare(String s1, int i1, String s2, int i2, int length, bool inCase) {
245 } else if (null == s2)
248 if (length < 0 || i1 < 0 || i2 < 0)
249 throw new ArgumentOutOfRangeException ();
251 if (i1 > s1.length || i2 > s2.length)
252 throw new ArgumentOutOfRangeException ();
257 return InternalCompare(s1, i1, s2, i2, length, inCase);
261 public static int Compare(String s1, int i1, String s2, int i2, int length, bool inCase, CultureInfo culture) {
262 return Compare(s1, i1, s2, i2, length, inCase);
265 public int CompareTo(Object value) {
269 if (!(value is String))
270 throw new ArgumentException();
272 return String.Compare(this, (String) value, false);
275 public int CompareTo(String str) {
279 return Compare(this, str, false);
282 public static int CompareOrdinal(String s1, String s2) {
283 if (null == s1 || null == s2) {
284 if ((Object)s1 == (Object) s2) {
288 return (s1 == null) ? -1 : 1;
291 return InternalCompare(s1, 0, s2, 0, Math.Max(s1.length, s2.length), false);
294 public static int CompareOrdinal(String s1, int i1, String s2, int i2, int length) {
295 if (null == s1 || null == s2) {
296 if ((Object)s1 == (Object) s2) {
300 return (s1 == null) ? -1 : 1;
303 if (i1 < 0 || i2 < 0 || length < 0)
304 throw new ArgumentOutOfRangeException ();
306 if (i1 > s1.length || i2 > s2.length)
307 throw new ArgumentOutOfRangeException ();
309 return InternalCompare(s1, i1, s2, i2, length, false);
312 public bool EndsWith(String value) {
314 throw new ArgumentNullException();
316 if (value.length > this.length) {
320 return (0 == Compare(this, length - value.length, value, 0, value.length));
323 public int IndexOfAny(char [] arr) {
325 throw new ArgumentNullException();
327 return InternalIndexOfAny(arr, 0, this.length);
330 public int IndexOfAny(char [] arr, int sindex) {
332 throw new ArgumentNullException();
333 if (sindex < 0 || sindex >= this.length)
334 throw new ArgumentOutOfRangeException();
336 return InternalIndexOfAny(arr, sindex, this.length - sindex);
339 public int IndexOfAny(char [] arr, int sindex, int count) {
341 throw new ArgumentNullException();
342 if (sindex < 0 || count < 0 || sindex + count > this.length)
343 throw new ArgumentOutOfRangeException ();
345 return InternalIndexOfAny(arr, sindex, count);
348 public int IndexOf(char value) {
349 return InternalIndexOf(value, 0, this.length);
352 public int IndexOf(String value) {
353 return IndexOf(value, 0, this.length);
356 public int IndexOf(char value, int sindex) {
357 if (sindex < 0 || sindex > this.length) {
358 throw new ArgumentOutOfRangeException();
361 if (sindex == this.length)
364 return InternalIndexOf(value, sindex, this.length - sindex);
367 public int IndexOf(String value, int sindex) {
368 if (sindex == this.length)
371 return IndexOf(value, sindex, this.length - sindex);
374 public int IndexOf(char value, int sindex, int count) {
375 if (sindex < 0 || count < 0 || sindex + count > this.length)
376 throw new ArgumentOutOfRangeException ();
378 if (sindex == 0 && this.length == 0)
381 return InternalIndexOf(value, sindex, count);
384 public int IndexOf(String value, int sindex, int count) {
386 throw new ArgumentNullException();
388 if (sindex < 0 || count < 0 || sindex + count > this.length)
389 throw new ArgumentOutOfRangeException ();
391 if (sindex == 0 && this.length == 0)
394 return InternalIndexOf(value, sindex, count);
397 public int LastIndexOfAny(char [] arr) {
399 throw new ArgumentNullException();
401 return InternalLastIndexOfAny(arr, this.length - 1, this.length);
404 public int LastIndexOfAny(char [] arr, int sindex) {
406 throw new ArgumentNullException();
408 if (sindex < 0 || sindex > this.length)
409 throw new ArgumentOutOfRangeException();
411 if (this.length == 0)
414 return InternalLastIndexOfAny(arr, sindex, sindex + 1);
417 public int LastIndexOfAny(char [] arr, int sindex, int count) {
419 throw new ArgumentNullException();
421 if (sindex < 0 || count < 0 || sindex > this.length || sindex - count < -1)
422 throw new ArgumentOutOfRangeException();
424 if (this.length == 0)
427 return InternalLastIndexOfAny(arr, sindex, count);
430 public int LastIndexOf(char value) {
431 return InternalLastIndexOf(value, this.length - 1, this.length);
434 public int LastIndexOf(String value) {
436 throw new ArgumentNullException();
438 if (value.length == 0)
441 if (this.length == 0)
444 return InternalLastIndexOf(value, this.length - 1, this.length);
447 public int LastIndexOf(char value, int sindex){
448 return LastIndexOf(value, sindex, sindex + 1);
451 public int LastIndexOf(String value, int sindex) {
452 return LastIndexOf(value, sindex, sindex + 1);
455 public int LastIndexOf(char value, int sindex, int count) {
456 if (sindex < 0 || count < 0)
457 throw new ArgumentOutOfRangeException ();
459 if (sindex >= this.length || sindex - count + 1 < 0)
460 throw new ArgumentOutOfRangeException ();
462 if (sindex == 0 && this.length == 0)
465 return InternalLastIndexOf(value, sindex, count);
468 public int LastIndexOf(String value, int sindex, int count) {
470 throw new ArgumentNullException();
472 if (sindex < 0 || sindex > this.length)
473 throw new ArgumentOutOfRangeException ();
475 if (count < 0 || sindex - count + 1 < 0)
476 throw new ArgumentOutOfRangeException ();
478 if (value.length > sindex)
481 if (value == String.Empty)
484 if (sindex == 0 && this.length == 0)
487 return InternalLastIndexOf(value, sindex, count);
490 public String PadLeft(int width) {
491 return PadLeft(width, ' ');
494 public String PadLeft(int width, char chr) {
496 throw new ArgumentException();
498 if (width < this.length)
499 return String.Copy(this);
501 return InternalPad(width, chr, false);
504 public String PadRight(int width) {
505 return PadRight(width, ' ');
508 public String PadRight(int width, char chr) {
510 throw new ArgumentException();
512 if (width < this.length)
513 return String.Copy(this);
515 return InternalPad(width, chr, true);
518 public bool StartsWith(String value) {
520 throw new ArgumentNullException();
522 if (this.length < value.length)
525 return (0 == Compare(this, 0, value, 0 , value.length));
529 public String Replace (char oldChar, char newChar) {
530 return InternalReplace(oldChar, newChar);
533 public String Replace(String oldValue, String newValue) {
534 if (null == oldValue)
535 throw new ArgumentNullException();
537 return InternalReplace(oldValue, newValue);
540 public String Remove(int sindex, int count) {
541 if (sindex < 0 || count < 0 || sindex + count > this.length)
542 throw new ArgumentOutOfRangeException ();
544 return InternalRemove(sindex, count);
547 public String ToLower() {
548 return InternalToLower();
551 [MonoTODO("By now, don't use culture info")]
552 public String ToLower(CultureInfo culture) {
553 return InternalToLower();
556 public String ToUpper() {
557 return InternalToUpper();
560 [MonoTODO("By now, don't use culture info")]
561 public String ToUpper(CultureInfo culture) {
562 return InternalToUpper();
565 public override String ToString() {
569 public String ToString(IFormatProvider provider) {
573 public String Trim() {
577 public static String Format(String format, Object arg0) {
578 return Format(null, format, new Object[] {arg0});
581 public static String Format(String format, Object arg0, Object arg1) {
582 return Format(null, format, new Object[] {arg0, arg1});
585 public static String Format(String format, Object arg0, Object arg1, Object arg2) {
586 return Format(null, format, new Object[] {arg0, arg1, arg2});
589 public static string Format (string format, params object[] args) {
590 return Format (null, format, args);
593 public static string Format (IFormatProvider provider, string format, params object[] args) {
594 if (format == null || args == null)
595 throw new ArgumentNullException ();
597 StringBuilder result = new StringBuilder ();
601 while (ptr < format.length) {
602 char c = format[ptr ++];
605 result.Append (format, start, ptr - start - 1);
607 // check for escaped open bracket
609 if (format[ptr] == '{') {
620 ParseFormatSpecifier (format, ref ptr, out n, out width, out left_align, out arg_format);
621 if (n >= args.Length)
622 throw new FormatException ("Index (zero based) must be greater than or equal to zero and less than the size of the argument list.");
626 object arg = args[n];
631 else if (arg is IFormattable)
632 str = ((IFormattable)arg).ToString (arg_format, provider);
634 str = arg.ToString ();
636 // pad formatted string and append to result
638 if (width > str.length) {
639 string pad = new String (' ', width - str.length);
655 else if (c == '}' && ptr < format.length && format[ptr] == '}') {
656 result.Append (format, start, ptr - start - 1);
660 throw new FormatException ("Input string was not in a correct format.");
664 if (start < format.length)
665 result.Append (format.Substring (start));
667 return result.ToString ();
670 public static String Copy (String str) {
672 throw new ArgumentNullException ();
674 int length = str.length;
676 String tmp = InternalAllocateStr(length);
677 InternalStrcpy(tmp, 0, str);
681 public static String Concat(Object obj) {
685 return obj.ToString();
688 public static String Concat(Object obj1, Object obj2)
696 return obj2.ToString ();
697 } else if (obj2 == null)
698 return obj1.ToString ();
700 s1 = obj1.ToString ();
701 s2 = obj2.ToString ();
702 String tmp = InternalAllocateStr (s1.Length + s2.Length);
703 InternalStrcpy (tmp, 0, s1);
704 InternalStrcpy (tmp, s1.length, s2);
709 public static String Concat(Object obj1, Object obj2, Object obj3)
715 s1 = obj1.ToString ();
720 s2 = obj2.ToString ();
725 s3 = obj3.ToString ();
727 return Concat (s1, s2, s3);
730 public static String Concat(String s1, String s2)
741 String tmp = InternalAllocateStr(s1.length + s2.length);
743 InternalStrcpy(tmp, 0, s1);
744 InternalStrcpy(tmp, s1.length, s2);
749 public static String Concat(String s1, String s2, String s3)
773 String tmp = InternalAllocateStr(s1.length + s2.length + s3.length);
775 InternalStrcpy(tmp, 0, s1);
776 InternalStrcpy(tmp, s1.length, s2);
777 InternalStrcpy(tmp, s1.length + s2.length, s3);
782 public static String Concat(String s1, String s2, String s3, String s4) {
783 if (null == s1 && null == s2 && null == s3 && null == s4) {
787 if (null == s1) { s1 = String.Empty; }
788 if (null == s2) { s2 = String.Empty; }
789 if (null == s3) { s3 = String.Empty; }
790 if (null == s4) { s4 = String.Empty; }
792 String tmp = InternalAllocateStr(s1.length + s2.length + s3.length + s4.length);
794 InternalStrcpy(tmp, 0, s1);
795 InternalStrcpy(tmp, s1.length, s2);
796 InternalStrcpy(tmp, s1.length + s2.length, s3);
797 InternalStrcpy(tmp, s1.length + s2.length + s3.length, s4);
802 public static String Concat(params Object[] args) {
804 int len, i, currentpos;
807 throw new ArgumentNullException ();
809 strings = new string [args.Length];
812 foreach (object arg in args) {
813 /* use Empty for each null argument */
815 strings[i] = String.Empty;
817 strings[i] = arg.ToString ();
818 len += strings[i].length;
827 String tmp = InternalAllocateStr(len);
828 for (i = 0; i < strings.Length; i++) {
829 InternalStrcpy(tmp, currentpos, strings[i]);
830 currentpos += strings[i].length;
836 public static String Concat(params String[] values) {
837 int len, i, currentpos;
840 throw new ArgumentNullException ();
843 foreach (string value in values)
844 len += value != null ? value.length : 0;
851 String tmp = InternalAllocateStr(len);
852 for (i = 0; i < values.Length; i++) {
853 if (values[i] == null)
856 InternalStrcpy(tmp, currentpos, values[i]);
857 currentpos += values[i].length;
863 public String Insert(int sindex, String value) {
865 throw new ArgumentNullException();
867 if (sindex < 0 || sindex > this.length)
868 throw new ArgumentOutOfRangeException();
870 return InternalInsert(sindex, value);
874 public static string Intern (string str) {
876 throw new ArgumentNullException ();
878 return InternalIntern(str);
881 public static string IsInterned (string str) {
883 throw new ArgumentNullException();
885 return InternalIsInterned(str);
888 public static string Join (string separator, string [] value) {
890 throw new ArgumentNullException ();
892 return Join(separator, value, 0, value.Length);
895 public static string Join(string separator, string[] value, int sindex, int count) {
897 throw new ArgumentNullException ();
899 if (sindex + count > value.Length)
900 throw new ArgumentOutOfRangeException ();
902 if (sindex == value.Length)
905 return InternalJoin(separator, value, sindex, count);
908 bool IConvertible.ToBoolean (IFormatProvider provider) {
909 return Convert.ToBoolean (this);
912 byte IConvertible.ToByte (IFormatProvider provider) {
913 return Convert.ToByte (this);
916 char IConvertible.ToChar (IFormatProvider provider) {
917 return Convert.ToChar (this);
920 DateTime IConvertible.ToDateTime (IFormatProvider provider) {
921 return Convert.ToDateTime (this);
924 decimal IConvertible.ToDecimal (IFormatProvider provider) {
925 return Convert.ToDecimal (this);
928 double IConvertible.ToDouble (IFormatProvider provider) {
929 return Convert.ToDouble (this);
932 short IConvertible.ToInt16 (IFormatProvider provider) {
933 return Convert.ToInt16 (this);
936 int IConvertible.ToInt32 (IFormatProvider provider) {
937 return Convert.ToInt32 (this);
940 long IConvertible.ToInt64 (IFormatProvider provider) {
941 return Convert.ToInt64 (this);
944 [CLSCompliant(false)]
945 sbyte IConvertible.ToSByte (IFormatProvider provider) {
946 return Convert.ToSByte (this);
949 float IConvertible.ToSingle (IFormatProvider provider) {
950 return Convert.ToSingle (this);
952 string IConvertible.ToString (IFormatProvider format) {
956 object IConvertible.ToType (Type conversionType, IFormatProvider provider) {
957 return Convert.ToType (this, conversionType, provider);
960 [CLSCompliant(false)]
961 ushort IConvertible.ToUInt16 (IFormatProvider provider) {
962 return Convert.ToUInt16 (this);
965 [CLSCompliant(false)]
966 uint IConvertible.ToUInt32 (IFormatProvider provider) {
967 return Convert.ToUInt32 (this);
970 [CLSCompliant(false)]
971 ulong IConvertible.ToUInt64 (IFormatProvider provider) {
972 return Convert.ToUInt64 (this);
975 TypeCode IConvertible.GetTypeCode () {
976 return TypeCode.String;
985 public CharEnumerator GetEnumerator () {
986 return new CharEnumerator (this);
989 IEnumerator IEnumerable.GetEnumerator () {
990 return new CharEnumerator (this);
993 private static void ParseFormatSpecifier (string str, ref int ptr, out int n, out int width, out bool left_align, out string format) {
994 // parses format specifier of form:
1000 // N = argument number (non-negative integer)
1002 n = ParseDecimal (str, ref ptr);
1004 throw new FormatException ("Input string was not in a correct format.");
1006 // M = width (non-negative integer)
1008 if (str[ptr] == ',') {
1009 // White space between ',' and number or sign.
1011 while (Char.IsWhiteSpace (str [ptr]))
1014 format = str.Substring (start, ptr - start);
1016 left_align = (str [ptr] == '-');
1020 width = ParseDecimal (str, ref ptr);
1022 throw new FormatException ("Input string was not in a correct format.");
1030 // F = argument format (string)
1032 if (str[ptr] == ':') {
1034 while (str[ptr] != '}')
1037 format += str.Substring (start, ptr - start);
1042 if (str[ptr ++] != '}')
1043 throw new FormatException ("Input string was not in a correct format.");
1045 catch (IndexOutOfRangeException) {
1046 throw new FormatException ("Input string was not in a correct format.");
1050 private static int ParseDecimal (string str, ref int ptr) {
1055 if (c < '0' || '9' < c)
1058 n = n * 10 + c - '0';
1069 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1070 private extern static string InternalJoin(string separator, string[] value, int sindex, int count);
1072 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1073 private extern String InternalInsert(int sindex, String value);
1075 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1076 private extern String InternalReplace(char oldChar, char newChar);
1078 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1079 private extern String InternalReplace(String oldValue, String newValue);
1081 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1082 private extern String InternalRemove(int sindex, int count);
1084 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1085 private extern void InternalCopyTo(int sindex, char[] dest, int dindex, int count);
1087 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1088 private extern String[] InternalSplit(char[] separator, int count);
1090 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1091 private extern String InternalTrim(char[] chars, int typ);
1093 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1094 private extern int InternalIndexOf(char value, int sindex, int count);
1096 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1097 private extern int InternalIndexOf(string value, int sindex, int count);
1099 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1100 private extern int InternalIndexOfAny(char [] arr, int sindex, int count);
1102 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1103 private extern int InternalLastIndexOf(char value, int sindex, int count);
1105 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1106 private extern int InternalLastIndexOf(String value, int sindex, int count);
1108 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1109 private extern int InternalLastIndexOfAny(char [] anyOf, int sindex, int count);
1111 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1112 private extern String InternalPad(int width, char chr, bool right);
1114 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1115 private extern String InternalToLower();
1117 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1118 private extern String InternalToUpper();
1120 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1121 private extern static String InternalAllocateStr(int length);
1123 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1124 private extern static void InternalStrcpy(String dest, int destPos, String src);
1126 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1127 private extern static void InternalStrcpy(String dest, int destPos, String src, int startPos, int count);
1129 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1130 private extern static string InternalIntern(string str);
1132 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1133 private extern static string InternalIsInterned(string str);
1135 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1136 private extern static int InternalCompare(String s1, int i1, String s2, int i2, int length, bool inCase);
1138 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1139 private extern static bool InternalEquals(String s1, String s2);