/// <summary> /// Copies from. /// </summary> /// <param name="array">The array.</param> /// <exception cref="InvalidOperationException"> /// ArithArray must be contiguous to copy from CLR array /// or /// ArithArray and array must have the same number of elements /// or /// ArithArray and array must have the same element types /// </exception> public void LoadFrom(Array array) { var elementType = DTypeBuilder.FromCLRType(array.GetType().GetElementType()); if (!this.IsContiguous()) { throw new InvalidOperationException("ArithArray must be contiguous to copy from CLR array"); } if (this.ElementCount() != array.LongLength) { throw new InvalidOperationException("ArithArray and array must have the same number of elements"); } if (this.ElementType != elementType) { throw new InvalidOperationException("ArithArray and array must have the same element types"); } var handle = GCHandle.Alloc(array, GCHandleType.Pinned); try { var length = Buffer.ByteLength(array); this.Storage.CopyToStorage(this.StorageOffset, handle.AddrOfPinnedObject(), length); } finally { handle.Free(); } }
/// <summary> /// Froms the array. /// </summary> /// <param name="allocator">The allocator.</param> /// <param name="array">The array.</param> /// <returns>ArithArray.</returns> public static SuperArray FromArray(Array array) { // From the CLI spec(section 8.9.1): // Array elements shall be laid out within the array object in row - major order // (i.e., the elements associated with the rightmost array dimension shall be laid out contiguously from lowest to highest index). // The actual storage allocated for each array element can include platform - specific padding. // This is already in the order we want - and here we will (potentially incorrectly) assume that there is no // 'platform-specific padding'. This appears to be a reasonable assumption on both CLR and Mono. // Assuming no platform-specific padding allows us to use memcpy instead of iterating and copying each element var elementType = DTypeBuilder.FromCLRType(array.GetType().GetElementType()); var dimSizes = Enumerable.Range(0, array.Rank) .Select(x => (long)array.GetLength(x)) .ToArray(); var result = new SuperArray(dimSizes, elementType); result.LoadFrom(array); return(result); }