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 mutable buffer.
63pub trait MutableBuffer: Buffer {
64    /// Returns a mutable reference to the buffer contents as a byte slice.
65    fn as_bytes_mut(&mut self) -> &mut [u8] {
66        let buf = self.as_ngx_buf_mut();
67        unsafe { slice::from_raw_parts_mut((*buf).pos, self.len()) }
68    }
69}
70
71/// Wrapper struct for a temporary buffer, providing methods for working with an `ngx_buf_t`.
72pub struct TemporaryBuffer(*mut ngx_buf_t);
73
74impl TemporaryBuffer {
75    /// Creates a new `TemporaryBuffer` from an `ngx_buf_t` pointer.
76    ///
77    /// # Panics
78    /// Panics if the given buffer pointer is null.
79    pub fn from_ngx_buf(buf: *mut ngx_buf_t) -> TemporaryBuffer {
80        assert!(!buf.is_null());
81        TemporaryBuffer(buf)
82    }
83}
84
85impl Buffer for TemporaryBuffer {
86    /// Returns the underlying `ngx_buf_t` pointer as a raw pointer.
87    fn as_ngx_buf(&self) -> *const ngx_buf_t {
88        self.0
89    }
90
91    /// Returns a mutable reference to the underlying `ngx_buf_t` pointer.
92    fn as_ngx_buf_mut(&mut self) -> *mut ngx_buf_t {
93        self.0
94    }
95}
96
97impl MutableBuffer for TemporaryBuffer {
98    /// Returns a mutable reference to the buffer contents as a byte slice.
99    fn as_bytes_mut(&mut self) -> &mut [u8] {
100        unsafe { slice::from_raw_parts_mut((*self.0).pos, self.len()) }
101    }
102}
103
104/// Wrapper struct for a memory buffer, providing methods for working with an `ngx_buf_t`.
105pub struct MemoryBuffer(*mut ngx_buf_t);
106
107impl MemoryBuffer {
108    /// Creates a new `MemoryBuffer` from an `ngx_buf_t` pointer.
109    ///
110    /// # Panics
111    /// Panics if the given buffer pointer is null.
112    pub fn from_ngx_buf(buf: *mut ngx_buf_t) -> MemoryBuffer {
113        assert!(!buf.is_null());
114        MemoryBuffer(buf)
115    }
116}
117
118impl Buffer for MemoryBuffer {
119    /// Returns the underlying `ngx_buf_t` pointer as a raw pointer.
120    fn as_ngx_buf(&self) -> *const ngx_buf_t {
121        self.0
122    }
123
124    /// Returns a mutable reference to the underlying `ngx_buf_t` pointer.
125    fn as_ngx_buf_mut(&mut self) -> *mut ngx_buf_t {
126        self.0
127    }
128}