use ffi;
use enums;
use libc::funcs::c95::stdio::{feof, fread};
use std::marker::PhantomData;
use std::ffi::CString;
pub struct NTuples<T> {
n: *mut ffi::gsl_ntuple,
p: PhantomData<T>
}
impl<T> NTuples<T> {
pub fn create(filename: &str, data: &mut T) -> Option<NTuples<T>> {
let t_data = unsafe { ::std::mem::transmute(data) };
let c_str = CString::new(filename.as_bytes()).unwrap();
let tmp = unsafe {
ffi::gsl_ntuple_create(c_str.as_ptr() as *mut i8, t_data, ::std::mem::size_of::<T>() as u64)
};
if tmp.is_null() {
None
} else {
Some(NTuples {
n: tmp,
p: PhantomData
})
}
}
pub fn open(filename: &str, data: &mut T) -> Option<NTuples<T>> {
let t_data = unsafe { ::std::mem::transmute(data) };
let c_str = CString::new(filename.as_bytes()).unwrap();
let tmp = unsafe {
ffi::gsl_ntuple_open(c_str.as_ptr() as *mut i8, t_data, ::std::mem::size_of::<T>() as u64)
};
if tmp.is_null() {
None
} else {
Some(NTuples {
n: tmp,
p: PhantomData
})
}
}
pub fn write(&self) -> enums::value::Value {
unsafe { ffi::gsl_ntuple_write(self.n) }
}
pub fn bookdata(&self) -> enums::value::Value {
unsafe { ffi::gsl_ntuple_bookdata(self.n) }
}
pub fn read(&self) -> enums::value::Value {
unsafe { ffi::gsl_ntuple_read(self.n) }
}
pub fn project<U, V>(&self, h: &::Histogram, value_func: ::value_function<T, U>, value_arg: &mut U,
select_func: ::select_function<T, V>, select_arg: &mut V) -> enums::value::Value {
unsafe {
loop {
let nread = fread((*self.n).ntuple_data, (*self.n).size, 1, (*self.n).file);
if nread == 0 && feof((*self.n).file) != 0 {
break;
}
if nread != 1 {
rgsl_error!("failed to read ntuple for projection", ::Value::Failed);
}
if select_func(::std::mem::transmute((*self.n).ntuple_data), select_arg) {
ffi::gsl_histogram_increment(ffi::FFI::unwrap(h), value_func(::std::mem::transmute((*self.n).ntuple_data), value_arg));
}
}
::Value::Success
}
}
}
impl<T> Drop for NTuples<T> {
fn drop(&mut self) {
unsafe { ffi::gsl_ntuple_close(self.n) };
self.n = ::std::ptr::null_mut();
}
}
impl<T> ffi::FFI<ffi::gsl_ntuple> for NTuples<T> {
fn wrap(n: *mut ffi::gsl_ntuple) -> NTuples<T> {
NTuples {
n: n,
p: PhantomData
}
}
fn unwrap(n: &NTuples<T>) -> *mut ffi::gsl_ntuple {
n.n
}
}