public static bool TryGetArray4Fast([MaybeNullWhen(false)] out object?[] instance) { // If the exclusion control is successfully obtained, I try to get the instance from the pool. if (_lock.TryEnter() == false) { instance = null; return(false); } try { instance = _root; if (instance is not null) { Debug.Assert(_pooledCount > 0); Debug.Assert(instance.Length == LengthOfPoolTargetArray); _pooledCount--; _root = SafeCast.As <object?[]>(MemoryMarshal.GetArrayDataReference(instance)); // _root = (object?[])instance[0]; MemoryMarshal.GetArrayDataReference(instance) = null; // instance[0] = null; return(true); } return(false); } finally { _lock.Exit(); } }
public static void ReturnArray4Fast(object?[] instance) { Debug.Assert(instance.Length == LengthOfPoolTargetArray); #if DEBUG Debug.Assert(instance.GetType() == typeof(object[])); for (int i = 0; i < LengthOfPoolTargetArray; i++) { Debug.Assert(instance[i] == null); } #endif // If the exclusion control is successfully obtained, add the instance to the pool. if (_lock.TryEnter() == false) { return; } try { var pooledCount = _pooledCount; if (pooledCount == MaxPoolingCount) { return; } var root = _root; _pooledCount = pooledCount + 1; _root = instance; if (root is not null) { MemoryMarshal.GetArrayDataReference(instance) = root; // instance[0] = root; } } finally { _lock.Exit(); } }
public static void CopyMemory(byte[] src, int srcIndex, byte[] dst, int dstIndex, int length) { uint nlen = unchecked ((uint)length); if (0u >= nlen) { return; } #if NET451 Buffer.BlockCopy(src, srcIndex, dst, dstIndex, length); #elif NET471 unsafe { fixed(byte *source = &src[srcIndex]) { fixed(byte *destination = &dst[dstIndex]) { Buffer.MemoryCopy(source, destination, length, length); } } } #elif NET Unsafe.CopyBlockUnaligned( ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dst), dstIndex), ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(src), srcIndex), nlen); #else Unsafe.CopyBlockUnaligned(ref dst[dstIndex], ref src[srcIndex], nlen); #endif }
public static void Fill(Color color) { if (!m_ready) { return; } byte r = color.R; byte g = color.G; byte b = color.B; byte a = color.A; fixed(byte *ptr = &MemoryMarshal.GetArrayDataReference(m_pixels)) { var len = m_pixels.Length - 4; for (int i = 0; i <= len; i += 4) { *(ptr + i) = b; *(ptr + i + 1) = g; *(ptr + i + 2) = r; *(ptr + i + 3) = a; } } m_blitter_dirty = true; }
/// <summary> /// Slices the specified array using the specified range. /// </summary> public static T[] GetSubArray <T>(T[] array, Range range) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } (int offset, int length) = range.GetOffsetAndLength(array.Length); if (default(T) ! != null || typeof(T[]) == array.GetType()) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757) { // We know the type of the array to be exactly T[]. if (length == 0) { return(Array.Empty <T>()); } var dest = new T[length]; Buffer.Memmove( ref MemoryMarshal.GetArrayDataReference(dest), ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), offset), (uint)length); return(dest); }
public static void ColorMult(float r, float g, float b, float a) { if (!m_ready) { return; } fixed(byte *ptr = &MemoryMarshal.GetArrayDataReference(m_pixels)) { for (int i = 0; i < m_pixels.Length / 4; ++i) { byte *ptr_idx = ptr + (i * 4); if (*(ptr_idx + 3) == 0) { continue; } var sb = (*(ptr_idx) * b); var sg = (*(ptr_idx + 1) * g); var sr = (*(ptr_idx + 2) * r); var sa = (*(ptr_idx + 3) * a); *(ptr_idx) = (byte)Calc.Clamp(sb, 0, 255); *(ptr_idx + 1) = (byte)Calc.Clamp(sg, 0, 255); *(ptr_idx + 2) = (byte)Calc.Clamp(sr, 0, 255); *(ptr_idx + 3) = (byte)Calc.Clamp(sa, 0, 255); } } m_blitter_dirty = true; }
private unsafe void ConvertToEngineRepresentation(bool premultiply_alpha = false) { var pd = pixel_data; fixed(byte *p = &MemoryMarshal.GetArrayDataReference(pd)) { var len = pd.Length - 4; for (int i = 0; i <= len; i += 4) { byte r = *(p + i); byte g = *(p + i + 1); byte b = *(p + i + 2); byte a = *(p + i + 3); if (!premultiply_alpha) { *(p + i) = b; *(p + i + 1) = g; *(p + i + 2) = r; } else { *(p + i) = (byte)((b * a) / 255); *(p + i + 1) = (byte)((g * a) / 255); *(p + i + 2) = (byte)(r * a / 255); } *(p + i + 3) = a; } } }
/// <summary> /// Slices the specified array using the specified range. /// </summary> public static T[] GetSubArray <T>(T[] array, Range range) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } (int offset, int length) = range.GetOffsetAndLength(array.Length); if (typeof(T).IsValueType || typeof(T[]) == array.GetType()) { // We know the type of the array to be exactly T[]. if (length == 0) { return(Array.Empty <T>()); } var dest = new T[length]; Buffer.Memmove( ref MemoryMarshal.GetArrayDataReference(dest), ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), offset), (uint)length); return(dest); } else { // The array is actually a U[] where U:T. T[] dest = (T[])Array.CreateInstance(array.GetType().GetElementType() !, length); Array.Copy(array, offset, dest, 0, length); return(dest); } }
public ReadOnlySpan(T[]?array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default; return; // returns default } #if TARGET_64BIT // See comment in Span<T>.Slice for how this works. if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)array.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #else if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #endif _pointer = new ByReference <T>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), start)); _length = length; }
// Used by ilmarshalers.cpp internal static unsafe void Memcpy(byte *pDest, int destIndex, byte[] src, int srcIndex, int len) { Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!"); Debug.Assert(src.Length - srcIndex >= len, "not enough bytes in src"); Memmove(ref *(pDest + (uint)destIndex), ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(src), (nint)(uint)srcIndex /* force zero-extension */), (uint)len); }
// Returns a substring of this string as an array of characters. // public char[] ToCharArray(int startIndex, int length) { // Range check everything. if (startIndex < 0 || startIndex > Length || startIndex > Length - length) { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); } if (length <= 0) { if (length == 0) { return(Array.Empty <char>()); } throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index); } char[] chars = new char[length]; Buffer.Memmove( destination: ref MemoryMarshal.GetArrayDataReference(chars), source: ref Unsafe.Add(ref _firstChar, startIndex), elementCount: (uint)length); return(chars); }
public unsafe void GetPointerAndCount(out ParameterDescriptionStruct **ptr, out int length) { EnsureInitialized(); ptr = (ParameterDescriptionStruct **)Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(PointerList)); length = PointerList.Length; }
public Span(T[]?array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default; return; // returns default } if (default(T) ! == null && array.GetType() != typeof(T[])) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757) { ThrowHelper.ThrowArrayTypeMismatchException(); } #if BIT64 // See comment in Span<T>.Slice for how this works. if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)array.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #else if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #endif _pointer = new ByReference <T>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), start)); _length = length; }
// Converts a substring of this string to an array of characters. Copies the // characters of this string beginning at position sourceIndex and ending at // sourceIndex + count - 1 to the character array buffer, beginning // at destinationIndex. // public unsafe void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) { if (destination == null) { throw new ArgumentNullException(nameof(destination)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount); } if (sourceIndex < 0) { throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_Index); } if (count > Length - sourceIndex) { throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_IndexCount); } if (destinationIndex > destination.Length - count || destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount); } Buffer.Memmove( destination: ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(destination), destinationIndex), source: ref Unsafe.Add(ref _firstChar, sourceIndex), elementCount: (uint)count); }
/// <summary> /// Converts this <see cref="Utf8Span"/> to a <see langword="char[]"/>. /// </summary> public unsafe char[] ToCharArray() { if (IsEmpty) { return(Array.Empty <char>()); } // TODO_UTF8STRING: Since we know the underlying data is immutable, well-formed UTF-8, // we can perform transcoding using an optimized code path that skips all safety checks. // We should also consider skipping the two-pass if possible. fixed(byte *pbUtf8 = &DangerousGetMutableReference()) { byte *pbUtf8Invalid = Utf8Utility.GetPointerToFirstInvalidByte(pbUtf8, this.Length, out int utf16CodeUnitCountAdjustment, out _); Debug.Assert(pbUtf8Invalid == pbUtf8 + this.Length, "Invalid UTF-8 data seen in buffer."); char[] asUtf16 = new char[this.Length + utf16CodeUnitCountAdjustment]; fixed(char *pbUtf16 = &MemoryMarshal.GetArrayDataReference(asUtf16)) { OperationStatus status = Utf8Utility.TranscodeToUtf16(pbUtf8, this.Length, pbUtf16, asUtf16.Length, out byte *pbUtf8End, out char *pchUtf16End); Debug.Assert(status == OperationStatus.Done, "The buffer changed out from under us unexpectedly?"); Debug.Assert(pbUtf8End == pbUtf8 + this.Length, "The buffer changed out from under us unexpectedly?"); Debug.Assert(pchUtf16End == pbUtf16 + asUtf16.Length, "The buffer changed out from under us unexpectedly?"); return(asUtf16); } } }
public static void Point(int x, int y, Color color) { if (!m_ready) { return; } int pw = m_surface_w; int ph = m_surface_h; byte r = color.R; byte g = color.G; byte b = color.B; byte a = color.A; fixed(byte *ptr = &MemoryMarshal.GetArrayDataReference(m_pixels)) { ClampAndWarp(ref x, ref y, pw, ph); byte *ptr_idx = ptr + (x + y * pw) * 4; *(ptr_idx) = b; *(ptr_idx + 1) = g; *(ptr_idx + 2) = r; *(ptr_idx + 3) = a; } m_blitter_dirty = true; }
private static string Ctor(char[] value, int startIndex, int length) { ArgumentNullException.ThrowIfNull(value); if (startIndex < 0) { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); } if (startIndex > value.Length - length) { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); } if (length == 0) { return(Empty); } string result = FastAllocateString(length); Buffer.Memmove( elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below destination: ref result._firstChar, source: ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(value), startIndex)); return(result); }
internal static unsafe IntPtr ConvertToNative(int flags, string strManaged) { if (null == strManaged) { return(IntPtr.Zero); } byte[]? bytes = null; int nb = 0; if (strManaged.Length > 0) { bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb); } uint length = (uint)nb; IntPtr bstr = Marshal.AllocBSTRByteLen(length); if (bytes != null) { Buffer.Memmove(ref *(byte *)bstr, ref MemoryMarshal.GetArrayDataReference(bytes), length); } return(bstr); }
public static void ColorAdd(byte r, byte g, byte b, byte a) { if (!m_ready) { return; } fixed(byte *ptr = &MemoryMarshal.GetArrayDataReference(m_pixels)) { for (int i = 0; i < m_pixels.Length / 4; ++i) { byte *ptr_idx = ptr + (i * 4); var sb = (*(ptr_idx) + b); var sg = (*(ptr_idx + 1) + g); var sr = (*(ptr_idx + 2) + r); var sa = (*(ptr_idx + 3) + a); *(ptr_idx) = (byte)Calc.Clamp(sb, 0, 255); *(ptr_idx + 1) = (byte)Calc.Clamp(sg, 0, 255); *(ptr_idx + 2) = (byte)Calc.Clamp(sr, 0, 255); *(ptr_idx + 3) = (byte)Calc.Clamp(sa, 0, 255); } } m_blitter_dirty = true; }
public Span(T[]?array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { ThrowHelper.ThrowArgumentOutOfRangeException(); } this = default; return; // returns default } if (!typeof(T).IsValueType && array.GetType() != typeof(T[])) { ThrowHelper.ThrowArrayTypeMismatchException(); } #if TARGET_64BIT // See comment in Span<T>.Slice for how this works. if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)array.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #else if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { ThrowHelper.ThrowArgumentOutOfRangeException(); } #endif _pointer = new ByReference <T>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), (nint)(uint)start /* force zero-extension */)); _length = length; }
/// <summary> /// Slices the specified array using the specified range. /// </summary> public static T[] GetSubArray <T>(T[] array, Range range) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } (int offset, int length) = range.GetOffsetAndLength(array.Length); if (length == 0) { return(Array.Empty <T>()); } T[] dest = new T[length]; // Due to array variance, it's possible that the incoming array is // actually of type U[], where U:T; or that an int[] <-> uint[] or // similar cast has occurred. In any case, since it's always legal // to reinterpret U as T in this scenario (but not necessarily the // other way around), we can use Buffer.Memmove here. Buffer.Memmove( ref MemoryMarshal.GetArrayDataReference(dest), ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), offset), (uint)length); return(dest); }
/// <summary> /// Implementation of the argument marshaling. /// It's used by JSImport code generator and should not be used by developers in source code. /// </summary> // this only supports array round-trip, there is no way how to create ArraySegment in JS public unsafe void ToManaged(out ArraySegment <byte> value) { var array = (byte[])((GCHandle)slot.GCHandle).Target !; var refPtr = (IntPtr)Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(array)); int byteOffset = (int)(slot.IntPtrValue - (nint)refPtr); value = new ArraySegment <byte>(array, byteOffset, slot.Length); }
static void fnLocalReseed(byte[] aeskey, byte[] ctBuffer) { var encryptor = s_aes.CreateEncryptor(rgbKey: aeskey, rgbIV: null); encryptor.TransformBlock(inputBuffer: s_ptBuffer, inputOffset: 0, inputCount: BUFFER_SIZE, outputBuffer: ctBuffer, outputOffset: 0); encryptor.Dispose(); Unsafe.CopyBlockUnaligned(destination: ref MemoryMarshal.GetArrayDataReference(aeskey), source: ref MemoryMarshal.GetArrayDataReference(ctBuffer), byteCount: SEEDKEY_SIZE); } //fnLocalReseed()
public static Span <byte> AsSpanFast(this byte[] data) { #if NET5_0 || NET5_0_OR_GREATER return(MemoryMarshal.CreateSpan(ref MemoryMarshal.GetArrayDataReference(data), data.Length)); #else return(data.AsSpan()); #endif }
public static byte GetByte(Array array, int index) { // array argument validation done via ByteLength if ((uint)index >= (uint)ByteLength(array)) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); } return(Unsafe.Add <byte>(ref MemoryMarshal.GetArrayDataReference(array), index)); }
public void ValidateRefCharAsBuffer() { char[] chars = CharacterMappings().Select(o => (char)o[0]).ToArray(); char[] expected = new char[chars.Length]; Array.Copy(chars, expected, chars.Length); Array.Reverse(expected); NativeExportsNE.ReverseBuffer(ref MemoryMarshal.GetArrayDataReference(chars), chars.Length); Assert.Equal(expected, chars); }
// Copies from one primitive array to another primitive array without // respecting types. This calls memmove internally. The count and // offset parameters here are in bytes. If you want to use traditional // array element indices and counts, use Array.Copy. public static unsafe void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count) { ArgumentNullException.ThrowIfNull(src); ArgumentNullException.ThrowIfNull(dst); nuint uSrcLen = src.NativeLength; if (src.GetType() != typeof(byte[])) { if (!src.GetCorElementTypeOfElementType().IsPrimitiveType()) { throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(src)); } uSrcLen *= (nuint)src.GetElementSize(); } nuint uDstLen = uSrcLen; if (src != dst) { uDstLen = dst.NativeLength; if (dst.GetType() != typeof(byte[])) { if (!dst.GetCorElementTypeOfElementType().IsPrimitiveType()) { throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(dst)); } uDstLen *= (nuint)dst.GetElementSize(); } } if (srcOffset < 0) { throw new ArgumentOutOfRangeException(nameof(srcOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32); } if (dstOffset < 0) { throw new ArgumentOutOfRangeException(nameof(dstOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_MustBeNonNegInt32); } nuint uCount = (nuint)count; nuint uSrcOffset = (nuint)srcOffset; nuint uDstOffset = (nuint)dstOffset; if ((uSrcLen < uSrcOffset + uCount) || (uDstLen < uDstOffset + uCount)) { throw new ArgumentException(SR.Argument_InvalidOffLen); } Memmove(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(dst), uDstOffset), ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(src), uSrcOffset), uCount); }
public unsafe IntPtr GetHostArray(int requiredSize) { if (_data == null || _data.Length < requiredSize) { _data = GC.AllocateUninitializedArray <byte>(requiredSize, true); _dataMap = (IntPtr)Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(_data)); } return(_dataMap); }
public ReadOnlySpan(T[]?array) { if (array == null) { this = default; return; // returns default } _pointer = new ByReference <T>(ref MemoryMarshal.GetArrayDataReference(array)); _length = array.Length; }
public DataSetArrayFixed(T[] data, bool validate = false) { Data = data; unsafe { DataPtr = (T *)Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(data)); } if (validate) { //Validate(this); } }