|
38 | 38 |
|
39 | 39 | using System; |
40 | 40 | using System.Collections.Generic; |
41 | | -using System.IO; |
42 | | -using System.Runtime.CompilerServices; |
43 | 41 | using System.Runtime.InteropServices; |
44 | 42 | using System.Text; |
45 | 43 |
|
46 | 44 | #if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER |
47 | 45 | using System.Buffers.Binary; |
| 46 | +#else |
| 47 | +using System.IO; |
48 | 48 | #endif |
49 | 49 |
|
50 | 50 | #if ENABLE_SPAN_T && !UNSAFE_BYTEBUFFER |
@@ -245,34 +245,36 @@ public static int ArraySize<T>(Span<T> x) |
245 | 245 | #endif |
246 | 246 |
|
247 | 247 | // Get a portion of the buffer casted into an array of type T, given |
248 | | - // the buffer position and length. |
249 | | -#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER |
250 | | - public T[] ToArray<T>(int pos, int len) |
| 248 | + // the buffer position (in bytes) and length (in bytes). |
| 249 | + public T[] ToArray<T>(int posInBytes, int lenInBytes) |
251 | 250 | where T : struct |
252 | 251 | { |
253 | | - AssertOffsetAndLength(pos, len); |
254 | | - return MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(pos)).Slice(0, len).ToArray(); |
255 | | - } |
| 252 | + AssertOffsetAndLength(posInBytes, lenInBytes); |
| 253 | +#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER |
| 254 | + return MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(posInBytes, lenInBytes)).ToArray(); |
256 | 255 | #else |
257 | | - public T[] ToArray<T>(int pos, int len) |
258 | | - where T : struct |
259 | | - { |
260 | | - AssertOffsetAndLength(pos, len); |
261 | | - T[] arr = new T[len]; |
262 | | - Buffer.BlockCopy(_buffer.Buffer, pos, arr, 0, ArraySize(arr)); |
263 | | - return arr; |
264 | | - } |
| 256 | + var lenInTs = ConvertBytesToTs<T>(lenInBytes); |
| 257 | + var arrayOfTs = new T[lenInTs]; |
| 258 | + Buffer.BlockCopy(_buffer.Buffer, posInBytes, arrayOfTs, 0, lenInBytes); |
| 259 | + return arrayOfTs; |
265 | 260 | #endif |
| 261 | + } |
266 | 262 |
|
267 | | - public T[] ToArrayPadded<T>(int pos, int len, int padLeft, int padRight) |
| 263 | + public T[] ToArrayPadded<T>(int posInBytes, int lenInBytes, int padLeftInBytes, int padRightInBytes) |
268 | 264 | where T : struct |
269 | 265 | { |
270 | | - AssertOffsetAndLength(pos, len); |
271 | | - int totalBytes = padLeft + len + padRight; |
272 | | - byte[] raw = _buffer.Buffer; |
273 | | - T[] arr = new T[totalBytes]; |
274 | | - Buffer.BlockCopy(raw, pos, arr, padLeft, len); |
275 | | - return arr; |
| 266 | + AssertOffsetAndLength(posInBytes, lenInBytes); |
| 267 | + var padLeftInTs = ConvertBytesToTs<T>(padLeftInBytes); |
| 268 | + var lenInTs = ConvertBytesToTs<T>(lenInBytes); |
| 269 | + var padRightInTs = ConvertBytesToTs<T>(padRightInBytes); |
| 270 | + var sizeInTs = padLeftInTs + lenInTs + padRightInTs; |
| 271 | + var arrayOfTs = new T[sizeInTs]; |
| 272 | +#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER |
| 273 | + MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(posInBytes, lenInBytes)).CopyTo(arrayOfTs.AsSpan().Slice(padLeftInTs)); |
| 274 | +#else |
| 275 | + Buffer.BlockCopy(_buffer.Buffer, posInBytes, arrayOfTs, padLeftInBytes, lenInBytes); |
| 276 | +#endif |
| 277 | + return arrayOfTs; |
276 | 278 | } |
277 | 279 |
|
278 | 280 | public byte[] ToSizedArrayPadded(int padLeft, int padRight) |
@@ -455,9 +457,31 @@ private void AssertOffsetAndLength(int offset, int length) |
455 | 457 | #endif |
456 | 458 | } |
457 | 459 |
|
| 460 | + public static int ConvertTsToBytes<T>(int valueInTs) |
| 461 | + where T : struct |
| 462 | + { |
| 463 | + var sizeOfT = SizeOf<T>(); |
| 464 | + var valueInBytes = valueInTs * sizeOfT; |
| 465 | + return valueInBytes; |
| 466 | + } |
| 467 | + |
| 468 | + public static int ConvertBytesToTs<T>(int valueInBytes) |
| 469 | + where T : struct |
| 470 | + { |
| 471 | + var sizeOfT = SizeOf<T>(); |
| 472 | + var valueInTs = valueInBytes / sizeOfT; |
| 473 | +#if !BYTEBUFFER_NO_BOUNDS_CHECK |
| 474 | + if (valueInTs * sizeOfT != valueInBytes) |
| 475 | + { |
| 476 | + throw new ArgumentException($"{valueInBytes} must be a multiple of SizeOf<{typeof(T).Name}>()={sizeOfT}"); |
| 477 | + } |
| 478 | +#endif |
| 479 | + return valueInTs; |
| 480 | + } |
| 481 | + |
458 | 482 | #if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER |
459 | 483 |
|
460 | | - public void PutSbyte(int offset, sbyte value) |
| 484 | + public void PutSbyte(int offset, sbyte value) |
461 | 485 | { |
462 | 486 | AssertOffsetAndLength(offset, sizeof(sbyte)); |
463 | 487 | _buffer.Span[offset] = (byte)value; |
|
0 commit comments