Skip to content

Commit 1fd19d3

Browse files
committed
refactor(sys): split ngx_str_t implementations into new file
1 parent 851da45 commit 1fd19d3

File tree

3 files changed

+170
-162
lines changed

3 files changed

+170
-162
lines changed

nginx-sys/src/detail.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,51 @@
22
#![allow(missing_docs)]
33

44
use core::fmt;
5+
use core::ptr::copy_nonoverlapping;
6+
7+
use crate::bindings::{ngx_pnalloc, ngx_pool_t, u_char};
8+
9+
/// Convert a byte slice to a raw pointer (`*mut u_char`) allocated in the given nginx memory pool.
10+
///
11+
/// # Safety
12+
///
13+
/// The caller must provide a valid pointer to the memory pool.
14+
pub unsafe fn bytes_to_uchar(pool: *mut ngx_pool_t, data: &[u8]) -> Option<*mut u_char> {
15+
let ptr: *mut u_char = ngx_pnalloc(pool, data.len()) as _;
16+
if ptr.is_null() {
17+
return None;
18+
}
19+
copy_nonoverlapping(data.as_ptr(), ptr, data.len());
20+
Some(ptr)
21+
}
22+
23+
/// Convert a string slice (`&str`) to a raw pointer (`*mut u_char`) allocated in the given nginx
24+
/// memory pool.
25+
///
26+
/// # Arguments
27+
///
28+
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
29+
/// * `data` - The string slice to convert to a raw pointer.
30+
///
31+
/// # Safety
32+
/// This function is marked as unsafe because it involves raw pointer manipulation and direct memory
33+
/// allocation using `ngx_pnalloc`.
34+
///
35+
/// # Returns
36+
/// A raw pointer (`*mut u_char`) to the allocated memory containing the converted string data.
37+
///
38+
/// # Example
39+
/// ```rust,ignore
40+
/// let pool: *mut ngx_pool_t = ...; // Obtain a pointer to the nginx memory pool
41+
/// let data: &str = "example"; // The string to convert
42+
/// let ptr = str_to_uchar(pool, data);
43+
/// ```
44+
pub unsafe fn str_to_uchar(pool: *mut ngx_pool_t, data: &str) -> *mut u_char {
45+
let ptr: *mut u_char = ngx_pnalloc(pool, data.len()) as _;
46+
debug_assert!(!ptr.is_null());
47+
copy_nonoverlapping(data.as_ptr(), ptr, data.len());
48+
ptr
49+
}
550

