eccodes/intermediate_bindings/
codes_get.rs1#![allow(non_camel_case_types)]
2#![allow(clippy::module_name_repetitions)]
3
4use std::ffi::{CStr, CString};
5
6use eccodes_sys::codes_handle;
7use libc::c_void;
8use num_traits::FromPrimitive;
9
10use crate::{
11 errors::{CodesError, CodesInternal},
12 pointer_guard,
13};
14
15use super::NativeKeyType;
16
17pub unsafe fn codes_get_native_type(
18 handle: *const codes_handle,
19 key: &str,
20) -> Result<NativeKeyType, CodesError> {
21 pointer_guard::non_null!(handle);
22
23 let key = CString::new(key).unwrap();
24 let mut key_type: i32 = 0;
25
26 let error_code = eccodes_sys::codes_get_native_type(handle, key.as_ptr(), &mut key_type);
27
28 if error_code != 0 {
29 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
30 return Err(err.into());
31 }
32
33 Ok(FromPrimitive::from_i32(key_type).unwrap())
34}
35
36pub unsafe fn codes_get_size(handle: *const codes_handle, key: &str) -> Result<usize, CodesError> {
37 pointer_guard::non_null!(handle);
38
39 let key = CString::new(key).unwrap();
40 let mut key_size: usize = 0;
41
42 let error_code = eccodes_sys::codes_get_size(handle, key.as_ptr(), &mut key_size);
43
44 if error_code != 0 {
45 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
46 return Err(err.into());
47 }
48
49 Ok(key_size)
50}
51
52pub unsafe fn codes_get_long(handle: *const codes_handle, key: &str) -> Result<i64, CodesError> {
53 pointer_guard::non_null!(handle);
54
55 let key = CString::new(key).unwrap();
56 let mut key_value: i64 = 0;
57
58 let error_code = eccodes_sys::codes_get_long(handle, key.as_ptr(), &mut key_value);
59
60 if error_code != 0 {
61 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
62 return Err(err.into());
63 }
64
65 Ok(key_value)
66}
67
68pub unsafe fn codes_get_double(handle: *const codes_handle, key: &str) -> Result<f64, CodesError> {
69 pointer_guard::non_null!(handle);
70
71 let key = CString::new(key).unwrap();
72 let mut key_value: f64 = 0.0;
73
74 let error_code = eccodes_sys::codes_get_double(handle, key.as_ptr(), &mut key_value);
75
76 if error_code != 0 {
77 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
78 return Err(err.into());
79 }
80
81 Ok(key_value)
82}
83
84pub unsafe fn codes_get_double_array(
85 handle: *const codes_handle,
86 key: &str,
87) -> Result<Vec<f64>, CodesError> {
88 pointer_guard::non_null!(handle);
89
90 let mut key_size = codes_get_size(handle, key)?;
91 let key = CString::new(key).unwrap();
92
93 let mut key_values: Vec<f64> = vec![0.0; key_size];
94
95 let error_code = eccodes_sys::codes_get_double_array(
96 handle,
97 key.as_ptr(),
98 key_values.as_mut_ptr().cast::<f64>(),
99 &mut key_size,
100 );
101
102 if error_code != 0 {
103 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
104 return Err(err.into());
105 }
106
107 Ok(key_values)
108}
109
110pub unsafe fn codes_get_long_array(
111 handle: *const codes_handle,
112 key: &str,
113) -> Result<Vec<i64>, CodesError> {
114 pointer_guard::non_null!(handle);
115
116 let mut key_size = codes_get_size(handle, key)?;
117 let key = CString::new(key).unwrap();
118
119 let mut key_values: Vec<i64> = vec![0; key_size];
120
121 let error_code = eccodes_sys::codes_get_long_array(
122 handle,
123 key.as_ptr(),
124 key_values.as_mut_ptr().cast::<i64>(),
125 &mut key_size,
126 );
127
128 if error_code != 0 {
129 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
130 return Err(err.into());
131 }
132
133 Ok(key_values)
134}
135
136pub unsafe fn codes_get_length(
137 handle: *const codes_handle,
138 key: &str,
139) -> Result<usize, CodesError> {
140 pointer_guard::non_null!(handle);
141
142 let key = CString::new(key).unwrap();
143 let mut key_length: usize = 0;
144
145 let error_code = eccodes_sys::codes_get_length(handle, key.as_ptr(), &mut key_length);
146
147 if error_code != 0 {
148 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
149 return Err(err.into());
150 }
151
152 Ok(key_length)
153}
154
155pub unsafe fn codes_get_string(
156 handle: *const codes_handle,
157 key: &str,
158) -> Result<String, CodesError> {
159 pointer_guard::non_null!(handle);
160
161 let mut key_length = codes_get_length(handle, key)?;
162 let key = CString::new(key).unwrap();
163
164 let mut key_message: Vec<u8> = vec![0; key_length];
165
166 let error_code = eccodes_sys::codes_get_string(
167 handle,
168 key.as_ptr(),
169 key_message.as_mut_ptr().cast::<i8>(),
170 &mut key_length,
171 );
172
173 if error_code != 0 {
174 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
175 return Err(err.into());
176 }
177
178 key_message.truncate(key_length);
179 let key_message_result = CStr::from_bytes_with_nul(key_message.as_ref());
180
181 let key_message_cstr = if let Ok(msg) = key_message_result {
182 msg
183 } else {
184 key_message.push(0);
185 CStr::from_bytes_with_nul(key_message.as_ref())?
186 };
187
188 let key_message_string = key_message_cstr.to_str()?.to_string();
189
190 Ok(key_message_string)
191}
192
193pub unsafe fn codes_get_bytes(
194 handle: *const codes_handle,
195 key: &str,
196) -> Result<Vec<u8>, CodesError> {
197 pointer_guard::non_null!(handle);
198
199 let mut key_size = codes_get_length(handle, key)?;
200 let key = CString::new(key).unwrap();
201
202 let mut buffer: Vec<u8> = vec![0; key_size];
203
204 let error_code = eccodes_sys::codes_get_bytes(
205 handle,
206 key.as_ptr(),
207 buffer.as_mut_ptr().cast::<u8>(),
208 &mut key_size,
209 );
210
211 if error_code != 0 {
212 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
213 return Err(err.into());
214 }
215
216 Ok(buffer)
217}
218
219pub unsafe fn codes_get_message_size(handle: *const codes_handle) -> Result<usize, CodesError> {
220 pointer_guard::non_null!(handle);
221
222 let mut size: usize = 0;
223
224 let error_code = eccodes_sys::codes_get_message_size(handle, &mut size);
225
226 if error_code != 0 {
227 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
228 return Err(err.into());
229 }
230
231 Ok(size)
232}
233
234pub unsafe fn codes_get_message(
235 handle: *const codes_handle,
236) -> Result<(*const c_void, usize), CodesError> {
237 pointer_guard::non_null!(handle);
238
239 let buffer_size = codes_get_message_size(handle)?;
240
241 let buffer: Vec<u8> = vec![0; buffer_size];
242 let mut buffer_ptr = buffer.as_ptr().cast::<libc::c_void>();
243
244 let mut message_size: usize = 0;
245
246 let error_code = eccodes_sys::codes_get_message(handle, &mut buffer_ptr, &mut message_size);
247
248 if error_code != 0 {
249 let err: CodesInternal = FromPrimitive::from_i32(error_code).unwrap();
250 return Err(err.into());
251 }
252
253 assert!(
254 buffer_size == message_size,
255 "Buffer and message sizes ar not equal in codes_get_message!
256 Please report this panic on Github."
257 );
258
259 Ok((buffer_ptr, message_size))
260}