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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//! This package was automatically generated with [`rust-bindgen`][1] and as such was not
//! user-generated.
//!
//! The functions contained are expected to be used with [`fitsio`][2], a high level API wrapper
//! around the low level direct C-bindings, though the bindings are complete enough to be usable.
//!
//! This code will not be directly documented, and so users should refer to the [`fitsio` C
//! documentation][3] for usage.
//!
//! ## Note about function names
//!
//! Unfortunately we must use fits short names throughout. The C-api exposes long names for
//! functions which are more descriptive, for example `fits_open_file` instead of `ffopen`, but the
//! symbols available in the library have only short names, and the long names are merely
//! preprocessor definitions.
//!
//! ## Examples
//!
//! ```rust
//! # extern crate fitsio_sys_bindgen as fitsio_sys;
//! use std::ptr;
//! use std::ffi;
//! # use fitsio_sys::{ffinit, ffphps, ffclos};
//!
//! # fn main() {
//! let filename = ffi::CString::new("!/tmp/test.fits").unwrap();
//! let mut fptr = ptr::null_mut();
//! let mut status = 0;
//!
//! unsafe {
//!     // Create a new file, clobbering any pre-existing file
//!     ffinit(&mut fptr as *mut *mut _,
//!         filename.as_ptr(),
//!         &mut status);
//!
//!     // Add an empty primary HDU
//!     ffphps(fptr, 8, 0, ptr::null_mut(), &mut status);
//!
//!     // Finally close the file
//!     ffclos(fptr, &mut status);
//! }
//!
//! assert_eq!(status, 0);
//! # }
//! ```
//!
//! [1]: https://github.com/servo/rust-bindgen
//! [2]: https://crates.io/crates/fitsio
//! [3]: http://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/cfitsio.html

#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(improper_ctypes)]

extern crate libc;

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[cfg(test)]
mod test {
    extern crate tempdir;

    use std::ffi;
    use std::ptr;
    use libc::c_char;
    use super::*;

    #[test]
    fn raw_opening_an_existing_file() {
        let mut fptr = ptr::null_mut();
        let mut status = -1;
        let c_filename = ffi::CString::new("../testdata/full_example.fits").unwrap();

        unsafe {
            ffopen(&mut fptr as *mut *mut fitsfile,
                   c_filename.as_ptr(),
                   0,
                   &mut status);
            ffclos(fptr, &mut status);
        }

        assert_eq!(status, 0);
    }

    #[test]
    fn raw_creating_a_new_file() {
        // Set up the test filename
        let tdir = tempdir::TempDir::new("rust-fitsio-").unwrap();
        let filename = tdir.path().join("test.fits");
        assert!(!filename.exists());

        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(filename.to_str().unwrap()).unwrap();

        unsafe {
            ffinit(&mut fptr as *mut *mut fitsfile,
                   c_filename.as_ptr(),
                   &mut status);
        }

        assert!(filename.exists());
    }

    #[test]
    fn getting_current_hdu_number() {
        let mut fptr = ptr::null_mut();
        let mut status = -1;
        let c_filename = ffi::CString::new("../testdata/full_example.fits").unwrap();
        let mut hdu_num = -1;

        unsafe {
            ffopen(&mut fptr as *mut *mut fitsfile,
                   c_filename.as_ptr(),
                   0,
                   &mut status);
            ffghdn(fptr, &mut hdu_num);
            ffclos(fptr, &mut status);
        }

        assert_eq!(hdu_num, 1);
    }

    #[test]
    fn changing_hdu_by_absolute_number() {
        let mut fptr = ptr::null_mut();
        let mut status = -1;
        let c_filename = ffi::CString::new("../testdata/full_example.fits").unwrap();

        let mut hdu_type = 0;
        let mut hdu_num = 0;

        unsafe {
            ffopen(&mut fptr as *mut *mut fitsfile,
                   c_filename.as_ptr(),
                   0,
                   &mut status);
            ffmahd(fptr, 2, &mut hdu_type, &mut status);
            ffghdn(fptr, &mut hdu_num);
            ffclos(fptr, &mut status);
        }

        assert_eq!(hdu_num, 2);
    }

    #[test]
    fn reading_header_key_value() {
        let mut fptr = ptr::null_mut();
        let mut status = -1;
        let c_filename = ffi::CString::new("../testdata/full_example.fits").unwrap();

        let mut long_value = 0;
        let mut float_value = 0.0;
        let mut double_value = 0.0;
        let keyname = ffi::CString::new("INTTEST").unwrap();
        let double_keyname = ffi::CString::new("DBLTEST").unwrap();
        let mut comment: Vec<c_char> = vec![0; 73];
        unsafe {
            ffopen(&mut fptr as *mut *mut fitsfile,
                   c_filename.as_ptr(),
                   0,
                   &mut status);
            ffgkyj(fptr,
                   keyname.as_ptr(),
                   &mut long_value,
                   ptr::null_mut(),
                   &mut status);
            ffgkye(fptr,
                   keyname.as_ptr(),
                   &mut float_value,
                   ptr::null_mut(),
                   &mut status);

            // Double version is different
            ffgkyd(fptr,
                   double_keyname.as_ptr(),
                   &mut double_value,
                   comment.as_mut_ptr(),
                   &mut status);
            ffclos(fptr, &mut status);
        }

        assert_eq!(long_value, 42);
        assert_eq!(float_value, 42.0);
        assert_eq!(double_value, 3. / 32.);

        // TODO Hacky way of getting a string out. This should be simplified.
        let comment: Vec<u8> = comment.iter().map(|&x| x as u8).filter(|&x| x != 0).collect();
        let comment = String::from_utf8(comment).unwrap();
        assert_eq!(comment, "Double value");
    }

    // #[test]
    // fn api_usage() {
    // use fitsio::FitsFile;
    //
    // let mut f = FitsFile::open("../testdata/full_example.fits");
    // let mut primary_hdu = f.primary_hdu();
    // let header = primary_hdu.header();
    // let exposure_time: f32 = header["exposure"];
    // }
    //
}