{
private const int StackallocIntBufferSizeLimit = 128;
- private static unsafe void FillStringChecked(string dest, int destPos, string src)
+ private static void FillStringChecked(string dest, int destPos, string src)
{
Debug.Assert(dest != null);
Debug.Assert(src != null);
throw new IndexOutOfRangeException();
}
- fixed (char* pDest = &dest._firstChar)
- fixed (char* pSrc = &src._firstChar)
- {
- wstrcpy(pDest + destPos, pSrc, src.Length);
- }
+ Buffer.Memmove(
+ destination: ref Unsafe.Add(ref dest._firstChar, destPos),
+ source: ref src._firstChar,
+ elementCount: (uint)src.Length);
}
public static string Concat(object? arg0) => arg0?.ToString() ?? string.Empty;
return InternalSubString(startIndex, length);
}
- private unsafe string InternalSubString(int startIndex, int length)
+ private string InternalSubString(int startIndex, int length)
{
Debug.Assert(startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
Debug.Assert(length >= 0 && startIndex <= this.Length - length, "length is out of range!");
string result = FastAllocateString(length);
- fixed (char* dest = &result._firstChar)
- fixed (char* src = &_firstChar)
- {
- wstrcpy(dest, src + startIndex, length);
- }
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref Unsafe.Add(ref _firstChar, startIndex));
return result;
}
return Empty;
string result = FastAllocateString(value.Length);
- unsafe
- {
- fixed (char* dest = &result._firstChar, source = value)
- wstrcpy(dest, source, value.Length);
- }
+
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref MemoryMarshal.GetArrayDataReference(value));
+
return result;
}
return Empty;
string result = FastAllocateString(length);
- unsafe
- {
- fixed (char* dest = &result._firstChar, source = value)
- wstrcpy(dest, source + startIndex, length);
- }
+
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(value), startIndex));
+
return result;
}
return Empty;
string result = FastAllocateString(count);
- fixed (char* dest = &result._firstChar)
- wstrcpy(dest, ptr, count);
+
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref *ptr);
+
return result;
}
throw new ArgumentOutOfRangeException(nameof(ptr), SR.ArgumentOutOfRange_PartialWCHAR);
string result = FastAllocateString(length);
- fixed (char* dest = &result._firstChar)
- wstrcpy(dest, pStart, length);
+
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref *pStart);
+
return result;
}
throw new ArgumentNullException(nameof(str));
string result = FastAllocateString(str.Length);
- fixed (char* dest = &result._firstChar, src = &str._firstChar)
- wstrcpy(dest, src, str.Length);
+
+ Buffer.Memmove(
+ elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
+ destination: ref result._firstChar,
+ source: ref str._firstChar);
+
return result;
}
if (destinationIndex > destination.Length - count || destinationIndex < 0)
throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount);
- fixed (char* src = &_firstChar, dest = destination)
- wstrcpy(dest + destinationIndex, src + sourceIndex, count);
+ Buffer.Memmove(
+ destination: ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(destination), destinationIndex),
+ source: ref Unsafe.Add(ref _firstChar, sourceIndex),
+ elementCount: (uint)count);
}
// Returns the entire string as an array of characters.
- public unsafe char[] ToCharArray()
+ public char[] ToCharArray()
{
if (Length == 0)
return Array.Empty<char>();
char[] chars = new char[Length];
- fixed (char* src = &_firstChar, dest = &chars[0])
- wstrcpy(dest, src, Length);
+
+ Buffer.Memmove(
+ destination: ref MemoryMarshal.GetArrayDataReference(chars),
+ source: ref _firstChar,
+ elementCount: (uint)Length);
+
return chars;
}
// Returns a substring of this string as an array of characters.
//
- public unsafe char[] ToCharArray(int startIndex, int length)
+ public char[] ToCharArray(int startIndex, int length)
{
// Range check everything.
if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
}
char[] chars = new char[length];
- fixed (char* src = &_firstChar, dest = &chars[0])
- wstrcpy(dest, src + startIndex, length);
+
+ Buffer.Memmove(
+ destination: ref MemoryMarshal.GetArrayDataReference(chars),
+ source: ref Unsafe.Add(ref _firstChar, startIndex),
+ elementCount: (uint)length);
+
return chars;
}