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}