/// <summary> /// Changes the perceived length of the underlying integer buffer for the duration of the <paramref name="action"/> invokation. The /// perceived buffer size is changed to <paramref name="length"/> and then the <paramref name="action"/> callback is invoked. During /// that time, the code in the <paramref name="action"/> callback sees the buffer as having the given <paramref name="length"/>. /// When the callback returns, the buffer's perceived size is returned to its normal value. /// </summary> /// <remarks>Note: This method is NOT thread safe! Do not expect delayed actions to perceive the buffer as having the given length, /// since the length will be returned to normal as soon as the action delegate finishes.</remarks> /// <param name="length">The length with which the underlying list buffer will be perceived. If it is less than zero, the action is /// not performed and this method exits immediately. If it is larger than the actual buffer size, this method acts as if it's the /// same as the buffer size.</param> /// <param name="action">The action delegate during whose invokation the buffer will have a modified length. If it is null, this /// method exits immediately.</param> public unsafe void AsArrayOfLength(int length, ArrayAction action) { if (action == null || length <= 0) { return; } if (length > size) { length = size; } void *pBuffer = GetBufferPointer(); // Get the header ArrayHeader *header = (ArrayHeader *)pBuffer - 1; // Change the length UIntPtr originalLength = header->length; header->length = new UIntPtr((ulong)length); // Do stuff with the changed array action(buffer); // Revert back to old length header->length = originalLength; }
public unsafe ulong OriginalLength() { void *pBuffer = GetBufferPointer(); // Get the header ArrayHeader *header = (ArrayHeader *)pBuffer - 1; // Change the length return(header->length.ToUInt32()); }
private unsafe static void HackArraySizeCall <TA>(TA[] array, ArrayHeader *header, int size, Action <TA[]> func) { int oriLen = header->length; header->length = size; try { func(array); } finally { header->length = oriLen; } }
/// <summary> /// DON'T USE IT! /// <para>Crash on GC!</para> /// </summary> public static T[] UnsafeInplaceCast <T>(this byte[] array) { unsafe { fixed(void *ptrArray = array) { ArrayHeader *ptrHeader = (ArrayHeader *)ptrArray - 1; ptrHeader->Length = (IntPtr)(array.Length / TypeCache <T> .UnsafeSize); ptrHeader->TypeHandle = TypeCache <T[]> .Type.TypeHandle.Value; } } return((T[])(object)array); }
public unsafe void SetArrayLength(ulong length) { if (length <= 0) { return; } //if (length > (ulong)size) length = (ulong)size; void *pBuffer = GetBufferPointer(); // Get the header ArrayHeader *header = (ArrayHeader *)pBuffer - 1; // Change the length header->length = new UIntPtr(length); }
public unsafe void AsArrayOfLength(ulong length) { if (length <= 0) { return; } if (length > (ulong)size) { length = (ulong)size; } void *pBuffer = GetBufferPointer(); // Get the header ArrayHeader *header = (ArrayHeader *)pBuffer - 1; // Change the length UIntPtr originalLength = header->length; header->length = new UIntPtr(length); }