ngx/core/
buffer.rs

1use core::slice;
2
3use crate::ffi::*;
4
5/// The `Buffer` trait provides methods for working with an nginx buffer (`ngx_buf_t`).
6///
7/// See <https://nginx.org/en/docs/dev/development_guide.html#buffer>
8pub trait Buffer {
9    /// Returns a raw pointer to the underlying `ngx_buf_t` of the buffer.
10    fn as_ngx_buf(&self) -> *const ngx_buf_t;
11
12    /// Returns a mutable raw pointer to the underlying `ngx_buf_t` of the buffer.
13    fn as_ngx_buf_mut(&mut self) -> *mut ngx_buf_t;
14
15    /// Returns the buffer contents as a byte slice.
16    fn as_bytes(&self) -> &[u8] {
17        let buf = self.as_ngx_buf();
18        unsafe { slice::from_raw_parts((*buf).pos, self.len()) }
19    }
20
21    /// Returns the length of the buffer contents.
22    fn len(&self) -> usize {
23        let buf = self.as_ngx_buf();
24        unsafe {
25            let pos = (*buf).pos;
26            let last = (*buf).last;
27            assert!(last >= pos);
28            usize::wrapping_sub(last as _, pos as _)
29        }
30    }
31
32    /// Returns `true` if the buffer is empty, i.e., it has zero length.
33    fn is_empty(&self) -> bool {
34        self.len() == 0
35    }
36
37    /// Sets the `last_buf` flag of the buffer.
38    ///
39    /// # Arguments
40    ///
41    /// * `last` - A boolean indicating whether the buffer is the last buffer in a request.
42    fn set_last_buf(&mut self, last: bool) {
43        let buf = self.as_ngx_buf_mut();
44        unsafe {
45            (*buf).set_last_buf(if last { 1 } else { 0 });
46        }
47    }
48
49    /// Sets the `last_in_chain` flag of the buffer.
50    ///
51    /// # Arguments
52    ///
53    /// * `last` - A boolean indicating whether the buffer is the last buffer in a chain of buffers.
54    fn set_last_in_chain(&mut self, last: bool) {
55        let buf = self.as_ngx_buf_mut();
56        unsafe {
57            (*buf).set_last_in_chain(if last { 1 } else { 0 });
58        }
59    }
60}
61
62/// The `MutableBuffer` trait extends the `Buffer` trait and provides methods for working with a
63/// mutable buffer.
64pub trait MutableBuffer: Buffer {
65    /// Returns a mutable reference to the buffer contents as a byte slice.
66    fn as_bytes_mut(&mut self) -> &mut [u8] {
67        let buf = self.as_ngx_buf_mut();
68        unsafe { slice::from_raw_parts_mut((*buf).pos, self.len()) }
69    }
70}
71
72/// Wrapper struct for a temporary buffer, providing methods for working with an `ngx_buf_t`.
73pub struct TemporaryBuffer(*mut ngx_buf_t);
74
75impl TemporaryBuffer {
76    /// Creates a new `TemporaryBuffer` from an `ngx_buf_t` pointer.
77    ///
78    /// # Panics
79    /// Panics if the given buffer pointer is null.
80    pub fn from_ngx_buf(buf: *mut ngx_buf_t) -> TemporaryBuffer {
81        assert!(!buf.is_null());
82        TemporaryBuffer(buf)
83    }
84}
85
86impl Buffer for TemporaryBuffer {
87    /// Returns the underlying `ngx_buf_t` pointer as a raw pointer.
88    fn as_ngx_buf(&self) -> *const ngx_buf_t {
89        self.0
90    }
91
92    /// Returns a mutable reference to the underlying `ngx_buf_t` pointer.
93    fn as_ngx_buf_mut(&mut self) -> *mut ngx_buf_t {
94        self.0
95    }
96}
97
98impl MutableBuffer for TemporaryBuffer {
99    /// Returns a mutable reference to the buffer contents as a byte slice.
100    fn as_bytes_mut(&mut self) -> &mut [u8] {
101        unsafe { slice::from_raw_parts_mut((*self.0).pos, self.len()) }
102    }
103}
104
105/// Wrapper struct for a memory buffer, providing methods for working with an `ngx_buf_t`.
106pub struct MemoryBuffer(*mut ngx_buf_t);
107
108impl MemoryBuffer {
109    /// Creates a new `MemoryBuffer` from an `ngx_buf_t` pointer.
110    ///
111    /// # Panics
112    /// Panics if the given buffer pointer is null.
113    pub fn from_ngx_buf(buf: *mut ngx_buf_t) -> MemoryBuffer {
114        assert!(!buf.is_null());
115        MemoryBuffer(buf)
116    }
117}
118
119impl Buffer for MemoryBuffer {
120    /// Returns the underlying `ngx_buf_t` pointer as a raw pointer.
121    fn as_ngx_buf(&self) -> *const ngx_buf_t {
122        self.0
123    }
124
125    /// Returns a mutable reference to the underlying `ngx_buf_t` pointer.
126    fn as_ngx_buf_mut(&mut self) -> *mut ngx_buf_t {
127        self.0
128    }
129}