polars_arrow/array/binview/
ffi.rs

1use std::sync::Arc;
2
3use polars_error::PolarsResult;
4
5use super::BinaryViewArrayGeneric;
6use crate::array::binview::{View, ViewType};
7use crate::array::{FromFfi, ToFfi};
8use crate::bitmap::align;
9use crate::ffi;
10
11unsafe impl<T: ViewType + ?Sized> ToFfi for BinaryViewArrayGeneric<T> {
12    fn buffers(&self) -> Vec<Option<*const u8>> {
13        let mut buffers = Vec::with_capacity(self.buffers.len() + 2);
14        buffers.push(self.validity.as_ref().map(|x| x.as_ptr()));
15        buffers.push(Some(self.views.storage_ptr().cast::<u8>()));
16        buffers.extend(self.buffers.iter().map(|b| Some(b.storage_ptr())));
17        buffers
18    }
19
20    fn offset(&self) -> Option<usize> {
21        let offset = self.views.offset();
22        if let Some(bitmap) = self.validity.as_ref() {
23            if bitmap.offset() == offset {
24                Some(offset)
25            } else {
26                None
27            }
28        } else {
29            Some(offset)
30        }
31    }
32
33    fn to_ffi_aligned(&self) -> Self {
34        let offset = self.views.offset();
35
36        let validity = self.validity.as_ref().map(|bitmap| {
37            if bitmap.offset() == offset {
38                bitmap.clone()
39            } else {
40                align(bitmap, offset)
41            }
42        });
43
44        Self {
45            dtype: self.dtype.clone(),
46            validity,
47            views: self.views.clone(),
48            buffers: self.buffers.clone(),
49            phantom: Default::default(),
50            total_bytes_len: self.total_bytes_len.clone(),
51            total_buffer_len: self.total_buffer_len,
52        }
53    }
54}
55
56impl<T: ViewType + ?Sized, A: ffi::ArrowArrayRef> FromFfi<A> for BinaryViewArrayGeneric<T> {
57    unsafe fn try_from_ffi(array: A) -> PolarsResult<Self> {
58        let dtype = array.dtype().clone();
59
60        let validity = unsafe { array.validity() }?;
61        let views = unsafe { array.buffer::<View>(1) }?;
62
63        // 2 - validity + views
64        let n_buffers = array.n_buffers();
65        let mut remaining_buffers = n_buffers - 2;
66        if remaining_buffers <= 1 {
67            return Ok(Self::new_unchecked_unknown_md(
68                dtype,
69                views,
70                Arc::from([]),
71                validity,
72                None,
73            ));
74        }
75
76        let n_variadic_buffers = remaining_buffers - 1;
77        let variadic_buffer_offset = n_buffers - 1;
78
79        let variadic_buffer_sizes =
80            array.buffer_known_len::<i64>(variadic_buffer_offset, n_variadic_buffers)?;
81        remaining_buffers -= 1;
82
83        let mut variadic_buffers = Vec::with_capacity(remaining_buffers);
84
85        let offset = 2;
86        for (i, &size) in (offset..remaining_buffers + offset).zip(variadic_buffer_sizes.iter()) {
87            let values = unsafe { array.buffer_known_len::<u8>(i, size as usize) }?;
88            variadic_buffers.push(values);
89        }
90
91        Ok(Self::new_unchecked_unknown_md(
92            dtype,
93            views,
94            Arc::from(variadic_buffers),
95            validity,
96            None,
97        ))
98    }
99}