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}