From 07dae144e19d53044f86cf8c07e0ee33e1bdfa90 Mon Sep 17 00:00:00 2001 From: Silas Pachali <80594111+Silas217209@users.noreply.github.com> Date: Thu, 21 May 2026 00:36:03 +0200 Subject: [PATCH 1/4] Add support for reading float arrays --- src/codes_message/read.rs | 16 ++++++++++++---- src/intermediate_bindings/codes_get.rs | 26 +++++++++++++++++++++++++- src/intermediate_bindings/mod.rs | 6 +++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/codes_message/read.rs b/src/codes_message/read.rs index 890297f..f2eea06 100644 --- a/src/codes_message/read.rs +++ b/src/codes_message/read.rs @@ -4,8 +4,9 @@ use crate::{ codes_message::CodesMessage, errors::CodesError, intermediate_bindings::{ - NativeKeyType, codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_long, - codes_get_long_array, codes_get_native_type, codes_get_size, codes_get_string, + NativeKeyType, codes_get_bytes, codes_get_double, codes_get_double_array, + codes_get_float_array, codes_get_long, codes_get_long_array, codes_get_native_type, + codes_get_size, codes_get_string, }, }; @@ -25,7 +26,7 @@ pub trait KeyRead { /// let mut file = CodesFile::new_from_file("./data/iceland.grib", ProductKind::GRIB)?; /// let message = file.ref_message_iter().next()?.context("no message")?; /// let short_name: String = message.read_key("shortName")?; - /// + /// /// assert_eq!(short_name, "msl"); /// # Ok(()) /// # } @@ -113,6 +114,13 @@ macro_rules! key_size_check { impl_key_read!(scalar, codes_get_long, NativeKeyType::Long, i64); impl_key_read!(scalar, codes_get_double, NativeKeyType::Double, f64); +// Double-typed ecCodes arrays can be decoded directly into f32. +impl_key_read!( + array, + codes_get_float_array, + NativeKeyType::Double, + Vec +); impl_key_read!(array, codes_get_string, NativeKeyType::Str, String); impl_key_read!(array, codes_get_bytes, NativeKeyType::Bytes, Vec); impl_key_read!(array, codes_get_long_array, NativeKeyType::Long, Vec); @@ -173,7 +181,7 @@ impl CodesMessage

{ /// let message = file.ref_message_iter().next()?.context("no message")?; /// let message_short_name = message.read_key_dynamic("shortName")?; /// let expected_short_name = DynamicKeyType::Str("msl".to_string()); - /// + /// /// assert_eq!(message_short_name, expected_short_name); /// # Ok(()) /// # } diff --git a/src/intermediate_bindings/codes_get.rs b/src/intermediate_bindings/codes_get.rs index 82ae4f7..2f7d687 100644 --- a/src/intermediate_bindings/codes_get.rs +++ b/src/intermediate_bindings/codes_get.rs @@ -95,6 +95,30 @@ pub unsafe fn codes_get_double_array( } } +pub unsafe fn codes_get_float_array( + handle: *const codes_handle, + key: &str, +) -> Result, CodesError> { + unsafe { + pointer_guard::non_null!(handle); + + let mut key_size = codes_get_size(handle, key)?; + let key = CString::new(key).unwrap(); + + let mut key_values: Vec = vec![0.0; key_size]; + + let error_code = eccodes_sys::codes_get_float_array( + handle, + key.as_ptr(), + key_values.as_mut_ptr().cast(), + &raw mut key_size, + ); + error_code_to_result(error_code)?; + + Ok(key_values) + } +} + pub unsafe fn codes_get_long_array( handle: *const codes_handle, key: &str, @@ -229,7 +253,7 @@ pub unsafe fn codes_get_message( debug_assert!( buffer_size == message_size, - "Buffer and message sizes ar not equal in codes_get_message! + "Buffer and message sizes ar not equal in codes_get_message! Please report this panic on Github." ); diff --git a/src/intermediate_bindings/mod.rs b/src/intermediate_bindings/mod.rs index 0338c1b..4320de1 100644 --- a/src/intermediate_bindings/mod.rs +++ b/src/intermediate_bindings/mod.rs @@ -5,7 +5,7 @@ //!These bindings convert Rust types to correct C types //!correctly represent data as pointers and utilize some other functions //!to make ecCodes usage safer and easier, -//!but they are unsafe as they operate on raw `codes_handle`. +//!but they are unsafe as they operate on raw `codes_handle`. mod codes_get; mod codes_handle; @@ -26,8 +26,8 @@ pub enum NativeKeyType { } pub use codes_get::{ - codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_long, - codes_get_long_array, codes_get_message, codes_get_native_type, codes_get_size, + codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_float_array, + codes_get_long, codes_get_long_array, codes_get_message, codes_get_native_type, codes_get_size, codes_get_string, }; pub use codes_handle::{codes_handle_clone, codes_handle_delete, codes_handle_new_from_file}; From f8241e03ad09a152d9860d30ee3429a4569878b4 Mon Sep 17 00:00:00 2001 From: Silas Pachali <80594111+Silas217209@users.noreply.github.com> Date: Thu, 21 May 2026 00:54:51 +0200 Subject: [PATCH 2/4] added benchmark --- benches/main.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/benches/main.rs b/benches/main.rs index 9fc90ff..364a5d5 100644 --- a/benches/main.rs +++ b/benches/main.rs @@ -1,6 +1,6 @@ use criterion::{Criterion, criterion_group, criterion_main}; -use eccodes::FallibleIterator; use eccodes::codes_file::{CodesFile, ProductKind}; +use eccodes::{FallibleIterator, KeyRead}; use std::hint::black_box; use std::path::Path; @@ -28,6 +28,14 @@ pub fn key_reading(c: &mut Criterion) { b.iter(|| msg.read_key_dynamic(black_box("values")).unwrap()) }); + c.bench_function("static double array reading", |b| { + b.iter(|| -> Vec { msg.read_key(black_box("values")).unwrap() }) + }); + + c.bench_function("static float array reading", |b| { + b.iter(|| -> Vec { msg.read_key(black_box("values")).unwrap() }) + }); + c.bench_function("string reading", |b| { b.iter(|| msg.read_key_dynamic(black_box("name")).unwrap()) }); From af4c38fea69820ce4f802309ca5ba6c6c4b1ba20 Mon Sep 17 00:00:00 2001 From: Silas Pachali <80594111+Silas217209@users.noreply.github.com> Date: Thu, 21 May 2026 01:09:11 +0200 Subject: [PATCH 3/4] whitespace --- benches/main.rs | 2 +- src/codes_message/read.rs | 4 ++-- src/intermediate_bindings/codes_get.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/benches/main.rs b/benches/main.rs index 364a5d5..73f62c1 100644 --- a/benches/main.rs +++ b/benches/main.rs @@ -1,6 +1,6 @@ use criterion::{Criterion, criterion_group, criterion_main}; -use eccodes::codes_file::{CodesFile, ProductKind}; use eccodes::{FallibleIterator, KeyRead}; +use eccodes::codes_file::{CodesFile, ProductKind}; use std::hint::black_box; use std::path::Path; diff --git a/src/codes_message/read.rs b/src/codes_message/read.rs index f2eea06..1254d07 100644 --- a/src/codes_message/read.rs +++ b/src/codes_message/read.rs @@ -26,7 +26,7 @@ pub trait KeyRead { /// let mut file = CodesFile::new_from_file("./data/iceland.grib", ProductKind::GRIB)?; /// let message = file.ref_message_iter().next()?.context("no message")?; /// let short_name: String = message.read_key("shortName")?; - /// + /// /// assert_eq!(short_name, "msl"); /// # Ok(()) /// # } @@ -181,7 +181,7 @@ impl CodesMessage

{ /// let message = file.ref_message_iter().next()?.context("no message")?; /// let message_short_name = message.read_key_dynamic("shortName")?; /// let expected_short_name = DynamicKeyType::Str("msl".to_string()); - /// + /// /// assert_eq!(message_short_name, expected_short_name); /// # Ok(()) /// # } diff --git a/src/intermediate_bindings/codes_get.rs b/src/intermediate_bindings/codes_get.rs index 2f7d687..7380254 100644 --- a/src/intermediate_bindings/codes_get.rs +++ b/src/intermediate_bindings/codes_get.rs @@ -253,7 +253,7 @@ pub unsafe fn codes_get_message( debug_assert!( buffer_size == message_size, - "Buffer and message sizes ar not equal in codes_get_message! + "Buffer and message sizes ar not equal in codes_get_message! Please report this panic on Github." ); From f28973e17048c7cf98c237f5677874187fd0c5ea Mon Sep 17 00:00:00 2001 From: Silas Pachali <80594111+Silas217209@users.noreply.github.com> Date: Thu, 21 May 2026 01:10:32 +0200 Subject: [PATCH 4/4] whitespace --- src/intermediate_bindings/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intermediate_bindings/mod.rs b/src/intermediate_bindings/mod.rs index 4320de1..23da50b 100644 --- a/src/intermediate_bindings/mod.rs +++ b/src/intermediate_bindings/mod.rs @@ -5,7 +5,7 @@ //!These bindings convert Rust types to correct C types //!correctly represent data as pointers and utilize some other functions //!to make ecCodes usage safer and easier, -//!but they are unsafe as they operate on raw `codes_handle`. +//!but they are unsafe as they operate on raw `codes_handle`. mod codes_get; mod codes_handle;