651
#[inline]
752
pub fn debug_bytes(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result {

nginx-sys/src/lib.rs

Lines changed: 2 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
pub mod detail;
66
mod event;
77
mod queue;
8+
mod string;
89

9-
use core::fmt;
1010
use core::mem::offset_of;
11-
use core::ptr::{self, copy_nonoverlapping};
12-
use core::slice;
11+
use core::ptr;
1312

1413
#[doc(hidden)]
1514
mod bindings {
@@ -45,165 +44,6 @@ pub const NGX_HTTP_SRV_CONF_OFFSET: usize = offset_of!(ngx_http_conf_ctx_t, srv_
4544
/// This is used to access the location configuration context for an HTTP module.
4645
pub const NGX_HTTP_LOC_CONF_OFFSET: usize = offset_of!(ngx_http_conf_ctx_t, loc_conf);
4746

48-
/// Convert a byte slice to a raw pointer (`*mut u_char`) allocated in the given nginx memory pool.
49-
///
50-
/// # Safety
51-
///
52-
/// The caller must provide a valid pointer to the memory pool.
53-
pub unsafe fn bytes_to_uchar(pool: *mut ngx_pool_t, data: &[u8]) -> Option<*mut u_char> {
54-
let ptr: *mut u_char = ngx_pnalloc(pool, data.len()) as _;
55-
if ptr.is_null() {
56-
return None;
57-
}
58-
copy_nonoverlapping(data.as_ptr(), ptr, data.len());
59-
Some(ptr)
60-
}
61-
62-
/// Convert a string slice (`&str`) to a raw pointer (`*mut u_char`) allocated in the given nginx
63-
/// memory pool.
64-
///
65-
/// # Arguments
66-
///
67-
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
68-
/// * `data` - The string slice to convert to a raw pointer.
69-
///
70-
/// # Safety
71-
/// This function is marked as unsafe because it involves raw pointer manipulation and direct memory
72-
/// allocation using `ngx_pnalloc`.
73-
///
74-
/// # Returns
75-
/// A raw pointer (`*mut u_char`) to the allocated memory containing the converted string data.
76-
///
77-
/// # Example
78-
/// ```rust,ignore
79-
/// let pool: *mut ngx_pool_t = ...; // Obtain a pointer to the nginx memory pool
80-
/// let data: &str = "example"; // The string to convert
81-
/// let ptr = str_to_uchar(pool, data);
82-
/// ```
83-
pub unsafe fn str_to_uchar(pool: *mut ngx_pool_t, data: &str) -> *mut u_char {
84-
let ptr: *mut u_char = ngx_pnalloc(pool, data.len()) as _;
85-
debug_assert!(!ptr.is_null());
86-
copy_nonoverlapping(data.as_ptr(), ptr, data.len());
87-
ptr
88-
}
89-
90-
impl ngx_str_t {
91-
/// Returns the contents of this `ngx_str_t` as a byte slice.
92-
///
93-
/// The returned slice will **not** contain the optional nul terminator that `ngx_str_t.data`
94-
/// may have.
95-
#[inline]
96-
pub fn as_bytes(&self) -> &[u8] {
97-
if self.is_empty() {
98-
&[]
99-
} else {
100-
// SAFETY: `ngx_str_t` with non-zero len must contain a valid correctly aligned pointer
101-
unsafe { slice::from_raw_parts(self.data, self.len) }
102-
}
103-
}
104-
105-
/// Returns the contents of this `ngx_str_t` as a mutable byte slice.
106-
#[inline]
107-
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
108-
if self.is_empty() {
109-
&mut []
110-
} else {
111-
// SAFETY: `ngx_str_t` with non-zero len must contain a valid correctly aligned pointer
112-
unsafe { slice::from_raw_parts_mut(self.data, self.len) }
113-
}
114-
}
115-
116-
/// Returns `true` if the string has a length of 0.
117-
#[inline]
118-
pub fn is_empty(&self) -> bool {
119-
self.len == 0
120-
}
121-
122-
/// Convert the nginx string to a string slice (`&str`).
123-
///
124-
/// # Panics
125-
/// This function panics if the `ngx_str_t` is not valid UTF-8.
126-
///
127-
/// # Returns
128-
/// A string slice (`&str`) representing the nginx string.
129-
pub fn to_str(&self) -> &str {
130-
core::str::from_utf8(self.as_bytes()).unwrap()
131-
}
132-
133-
/// Creates an empty `ngx_str_t` instance.
134-
///
135-
/// This method replaces the `ngx_null_string` C macro.
136-
pub const fn empty() -> Self {
137-
ngx_str_t {
138-
len: 0,
139-
data: ptr::null_mut(),
140-
}
141-
}
142-
143-
/// Create an `ngx_str_t` instance from a byte slice.
144-
///
145-
/// # Safety
146-
///
147-
/// The caller must provide a valid pointer to a memory pool.
148-
pub unsafe fn from_bytes(pool: *mut ngx_pool_t, src: &[u8]) -> Option<Self> {
149-
bytes_to_uchar(pool, src).map(|data| Self {
150-
data,
151-
len: src.len(),
152-
})
153-
}
154-
155-
/// Create an `ngx_str_t` instance from a string slice (`&str`).
156-
///
157-
/// # Arguments
158-
///
159-
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
160-
/// * `data` - The string slice from which to create the nginx string.
161-
///
162-
/// # Safety
163-
/// This function is marked as unsafe because it accepts a raw pointer argument. There is no
164-
/// way to know if `pool` is pointing to valid memory. The caller must provide a valid pool to
165-
/// avoid indeterminate behavior.
166-
///
167-
/// # Returns
168-
/// An `ngx_str_t` instance representing the given string slice.
169-
pub unsafe fn from_str(pool: *mut ngx_pool_t, data: &str) -> Self {
170-
ngx_str_t {
171-
data: str_to_uchar(pool, data),
172-
len: data.len(),
173-
}
174-
}
175-
}
176-
177-
impl Default for ngx_str_t {
178-
fn default() -> Self {
179-
Self::empty()
180-
}
181-
}
182-
183-
impl From<ngx_str_t> for &[u8] {
184-
fn from(s: ngx_str_t) -> Self {
185-
if s.len == 0 || s.data.is_null() {
186-
return Default::default();
187-
}
188-
unsafe { slice::from_raw_parts(s.data, s.len) }
189-
}
190-
}
191-
192-
impl fmt::Display for ngx_str_t {
193-
#[inline]
194-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
195-
detail::display_bytes(f, self.as_bytes())
196-
}
197-
}
198-
199-
impl TryFrom<ngx_str_t> for &str {
200-
type Error = core::str::Utf8Error;
201-
202-
fn try_from(s: ngx_str_t) -> Result<Self, Self::Error> {
203-
core::str::from_utf8(s.into())
204-
}
205-
}
206-
20747
impl ngx_command_t {
20848
/// Creates a new empty [`ngx_command_t`] instance.
20949
///

nginx-sys/src/string.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use core::fmt;
2+
use core::ptr;
3+
use core::slice;
4+
5+
use crate::bindings::{ngx_pool_t, ngx_str_t};
6+
use crate::detail;
7+
8+
impl ngx_str_t {
9+
/// Returns the contents of this `ngx_str_t` as a byte slice.
10+
///
11+
/// The returned slice will **not** contain the optional nul terminator that `ngx_str_t.data`
12+
/// may have.
13+
#[inline]
14+
pub fn as_bytes(&self) -> &[u8] {
15+
if self.is_empty() {
16+
&[]
17+
} else {
18+
// SAFETY: `ngx_str_t` with non-zero len must contain a valid correctly aligned pointer
19+
unsafe { slice::from_raw_parts(self.data, self.len) }
20+
}
21+
}
22+
23+
/// Returns the contents of this `ngx_str_t` as a mutable byte slice.
24+
#[inline]
25+
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
26+
if self.is_empty() {
27+
&mut []
28+
} else {
29+
// SAFETY: `ngx_str_t` with non-zero len must contain a valid correctly aligned pointer
30+
unsafe { slice::from_raw_parts_mut(self.data, self.len) }
31+
}
32+
}
33+
34+
/// Returns `true` if the string has a length of 0.
35+
#[inline]
36+
pub fn is_empty(&self) -> bool {
37+
self.len == 0
38+
}
39+
40+
/// Convert the nginx string to a string slice (`&str`).
41+
///
42+
/// # Panics
43+
/// This function panics if the `ngx_str_t` is not valid UTF-8.
44+
///
45+
/// # Returns
46+
/// A string slice (`&str`) representing the nginx string.
47+
pub fn to_str(&self) -> &str {
48+
core::str::from_utf8(self.as_bytes()).unwrap()
49+
}
50+
51+
/// Creates an empty `ngx_str_t` instance.
52+
///
53+
/// This method replaces the `ngx_null_string` C macro.
54+
pub const fn empty() -> Self {
55+
ngx_str_t {
56+
len: 0,
57+
data: ptr::null_mut(),
58+
}
59+
}
60+
61+
/// Create an `ngx_str_t` instance from a byte slice.
62+
///
63+
/// # Safety
64+
///
65+
/// The caller must provide a valid pointer to a memory pool.
66+
pub unsafe fn from_bytes(pool: *mut ngx_pool_t, src: &[u8]) -> Option<Self> {
67+
detail::bytes_to_uchar(pool, src).map(|data| Self {
68+
data,
69+
len: src.len(),
70+
})
71+
}
72+
73+
/// Create an `ngx_str_t` instance from a string slice (`&str`).
74+
///
75+
/// # Arguments
76+
///
77+
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
78+
/// * `data` - The string slice from which to create the nginx string.
79+
///
80+
/// # Safety
81+
/// This function is marked as unsafe because it accepts a raw pointer argument. There is no
82+
/// way to know if `pool` is pointing to valid memory. The caller must provide a valid pool to
83+
/// avoid indeterminate behavior.
84+
///
85+
/// # Returns
86+
/// An `ngx_str_t` instance representing the given string slice.
87+
pub unsafe fn from_str(pool: *mut ngx_pool_t, data: &str) -> Self {
88+
ngx_str_t {
89+
data: detail::str_to_uchar(pool, data),
90+
len: data.len(),
91+
}
92+
}
93+
}
94+
95+
impl Default for ngx_str_t {
96+
fn default() -> Self {
97+
Self::empty()
98+
}
99+
}
100+
101+
impl From<ngx_str_t> for &[u8] {
102+
fn from(s: ngx_str_t) -> Self {
103+
if s.len == 0 || s.data.is_null() {
104+
return Default::default();
105+
}
106+
unsafe { slice::from_raw_parts(s.data, s.len) }
107+
}
108+
}
109+
110+
impl fmt::Display for ngx_str_t {
111+
#[inline]
112+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113+
detail::display_bytes(f, self.as_bytes())
114+
}
115+
}
116+
117+
impl TryFrom<ngx_str_t> for &str {
118+
type Error = core::str::Utf8Error;
119+
120+
fn try_from(s: ngx_str_t) -> Result<Self, Self::Error> {
121+
core::str::from_utf8(s.into())
122+
}
123+
}

0 commit comments

Comments
 (0)