Skip to content

Commit 84c845a

Browse files
committed
feat(sys): add ngx_array_t::as_slice method
1 parent 7349dc4 commit 84c845a

File tree

6 files changed

+62
-23
lines changed

6 files changed

+62
-23
lines changed

examples/async.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::ffi::{c_char, c_void};
22
use std::ptr::{addr_of, addr_of_mut};
3-
use std::slice;
43
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
54
use std::sync::{Arc, OnceLock};
65
use std::time::Instant;
@@ -205,7 +204,7 @@ extern "C" fn ngx_http_async_commands_set_enable(
205204
) -> *mut c_char {
206205
unsafe {
207206
let conf = &mut *(conf as *mut ModuleConfig);
208-
let args = slice::from_raw_parts((*(*cf).args).elts as *mut ngx_str_t, (*(*cf).args).nelts);
207+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
209208
let val = args[1].to_str();
210209

211210
// set default value optionally

examples/awssig.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ extern "C" fn ngx_http_awssigv4_commands_set_enable(
175175
) -> *mut c_char {
176176
unsafe {
177177
let conf = &mut *(conf as *mut ModuleConfig);
178-
let args = (*(*cf).args).elts as *mut ngx_str_t;
179-
let val = (*args.add(1)).to_str();
178+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
179+
let val = args[1].to_str();
180180

181181
// set default value optionally
182182
conf.enable = false;
@@ -198,8 +198,8 @@ extern "C" fn ngx_http_awssigv4_commands_set_access_key(
198198
) -> *mut c_char {
199199
unsafe {
200200
let conf = &mut *(conf as *mut ModuleConfig);
201-
let args = (*(*cf).args).elts as *mut ngx_str_t;
202-
conf.access_key = (*args.add(1)).to_string();
201+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
202+
conf.access_key = args[1].to_string();
203203
};
204204

205205
ngx::core::NGX_CONF_OK
@@ -212,8 +212,8 @@ extern "C" fn ngx_http_awssigv4_commands_set_secret_key(
212212
) -> *mut c_char {
213213
unsafe {
214214
let conf = &mut *(conf as *mut ModuleConfig);
215-
let args = (*(*cf).args).elts as *mut ngx_str_t;
216-
conf.secret_key = (*args.add(1)).to_string();
215+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
216+
conf.secret_key = args[1].to_string();
217217
};
218218

219219
ngx::core::NGX_CONF_OK
@@ -226,8 +226,8 @@ extern "C" fn ngx_http_awssigv4_commands_set_s3_bucket(
226226
) -> *mut c_char {
227227
unsafe {
228228
let conf = &mut *(conf as *mut ModuleConfig);
229-
let args = (*(*cf).args).elts as *mut ngx_str_t;
230-
conf.s3_bucket = (*args.add(1)).to_string();
229+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
230+
conf.s3_bucket = args[1].to_string();
231231
if conf.s3_bucket.len() == 1 {
232232
println!("Validation failed");
233233
return ngx::core::NGX_CONF_ERROR;

examples/curl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ extern "C" fn ngx_http_curl_commands_set_enable(
117117
) -> *mut c_char {
118118
unsafe {
119119
let conf = &mut *(conf as *mut ModuleConfig);
120-
let args = (*(*cf).args).elts as *mut ngx_str_t;
120+
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
121121

122-
let val = (*args.add(1)).to_str();
122+
let val = args[1].to_str();
123123

124124
// set default value optionally
125125
conf.enable = false;

examples/shared_dict.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![no_std]
22
use ::core::ffi::{c_char, c_void};
3-
use ::core::{mem, ptr, slice};
3+
use ::core::{mem, ptr};
44

55
use nginx_sys::{
66
ngx_command_t, ngx_conf_t, ngx_http_add_variable, ngx_http_compile_complex_value_t,
@@ -127,8 +127,7 @@ extern "C" fn ngx_http_shared_dict_add_zone(
127127
// - `cf.args` is guaranteed to be a pointer to an array with 3 elements (NGX_CONF_TAKE2).
128128
// - The pointers are well-aligned by construction method (`ngx_palloc`).
129129
debug_assert!(!cf.args.is_null() && unsafe { (*cf.args).nelts >= 3 });
130-
let args =
131-
unsafe { slice::from_raw_parts_mut((*cf.args).elts as *mut ngx_str_t, (*cf.args).nelts) };
130+
let args = unsafe { (*cf.args).as_slice_mut() };
132131

133132
let name: ngx_str_t = args[1];
134133
let size = unsafe { ngx_parse_size(&mut args[2]) };
@@ -210,8 +209,7 @@ extern "C" fn ngx_http_shared_dict_add_variable(
210209
// - `cf.args` is guaranteed to be a pointer to an array with 3 elements (NGX_CONF_TAKE2).
211210
// - The pointers are well-aligned by construction method (`ngx_palloc`).
212211
debug_assert!(!cf.args.is_null() && unsafe { (*cf.args).nelts >= 3 });
213-
let args =
214-
unsafe { slice::from_raw_parts_mut((*cf.args).elts as *mut ngx_str_t, (*cf.args).nelts) };
212+
let args = unsafe { (*cf.args).as_slice_mut() };
215213

216214
let mut ccv: ngx_http_compile_complex_value_t = unsafe { mem::zeroed() };
217215
ccv.cf = cf;

examples/upstream.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99
use std::ffi::{c_char, c_void};
1010
use std::mem;
11-
use std::slice;
1211

1312
use ngx::core::{Pool, Status};
1413
use ngx::ffi::{
@@ -267,19 +266,18 @@ unsafe extern "C" fn ngx_http_upstream_commands_set_custom(
267266
// SAFETY: this function is called with non-NULL cf always
268267
let cf = &mut *cf;
269268
ngx_log_debug_mask!(DebugMask::Http, cf.log, "CUSTOM UPSTREAM module init");
269+
let args: &[ngx_str_t] = (*cf.args).as_slice();
270270

271271
let ccf = &mut (*(conf as *mut SrvConfig));
272272

273-
if (*cf.args).nelts == 2 {
274-
let value: &[ngx_str_t] =
275-
slice::from_raw_parts((*cf.args).elts as *const ngx_str_t, (*cf.args).nelts);
276-
let n = ngx_atoi(value[1].data, value[1].len);
273+
if let Some(value) = args.get(1) {
274+
let n = ngx_atoi(value.data, value.len);
277275
if n == (NGX_ERROR as isize) || n == 0 {
278276
ngx_conf_log_error!(
279277
NGX_LOG_EMERG,
280278
cf,
281279
"invalid value \"{}\" in \"{}\" directive",
282-
value[1],
280+
value,
283281
&(*cmd).name
284282
);
285283
return ngx::core::NGX_CONF_ERROR;

nginx-sys/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,50 @@ pub const NGX_ALIGNMENT: usize = NGX_RS_ALIGNMENT;
4646
// requirements.
4747
const _: () = assert!(core::mem::align_of::<ngx_str_t>() <= NGX_ALIGNMENT);
4848

49+
impl ngx_array_t {
50+
/// Returns the contents of this array as a slice of `T`.
51+
///
52+
/// # Safety
53+
///
54+
/// The array must be a valid, initialized array containing elements of type T or compatible in
55+
/// layout with T (e.g. `#[repr(transparent)]` wrappers).
56+
pub unsafe fn as_slice<T>(&self) -> &[T] {
57+
debug_assert_eq!(
58+
core::mem::size_of::<T>(),
59+
self.size,
60+
"ngx_array_t::as_slice(): element size mismatch"
61+
);
62+
if self.nelts == 0 {
63+
&[]
64+
} else {
65+
// SAFETY: in a valid array, `elts` is a valid well-aligned pointer to at least `nelts`
66+
// elements of size `size`
67+
core::slice::from_raw_parts(self.elts.cast(), self.nelts)
68+
}
69+
}
70+
71+
/// Returns the contents of this array as a mutable slice of `T`.
72+
///
73+
/// # Safety
74+
///
75+
/// The array must be a valid, initialized array containing elements of type T or compatible in
76+
/// layout with T (e.g. `#[repr(transparent)]` wrappers).
77+
pub unsafe fn as_slice_mut<T>(&mut self) -> &mut [T] {
78+
debug_assert_eq!(
79+
core::mem::size_of::<T>(),
80+
self.size,
81+
"ngx_array_t::as_slice_mut(): element size mismatch"
82+
);
83+
if self.nelts == 0 {
84+
&mut []
85+
} else {
86+
// SAFETY: in a valid array, `elts` is a valid well-aligned pointer to at least `nelts`
87+
// elements of size `size`
88+
core::slice::from_raw_parts_mut(self.elts.cast(), self.nelts)
89+
}
90+
}
91+
}
92+
4993
impl ngx_command_t {
5094
/// Creates a new empty [`ngx_command_t`] instance.
5195
///

0 commit comments

Comments
 (0)