diff --git a/FeatherDotNet/Column.cs b/FeatherDotNet/Column.cs index 9ec80e7..f002299 100644 --- a/FeatherDotNet/Column.cs +++ b/FeatherDotNet/Column.cs @@ -288,7 +288,11 @@ public void GetRange(long rowSourceIndex, int length, ref T[] array, int dest if (CanBeBlitted()) { - Parent.UnsafeFastGetRowRange(translatedIndex, TranslatedColumnIndex, array, destinationIndex, length); + if (typeof(T) == Type) { + Parent.UnsafeFastGetRowRange(translatedIndex, TranslatedColumnIndex, array, destinationIndex, length); + } else { + Parent.GetRowRangeWithTypeCast(translatedIndex, TranslatedColumnIndex, array, destinationIndex, length); + } return; } diff --git a/FeatherDotNet/DataFrame.cs b/FeatherDotNet/DataFrame.cs index 3e778e5..2c921e5 100644 --- a/FeatherDotNet/DataFrame.cs +++ b/FeatherDotNet/DataFrame.cs @@ -427,6 +427,38 @@ internal void UnsafeFastGetRowRange(long translatedRowIndex, long translatedC UnsafeArrayReader.ReadArray(View, byteIndex, array, 0, length); } + private Array ReadNativeArrayUnsafe(long byteIndex, int length) { + T[] array = new T[length]; + UnsafeArrayReader.ReadArray(View, byteIndex, array, 0, length); + return array; + } + + internal void GetRowRangeWithTypeCast(long translatedRowIndex, long translatedColumnIndex, T[] array, int destinationIndex, int length) + { + var columnMetadata = Metadata.Columns[translatedColumnIndex]; + var entrySize = columnMetadata.Type.GetAlignment(); + var dataStart = columnMetadata.DataOffset; + var byteOffset = translatedRowIndex * entrySize; + + var byteIndex = dataStart + byteOffset; + + Array uncastedArray; + switch (columnMetadata.Type) { + case ColumnType.Int8: uncastedArray = ReadNativeArrayUnsafe (byteIndex, length); break; + case ColumnType.Int16: uncastedArray = ReadNativeArrayUnsafe (byteIndex, length); break; + case ColumnType.Int32: uncastedArray = ReadNativeArrayUnsafe (byteIndex, length); break; + case ColumnType.Int64: uncastedArray = ReadNativeArrayUnsafe (byteIndex, length); break; + case ColumnType.Uint8: uncastedArray = ReadNativeArrayUnsafe (byteIndex, length); break; + case ColumnType.Uint16: uncastedArray = ReadNativeArrayUnsafe(byteIndex, length); break; + case ColumnType.Uint32: uncastedArray = ReadNativeArrayUnsafe(byteIndex, length); break; + case ColumnType.Uint64: uncastedArray = ReadNativeArrayUnsafe(byteIndex, length); break; + case ColumnType.Float: uncastedArray = ReadNativeArrayUnsafe(byteIndex, length); break; + case ColumnType.Double: uncastedArray = ReadNativeArrayUnsafe(byteIndex, length); break; + default: throw new InvalidOperationException($"Invalid cast {columnMetadata.Name}: {columnMetadata.Type} -> {typeof(T)}"); + } + Array.Copy(uncastedArray, 0, array, destinationIndex, length); + } + internal bool IsNullTranslated(long translatedRowIndex, long translatedColumnIndex) { var columnMetadata = Metadata.Columns[translatedColumnIndex];