This repository has been archived by the owner on Feb 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 221
/
ffi.rs
86 lines (77 loc) · 2.88 KB
/
ffi.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::datatypes::PhysicalType;
use crate::{array::*, ffi};
use crate::error::Result;
/// Trait describing how a struct presents itself to the
/// [C data interface](https://arrow.apache.org/docs/format/CDataInterface.html) (FFI).
/// # Safety
/// Implementing this trait incorrect will lead to UB
pub(crate) unsafe trait ToFfi {
/// The pointers to the buffers.
fn buffers(&self) -> Vec<Option<*const u8>>;
/// The children
fn children(&self) -> Vec<Box<dyn Array>> {
vec![]
}
/// The offset
fn offset(&self) -> Option<usize>;
/// return a partial clone of self with an offset.
fn to_ffi_aligned(&self) -> Self;
}
/// Trait describing how a struct imports into itself from the
/// [C data interface](https://arrow.apache.org/docs/format/CDataInterface.html) (FFI).
pub(crate) trait FromFfi<T: ffi::ArrowArrayRef>: Sized {
/// Convert itself from FFI.
/// # Safety
/// This function is intrinsically `unsafe` as it requires the FFI to be made according
/// to the [C data interface](https://arrow.apache.org/docs/format/CDataInterface.html)
unsafe fn try_from_ffi(array: T) -> Result<Self>;
}
macro_rules! ffi_dyn {
($array:expr, $ty:ty) => {{
let array = $array.as_any().downcast_ref::<$ty>().unwrap();
(
array.offset().unwrap(),
array.buffers(),
array.children(),
None,
)
}};
}
type BuffersChildren = (
usize,
Vec<Option<*const u8>>,
Vec<Box<dyn Array>>,
Option<Box<dyn Array>>,
);
pub fn offset_buffers_children_dictionary(array: &dyn Array) -> BuffersChildren {
use PhysicalType::*;
match array.data_type().to_physical_type() {
Null => ffi_dyn!(array, NullArray),
Boolean => ffi_dyn!(array, BooleanArray),
Primitive(primitive) => with_match_primitive_type!(primitive, |$T| {
ffi_dyn!(array, PrimitiveArray<$T>)
}),
Binary => ffi_dyn!(array, BinaryArray<i32>),
LargeBinary => ffi_dyn!(array, BinaryArray<i64>),
FixedSizeBinary => ffi_dyn!(array, FixedSizeBinaryArray),
Utf8 => ffi_dyn!(array, Utf8Array::<i32>),
LargeUtf8 => ffi_dyn!(array, Utf8Array::<i64>),
List => ffi_dyn!(array, ListArray::<i32>),
LargeList => ffi_dyn!(array, ListArray::<i64>),
FixedSizeList => ffi_dyn!(array, FixedSizeListArray),
Struct => ffi_dyn!(array, StructArray),
Union => ffi_dyn!(array, UnionArray),
Map => ffi_dyn!(array, MapArray),
Dictionary(key_type) => {
match_integer_type!(key_type, |$T| {
let array = array.as_any().downcast_ref::<DictionaryArray<$T>>().unwrap();
(
array.offset().unwrap(),
array.buffers(),
array.children(),
Some(array.values().clone()),
)
})
}
}
}