Skip to content

Commit 11bf1d8

Browse files
authored
Merge pull request #152 from magnusuMET/feature/raw_values
Add back get_raw_values/get_raw_values_into
2 parents 9a8eb99 + 593fecd commit 11bf1d8

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

netcdf/src/putget.rs

+28
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,34 @@ pub(crate) fn get_vars<T>(
184184
get_vars_mono(var, tp, start, count, stride, values.cast())
185185
}
186186

187+
/// Non-typechecked version of get_vars
188+
/// to support getting a bag of bytes
189+
pub fn get_raw_values_into(
190+
variable: &crate::Variable,
191+
buffer: &mut [u8],
192+
extents: crate::Extents,
193+
) -> crate::error::Result<()> {
194+
let dims = variable.dimensions();
195+
let (start, count, stride) = extents.get_start_count_stride(dims)?;
196+
let number_of_elements = count.iter().copied().fold(1_usize, usize::saturating_mul);
197+
let varsize = variable.vartype().size();
198+
if number_of_elements * varsize != buffer.len() {
199+
return Err("Buffer is not of requisite size".into());
200+
}
201+
checked_with_lock(|| unsafe {
202+
netcdf_sys::nc_get_vars(
203+
variable.ncid,
204+
variable.varid,
205+
start.as_ptr(),
206+
count.as_ptr(),
207+
stride.as_ptr(),
208+
buffer.as_mut_ptr().cast(),
209+
)
210+
})?;
211+
212+
Ok(())
213+
}
214+
187215
#[allow(clippy::too_many_lines)]
188216
fn put_vars_mono(
189217
var: &mut crate::VariableMut,

netcdf/src/variable.rs

+36
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,42 @@ impl<'g> Variable<'g> {
537537
let extents: Extents = extents.try_into().map_err(Into::into)?;
538538
self.values_to_mono(buffer, &extents)
539539
}
540+
541+
/// Fetches variable and returns the bytes.
542+
/// It is up to the caller to decide what to do with these bytes,
543+
/// including interpretation and freeing memory if
544+
/// this is a vlen/string type
545+
pub fn get_raw_values<E>(&self, extents: E) -> error::Result<Vec<u8>>
546+
where
547+
E: TryInto<Extents>,
548+
E::Error: Into<error::Error>,
549+
{
550+
let extents: Extents = extents.try_into().map_err(Into::into)?;
551+
let dims = self.dimensions();
552+
let (_, count, _) = extents.get_start_count_stride(dims)?;
553+
let number_of_elements = count.iter().copied().fold(1_usize, usize::saturating_mul);
554+
let varsize = self.vartype().size();
555+
let mut buffer = vec![0_u8; number_of_elements * varsize];
556+
557+
super::putget::get_raw_values_into(self, &mut buffer, extents)?;
558+
559+
Ok(buffer)
560+
}
561+
562+
/// Fetches variable into provided buffer.
563+
/// This functions returns bytes and it is up to the caller to
564+
/// decide what to do with it, including freeing memory if
565+
/// this is a vlen/string type
566+
pub fn get_raw_values_into<E>(&self, buffer: &mut [u8], extents: E) -> error::Result<()>
567+
where
568+
E: TryInto<Extents>,
569+
E::Error: Into<error::Error>,
570+
{
571+
let extents: Extents = extents.try_into().map_err(Into::into)?;
572+
super::putget::get_raw_values_into(self, buffer, extents)?;
573+
574+
Ok(())
575+
}
540576
}
541577

542578
impl<'g> VariableMut<'g> {

netcdf/tests/common/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/// Get location of the test files
2+
#[allow(dead_code)]
23
pub(crate) fn test_location() -> std::path::PathBuf {
34
use std::path::Path;
45

netcdf/tests/lib.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1766,3 +1766,32 @@ fn close_file() {
17661766
let f = netcdf::open(path).unwrap();
17671767
f.close().unwrap();
17681768
}
1769+
1770+
#[test]
1771+
fn read_raw_values() {
1772+
let path = test_location().join("sfc_pres_temp.nc");
1773+
let file = netcdf::open(path).unwrap();
1774+
1775+
let var = file.variable("pressure").unwrap();
1776+
let d_lat = 6;
1777+
let d_lon = 12;
1778+
1779+
let buffer = var.get_raw_values(..).unwrap();
1780+
assert_eq!(buffer.len(), d_lat * d_lon * std::mem::size_of::<f32>());
1781+
let buffer = var.get_raw_values((0, ..)).unwrap();
1782+
assert_eq!(buffer.len(), 1 * d_lon * std::mem::size_of::<f32>());
1783+
let buffer = var.get_raw_values((.., 0)).unwrap();
1784+
assert_eq!(buffer.len(), d_lat * 1 * std::mem::size_of::<f32>());
1785+
1786+
let mut buffer = vec![0; d_lat * d_lon * std::mem::size_of::<f32>()];
1787+
var.get_raw_values_into(&mut buffer, ..).unwrap();
1788+
1789+
var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4], (0, ..))
1790+
.unwrap();
1791+
1792+
// Mismatched buffers
1793+
var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4 - 1], (0, ..))
1794+
.unwrap_err();
1795+
var.get_raw_values_into(&mut buffer[..d_lon * 1 * 4 + 1], (0, ..))
1796+
.unwrap_err();
1797+
}

0 commit comments

Comments
 (0)