diff --git a/CHANGELOG.md b/CHANGELOG.md index f779cf7..ec0432d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Changes in each release are listed below. +## 0.9.1 09-Aug-2021 (Pre-release) +* Added alternative version of mwalib_metafits_context_new (mwalib_metafits_context_new2) to FFI interface which does not require an MWAVersion and will determine it via the MODE keyword. +* Fixed errors, ommissions in comment/documentation for FFI function mwalib_metafits_get_expected_volt_filename(). + ## 0.9.0 09-Aug-2021 (Pre-release) * Added mwa_version > to MetafitsContext struct. * When working only with a MetafitsContext, a None can be passed in lieu of an MWAVersion, and mwalib will attempt to determine the correct MWAVersion based on the MODE keyword from the metafits file. diff --git a/Cargo.toml b/Cargo.toml index e57a99d..fd8d60a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mwalib" -version = "0.9.0" +version = "0.9.1" homepage = "https://github.com/MWATelescope/mwalib" repository = "https://github.com/MWATelescope/mwalib" readme = "README.md" diff --git a/examples/mwalib-print-context.c b/examples/mwalib-print-context.c index dfb66a2..6df2ef3 100644 --- a/examples/mwalib-print-context.c +++ b/examples/mwalib-print-context.c @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) if (file_count == 1) { // Metafits only - if (mwalib_metafits_context_new(argv[1], CorrLegacy, &metafits_context, error_message, ERROR_MESSAGE_LEN) != EXIT_SUCCESS) + if (mwalib_metafits_context_new2(argv[1], &metafits_context, error_message, ERROR_MESSAGE_LEN) != EXIT_SUCCESS) { printf("Error getting metafits context: %s\n", error_message); exit(-1); diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 1070c0b..2333721 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -185,14 +185,13 @@ fn ffi_array_to_boxed_slice(v: Vec) -> *mut T { } } -/// Create and return a pointer to an `MetafitsContext` struct given only a metafits file +/// Create and return a pointer to an `MetafitsContext` struct given only a metafits file and MWAVersion. /// /// # Arguments /// /// * `metafits_filename` - pointer to char* buffer containing the full path and filename of a metafits file. /// /// * `mwa_version` - enum providing mwalib with the intended mwa version which the metafits should be interpreted. -/// Pass 0 to get mwalib to detect the version from the MODE metafits keyword. /// /// * `out_metafits_context_ptr` - A Rust-owned populated `MetafitsContext` pointer. Free with `mwalib_metafits_context_free'. /// @@ -222,16 +221,59 @@ pub unsafe extern "C" fn mwalib_metafits_context_new( .unwrap() .to_string(); - // In C/FFI any value can be passed in, even 0 - let int_mwa_version = mwa_version as u8; + let context = match MetafitsContext::new(&m, Some(mwa_version)) { + Ok(c) => c, + Err(e) => { + set_c_string( + &format!("{}", e), + error_message as *mut u8, + error_message_length, + ); + // Return failure + return MWALIB_FAILURE; + } + }; - let context = match MetafitsContext::new( - &m, - match int_mwa_version { - 0 => None, - _ => Some(mwa_version), - }, - ) { + *out_metafits_context_ptr = Box::into_raw(Box::new(context)); + + // Return success + MWALIB_SUCCESS +} + +/// Create and return a pointer to an `MetafitsContext` struct given only a metafits file. Same as mwalib_metafits_context_new, but mwalib will guess the MWAVersion. +/// +/// # Arguments +/// +/// * `metafits_filename` - pointer to char* buffer containing the full path and filename of a metafits file. +/// +/// * `out_metafits_context_ptr` - A Rust-owned populated `MetafitsContext` pointer. Free with `mwalib_metafits_context_free'. +/// +/// * `error_message` - pointer to already allocated buffer for any error messages to be returned to the caller. +/// +/// * `error_message_length` - length of error_message char* buffer. +/// +/// +/// # Returns +/// +/// * return MWALIB_SUCCESS on success, non-zero on failure +/// +/// +/// # Safety +/// * `error_message` *must* point to an already allocated `char*` buffer for any error messages. +/// * Caller *must* call the `mwalib_metafits_context_free` function to release the rust memory. +#[no_mangle] +pub unsafe extern "C" fn mwalib_metafits_context_new2( + metafits_filename: *const c_char, + out_metafits_context_ptr: &mut *mut MetafitsContext, + error_message: *const c_char, + error_message_length: size_t, +) -> i32 { + let m = CStr::from_ptr(metafits_filename) + .to_str() + .unwrap() + .to_string(); + + let context = match MetafitsContext::new(&m, None) { Ok(c) => c, Err(e) => { set_c_string( diff --git a/src/ffi/test.rs b/src/ffi/test.rs index d4e3876..395f321 100644 --- a/src/ffi/test.rs +++ b/src/ffi/test.rs @@ -327,6 +327,42 @@ fn test_mwalib_metafits_context_display() { } } +#[test] +fn test_mwalib_metafits_context_new_guess_mwa_version() { + let error_len: size_t = 128; + let error_message = CString::new(" ".repeat(error_len)).unwrap(); + let error_message_ptr = error_message.as_ptr() as *const c_char; + + let metafits_file = + CString::new("test_files/1101503312_1_timestep/1101503312.metafits").unwrap(); + let metafits_file_ptr = metafits_file.as_ptr(); + + unsafe { + // Create a MetafitsContext + let mut metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut(); + let retval = mwalib_metafits_context_new2( + metafits_file_ptr, + &mut metafits_context_ptr, + error_message_ptr, + error_len, + ); + + // Check return value of mwalib_metafits_context_new + assert_eq!(retval, 0, "mwalib_metafits_context_new failure"); + + // Check we got valid MetafitsContext pointer + let context_ptr = metafits_context_ptr.as_mut(); + assert!(context_ptr.is_some()); + + let metafits_context = context_ptr.unwrap(); + + assert_eq!( + metafits_context.mwa_version.unwrap(), + MWAVersion::CorrLegacy + ); + } +} + #[test] fn test_mwalib_metafits_context_display_null_ptr() { let metafits_context_ptr: *mut MetafitsContext = std::ptr::null_mut(); diff --git a/src/metafits_context/test.rs b/src/metafits_context/test.rs index 7838b6f..1354691 100644 --- a/src/metafits_context/test.rs +++ b/src/metafits_context/test.rs @@ -378,6 +378,19 @@ fn test_populate_expected_coarse_channels_corr_mwaxv2() { } } +#[test] +fn test_metafits_context_new_guess_version() { + // Open the test metafits file + let metafits_filename = "test_files/1101503312_1_timestep/1101503312.metafits"; + + // Open a context and load in a test metafits + let result = MetafitsContext::new(&metafits_filename, None); + assert!(result.is_ok()); + + let context = result.unwrap(); + assert_eq!(context.mwa_version.unwrap(), MWAVersion::CorrLegacy); +} + #[test] fn test_generate_expected_volt_filename_legacy_vcs() { // Open the test metafits file