|
1 | 1 | // Licensed under the MIT License. See LICENSE in the project root for license information. |
2 | 2 |
|
3 | 3 | using System; |
| 4 | +using System.Buffers; |
4 | 5 | using System.IO; |
| 6 | +using System.Threading; |
| 7 | +using System.Threading.Tasks; |
5 | 8 | using Unity.Collections; |
6 | 9 | using Unity.Collections.LowLevel.Unsafe; |
7 | 10 |
|
@@ -59,6 +62,7 @@ public static unsafe NativeArray<byte> ToNativeArray(this MemoryStream stream, i |
59 | 62 |
|
60 | 63 | var bytes = (int)lengthValue; |
61 | 64 | var native = new NativeArray<byte>(bytes, allocator); |
| 65 | + |
62 | 66 | try |
63 | 67 | { |
64 | 68 | fixed (byte* srcPtr = &seg.Array[srcOffset]) |
@@ -368,5 +372,49 @@ static char GetBase64Char(uint value) |
368 | 372 | }; |
369 | 373 | } |
370 | 374 | } |
| 375 | + |
| 376 | + public static async Task WriteAsync<T>(this T stream, NativeArray<byte> nativeArray, int? offset = null, int? count = null, CancellationToken cancellationToken = default) where T : Stream |
| 377 | + { |
| 378 | + if (stream is null) |
| 379 | + { |
| 380 | + throw new ArgumentNullException(nameof(stream)); |
| 381 | + } |
| 382 | + |
| 383 | + var offsetValue = offset.GetValueOrDefault(0); |
| 384 | + |
| 385 | + if (offsetValue < 0 || offsetValue > nativeArray.Length) |
| 386 | + { |
| 387 | + throw new ArgumentOutOfRangeException(nameof(offset), "Offset must be between 0 and nativeArray.Length."); |
| 388 | + } |
| 389 | + |
| 390 | + var countValue = count ?? (nativeArray.Length - offsetValue); |
| 391 | + |
| 392 | + if (countValue < 0 || offsetValue + countValue > nativeArray.Length) |
| 393 | + { |
| 394 | + throw new ArgumentOutOfRangeException(nameof(count), "Invalid count for the provided offset and nativeArray length."); |
| 395 | + } |
| 396 | + |
| 397 | + if (countValue == 0) { return; } |
| 398 | + |
| 399 | + var buffer = ArrayPool<byte>.Shared.Rent(countValue); |
| 400 | + |
| 401 | + try |
| 402 | + { |
| 403 | + unsafe |
| 404 | + { |
| 405 | + fixed (byte* bufferPtr = &buffer[0]) |
| 406 | + { |
| 407 | + var srcPtr = (byte*)nativeArray.GetUnsafeReadOnlyPtr(); |
| 408 | + UnsafeUtility.MemCpy(bufferPtr, srcPtr + offsetValue, countValue); |
| 409 | + } |
| 410 | + } |
| 411 | + |
| 412 | + await stream.WriteAsync(buffer, 0, countValue, cancellationToken).ConfigureAwait(false); |
| 413 | + } |
| 414 | + finally |
| 415 | + { |
| 416 | + ArrayPool<byte>.Shared.Return(buffer); |
| 417 | + } |
| 418 | + } |
371 | 419 | } |
372 | 420 | } |
0 commit comments