| File: System\Text\StringBuilder.NativeAot.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj (System.Private.CoreLib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace System.Text { public partial class StringBuilder { /// <summary> /// Calculate the new length for array allocation when marshalling StringBuilder in interop /// while taking current capacity into account /// This is needed to ensure compat with desktop CLR behavior /// </summary> internal int GetAllocationLength(int requiredLength) { int currentLength = Capacity; if (currentLength < requiredLength) { // round the current length to the nearest multiple of 2 // that is >= the required length return (requiredLength + 1) & ~1; } return currentLength; } /// <summary> /// Throw away the current contents in this StringBuffer and replace it with a new char[] /// NOTE: The buffer in StringBuilder is *not* NULL-terminated. /// This is only called from MCG code /// </summary> internal unsafe void ReplaceBuffer(char* newBuffer) { int len = string.wcslen(newBuffer); // the '+1' is for back-compat with desktop CLR in terms of length calculation because desktop // CLR had '\0' char[] chunkChars = new char[GetAllocationLength(len + 1)]; new ReadOnlySpan<char>(newBuffer, len).CopyTo(chunkChars); ReplaceBufferInternal(chunkChars, len); } /// <summary> /// Throw away the current contents in this StringBuffer and replace it with a new char[] /// NOTE: The buffer in StringBuilder is *not* NULL-terminated. /// This is only called from MCG code /// </summary> internal void ReplaceBuffer(char[] chunkCharsCandidate) { int len = chunkCharsCandidate.Length; int newLen = GetAllocationLength(len + 1); if (len == newLen) { ReplaceBufferInternal(chunkCharsCandidate, len); } else { char[] chunkChars = new char[GetAllocationLength(len + 1)]; new ReadOnlySpan<char>(chunkCharsCandidate, 0, len).CopyTo(chunkChars); ReplaceBufferInternal(chunkChars, len); } } /// <summary> /// Replace the internal buffer with the specified length /// This is only called from MCG code /// </summary> private void ReplaceBufferInternal(char[] chunkChars, int length) { m_ChunkChars = chunkChars; m_ChunkOffset = 0; m_ChunkLength = length; m_ChunkPrevious = null; } /// <summary> /// Return buffer if single chunk, for MCG interop /// </summary> internal char[] GetBuffer(out int len) { len = 0; if (m_ChunkOffset == 0) { len = Length; return m_ChunkChars; } else { return null; } } } }