// == == // // // Copyright (C) 2002 Microsoft Corporation. All Rights Reserved.// // The Use and Distribution Terms for this Software Are Contained in the file // Named license.txt, Which can be found in the root of this distribution.// by using this software in any fashion, you are agreeing to be bound by the // Terms of this license./// You Must Not Remove this Notice, or any Other , from this software.// // // == - == / ** // * ============================= ========================================== **** Class: String **** **** PURPOSE: ContaS Headers for the string class. Actual usmentations ** is in string.cpp **** Date: March 15, 1998 ** ======================= =============================================== * / Namespace system ... {using system.text; Using system; using system.threading; using system.collections; using system.runtime.compilerServices; using va_list = system.Argiterator; usin g _unmanagedmemorystream = system.io .__ unmanagedmemorystream;
// // For Information on these methods, please see COMString.cpp // // The String class represents a static string of characters. Many of // the String methods perform some type of transformation on the current // instance and return the result as a new String. All comparison methods are // implemented as a part of String. As with arrays, character positions // (indices) are zero-based. // // When passing a null string into a constructor in VJ and VC, The Null Should Be // Explicitly Type Cast To A String. // for Example: // String S = New String (String) NULL); // text.out.writeline (// / ** [Serializable] public sealed class String: IComparable, ICloneable, IConvertible, IEnumerable ... {// // NOTE NOTE NOTE NOTE // These fields map directly onto the fields in an EE stringObject See object.h for the layout /.. / [Nonserialized] private int m_ArrayLength; [Nonserialized] Private INT M_ StringLength; [Nonserialized] private char m_firstchar;
// private static readonly char FmtMsgMarkerChar = '%'; // private static readonly char FmtMsgFmtCodeChar = '!';. // These are defined in Com99 / src / vm / COMStringCommon.h and must be kept in sync private const int TrimHead = 0; private const int TrimTail = 1; private const int TrimBoth = 2;. // The empty constant holds the empty string value // We need to call the String constructor so that the compiler does not mark this as a literal. // Marking this as a literal 10 i this as a literal would Mean That It Doesn't show up as a field which we can access // from native. / ** public static readonly string Empty = ""; // // native static methods // // // / / JOINS An Array of Strings Together As One String With a Separator Between Each Original String. // ** Public Stia (String Separator, String [] Value ... {if (value == null) ... {Throw new argumentnullexc Eption ("Value");} Return Join (Separator, Value, 0, Value.Length);} // joins an array of strings together as one string with a separator betWeen Each Original String. // / ** [MethodImplattribute ( MethodImplOptions.InternalCall)] public static extern String Join (String separator, String [] value, int startIndex, int count); [MethodImplAttribute (MethodImplOptions.InternalCall)] internal static extern int nativeCompareOrdinal (String strA, String strB, bool bIgnoreCase);
[MethodImplAttribute (MethodImplOptions.InternalCall)] internal static extern int nativeCompareOrdinalEx (String strA, int indexA, String strB, int indexB, int count); // This will not work in case-insensitive mode for any character greater than 0x80 //. We'll throw an ArgumentException [MethodImplAttribute (MethodImplOptions.InternalCall)] unsafe internal static extern int nativeCompareOrdinalWC (String strA, char * strBChars, bool bIgnoreCase, out bool success);. // // This is a helper method for the team security . They need to uppercase some strings (guaranteed to be less // than 0x80) before security is fully initialized. Without security initialized, we can not grab resources (the nlp's) // from the assembly. This provides a workaround for that problem And Should Not Be Used Anywhere Else. // INTERNAL STATIC STRING SMALLCHARTOUPPER (STRING STRING = Fastallocatestring (stra.length); NativesMallChartoupper (Stra, Newstring); Return Newstring;
[Methodimplattribute (MethodImploptions.InternalCall)] Private static extern void nativesmallchartoupper (String Strin, String Strout);
// This is a helper method for the security team. They need to construct strings from a char [] // within their homebrew XML parser. They guarantee that the char [] they pass in is not null and // that the provided indices are valid so we just stuff real fast internal static String CreateFromCharArray (char [] array, int start, int count) ... {String newString = FastAllocateString (count);. FillStringArray (newString, 0, array, start, count) ; return newString;.} // // // NATIVE INSTANCE METHODS // // // // Search / Query methods // // Determines whether two strings match / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern override Bool Equals (Object Obj); // DETERMINES WHETHER TWO STRINGS MATCH. / * [MethodImplattribute (MethodImploptions.InternalCall)] Public Extern Bool Equals (Strin G value); // determines WHETHER TWO strings match. / ** public static bool equals (string a, string b) ... {if ((object) a == (Object) b) ... {Return True; } IF ((Object) a == null || (Object) b == null) ... {return false;} return a.equals (b);}
/ ** public static bool Operator == (string a, string b) ... {return string.equals (a, b);}
/ ** public static bool operator! = (String a, string b) ... {return! String.equals (a, b);}
[MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern char InternalGetChar (int index);. // Gets the character at a specified position // / ** [System.Runtime.CompilerServices.IndexerName ( "Chars")] public char this [ INT INDEX] ... {Get ... {Return INTERGETCHAR (INDEX);}}
// Converts a substring of this string to an array of characters Copies the // characters of this string beginning at position startIndex and ending at // startIndex length -. 1 to the character array buffer, beginning // at bufferStartIndex //. / ** public void CopyTo (int sourceIndex, char [] destination, int destinationIndex, int count) ... {if (destination == null) throw new ArgumentNullException ( "destination"); if (count <0) throw new ArgumentOutOfRangeException ( "count", Environment.GetResourceString ( "ArgumentOutOfRange_NegativeCount")); if (sourceIndex <0) throw new ArgumentOutOfRangeException ( "sourceIndex", Environment.GetResourceString ( "ArgumentOutOfRange_Index")); if (count> Length - sourceIndex) throw new ArgumentOutOfRangeException ("SourceIndex", Environment.getResourceString ("argumentoutofrange_indexcount")))); if (destinationIndex> destination.Length-count || destinationIndex <0) throw new ArgumentOutOfRangeException ( "destinationIndex", Environment.GetResourceString ( "ArgumentOutOfRange_IndexCount")); InternalCopyTo (sourceIndex, destination, destinationIndex, count);}
[MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern void InternalCopyTo (int sourceIndex, char [] destination, int destinationIndex, int count); [MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern void CopyToByteArray (int sourceIndex, byte [] destination, int DestinationIndex, int charcount; // returns the entire string as an array of character string as an array of character () ... {Return TochaRray (0, Length);} // Returns a Substring of this string as An Array of Characters. // / ** public char [] Tochararray (int startex, int tent) ... {// range check everything. if (StartIndex <0 || StartIndex> length || StartIndex> Length - Length) Throw New ArgumentOutofrangeException ("StartIndex", Environment.GetResourceString ("argumentoutofrange_index"); if (Length <0) Throw new Argum ENTOUTOFRANGEXCEPTION ("Length", Environment.getResourceString ("argumentoutofrange_index");
Char [] chars = new char [length]; INTERNALCOPYTO (StartIndex, Chars, 0, Length); Return Chars;} // Gets a Hash Code for this string. if strings a and b are resha a.equals (b) , then // they will return the same hash code / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern override int GetHashCode ();. // Gets the length of this string / ** public int length ... {get ... {return InternalLength ();}} / ** This is a EE implemented function so that the JIT can recognise is specially /// and eliminate checks on character fetchs [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern int InternalLength. (); / ** INTERNAL INT ArrayLength ... {Get ... {return (m_Arraylength);}} // used by StringBuilder Internal INT CAPACITY ... {Get ... {Return (M_ArrayLength - 1); }
// Creates an array of strings by splitting this string at each // occurence of a separator. The separator is searched for, and if found, // the substring preceding the occurence is stored as the first element in // the array of strings . We then continue in this manner by searching // the substring that follows the occurence. On the other hand, if the separator // is not found, the array of strings will contain this instance as its only element. // If the separator Is Null // Whitespace (IE, Character.iswhitespace) is buy as the separator. // / ** public string [] split (params char [] separator) ... {Return Split (separator, int32.maxvalue);} // Creates an array of strings by splitting this string at each // occurence of a separator. The separator is searched for, and if found, // the substring preceding the occurence is stored as the first element in // the ar ray of strings. We then continue in this manner by searching // the substring that follows the occurence. On the other hand, if the separator // is not found, the array of strings will contain this instance as its only element. // If the spearator is the empty string (ie, string.empty), then// Whitespace (IE, Character.IsWhitespace) is used as the separator. //Iff there is more than count different strings, The last n- (count- 1) // Elements Are Concatenated and added as the last string. // / ** [MethodImplattribute (MethodImploptions.InternalCall)] public extern string [] split (char [] separator, int count);
// Returns a substring of this string. // ** public string substring (int start "... {Return this.substring (startIndex, length-startIndex);} // Returns a substring of this string. // / ** public String Substring (int startIndex, int length) ... {int thisLength = length;. // Bounds Checking if (startIndex <0) ... {throw new ArgumentOutOfRangeException ( "startIndex", Environment.GetResourceString ( "ArgumentOutOfRange_StartIndex "));} If (Length <0) ... {throw new argumentOfrangeException (" length ", Environment.getResourceString (" argumentoutofrange_negativeLength));}
IF (StartIndex> thislength-length) ... {throw new argumentOutofrangeException ("length", Environment.getResourceString ("argumentoutofrange_indexlength));}
String s = fastallocatestring (length); Fillsubstring (S, 0, this, StartIndex, Length);
return s;} [MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern String TrimHelper (char [] trimChars, int trimType);. // This should really live on System.Globalization.CharacterInfo However, // Trim gets called by security while resgen is running, so we can not run // CharacterInfo's class initializer (which goes to native and looks for a // resource table that has not yet been attached to the assembly when resgen // runs. internal static readonly char [] WhitespaceChars = ... {(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, (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200a, (char) 0x200b, (char) 0x3000, (char) 0xFeff}; // Removes a string of characters from the ends of this string. / ** Public String Trim (params char [] trimchars) ... {if (null == trimchars || trimchars.length == 0) ... {Trimchars = Whitespacechars;} Return TrimHELPER (Trimchars, Trimboth);} / / ** public string of this string. / ** public string trimstart (params char [] trimchars ... {if (null == trimchars || trimchars.length == 0) ... {TrimChars = Whitespacechars;} Return TrimHELPER (Trimchars, Trimhead);
} // Removes a string of character string. / ** public string trimend (params char [] trimchars) ... {if (null == trimchars || Trimchars.length == 0) ... {trimChars = WhitespaceChars;} return TrimHelper (trimChars, TrimTail);} // Creates a new string with the characters copied in from ptr If // ptr is null, a string initialized to. "; <; No Object>;"; (ie, // String.NullString) is created // // Issue:.. This method is only accessible from VC / ** [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)] unsafe public extern String (char * value ); / ** [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)] unsafe public extern String (char * value, int startIndex, int length); / ** [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]unsafe public extern String (sbyte * value); / ** [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)] unsafe public extern String (sbyte * value, int startIndex, int length);
/ ** [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)] unsafe public extern String (sbyte * value, int startIndex, int length, Encoding enc); unsafe static private String CreateString (sbyte * value, int startIndex, int length , Encoding enc) ... {if (enc == null) return new String (value, startIndex, length); // default to ANSI if (length <0) throw new ArgumentOutOfRangeException ( "length", Environment.GetResourceString ( " Argumentoutofrange_neednonnegnum ")); byte [] b = new byte [length]; __unmanagedmemorystream.memcpy ((byte *) Value, StartIndex, B, 0, Length; Return Enc.getstring (b);}
// for asciiencoding :: getString () unsafe static infrink CreateStringFromascii (Byte [] Bytes, int Startindex, Int Length) ... {bcldebug.assert (Bytes! = Null, "NEED A BYTE []."); Bcldebug .Assert (StartIndex> = 0 && (StartIndex
[MethodImpLOptions.InternalCall] Private Extern Static Void FillStringChecked (String Dest, Int Destpos, String SRC);
[MethodImpLOptions.InternalCall] Private Extern Static Void FillStringex (String Dest, Int Destpos, String SRC, INT SRCLENGTH);
[MethodImPlocktions.internalCall] Private Extern Static void FillStringArray (String Dest, int stringstart, char [] array, int tart, int count);
[MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static void FillSubstring (String dest, int destPos, String src, int startPos, int count);. // Creates a new string from the characters in a subarray The new string will // be created from the characters in value between startIndex and // startIndex length - 1. // / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String (char [] value, int startIndex, int length); // Creates a . new string from the characters in a subarray The new string will be // created from the characters in value // / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String (char [] value);. / ** [ MethodImplattribute (MethodImploptions.InternalCall)] Public Extern String (CHAR C, INT Count);
// // // INSTANCE METHODS // // // Provides a culture-correct string comparison. StrA is compared to StrB // to determine whether it is lexicographically less, equal, or greater, and then returns // either a negative integer, 0, or a positive integer;. respectively // / ** public static int Compare (String strA, String strB) ... {return CultureInfo.CurrentCulture.CompareInfo.Compare (strA, strB, CompareOptions.None);} . // Provides a culture-correct string comparison strA is compared to strB // to determine whether it is lexicographically less, equal, or greater, and then a // negative integer, 0, or a positive integer is returned; respectively /. / The case-sensitive option is set by ignorecase // / ** public static int compare (String Stra, String strb, bool ignorecase) ... {if (ignorecase) ... {Return CultureInfo.curre ntCulture.CompareInfo.Compare (strA, strB, CompareOptions.IgnoreCase);} return CultureInfo.CurrentCulture.CompareInfo.Compare (strA, strB, CompareOptions.None);.} // Provides a culture-correct string comparison strA is compared to strB // to determine whether it is lexicographically less, equal, or greater, and then a // negative integer, 0, or a positive integer is returned;. respectively // The case-sensitive option is set by ignoreCase, and the culture is Set // by culture // / ** Public Static Int Compare (String Stra, String strb, bool ignorecase, cultureInfo culture ... {if (culture ==
null) ... {throw new ArgumentNullException ( "culture");} if (ignoreCase) ... {return culture.CompareInfo.Compare (strA, strB, CompareOptions.IgnoreCase);} return culture.CompareInfo.Compare (strA, strB, CompareOptions.None);} // Determines whether two string regions match The substring of strA beginning // at indexA of length count is compared with the substring of strB // beginning at indexB of the same length // / *.. * Public Static Int Compare (String Stra, INDEXA, STRING STRB, INDEXB, INT LENGTH ... {INT longtha = length; INT longthb = length; if (stra! = Null) ... {IF (Stra. Length - Indexa IF (strb! = null) ... {IF (strb.length - indexb IF (stra! = null) ... {IF (stra.Length - Indexa if (ignoreCase) ... {return CultureInfo.CurrentCulture.CompareInfo.Compare (strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.IgnoreCase);} return CultureInfo.CurrentCulture.CompareInfo.Compare (strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);} // Determines whether two string regions match The substring of strA beginning // at indexA of length length is compared with the substring of strB // beginning at indexB of the same length.. Case sensitivity is determined by the ignoreCase boolean, // and the culture is set by culture. // / ** public static int Compare (String strA, int indexA, String strB, int indexB, int length, bool ignoreCase, CultureInfo culture) ... {if (culture == null) ... {throw new argumentnull {"culture");} INT length; IF (stra! = null) ... {IF (stra.Length - Indexa IF (strb! = null) ... {if (strb.length - indexb Return string.compare (this, (string) value;} // determines the sorting rate. // ** public int COMPARETO (STRING STRB) ... {if (strb == null) ... {RETURN 1;} return cultureinfo.currentculture.comPareInfo.compare (this, strb, 0);} // Compares Stra and strb Using An Ordinal (Code-Point) Comparison. // / ** Public Static Int Compareordinal (String stra, string strbs ... {== null || strb == null) ... {if ((object) stra == (Object) strb) ... {// they're Both NULL; RETURN 0;} return (stra == null)? -1: 1; // - 1 IF a is null, 1 if b is null.} Return NativeCompareOrdinal (Stra, Strb, False);} // Compares Stra and strb using an order (code-point) comparison. // / ** public static int co MpareRinal (String Stra, Int Indexa, String Strb, Int Indexb, Int Length) ... {if (stra == null || strb == null) ... {if ((object) stra == (Object) strb ) ... {// They're Both NULL; RETURN 0;} return (stra == null)? -1: 1; // - 1 if a is null, 1 if b is null.} Return NativeCompareRDinalex (Stra , INDEXA, STRB, INDEXB, LENGTH; } // Determines whether a specified string is a suffix of the the current instance. // // The case-sensitive and culture-sensitive option is set by options, // and the default culture is used. // / ** public Bool endswith (string value) ... {if (null == value) ... {throw new argumentnullexception ("value");} int valueelen = value.length; int thislen = this.length; if (Valuelen> thislen ... {Return False;} return (0 == Compare (this, thislen-valueelen);} INTERNAL BOOL Endswith (Char Value) ... {INT thislen = this.length; if (thislen! = 0) ... {IF (this [thislen - 1] == value) Return true;} return false;} / / Returns the index of the first occurance of value in the current instance. // The search starts at startIndex and runs thorough the next count characters. // / ** public int IndexOf (char value) ... {return IndexOf (value , 0, this.Length);} / ** public int IndexOf (char value, int startIndex) ... {return IndexOf (value, startIndex, this.Length - startIndex);} / ** [MethodImplAttribute (MethodImplOptions.InternalCall )] public extern int IndexOf (char value, int startIndex, int count);. // Returns the index of the first occurance of any character in value in the current instance // The search starts at startIndex and Runs to EndIndex-1. [StartIndex, EndIndex). // / ** public int indexofany (char [】 iNYOF) ... {Return Indexofany (anyof, 0, this.length);} / ** public int indexofany char [] anyOf, int startIndex) ... {return IndexOfAny (anyOf, startIndex, this.Length - startIndex);} / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern int IndexOfAny (char [] anyOf, int startIndex INT count); // Determines the position within this string of the first occurence of the specified // string, according to the specified search criteria. The search begins at // the first character of this string, it is case-sensitive and culture-sensitive, / / and the default culture is used // / ** public int IndexOf (String value) ... {return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value);}. // Determines the position within this string of the first occurence of the specified // string, according to the specified search criteria. The search begins at // startIndex, it is case-sensitive and culture-sensitve, and the default culture is used. // / ** public int IndexOf (String Value, int StartIndex) ... {Return CultureInfo.currentculture.comPareInfo.indexof (this, value, startindex);} // determines the position of THISIN THIS STRING OF THE FIRST OCCURENCE OF T he specified // string, according to the specified search criteria. The search begins at // startIndex, ends at endIndex and the default culture is used. // / ** public int IndexOf (String value, int startIndex, int count). .. {if (startIndex count> this.Length) ... {throw new ArgumentOutOfRangeException ( "count", Environment.GetResourceString ( "ArgumentOutOfRange_Index"));} return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, startIndex , COUNT, CompareOptions.none; } // Returns the index of the last occurance of value in the current instance. // The search starts at startIndex and runs to endIndex. [StartIndex, endIndex]. // The character at position startIndex is included in the search. StartIndex is The larger // index with the string. // ** public int lastindexof (char value) ... {Return LastIndexof (Value, this.Length-1, this.Length);} / ** public int LastIndexof (charr value, int startIndex) ... {return LastIndexOf (value, startIndex, startIndex 1);} / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern int LastIndexOf (char value, int startIndex, int count); // Returns the index of the laast occurance of any character in value in the cut starts at startindex and runs to endindex. [StartIndex, endindex]. // the character at position start DEX is incrude in the search. startindex is the larger // index within the string. // ** public int lastindexofany (char [] anyof) ... {Return LastIndexofany (Anyof, this.length-1, this.length );} / ** public int LastIndexOfAny (char [] anyOf, int startIndex) ... {return LastIndexOfAny (anyOf, startIndex, startIndex 1);} / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern int LastIndexOfAny (char [] Anyof, int StartIndex, int count); // Returns the index of the last occurance of any character in value in the current instance. // The search starts at startIndex and runs to endIndex. [StartIndex, endIndex]. // The character at position startIndex is included in the search. StartIndex is the larger // index within the string. // / ** public int LastIndexof (string value) ... {Return LastIndexof (Value, this.length-1, this.length);} / ** public int LastIndexof (String value, int startex) ... {Return LastIndexof (Value, StartIndex, StartIndex 1);} / ** public int LastIndexof (String Value, Int StartIndex, Int Count) ... {if (count <0) ... {throw new ArgumentOutOfRangeException ( "count", Environment.GetResourceString ( "ArgumentOutOfRange_Count"));} return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, startIndex, count, CompareOptions.None); } /// / ** Public String Padleft (int Totalwidth) ... {Return Padhelper (TotalWidth, ', false);} / ** public string Padleft (int Totalwidth, char Paddingcha) ... {Return Padhelper (totalWidth, paddingChar, false);} / ** public String PadRight (int totalWidth) ... {return PadHelper (totalWidth, '', true);} / ** public String PadRight (int totalWidth, char paddingChar) .. . {Return Padhelper (TotalWidth, PaddingChar, True); } [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern String PadHelper (int totalWidth, char paddingChar, bool isRightPadded); // Determines whether a specified string is a prefix of the current instance // / ** public bool StartsWith (String value) ... {if (null == value) ... {throw new argumentnullexception ("value");} f (this.Length Return False;} return (0 == Compare (this, 0, value, 0, value .Length);} // creates a copy of this string in locu. / ** public string tolower () ... {Return this.tolower (CultureInfo.currentculture);} // Creates A Copy of this string in Lower Case. The Case. The Culture IS Set by Culture. / ** Public String Tool (CultureInfo Culture) ... {if (Culture == Null) ... {throw new argumentnullexception ("culture"); Return Culture.TextInfo.tolower (this);} // Creates a Copy of this string in Upper case () ... {returnifo.currentculture;} // creates A copy of this string in Upper case. The culture is set by culture. / ** public string Toupper (if (culture == null) ... {throw new argumentnullexception ("culture); } Return Culture.TextInfo.toupper (this);} // Returns this string. / ** public override string Tostring () ... {Return this; } / ** public String ToString (IFormatProvider provider) ... {return this;} // Method required for the ICloneable interface // There's no point in cloning a string since they're immutable, so we simply return this /.. ** public object clone () ... {Return this;} // trims the whitespace from Both Ends of the string. Whitespace is defined by // CharacterInfo.whitespacechars. // / ** public string Trim () ... {return this.Trim (WhitespaceChars);} // // / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String Insert (int startIndex, String value); // Replaces all instances of oldChar with newChar // /. ** [MethodImPlattribute (MethodImplocks.InternalCall)] Public Extern String Replace (Char oldchar, char newcha); // This method contains the same functionality as StringBuilder Replace. The only difference is that // a new String has to be allocated since Strings are immutable / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String Replace (String oldValue, String newValue); // // / ** [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern String Remove (int startIndex, int count); / ** public static String Format (String format, Object arg0) ... {return Format (NULL, FORMAT, New Object [] ... {Arg0});} / ** public static string format (String Format, Object Arg0, Object Arg1) ... {RETURN FORMAT (NULL, FORMAT, New Object [] ... {Arg0, Arg1};} / ** public static string format (String Format, Object Arg0, Object Arg1, Object Arg2) ... {Return Format (Null, Format, New Object [] { Arg0, Arg1, Arg2}); } / ** public static string format (string format, params object [] args) ... {Return Format (null, format, args);} / ** public static string format (iformatProvider Provider, String Format, params object [] Args) ... {if (format == null || args == null) throw new argumentnullexception (Format == NULL)? "format": "args"); stringbuilder sb = new stringbuilder (Format.length Args .Length * 8); sb.appendformat (provider, format, args); return sb.toString ();} / ** public static string copy (string str) ... {if (str == null) ... {Throw new argumentnullexception ("str");} intleth = str.length String result = fastallocatestring (length); FillString (Result, 0, Str); Return Result;} // Used by StringBuilder to avoid data corruption internal static String InternalCopy (String str) ... {int length = str.Length; String result = FastAllocateString (length); FillStringEx (result, 0, str, length); // The Underlying's string can change length is stringbuilder return result;} / ** public static string concat (object arg0) ... {if (arg0 == null) ... {return string.empty;} return arg0.tostring ();} / ** public static string concat (Object Arg0 , Object arg1) ... {IF (arg0 == null) ... {arg0 = string.empty;} if (arg1 == null) ... {arg1 = string.empty;} returnincat (arg0.tostring (), arg1.toString ());} / ** public static string concat (Object arg0, object arg1, object arg2) ... {if (arg0 == null) ... {arg0 = string.empty; IF (arg1 == null) ... {arg1 = string.empty;} if (arg2 == null) ... {arg2 = string.empty;} return constat (arg0.tostring (), arg1.tostring () arg2.toString ());} / ** [clscompliant (false)] Public Static String co Ncat (Object Arg0, Object Arg1, Object Arg2, Object Arg3, __ARGLIST ... {Object [] objargs; int argcount; argiterator args = new argiterator (__ arglist); // 4 to account for the 4 hard-coded arguments at the beginning of the list argCount = args.GetRemainingCount () 4;. ObjArgs = new Object [argCount]; // Handle the hard-coded arguments objArgs [0] = arg0; objargs [1] = arg1; objargs [2] = arg2; objargs [3] = arg3; // walk all of the arg3; // walk all of the args in the variable part of the argument list. for (int i = 4; I objargs [ I] = typedreference.toobject (args.getnextarg ());} Return Concat (Objargs); / ** public static string concat (params object [] args ... {if (args == null) ... {throw new argumentnullexception ("args");} String [] Sargs = new string [args.length ]; Int Totallength = 0; for (int i = 0; I Sargs [i] = ((Args [i] == null) :( args [i] .tostring ()); Totallength = Sargs [i] .length;} Return Concatarray (SARGS, TOTALLENGTH); / ** public static string concat (string str000, string str1) ... {if (str000 == null) ... {if (str1 == null) ... {return string.empty;} return str1;} IF (str1 == null) ... {RETURN STR0;} int str0Length = str0.Length; String result = FastAllocateString (str0Length str1.Length); FillStringChecked (result, 0, str0); FillStringChecked (result, str0Length, str1); return result;} / ** public static String Concat (String STR0, STRING STR1, STRING STR2 ... {IF (str0 == null && str1 == null && str2 == null) ... {return.empty; IF (str0 == null) ... {str0 = string.empty;} IF (str1 == null) ... {str1 = String.empty;} IF (str2 == null) ... {str2 = String.empty;} INT TOTALLENGTH = STR0.LENGTH STR1.LENGTH STR2.LENGTH; String result = FastAllocateString (totalLength); FillStringChecked (result, 0, str0); FillStringChecked (result, str0.Length, str1); FillStringChecked (result, str0.Length str1.Length, str2); Return Result;} / ** Public Static String Concat (String Str0, String Str1, String Str2, String Str3) ... {if (str000 == null && str1 == null && str2 == null& str3 == null) ... { Return string.empty; IF (str0 == null) ... {str0 = string.empty;} IF (str1 == null) ... {str1 = String.empty;} IF (str2 == null) ... {str2 = String.empty;} if (str3 == null) ... {str3 = string.empty; int totalLength = str0.Length str1.Length str2.Length str3.Length; String result = FastAllocateString (totalLength); FillStringChecked (result, 0, str0); FillStringChecked (result, str0.Length, str1); FillStringChecked (result Str0.length str1.length, str2); FillStringChecked (Result, Str0.length str1.length str2.length, str3); Return Result;} Private static string concatarray (String [] Values, Int Totallength ... {string result = fastallocatestring (Totallength); int currpos = 0; For (int i = 0; I bcldebug.assert ((Currpos VALUES [i] .length <= Totallength), "[String.concatarray] (Currpos VALUES [I] .length <= Totallength)"); FillStringChecked (Result, Currpos, Values [i]); currpos = values [i] .length;} Return Result;} Private static string [] COPYARRAYONNULL (String [] VALUES, OUT INT TOTALLENGTH ... {TOTALLENGTH = 0; string [] OUTVALUES = New String [VALUES.LENGTH]; for (int i = 0; I Outvalues [i] = ((VALUES [I] == NULL)? String.empty: Values [I]); Totallength = Outvalues [i] .length;} return outvalues;} / ** public static string concat (params string [] value) ... {int Totallength = 0; IF (value == null) ... {throw new argumentnullexception ("values");} For (int i = 0; I I I I = == null) ... {Values = CopyArrayonnNull (Values, Out Totallength); Break;} else ... {TOTALLENGTH = VALUES [i] .length; }}}}} / ** public static string in (String Str) ... {if (str == null) ... {throw new argumentnullexception ("str");} Return Thread. GetDomain (). Getorinternstring (str); / ** public static string isInterned (String Str) ... {if (str == null) ... {throw new argumentnullexception ("str");} return thread.getdomain (). IsstringInterned (str);} ///////////////////////////////////////////////////////////////////////////////////////////////////// ' / ** /// Bool iConvertible.toboolean (iformatProvider Provider) ... {Return Convert.TOBOOLEAN (this, provider);} / ** /// car iconvertible.tochar (iformatProvider provides ... {Return Convert.TOCHAR (this, provider);} / ** /// [ClsCompliant (false)] sbyte iconvertible.tosbyte (iformatprovider provides) ... {Return Convert.TOSBYTE (this, provider);} / ** /// Byte iconvertible.tobyte (iformatprovider provider) ... {Return Convert.Tobyte (this, provider);} / ** /// short iconvertible.toint16 (iFORMATPROVIDER Provider) ... {Return Convert.Toint16 (this, provider);} / ** /// [CLSCompliant (false)] ushort IConvertible.ToUInt16 (IFormatProvider provider) ... {return Convert.ToUInt16 (this, provider);} / ** /// int IConvertible.ToInt32 (IFormatProvider provider). .. {Return Convert.Toint32 (this, provider);} / ** /// [ClsCompliant (false)] uint iconvertible.touint32 (iformatProvider provides ... {Return Convert.touint32 (this, provider);} / ** /// long iconvertible.toint64 (iFormatProvider Provider) ... {Return Convert.Toint64 (this, provider);} / ** /// [ClsCompliant (false)] ulong iconvertible.touint64 (iformatProvider provides) ... {Return Convert.touint64 (this, provider);} / ** /// FLOAT ICONVERTIBLE.TOSINGLE (IFORMATPROVIDER Provider) ... {Return Convert.TOSINGLE (this, provider);} / ** /// Double iconvertible.todouble (iformatprovider provider) ... {Return Convert.todouble (this, provider);} / ** /// Decimal iConvertible.todecimal (iformatProvider Provider) ... {Return Convert.Todecimal (this, provider);} / ** // / datetime iconvertible.todatetime (iformatprovider provider) ... {Return Convert.TodateTime (this, provider);} / ** /// Object iconvertible.totype (Type Type, IFORMATPROVIDER Provider) ... {Return Convert.defaulttotype (iconvertible) This, Type, Provider;} // Is this a string that can be compared quickly (that is it has only characters> 0x80 // and not a - or '[MethodImplAttribute (MethodImplOptions.InternalCall)] internal extern bool IsFastSort (); / ** unsafe internal void SetChar (int index, char value) ... {# i_Debug bcldebug.assert (ValidModifiableString (), "Modifiable String Must Not Hight"); # endif // Bounds check and the set the actual bit. if (( UINT32) INDEX> = (uint32) Length) Throw New ArgumentOutofrangeException ("index", Environment.getResourceString ("argumentoutofrange_index"); Fixed (char * p = & this.m_firstchar) ... {// set the character. p [index] = value;}} #if _DEBUG // Only used in debug build Insure that the HighChar state information for a string is not set as known [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern bool ValidModifiableString ();. # endif / ** unsafe internal void AppendInPlace (char value, int currentLength) ... {BCLDebug.Assert (currentLength Fixed (char * p = & this.m_firstchar) ... {// append the character. p [currentlength] = value; p [ currentlength] = '/ 0'; m_StringLength = CurrentLength;}} / ** unsafe internal void AppendInPlace (char value, int repeatCount, int currentLength) ... {BCLDebug.Assert (currentLength repeatCount / ** internal unsafe void AppendInPlace (String value, int currentLength) ... {BCLDebug.Assert (! Value = null, "! [String.AppendInPlace] value = null"); BCLDebug.Assert (value.Length currentLength < this.m_arrayLength, "[String.AppendInPlace] Length is wrong."); # if _DEBUG BCLDebug.Assert (ValidModifiableString (), "Modifiable string must not have highChars flags set"); # endif fillString (this, currentLength, value) ; SetLength (currentLength value.Length); NullTerminate ();!} internal void AppendInPlace (String value, int startIndex, int count, int currentLength) ... {BCLDebug.Assert (value = null, "[String.AppendInPlace] ! value = null "); BCLDebug.Assert (count currentLength internal unsafe void AppendInPlace (char * value, int count, int currentLength) ... {BCLDebug.Assert (! value = null, "! [String.AppendInPlace] value = null"); BCLDebug.Assert (count currentLength FillStringArray (this, currentlength, value, start, count); this.m_stringLength = (CurrentLength Count); this.nullterminate ();} / ** unsafe internal void ReplaceCharInPlace (char oldChar, char newChar, int startIndex, int count, int currentLength) ... {BCLDebug.Assert (startIndex> = 0, "[String.ReplaceCharInPlace] startIndex> 0"); BCLDebug. Assert (startIndex <= currentLength, "[String.ReplaceCharInPlace] startIndex> = Length"); BCLDebug.Assert ((startIndex <= currentLength-count), "[String.ReplaceCharInPlace] count> 0 && startIndex <= currentLength-count" ); # i_debug bcldebug.assert (ValidModifiableString (), "Modifiable String Must Not Have Highchars Flags Set"); # endifint endindex = startIndex count; Fixed (char * p = & this.m_firstcha ... {for (int i = startIndex; i I I I I I = == ilchar) ... {p [i] = newchar;}}}} / ** internal static String GetStringForStringBuilder (String value, int capacity) ... {BCLDebug.Assert (! Value = null, "! [String.GetStringForStringBuilder] value = null"); BCLDebug.Assert (capacity> = value.Length , "[String.GetStringForStringBuilder] capacity> = value.Length"); String newStr = FastAllocateString (capacity); if (value.Length == 0) ... {newStr.m_stringLength = 0; newStr.m_firstChar = '/ 0 '; Return NewStr;} FillString (newstr, 0, value); newstr.m_stringLength = value.m_stringLENGTH; RETURN newsTR;} / ** Private unsafe void NullTerminate () ... {Fixed (char * p = & this.m_firstcha) ... {p [m_stringLength] = '/ 0';}} / ** unsafe Internal void ClearPostnullchar () .. . {Int newlength = Length 1; if (Newlength Fixed (Char * P = & this.m_firstchar) ... {p [newlength] = '/ 0';}}} / ** INTERNAL VOID SETLENGTH (INT NEWLENGTH) ... {bcldebug.assert (Newlength <= m_Arraylength); M_StringLength = NewLength;} / ** public CharEnumerator GetEnumerator () ... {BCLDebug.Perf (false, "Avoid using String's CharEnumerator until C # special cases foreach on String - use the indexed property on String instead."); Return new CharEnumerator (this);} / ** /// IEnumerator IEnumerable.GetEnumerator () ... {BCLDebug.Perf (false, "Avoid using String's CharEnumerator until C # special cases foreach on String - use the indexed property on String instead."); Return new CharEnumerator ( THIS); // // This is just designed to prevent compiler warnings // This field is used from native, but we need to prevent the compiler warnings // # if _DEBUG private void DontTouchThis () ... {m_arrayLength = 0;.. M_stringLength = 0; m_firstchar = m_firstchar;} #ENDIF INTERNAL NSAFE VOID INTERSETCHARNOBOUNDSCHECK (int index, char value) ... {Fixed (char * p = & this.m_firstchar) ... {p [index] = value;}} // copies the source string (byte buffer) To the Destination INTPTR MEMORY Allocated with Len Bytes. Internal UNSAFE Static Void INTERCOPY (STRING SRC, INTPTR DEST, INT LEN) ... {if (len == 0) Return; Fixed (char * charptr = & src.m_firstchar) ... { BYTE * SRCPTR = (byte *) Charptr; Byte * Dstptr = (byte *) dest.topointer (); system.io .__ unmanagedMemoryStream.MemcpyImpl (srcptr, dstptr, len);}} . // memcopies characters inside a String internal unsafe static void InternalMemCpy (String src, int srcOffset, String dst, int destOffset, int len) ... {if (len == 0) return; fixed (char * srcPtr = & src. m_firstChar) ... {fixed (char * dstPtr = & dst.m_firstChar) ... {System.IO .__ UnmanagedMemoryStream.memcpyimpl ((byte *) (srcPtr srcOffset), (byte *) (dstPtr destOffset), len) }}} INTERNAL UNSAFE Static Void RevmemcpyImpl (Byte * SRC, BYTE * DEST, INT LEN) ... {IF (len == 0) Return; DEST = LEN; SRC = LEN; IF ((long) SRC & 3)! = 0) ... {DO ... {DEST -; SRC -; len ---; * dest = * src WHILE (LEN> 0 && ((long) src & 3)! = 0);}} (len> = 16) ... {LEN - = 16; do ... {dest - = (byte *) 16; SRC - = (Byte *) 16; (INT *) DEST) [3] = ((int *) src) [3]; (int *) dest) [2] = ((int *) src ) [2]; (INT *) DEST) [1] = ((int *) src) [1]; (INT *) DEST) [0] = ((int *) src) [0];} While ((LEN - = 16)> = 0);} f ((Len & 8)> 0) ... {DEST - = (Byte *) 8; SRC - = (Byte *) 8; (INT * ) DEST) [1] = ((int *) src) [1]; (INT *) DEST) [0] = ((int *) src) [0];} IF ((Len & 4)> 0 ) ... {DEST - = (BYTE *) 4; SRC - = (Byte *) 4; (INT *) DEST) [0] = ((int *) src) [0];} IF ((Len &) 2)! = 0) ... {DEST - = (Byte *) 2; SRC - = (Byte *) 2; ((Short *) DEST) [0] = ((Short *) src) [0]; } IF ((len & 1)! = 0) ... {DEST ---; SRC--; * DEST = * src;}} // Copies the Source String (Byte Buffer) To The Destination INTPTR MEMORY Allocated with Len Bytes. Internal UNSAFE Static Void Internal Void (String src, Byte [] DEST, INT LEN) ... {IF (len == 0) Return; fixed (char * charPtr = & src.m_firstChar) ... {fixed (byte * destPtr = dest) ... {byte * srcPtr = (byte *) charPtr; System.IO .__ UnmanagedMemoryStream.memcpyimpl (srcPtr, destPtr, len) }}} internal unsafe void InsertInPlace (int index, String value, int repeatCount, int currentLength, int requiredLength) ... {BCLDebug.Assert (requiredLength