Skip to content

Commit

Permalink
Merge pull request #152 from magnusuMET/feature/raw_values
Browse files Browse the repository at this point in the history
Add back get_raw_values/get_raw_values_into
  • Loading branch information
magnusuMET authored Aug 9, 2024
2 parents 9a8eb99 + 593fecd commit 11bf1d8
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
28 changes: 28 additions & 0 deletions netcdf/src/putget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,34 @@ pub(crate) fn get_vars<T>(
get_vars_mono(var, tp, start, count, stride, values.cast())
}

/// Non-typechecked version of get_vars
/// to support getting a bag of bytes
pub fn get_raw_values_into(
variable: &crate::Variable,
buffer: &mut [u8],
extents: crate::Extents,
) -> crate::error::Result<()> {
let dims = variable.dimensions();
let (start, count, stride) = extents.get_start_count_stride(dims)?;
let number_of_elements = count.iter().copied().fold(1_usize, usize::saturating_mul);
let varsize = variable.vartype().size();
if number_of_elements * varsize != buffer.len() {
return Err("Buffer is not of requisite size".into());
}
checked_with_lock(|| unsafe {
netcdf_sys::nc_get_vars(
variable.ncid,
variable.varid,
start.as_ptr(),
count.as_ptr(),
stride.as_ptr(),
buffer.as_mut_ptr().cast(),
)
})?;

Ok(())
}

#[allow(clippy::too_many_lines)]
fn put_vars_mono(
var: &mut crate::VariableMut,
Expand Down
36 changes: 36 additions & 0 deletions netcdf/src/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,42 @@ impl<'g> Variable<'g> {
let extents: Extents = extents.try_into().map_err(Into::into)?;
self.values_to_mono(buffer, &extents)
}

/// Fetches variable and returns the bytes.
/// It is up to the caller to decide what to do with these bytes,
/// including interpretation and freeing memory if
/// this is a vlen/string type
pub fn get_raw_values<E>(&self, extents: E) -> error::Result<Vec<u8>>
where
E: TryInto<Extents>,
E::Error: Into<error::Error>,
{
let extents: Extents = extents.try_into().map_err(Into::into)?;
let dims = self.dimensions();
let (_, count, _) = extents.get_start_count_stride(dims)?;
let number_of_elements = count.iter().copied().fold(1_usize, usize::saturating_mul);
let varsize = self.vartype().size();
let mut buffer = vec![0_u8; number_of_elements * varsize];

super::putget::get_raw_values_into(self, &mut buffer, extents)?;

Ok(buffer)
}

/// Fetches variable into provided buffer.
/// This functions returns bytes and it is up to the caller to
/// decide what to do with it, including freeing memory if
/// this is a vlen/string type
pub fn get_raw_values_into<E>(&self, buffer: &mut [u8], extents: E) -> error::Result<()>
where
E: TryInto<Extents>,
E::Error: Into<error::Error>,
{
let extents: Extents = extents.try_into().map_err(Into::into)?;
super::putget::get_raw_values_into(self, buffer, extents)?;

Ok(())
}
}

impl<'g> VariableMut<'g> {
Expand Down
1 change: 1 addition & 0 deletions netcdf/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/// Get location of the test files
#[allow(dead_code)]
pub(crate) fn test_location() -> std::path::PathBuf {
use std::path::Path;

Expand Down
29 changes: 29 additions & 0 deletions netcdf/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1766,3 +1766,32 @@ fn close_file() {
let f = netcdf::open(path).unwrap();
f.close().unwrap();
}

#[test]
fn read_raw_values() {
let path = test_location().join("sfc_pres_temp.nc");
let file = netcdf::open(path).unwrap();

let var = file.variable("pressure").unwrap();
let d_lat = 6;
let d_lon = 12;

let buffer = var.get_raw_values(..).unwrap();
assert_eq!(buffer.len(), d_lat * d_lon * std::mem::size_of::<f32>());
let buffer = var.get_raw_values((0, ..)).unwrap();
assert_eq!(buffer.len(), 1 * d_lon * std::mem::size_of::<f32>());
let buffer = var.get_raw_values((.., 0)).unwrap();
assert_eq!(buffer.len(), d_lat * 1 * std::mem::size_of::<f32>());

let mut buffer = vec![0; d_lat * d_lon * std::mem::size_of::<f32>()];
var.get_raw_values_into(&mut buffer, ..).unwrap();

var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4], (0, ..))
.unwrap();

// Mismatched buffers
var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4 - 1], (0, ..))
.unwrap_err();
var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4 + 1], (0, ..))
.unwrap_err();
}

0 comments on commit 11bf1d8

Please sign in to comment.