netcdf_sys/
lib.rs

1#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case)]
2#![allow(clippy::type_complexity)]
3#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4
5extern crate hdf5_sys;
6
7#[cfg(feature = "dap")]
8extern crate curl_sys;
9
10#[cfg(feature = "static")]
11extern crate netcdf_src;
12
13mod consts;
14mod functions;
15pub use consts::*;
16pub use functions::*;
17
18#[cfg(feature = "4.8.0")]
19mod dispatch;
20#[cfg(feature = "4.8.0")]
21pub use dispatch::*;
22
23#[cfg(feature = "has-mmap")]
24mod mmap;
25#[cfg(feature = "has-mmap")]
26pub use mmap::*;
27
28#[cfg(feature = "4.8.0")]
29mod filter;
30#[cfg(feature = "4.8.0")]
31pub use filter::*;
32
33#[cfg(feature = "mpi")]
34pub mod par;
35
36/// Global netCDF lock for using all functions in the netCDF library
37///
38/// Per the NetCDF FAQ: "THE C-BASED LIBRARIES ARE NOT THREAD-SAFE"
39/// This lock is the same as the one in `hdf5`, so the two libraries
40/// can be used at the same time
41pub use hdf5_sys::LOCK as libnetcdf_lock;
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    use std::env;
47    use std::ffi;
48    use std::path;
49
50    #[test]
51    fn test_nc_open_close() {
52        let mnf_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
53        let test_data_path = path::Path::new(&mnf_dir)
54            .join("testdata")
55            .join("simple_xy.nc");
56        let f = ffi::CString::new(test_data_path.to_str().unwrap()).unwrap();
57
58        let mut ncid: nc_type = -999_999;
59        unsafe {
60            let _g = libnetcdf_lock.lock();
61            let err = nc_open(f.as_ptr(), NC_NOWRITE, &mut ncid);
62            assert_eq!(err, NC_NOERR);
63            let err = nc_close(ncid);
64            assert_eq!(err, NC_NOERR);
65        }
66    }
67
68    #[test]
69    fn test_inq_varid() {
70        let mnf_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
71        let test_data_path = path::Path::new(&mnf_dir)
72            .join("testdata")
73            .join("simple_xy.nc");
74        let f = ffi::CString::new(test_data_path.to_str().unwrap()).unwrap();
75        let varname = ffi::CString::new("data").unwrap();
76
77        let mut ncid: nc_type = -999_999;
78        let mut varid: nc_type = -999_999;
79        let mut nvars: nc_type = -999_999;
80        unsafe {
81            let _g = libnetcdf_lock.lock();
82            let err = nc_open(f.as_ptr(), NC_NOWRITE, &mut ncid);
83            assert_eq!(err, NC_NOERR);
84            let err = nc_inq_nvars(ncid, &mut nvars);
85            assert_eq!(err, NC_NOERR);
86            assert_eq!(nvars, 1);
87            let err = nc_inq_varid(ncid, varname.as_ptr(), &mut varid);
88            assert_eq!(err, NC_NOERR);
89            let err = nc_close(ncid);
90            assert_eq!(err, NC_NOERR);
91        }
92    }
93
94    #[test]
95    fn test_get_var() {
96        let mnf_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
97        let test_data_path = path::Path::new(&mnf_dir)
98            .join("testdata")
99            .join("simple_xy.nc");
100        let f = ffi::CString::new(test_data_path.to_str().unwrap()).unwrap();
101        let varname = ffi::CString::new("data").unwrap();
102
103        let mut ncid: nc_type = -999_999;
104        let mut varid: nc_type = -999_999;
105        let mut buf: Vec<nc_type> = vec![0; 6 * 12];
106        unsafe {
107            let _g = libnetcdf_lock.lock();
108            let err = nc_open(f.as_ptr(), NC_NOWRITE, &mut ncid);
109            assert_eq!(err, NC_NOERR);
110
111            let err = nc_inq_varid(ncid, varname.as_ptr(), &mut varid);
112            assert_eq!(err, NC_NOERR);
113
114            let err = nc_get_var_int(ncid, varid, buf.as_mut_ptr());
115            assert_eq!(err, NC_NOERR);
116
117            let err = nc_close(ncid);
118            assert_eq!(err, NC_NOERR);
119        }
120
121        for (x, d) in buf.into_iter().enumerate() {
122            assert_eq!(d, x as _);
123        }
124    }
125}