445 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			445 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using Unity.Collections.LowLevel.Unsafe; | ||
|  | 
 | ||
|  | namespace Unity.Collections | ||
|  | { | ||
|  |     /// <summary> | ||
|  |     /// Provides extension methods for FixedString*N*Bytes. | ||
|  |     /// </summary> | ||
|  |     [GenerateTestsForBurstCompatibility] | ||
|  |     public unsafe static partial class FixedStringMethods | ||
|  |     { | ||
|  |         /// <summary> | ||
|  |         /// Appends a Unicode.Rune to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="rune">A Unicode.Rune to append.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, Unicode.Rune rune) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             var len = fs.Length; | ||
|  |             var runeLen = rune.LengthInUtf8Bytes(); | ||
|  |             if (!fs.TryResize(len + runeLen, NativeArrayOptions.UninitializedMemory)) | ||
|  |                 return FormatError.Overflow; | ||
|  |             return fs.Write(ref len, rune); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a char to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="ch">A char to append.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, char ch) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             return fs.Append((Unicode.Rune) ch); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a byte to this string. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// No validation is performed: it is your responsibility for the data to be valid UTF-8 when you're done appending bytes. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="a">A byte to append.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError AppendRawByte<T>(ref this T fs, byte a) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             var origLength = fs.Length; | ||
|  |             if (!fs.TryResize(origLength + 1, NativeArrayOptions.UninitializedMemory)) | ||
|  |                 return FormatError.Overflow; | ||
|  |             fs.GetUnsafePtr()[origLength] = a; | ||
|  |             return FormatError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a Unicode.Rune a number of times to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="rune">A Unicode.Rune to append some number of times.</param> | ||
|  |         /// <param name="count">The number of times to append the rune.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, Unicode.Rune rune, int count) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             var origLength = fs.Length; | ||
|  | 
 | ||
|  |             if (!fs.TryResize(origLength + rune.LengthInUtf8Bytes() * count, NativeArrayOptions.UninitializedMemory)) | ||
|  |                 return FormatError.Overflow; | ||
|  | 
 | ||
|  |             var cap = fs.Capacity; | ||
|  |             var b = fs.GetUnsafePtr(); | ||
|  |             int offset = origLength; | ||
|  |             for (int i = 0; i < count; ++i) | ||
|  |             { | ||
|  |                 var error = Unicode.UcsToUtf8(b, ref offset, cap, rune); | ||
|  |                 if (error != ConversionError.None) | ||
|  |                     return FormatError.Overflow; | ||
|  |             } | ||
|  | 
 | ||
|  |             return FormatError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a number (converted to UTF-8 characters) to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="input">A long integer to append to the string.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, long input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             const int maximumDigits = 20; | ||
|  |             var temp = stackalloc byte[maximumDigits]; | ||
|  |             int offset = maximumDigits; | ||
|  |             if (input >= 0) | ||
|  |             { | ||
|  |                 do | ||
|  |                 { | ||
|  |                     var digit = (byte)(input % 10); | ||
|  |                     temp[--offset] = (byte)('0' + digit); | ||
|  |                     input /= 10; | ||
|  |                 } | ||
|  |                 while (input != 0); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 do | ||
|  |                 { | ||
|  |                     var digit = (byte)(input % 10); | ||
|  |                     temp[--offset] = (byte)('0' - digit); | ||
|  |                     input /= 10; | ||
|  |                 } | ||
|  |                 while (input != 0); | ||
|  |                 temp[--offset] = (byte)'-'; | ||
|  |             } | ||
|  | 
 | ||
|  |             return fs.Append(temp + offset, maximumDigits - offset); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a number (converted to UTF-8 characters) to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="input">An int to append to the string.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, int input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             return fs.Append((long)input); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a number (converted to UTF-8 characters) to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="input">A ulong integer to append to the string.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, ulong input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             const int maximumDigits = 20; | ||
|  |             var temp = stackalloc byte[maximumDigits]; | ||
|  |             int offset = maximumDigits; | ||
|  |             do | ||
|  |             { | ||
|  |                 var digit = (byte)(input % 10); | ||
|  |                 temp[--offset] = (byte)('0' + digit); | ||
|  |                 input /= 10; | ||
|  |             } | ||
|  |             while (input != 0); | ||
|  | 
 | ||
|  |             return fs.Append(temp + offset, maximumDigits - offset); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a number (converted to UTF-8 characters) to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="input">A uint to append to the string.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, uint input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             return fs.Append((ulong)input); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends a number (converted to UTF-8 characters) to this string. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of FixedString*N*Bytes.</typeparam> | ||
|  |         /// <param name="fs">A FixedString*N*Bytes.</param> | ||
|  |         /// <param name="input">A float to append to the string.</param> | ||
|  |         /// <param name="decimalSeparator">The character to use as the decimal separator. Defaults to a period ('.').</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T>(ref this T fs, float input, char decimalSeparator = '.') | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             FixedStringUtils.UintFloatUnion ufu = new FixedStringUtils.UintFloatUnion(); | ||
|  |             ufu.floatValue = input; | ||
|  |             var sign = ufu.uintValue >> 31; | ||
|  |             ufu.uintValue &= ~(1 << 31); | ||
|  |             FormatError error; | ||
|  |             if ((ufu.uintValue & 0x7F800000) == 0x7F800000) | ||
|  |             { | ||
|  |                 if (ufu.uintValue == 0x7F800000) | ||
|  |                 { | ||
|  |                     if (sign != 0 && ((error = fs.Append('-')) != FormatError.None)) | ||
|  |                         return error; | ||
|  |                     return fs.Append('I', 'n', 'f', 'i', 'n', 'i', 't', 'y'); | ||
|  |                 } | ||
|  |                 return fs.Append('N', 'a', 'N'); | ||
|  |             } | ||
|  |             if (sign != 0 && ufu.uintValue != 0) // C# prints -0 as 0 | ||
|  |                 if ((error = fs.Append('-')) != FormatError.None) | ||
|  |                     return error; | ||
|  |             ulong decimalMantissa = 0; | ||
|  |             int decimalExponent = 0; | ||
|  |             FixedStringUtils.Base2ToBase10(ref decimalMantissa, ref decimalExponent, ufu.floatValue); | ||
|  |             var backwards = stackalloc char[9]; | ||
|  |             int decimalDigits = 0; | ||
|  |             do | ||
|  |             { | ||
|  |                 if (decimalDigits >= 9) | ||
|  |                     return FormatError.Overflow; | ||
|  |                 var decimalDigit = decimalMantissa % 10; | ||
|  |                 backwards[8 - decimalDigits++] = (char)('0' + decimalDigit); | ||
|  |                 decimalMantissa /= 10; | ||
|  |             } | ||
|  |             while (decimalMantissa > 0); | ||
|  |             char *ascii = backwards + 9 - decimalDigits; | ||
|  |             var leadingZeroes = -decimalExponent - decimalDigits + 1; | ||
|  |             if (leadingZeroes > 0) | ||
|  |             { | ||
|  |                 if (leadingZeroes > 4) | ||
|  |                     return fs.AppendScientific(ascii, decimalDigits, decimalExponent, decimalSeparator); | ||
|  |                 if ((error = fs.Append('0', decimalSeparator)) != FormatError.None) | ||
|  |                     return error; | ||
|  |                 --leadingZeroes; | ||
|  |                 while (leadingZeroes > 0) | ||
|  |                 { | ||
|  |                     if ((error = fs.Append('0')) != FormatError.None) | ||
|  |                         return error; | ||
|  |                     --leadingZeroes; | ||
|  |                 } | ||
|  |                 for (var i = 0; i < decimalDigits; ++i) | ||
|  |                 { | ||
|  |                     if ((error = fs.Append(ascii[i])) != FormatError.None) | ||
|  |                         return error; | ||
|  |                 } | ||
|  |                 return FormatError.None; | ||
|  |             } | ||
|  |             var trailingZeroes = decimalExponent; | ||
|  |             if (trailingZeroes > 0) | ||
|  |             { | ||
|  |                 if (trailingZeroes > 4) | ||
|  |                     return fs.AppendScientific(ascii, decimalDigits, decimalExponent, decimalSeparator); | ||
|  |                 for (var i = 0; i < decimalDigits; ++i) | ||
|  |                 { | ||
|  |                     if ((error = fs.Append(ascii[i])) != FormatError.None) | ||
|  |                         return error; | ||
|  |                 } | ||
|  |                 while (trailingZeroes > 0) | ||
|  |                 { | ||
|  |                     if ((error = fs.Append('0')) != FormatError.None) | ||
|  |                         return error; | ||
|  |                     --trailingZeroes; | ||
|  |                 } | ||
|  |                 return FormatError.None; | ||
|  |             } | ||
|  |             var indexOfSeparator = decimalDigits + decimalExponent; | ||
|  |             for (var i = 0; i < decimalDigits; ++i) | ||
|  |             { | ||
|  |                 if (i == indexOfSeparator) | ||
|  |                     if ((error = fs.Append(decimalSeparator)) != FormatError.None) | ||
|  |                         return error; | ||
|  |                 if ((error = fs.Append(ascii[i])) != FormatError.None) | ||
|  |                     return error; | ||
|  |             } | ||
|  |             return FormatError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends another string to this string. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <typeparam name="T2">The type of the source string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="input">The source string.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the destination string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes), typeof(FixedString128Bytes) })] | ||
|  |         public static FormatError Append<T,T2>(ref this T fs, in T2 input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |             where T2 : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             ref var inputRef = ref UnsafeUtilityExtensions.AsRef(input); | ||
|  |             return fs.Append(inputRef.GetUnsafePtr(), inputRef.Length); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Copies another string to this string (making the two strings equal). | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <typeparam name="T2">The type of the source string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="input">The source string.</param> | ||
|  |         /// <returns>CopyError.None if successful. Returns CopyError.Truncation if the source string is too large to fit in the destination.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes), typeof(FixedString128Bytes) })] | ||
|  |         public static CopyError CopyFrom<T, T2>(ref this T fs, in T2 input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |             where T2 : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             fs.Length = 0; | ||
|  |             var fe = Append(ref fs, input); | ||
|  |             if (fe != FormatError.None) | ||
|  |                 return CopyError.Truncation; | ||
|  |             return CopyError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends bytes to this string. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// | ||
|  |         /// No validation is performed: it is your responsibility for the destination to contain valid UTF-8 when you're done appending bytes. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="utf8Bytes">The bytes to append.</param> | ||
|  |         /// <param name="utf8BytesLength">The number of bytes to append.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the destination string is exceeded.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes) })] | ||
|  |         public unsafe static FormatError Append<T>(ref this T fs, byte* utf8Bytes, int utf8BytesLength) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             var origLength = fs.Length; | ||
|  |             if (!fs.TryResize(origLength + utf8BytesLength, NativeArrayOptions.UninitializedMemory)) | ||
|  |                 return FormatError.Overflow; | ||
|  |             UnsafeUtility.MemCpy(fs.GetUnsafePtr() + origLength, utf8Bytes, utf8BytesLength); | ||
|  |             return FormatError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Appends another string to this string. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="s">The string to append.</param> | ||
|  |         /// <returns>FormatError.None if successful. Returns FormatError.Overflow if the capacity of the destination string is exceeded.</returns> | ||
|  |         [ExcludeFromBurstCompatTesting("Takes managed string")] | ||
|  |         public unsafe static FormatError Append<T>(ref this T fs, string s) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             // we don't know how big the expansion from UTF16 to UTF8 will be, so we account for worst case. | ||
|  |             int worstCaseCapacity = s.Length * 4; | ||
|  |             byte* utf8Bytes = stackalloc byte[worstCaseCapacity]; | ||
|  |             int utf8Len; | ||
|  | 
 | ||
|  |             fixed (char* chars = s) | ||
|  |             { | ||
|  |                 var err = UTF8ArrayUnsafeUtility.Copy(utf8Bytes, out utf8Len, worstCaseCapacity, chars, s.Length); | ||
|  |                 if (err != CopyError.None) | ||
|  |                 { | ||
|  |                     return FormatError.Overflow; | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             return fs.Append(utf8Bytes, utf8Len); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Copies another string to this string (making the two strings equal). | ||
|  |         /// Replaces any existing content of the FixedString. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="s">The source string.</param> | ||
|  |         /// <returns>CopyError.None if successful. Returns CopyError.Truncation if the source string is too large to fit in the destination.</returns> | ||
|  |         [ExcludeFromBurstCompatTesting("Takes managed string")] | ||
|  |         public static CopyError CopyFrom<T>(ref this T fs, string s) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             fs.Length = 0; | ||
|  |             var fe = Append(ref fs, s); | ||
|  |             if (fe != FormatError.None) | ||
|  |                 return CopyError.Truncation; | ||
|  |             return CopyError.None; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Copies another string to this string. If the string exceeds the capacity it will be truncated. | ||
|  |         /// Replaces any existing content of the FixedString. | ||
|  |         /// </summary> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="s">The source string.</param> | ||
|  |         /// <returns>CopyError.None if successful. Returns CopyError.Truncation if the source string is too large to fit in the destination.</returns> | ||
|  |         [ExcludeFromBurstCompatTesting("Takes managed string")] | ||
|  |         public static CopyError CopyFromTruncated<T>(ref this T fs, string s) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             int utf8Len; | ||
|  |             fixed (char* chars = s) | ||
|  |             { | ||
|  |                 var error = UTF8ArrayUnsafeUtility.Copy(fs.GetUnsafePtr(), out utf8Len, fs.Capacity, chars, s.Length); | ||
|  |                 fs.Length = utf8Len; | ||
|  |                 return error; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Copies another string to this string. If the string exceeds the capacity it will be truncated. | ||
|  |         /// </summary> | ||
|  |         /// <remarks> | ||
|  |         /// When the method returns an error, the destination string is not modified. | ||
|  |         /// </remarks> | ||
|  |         /// <typeparam name="T">The type of the destination string.</typeparam> | ||
|  |         /// <typeparam name="T2">The type of the source string.</typeparam> | ||
|  |         /// <param name="fs">The destination string.</param> | ||
|  |         /// <param name="input">The source string.</param> | ||
|  |         /// <returns>CopyError.None if successful. Returns CopyError.Truncation if the source string is too large to fit in the destination.</returns> | ||
|  |         [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(FixedString128Bytes), typeof(FixedString128Bytes) })] | ||
|  |         public static CopyError CopyFromTruncated<T, T2>(ref this T fs, in T2 input) | ||
|  |             where T : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |             where T2 : unmanaged, INativeList<byte>, IUTF8Bytes | ||
|  |         { | ||
|  |             var error = UTF8ArrayUnsafeUtility.Copy(fs.GetUnsafePtr(), out int utf8Len, fs.Capacity, input.GetUnsafePtr(), input.Length); | ||
|  |             fs.Length = utf8Len; | ||
|  |             return error; | ||
|  |         } | ||
|  |     } | ||
|  | } |