use cxx::{let_cxx_string, UniquePtr};
use errors::{OrcError, OrcResult};
use kind;
use vector;
#[cxx::bridge]
pub(crate) mod ffi {
#[namespace = "orcxx_rs::utils"]
unsafe extern "C++" {
include!("cpp-utils.hh");
include!("orc/OrcFile.hh");
#[rust_name = "ReaderOptions_new"]
fn construct() -> UniquePtr<ReaderOptions>;
#[rust_name = "RowReaderOptions_new"]
fn construct() -> UniquePtr<RowReaderOptions>;
#[rust_name = "RowReaderOptions_copy"]
fn construct_copy(_: &UniquePtr<RowReaderOptions>) -> UniquePtr<RowReaderOptions>;
#[rust_name = "StringList_new"]
fn construct() -> UniquePtr<StringList>;
}
#[namespace = "orcxx_rs"]
unsafe extern "C++" {
type StringList;
fn push_back(self: Pin<&mut StringList>, value: &CxxString);
}
#[namespace = "orc"]
unsafe extern "C++" {
type ColumnVectorBatch = crate::vector::ffi::ColumnVectorBatch;
type Type = crate::kind::ffi::Type;
}
#[namespace = "orc"]
unsafe extern "C++" {
type InputStream;
type ReaderOptions;
fn readLocalFile(path: &CxxString) -> Result<UniquePtr<InputStream>>;
}
#[namespace = "orc"]
unsafe extern "C++" {
type RowReaderOptions;
#[rust_name = "include_names"]
fn include<'a>(
self: Pin<&'a mut RowReaderOptions>,
include: &StringList,
) -> Pin<&'a mut RowReaderOptions>;
}
#[namespace = "orc"]
unsafe extern "C++" {
type Reader;
fn createReader(
inStream: UniquePtr<InputStream>,
options: &ReaderOptions,
) -> Result<UniquePtr<Reader>>;
fn createRowReader(
&self,
rowReaderOptions: &RowReaderOptions,
) -> Result<UniquePtr<RowReader>>;
fn getType(&self) -> &Type;
fn getNumberOfStripes(&self) -> u64;
fn getStripe(&self, stripeIndex: u64) -> UniquePtr<StripeInformation>;
}
#[namespace = "orc"]
unsafe extern "C++" {
type RowReader;
fn createRowBatch(&self, size: u64) -> UniquePtr<ColumnVectorBatch>;
fn next(self: Pin<&mut RowReader>, data: Pin<&mut ColumnVectorBatch>) -> bool;
fn getSelectedType(&self) -> &Type;
fn getRowNumber(&self) -> u64;
fn seekToRow(self: Pin<&mut RowReader>, rowNumber: u64);
}
#[namespace = "orc"]
unsafe extern "C++" {
type StripeInformation;
fn getLength(&self) -> u64;
fn getNumberOfRows(&self) -> u64;
}
}
pub struct ReaderOptions(UniquePtr<ffi::ReaderOptions>);
impl Default for ReaderOptions {
fn default() -> ReaderOptions {
ReaderOptions(ffi::ReaderOptions_new())
}
}
unsafe impl Send for ReaderOptions {}
unsafe impl Sync for ReaderOptions {}
pub struct InputStream(UniquePtr<ffi::InputStream>);
impl InputStream {
pub fn from_local_file(file_name: &str) -> OrcResult<InputStream> {
let_cxx_string!(cxx_file_name = file_name);
ffi::readLocalFile(&cxx_file_name)
.map(InputStream)
.map_err(OrcError)
}
}
unsafe impl Send for InputStream {}
pub struct Reader(UniquePtr<ffi::Reader>);
impl Reader {
pub fn new(input_stream: InputStream) -> OrcResult<Reader> {
Reader::new_with_options(input_stream, ReaderOptions::default())
}
pub fn new_with_options(
input_stream: InputStream,
options: ReaderOptions,
) -> OrcResult<Reader> {
ffi::createReader(input_stream.0, &options.0)
.map_err(OrcError)
.map(Reader)
}
pub fn row_reader(&self, options: &RowReaderOptions) -> OrcResult<RowReader> {
self.0
.createRowReader(&options.0)
.map(RowReader)
.map_err(OrcError)
}
pub fn kind(&self) -> kind::Kind {
kind::Kind::new_from_orc_type(self.0.getType())
}
pub fn stripes(&self) -> impl Iterator<Item = StripeInformation> + '_ {
(0..self.0.getNumberOfStripes()).map(move |i| StripeInformation(self.0.getStripe(i)))
}
pub fn row_count(&self) -> u64 {
self.stripes()
.map(|stripe| stripe.rows_count())
.sum::<u64>()
}
}
unsafe impl Send for Reader {}
unsafe impl Sync for Reader {}
pub struct RowReaderOptions(UniquePtr<ffi::RowReaderOptions>);
impl Default for RowReaderOptions {
fn default() -> RowReaderOptions {
RowReaderOptions(ffi::RowReaderOptions_new())
}
}
impl RowReaderOptions {
pub fn include_names<I, S>(mut self, names: I) -> RowReaderOptions
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
let mut cxx_names = ffi::StringList_new();
for name in names.into_iter() {
let_cxx_string!(cxx_name = name.as_ref());
cxx_names.pin_mut().push_back(&cxx_name);
}
self.0.pin_mut().include_names(&cxx_names);
self
}
}
impl Clone for RowReaderOptions {
fn clone(&self) -> RowReaderOptions {
RowReaderOptions(ffi::RowReaderOptions_copy(&self.0))
}
}
unsafe impl Send for RowReaderOptions {}
unsafe impl Sync for RowReaderOptions {}
pub struct RowReader(UniquePtr<ffi::RowReader>);
impl RowReader {
pub fn row_batch(&mut self, size: u64) -> vector::OwnedColumnVectorBatch {
vector::OwnedColumnVectorBatch(self.0.createRowBatch(size))
}
pub fn read_into(&mut self, batch: &mut vector::OwnedColumnVectorBatch) -> bool {
self.0.pin_mut().next(batch.0.pin_mut())
}
pub fn selected_kind(&self) -> kind::Kind {
kind::Kind::new_from_orc_type(self.0.getSelectedType())
}
pub fn get_row_number(&self) -> u64 {
self.0.getRowNumber()
}
pub fn seek_to_row(&mut self, row_number: u64) {
self.0.pin_mut().seekToRow(row_number)
}
}
unsafe impl Send for RowReader {}
pub struct StripeInformation(UniquePtr<ffi::StripeInformation>);
impl StripeInformation {
pub fn bytes_count(&self) -> u64 {
self.0.getLength()
}
pub fn rows_count(&self) -> u64 {
self.0.getNumberOfRows()
}
}
unsafe impl Send for StripeInformation {}
unsafe impl Sync for StripeInformation {}