// Returns a substring of this string.
//
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public String Substring (int startIndex) {
return this.Substring (startIndex, Length-startIndex);
}
// Returns a substring of this string.
//
[System.Security.SecuritySafeCritical] // auto-generated
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public String Substring(int startIndex, int length) {
// okay to not enforce copying in the case of Substring(0, length), since we assume
// String instances are immutable.
return InternalSubStringWithChecks(startIndex, length, false);
}
[System.Security.SecurityCritical] // auto-generated
internal String InternalSubStringWithChecks (int startIndex, int length, bool fAlwaysCopy) {
//Bounds Checking.
if (startIndex < 0) {
throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (startIndex > Length) {
throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
}
if (length < 0) {
throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (startIndex > Length - length) {
throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
}
Contract.EndContractBlock();
if( length == 0) {
return String.Empty;
}
return InternalSubString(startIndex, length, fAlwaysCopy);
}
[System.Security.SecurityCritical] // auto-generated
unsafe string InternalSubString(int startIndex, int length, bool fAlwaysCopy) {
Contract.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
Contract.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!");
if( startIndex == 0 && length == this.Length && !fAlwaysCopy) {
return this;
}
String result = FastAllocateString(length);
fixed(char* dest = &result.m_firstChar)
fixed(char* src = &this.m_firstChar) {
wstrcpy(dest, src + startIndex, length);
}
return result;
}