diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs
new file mode 100644
index 0000000..c8a9a0e
--- /dev/null
+++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs
@@ -0,0 +1,239 @@
+#if ZSTRING_COLLECTIONS_SUPPORT
+using System;
+using System.Buffers;
+using System.Runtime.CompilerServices;
+using System.Text;
+using Unity.Collections;
+
+namespace Cysharp.Text
+{
+ partial struct Utf16ValueStringBuilder
+ {
+ private static readonly Encoding UTF8NoBom = new UTF8Encoding(false);
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the byte length of the buffer exceeds 29 bytes.
+ public FixedString32Bytes AsFixedString32Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString32Bytes();
+ }
+
+ int byteCount = GetUtf8ByteCount(in buffer, in index);
+
+ if (byteCount > FixedString32Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString32Bytes ({FixedString32Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in byteCount))
+ {
+ return new FixedString32Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the byte length of the buffer exceeds 61 bytes.
+ public FixedString64Bytes AsFixedString64Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString64Bytes();
+ }
+
+ int byteCount = GetUtf8ByteCount(in buffer, in index);
+
+ if (byteCount > FixedString64Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString64Bytes ({FixedString64Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in byteCount))
+ {
+ return new FixedString64Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the byte length of the buffer exceeds 125 bytes.
+ public FixedString128Bytes AsFixedString128Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString128Bytes();
+ }
+
+ int byteCount = GetUtf8ByteCount(in buffer, in index);
+
+ if (byteCount > FixedString128Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString128Bytes ({FixedString128Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in byteCount))
+ {
+ return new FixedString128Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the byte length of the buffer exceeds 509 bytes.
+ public FixedString512Bytes AsFixedString512Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString512Bytes();
+ }
+
+ int byteCount = GetUtf8ByteCount(in buffer, in index);
+
+ if (byteCount > FixedString512Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString512Bytes ({FixedString512Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in byteCount))
+ {
+ return new FixedString512Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the byte length of the buffer exceeds 4093 bytes.
+ public FixedString4096Bytes AsFixedString4096Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString4096Bytes();
+ }
+
+ int byteCount = GetUtf8ByteCount(in buffer, in index);
+
+ if (byteCount > FixedString4096Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString4096Bytes ({FixedString4096Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in byteCount))
+ {
+ return new FixedString4096Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Helper method to copy a array buffer to
+ ///
+ /// The current buffer.
+ /// The amount of bytes this buffer requires.
+ /// with the written to it.
+ private static NativeText CopyToNativeText(in char[] buffer, in int byteCount)
+ {
+ byte[]? destinationArray = ArrayPool.Shared.Rent(byteCount);
+ Span destination = destinationArray.AsSpan(0, byteCount);
+ int writtenBytes = UTF8NoBom.GetBytes(buffer, destination);
+
+ NativeText text = new NativeText(writtenBytes, Allocator.Temp);
+ for (int i = 0; i < writtenBytes; i++)
+ {
+ text.Add(destination[i]);
+ }
+
+ ArrayPool.Shared.Return(destinationArray);
+
+ return text;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static int GetUtf8ByteCount(in char[] buffer, in int length)
+ {
+ return UTF8NoBom.GetByteCount(buffer, 0, length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString32Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString64Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString128Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString512Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString4096Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Helper method to append a fixed string to the builder.
+ ///
+ /// The fixed string.
+ /// The length of the string byte buffer.
+ /// The type of FixedString.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void AppendFixedString(T value, int length) where T : unmanaged, IUTF8Bytes
+ {
+ unsafe
+ {
+ byte* bytes = value.GetUnsafePtr();
+ ReadOnlySpan span = new ReadOnlySpan(bytes, length);
+
+ int charCount = UTF8NoBom.GetCharCount(span);
+
+ char[]? charBuffer = ArrayPool.Shared.Rent(charCount);
+ int written = UTF8NoBom.GetChars(span, charBuffer);
+
+ Append(charBuffer.AsSpan(0, written));
+
+ ArrayPool.Shared.Return(charBuffer);
+ }
+ }
+ }
+}
+#endif
diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs.meta
new file mode 100644
index 0000000..95642f1
--- /dev/null
+++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.UnityCollections.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8460f7c414464d7493c8212d7d7520ee
+timeCreated: 1760212117
\ No newline at end of file
diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs
new file mode 100644
index 0000000..726d83d
--- /dev/null
+++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs
@@ -0,0 +1,204 @@
+#if ZSTRING_COLLECTIONS_SUPPORT
+using System;
+using System.Runtime.CompilerServices;
+using Unity.Collections;
+
+namespace Cysharp.Text
+{
+ partial struct Utf8ValueStringBuilder
+ {
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the of the buffer exceeds 29 bytes.
+ public FixedString32Bytes AsFixedString32Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString32Bytes();
+ }
+
+ if (Length > FixedString32Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString32Bytes ({FixedString32Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in index))
+ {
+ return new FixedString32Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the of the buffer exceeds 61 bytes.
+ public FixedString64Bytes AsFixedString64Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString64Bytes();
+ }
+
+ if (Length > FixedString64Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString64Bytes ({FixedString64Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in index))
+ {
+ return new FixedString64Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the of the buffer exceeds 125 bytes.
+ public FixedString128Bytes AsFixedString128Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString128Bytes();
+ }
+
+ if (Length > FixedString128Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString128Bytes ({FixedString128Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in index))
+ {
+ return new FixedString128Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the of the buffer exceeds 509 bytes.
+ public FixedString512Bytes AsFixedString512Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString512Bytes();
+ }
+
+ if (Length > FixedString512Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString512Bytes ({FixedString512Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in index))
+ {
+ return new FixedString512Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Get the written buffer data as a .
+ ///
+ /// If the of the buffer exceeds 4093 bytes.
+ public FixedString4096Bytes AsFixedString4096Bytes()
+ {
+ if (buffer == null || Length == 0)
+ {
+ return new FixedString4096Bytes();
+ }
+
+ if (Length > FixedString4096Bytes.UTF8MaxLengthInBytes)
+ {
+ throw new InvalidOperationException(
+ $"The current length ({Length}) exceeds the maximum length of FixedString4096Bytes ({FixedString4096Bytes.UTF8MaxLengthInBytes}).");
+ }
+
+ using (NativeText text = CopyToNativeText(in buffer, in index))
+ {
+ return new FixedString4096Bytes(text.AsReadOnly());
+ }
+ }
+
+ ///
+ /// Helper method to copy a array buffer to
+ ///
+ /// The current buffer.
+ /// The length of written elements in the buffer.
+ /// with the written to it.
+ private static NativeText CopyToNativeText(in byte[] buffer, in int length)
+ {
+ NativeText text = new NativeText(length, Allocator.Temp);
+ for (int i = 0; i < length; i++)
+ {
+ text.Add(buffer[i]);
+ }
+
+ return text;
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString32Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString64Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString128Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString512Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Append a to the builder.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Append(FixedString4096Bytes value)
+ {
+ AppendFixedString(value, value.Length);
+ }
+
+ ///
+ /// Helper method to append a fixed string to the builder.
+ ///
+ /// The fixed string.
+ /// The length of the string byte buffer.
+ /// The type of FixedString.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void AppendFixedString(T value, int length) where T : unmanaged, IUTF8Bytes
+ {
+ unsafe
+ {
+ byte* bytes = value.GetUnsafePtr();
+ AppendLiteral(new ReadOnlySpan(bytes, length));
+ }
+ }
+ }
+}
+#endif
diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs.meta
new file mode 100644
index 0000000..4aa42c8
--- /dev/null
+++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.UnityCollections.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 2c1cf0f17b4941be9dec84565c8a644a
+timeCreated: 1760210314
\ No newline at end of file
diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef
index 40c88be..65dee81 100644
--- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef
+++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef
@@ -1,7 +1,8 @@
{
"name": "ZString",
"references": [
- "Unity.TextMeshPro"
+ "Unity.TextMeshPro",
+ "Unity.Collections"
],
"includePlatforms": [],
"excludePlatforms": [],
@@ -20,6 +21,11 @@
"name": "com.unity.ugui",
"expression": "2.0.0",
"define": "ZSTRING_TEXTMESHPRO_SUPPORT"
+ },
+ {
+ "name": "com.unity.collections",
+ "expression": "2.0.0",
+ "define": "ZSTRING_COLLECTIONS_SUPPORT"
}
]
}
\ No newline at end of file