summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs88
1 files changed, 33 insertions, 55 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs
index 3bef38a0b7..eb2a2cba14 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ArrayWithOffset.cs
@@ -4,19 +4,50 @@
using System.Runtime.CompilerServices;
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
namespace System.Runtime.InteropServices
{
public struct ArrayWithOffset
{
+ private object m_array;
+ private int m_offset;
+ private int m_count;
+
// From MAX_SIZE_FOR_INTEROP in mlinfo.h
private const int MaxSizeForInterop = 0x7ffffff0;
public ArrayWithOffset(object array, int offset)
{
+ int totalSize = 0;
+ if (array != null)
+ {
+ if (!(array is Array arrayObj) || (arrayObj.Rank != 1) || !Marshal.IsPinnable(arrayObj))
+ {
+ throw new ArgumentException(SR.Argument_NotIsomorphic);
+ }
+
+ nuint nativeTotalSize = (nuint)arrayObj.LongLength * (nuint)arrayObj.GetElementSize();
+ if (nativeTotalSize > MaxSizeForInterop)
+ {
+ throw new ArgumentException(SR.Argument_StructArrayTooLarge);
+ }
+
+ totalSize = (int)nativeTotalSize;
+ }
+
+ if ((uint)offset > (uint)totalSize)
+ {
+ throw new IndexOutOfRangeException(SR.IndexOutOfRange_ArrayWithOffset);
+ }
+
m_array = array;
m_offset = offset;
- m_count = 0;
- m_count = CalculateCount();
+ m_count = totalSize - offset;
}
public object GetArray() => m_array;
@@ -44,58 +75,5 @@ namespace System.Runtime.InteropServices
{
return !(a == b);
}
-
-#if CORECLR // TODO: Cleanup
- [MethodImpl(MethodImplOptions.InternalCall)]
- private extern int CalculateCount();
-#else
- private int CalculateCount()
- {
- if (m_array == null)
- {
- if (m_offset != 0)
- {
- throw new IndexOutOfRangeException(SR.IndexOutOfRange_ArrayWithOffset);
- }
-
- return 0;
- }
- else
- {
- Array arrayObj = m_array as Array;
- if (arrayObj == null)
- {
- throw new ArgumentException(SR.Argument_NotIsomorphic);
- }
-
- if (arrayObj.Rank != 1)
- {
- throw new ArgumentException(SR.Argument_NotIsomorphic);
- }
-
- if (!arrayObj.IsBlittable())
- {
- throw new ArgumentException(SR.Argument_NotIsomorphic);
- }
-
- int totalSize = checked(arrayObj.Length * arrayObj.GetElementSize());
- if (totalSize > MaxSizeForInterop)
- {
- throw new ArgumentException(SR.Argument_StructArrayTooLarge);
- }
-
- if (m_offset > totalSize)
- {
- throw new IndexOutOfRangeException(SR.IndexOutOfRange_ArrayWithOffset);
- }
-
- return totalSize - m_offset;
- }
- }
-#endif // !CORECLR
-
- private object m_array;
- private int m_offset;
- private int m_count;
}
}