System.String 类的实现代码

// ==++==
//
//  
//    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: Contains headers for the String class.  Actual implementations
** are in String.cpp
**
** Date:  March 15, 1998
**
===========================================================*/
namespace System ...{
    using System.Text;
    using System;
    using System.Globalization;
    using System.Threading;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using va_list = System.ArgIterator;
    using __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(s);
    //
    /**
    [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 doesn't mark this as a literal.
        //Marking 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 static String Join (String separator, String[] value) ...{
            if (value==null) ...{
                throw new ArgumentNullException("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 security team.  They need to uppercase some strings (guaranteed to be less
        // than 0x80) before security is fully initialized.  Without security initialized, we can't 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 strA) ...{
            String newString = 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 isn't 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(String 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 InternalGetChar(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 characters.
        /**
        public char[] ToCharArray() ...{
            return ToCharArray(0,Length);
        }
   
        // Returns a substring of this string as an array of characters.
        //
        /**
        public char[] ToCharArray(int startIndex, int length)
        ...{
            // Range check everything.
            if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
                throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
            if (length < 0)
                throw new ArgumentOutOfRangeException("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 such that 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 (i.e., Character.IsWhitespace) is used 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 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 spearator is the empty string (i.e., String.Empty), then
        // whitespace (i.e., Character.IsWhitespace) is used as the separator.
        // If there are 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 startIndex) ...{
            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 ArgumentOutOfRangeException("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't run
        //CharacterInfo's class initializer (which goes to native and looks for a
        //resource table that hasn't 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);
        }
   
        // Removes a string of characters from the beginning 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 characters from the end of this 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>;"; (i.e.,
        // 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 internal String CreateStringFromASCII(byte[] bytes, int startIndex, int length) ...{
            BCLDebug.Assert(bytes != null, "need a byte[].");
            BCLDebug.Assert(startIndex >= 0 && (startIndex < bytes.Length || bytes.Length == 0), "startIndex >= 0 && startIndex < bytes.Length");
            BCLDebug.Assert(length >= 0 && length <= bytes.Length - startIndex, "length >= 0 && length <= bytes.Length - startIndex");
            if (length == 0)
                return String.Empty;
            String s = FastAllocateString(length);
            fixed(char* pChars = &s.m_firstChar) ...{
                for(int i=0; i                    pChars[i] = (char) (bytes[i+startIndex] & 0x7f);
            }
            return s;
        }
   
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern static String FastAllocateString(int length);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern static void FillString(String dest, int destPos, String src);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern static void FillStringChecked(String dest, int destPos, String src);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern static void FillStringEx(String dest, int destPos, String src,int srcLength);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private extern static void FillStringArray(String dest, int stringStart, char[] array, int charStart, 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.CurrentCulture.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, int indexA, String strB, int indexB, int length) ...{
            int lengthA = length;
            int lengthB = length;

            if (strA!=null) ...{
                if (strA.Length - indexA < lengthA) ...{
                  lengthA = (strA.Length - indexA);
                }
            }

            if (strB!=null) ...{
                if (strB.Length - indexB < lengthB) ...{
                    lengthB = (strB.Length - indexB);
                }
            }
            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 count is compared with the substring of strB
        // beginning at indexB of the same length.  Case sensitivity is determined by the ignoreCase boolean.
        //
        /**
        public static int Compare(String strA, int indexA, String strB, int indexB, int length, bool ignoreCase) ...{
            int lengthA = length;
            int lengthB = length;

            if (strA!=null) ...{
                if (strA.Length - indexA < lengthA) ...{
                  lengthA = (strA.Length - indexA);
                }
            }

            if (strB!=null) ...{
                if (strB.Length - indexB < lengthB) ...{
                    lengthB = (strB.Length - indexB);
                }
            }

            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 ArgumentNullException("culture");
            }

            int lengthA = length;
            int lengthB = length;

            if (strA!=null) ...{
                if (strA.Length - indexA < lengthA) ...{
                  lengthA = (strA.Length - indexA);
                }
            }

            if (strB!=null) ...{
                if (strB.Length - indexB < lengthB) ...{
                    lengthB = (strB.Length - indexB);
                }
            }
   
            if (ignoreCase) ...{
                return culture.CompareInfo.Compare(strA,indexA,lengthA, strB, indexB, lengthB,CompareOptions.IgnoreCase);
            } else ...{
                return culture.CompareInfo.Compare(strA,indexA,lengthA, strB, indexB, lengthB,CompareOptions.None);
            }
        }
   
        // Compares this object to another object, returning an integer that
        // indicates the relationship. This method returns a value less than 0 if this is less than value, 0
        // if this is equal to value, or a value greater than 0
        // if this is greater than value.  Strings are considered to be
        // greater than all non-String objects.  Note that this means sorted
        // arrays would contain nulls, other objects, then Strings in that order.
        //
        /**
        public int CompareTo(Object value) ...{
            if (value == null) ...{
                return 1;
            }
           
            if (!(value is String)) ...{
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeString"));
            }

            return String.Compare(this,(String)value);
        }
   
        // Determines the sorting relation of StrB to the current instance.
        //
        /**
        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 strB) ...{
            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 nativeCompareOrdinal(strA, strB, false);
        }
   
        // Compares strA and strB using an ordinal (code-point) comparison.
        //
        /**
        public static int CompareOrdinal(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 nativeCompareOrdinalEx(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 valueLen = value.Length;
            int thisLen = this.Length;
            if (valueLen>thisLen) ...{
                return false;
            }
            return (0==Compare(this, thisLen-valueLen, value, 0, valueLen));
        }

        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 [] anyOf) ...{
            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 within this string of the first occurence of the 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 within the string.
        //
        /**
        public int LastIndexOf(char value) ...{
            return LastIndexOf(value, this.Length-1, this.Length);
        }
   
        /**
        public int LastIndexOf(char 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 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 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 startIndex) ...{
            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 paddingChar) ...{
            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");
            }
            if (this.Length
                return false;
            }
            return (0==Compare(this,0, value,0, value.Length));
        }
   
        // Creates a copy of this string in lower case.
        /**
        public String ToLower() ...{
            return this.ToLower(CultureInfo.CurrentCulture);
        }
   
        // Creates a copy of this string in lower case.  The culture is set by culture.
        /**
        public String ToLower(CultureInfo culture) ...{
            if (culture==null) ...{
                throw new ArgumentNullException("culture");
            }
            return culture.TextInfo.ToLower(this);
        }
   
        // Creates a copy of this string in upper case.
        /**
        public String ToUpper() ...{
            return this.ToUpper(CultureInfo.CurrentCulture);
        }
   
        // Creates a copy of this string in upper case.  The culture is set by culture.
        /**
        public String ToUpper(CultureInfo culture) ...{
            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(MethodImplOptions.InternalCall)]
        public extern String Replace (char oldChar, char newChar);

    // 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");
            }

            int length = 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 changed 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;
            }
            return Concat(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 Concat(arg0.ToString(), arg1.ToString(), arg2.ToString());
        }

        /**
        [CLSCompliant(false)]
        public static String Concat(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 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)?(String.Empty):(args[i].ToString()));
                totalLength += sArgs[i].Length;
            }
            return ConcatArray(sArgs, totalLength);
        }


        /**
        public static String Concat(String str0, String str1) ...{
            if (str0 == 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 String.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 (str0==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[] values) ...{
            int totalLength=0;

            if (values==null) ...{
                throw new ArgumentNullException("values");
            }

            for (int i=0; i                if (values[i]==null) ...{
                    values = CopyArrayOnNull(values, out totalLength);
                    break;
                } else ...{
                    totalLength += values[i].Length;
                }
            }
           
            return ConcatArray(values, totalLength);
        }

        /**
        public static String Intern(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);
        }


        //
        // IValue implementation
        //
       
        /**
        public TypeCode GetTypeCode() ...{
            return TypeCode.String;
        }

        /**
        ///
        bool IConvertible.ToBoolean(IFormatProvider provider) ...{
            return Convert.ToBoolean(this, provider);
        }

        /**
        ///
        char IConvertible.ToChar(IFormatProvider provider) ...{
            return Convert.ToChar(this, provider);
        }

        /**
        ///
        [CLSCompliant(false)]
        sbyte IConvertible.ToSByte(IFormatProvider provider) ...{
            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 provider) ...{
            return Convert.ToUInt32(this, provider);
        }

        /**
        ///
        long IConvertible.ToInt64(IFormatProvider provider) ...{
            return Convert.ToInt64(this, provider);
        }

        /**
        ///
        [CLSCompliant(false)]
        ulong IConvertible.ToUInt64(IFormatProvider provider) ...{
            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)
        ...{
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif

            //Bounds check and then 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 < m_arrayLength, "[String.AppendInPlace(char)currentLength < m_arrayLength");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif

            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 < m_arrayLength, "[String.AppendInPlace]currentLength+repeatCount < m_arrayLength");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif
           
            int newLength = currentLength + repeatCount;


            fixed (char *p = &this.m_firstChar)
            ...{
                int i;
                for (i=currentLength; i                    p[i] = value;
                }
                p[i] = '/0';
            }
            this.m_stringLength = newLength;
        }

        /**
       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 < this.m_arrayLength, "[String.AppendInPlace]count + currentLength < this.m_arrayLength");
            BCLDebug.Assert(count>=0, "[String.AppendInPlace]count>=0");
            BCLDebug.Assert(startIndex>=0, "[String.AppendInPlace]startIndex>=0");
            BCLDebug.Assert(startIndex <= (value.Length - count), "[String.AppendInPlace]startIndex <= (value.Length - count)");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif
           
            FillSubstring(this, currentLength, value, startIndex, count);
            SetLength(currentLength + count);
            NullTerminate();
        }

        internal unsafe void AppendInPlace(char *value, int count,int currentLength) ...{
            BCLDebug.Assert(value!=null, "[String.AppendInPlace]value!=null");
            BCLDebug.Assert(count + currentLength < this.m_arrayLength, "[String.AppendInPlace]count + currentLength < this.m_arrayLength");
            BCLDebug.Assert(count>=0, "[String.AppendInPlace]count>=0");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif
            fixed(char *p = &this.m_firstChar) ...{
                int i;
                for (i=0; i                    p[currentLength+i] = value[i];
                }
            }
            SetLength(currentLength + count);
            NullTerminate();
        }


        /**
        internal unsafe void AppendInPlace(char[] value, int start, int count, int currentLength) ...{
            BCLDebug.Assert(value!=null, "[String.AppendInPlace]value!=null");
            BCLDebug.Assert(count + currentLength < this.m_arrayLength, "[String.AppendInPlace]Length is wrong.");
            BCLDebug.Assert(value.Length-count>=start, "[String.AppendInPlace]value.Length-count>=start");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif

            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");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif

            int endIndex = startIndex+count;

            fixed (char *p = &this.m_firstChar) ...{
                for (int i=startIndex;i                    if (p[i]==oldChar) ...{
                        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_firstChar) ...{
                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, "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 unsafe void InternalSetCharNoBoundsCheck(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 InternalCopy(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);
            }
           
            if (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);
            }
            if ((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 InternalCopy(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  < m_arrayLength, "[String.InsertString] requiredLength  < m_arrayLength");
            BCLDebug.Assert(index + value.Length * repeatCount < m_arrayLength, "[String.InsertString] index + value.Length * repeatCount < m_arrayLength");
#if _DEBUG
            BCLDebug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
#endif
              //Copy the old characters over to make room and then insert the new characters.
            fixed(char* srcPtr = &this.m_firstChar) ...{
                fixed(char* valuePtr = &value.m_firstChar) ...{
                   revmemcpyimpl((byte*)(srcPtr + index),(byte*)(srcPtr + index + value.Length * repeatCount), (currentLength - index) * sizeof(char));
                   for (int i=0; i                        System.IO.__UnmanagedMemoryStream.memcpyimpl((byte*)valuePtr, (byte*)(srcPtr + index + i * value.Length), value.Length * sizeof(char));
                   }
                }
                srcPtr[requiredLength] = '/0';
            }
            this.m_stringLength = requiredLength;
        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值