1
/// A buffer struct that represents a contiguous memory region owned by Envoy.
2
/// This is immutable and is meant to be used for reading underlying bytes.
3
///
4
/// This is cloneable and copyable, but the underlying memory is not copied. It can be
5
/// thought of as an alias to &\[u8\] but the underlying memory is owned by Envoy.
6
//
7
// Implementation note: The lifetime parameter `'a` is used to ensure that the memory region pointed
8
// to by `raw_ptr` is valid. The invalidation can happen when the mutable
9
// methods of [`crate::EnvoyHttpFilter`] are called.
10
#[repr(C)]
11
#[derive(Debug, Clone, Copy)]
12
pub struct EnvoyBuffer<'a> {
13
  raw_ptr: *const u8,
14
  length: usize,
15
  _marker: std::marker::PhantomData<&'a ()>,
16
}
17

            
18
impl Default for EnvoyBuffer<'_> {
19
  fn default() -> Self {
20
    Self {
21
      raw_ptr: std::ptr::null(),
22
      length: 0,
23
      _marker: std::marker::PhantomData,
24
    }
25
  }
26
}
27

            
28
impl EnvoyBuffer<'_> {
29
  /// This is a helper function to create an [`EnvoyBuffer`] from a static string.
30
  ///
31
  /// This is meant for use by the end users in unit tests.
32
  // TODO: relax the lifetime constraint to 'static, so that it becomes more flexible.
33
  pub fn new(static_str: &'static str) -> Self {
34
    Self {
35
      raw_ptr: static_str.as_ptr(),
36
      length: static_str.len(),
37
      _marker: std::marker::PhantomData,
38
    }
39
  }
40

            
41
  /// This is a helper function to create an [`EnvoyBuffer`] from a raw pointer and length.
42
  ///
43
  /// # Safety
44
  ///
45
  /// This is not meant to be used by the end users, but rather by the SDK itself in the
46
  /// actual integration with Envoy.
47
  pub unsafe fn new_from_raw(raw_ptr: *const u8, length: usize) -> Self {
48
    Self {
49
      raw_ptr,
50
      length,
51
      _marker: std::marker::PhantomData,
52
    }
53
  }
54

            
55
  pub fn as_slice(&self) -> &[u8] {
56
    if self.raw_ptr.is_null() {
57
      return &[];
58
    }
59
    unsafe { std::slice::from_raw_parts(self.raw_ptr, self.length) }
60
  }
61
}
62

            
63
/// This is exactly the same as [`EnvoyBuffer`] except that it is mutable and data can be written
64
/// in-place. See [`EnvoyBuffer`] for more details.
65
#[repr(C)]
66
#[derive(Debug, Clone, Copy)]
67
pub struct EnvoyMutBuffer<'a> {
68
  raw_ptr: *mut u8,
69
  length: usize,
70
  _marker: std::marker::PhantomData<&'a ()>,
71
}
72

            
73
impl EnvoyMutBuffer<'_> {
74
  /// This is a helper function to create an [`EnvoyMutBuffer`] from a raw pointer to static
75
  /// mutable storage. This is only meant to be used in unit tests.
76
  ///
77
  /// # Safety
78
  ///
79
  /// The caller must ensure that the pointer is valid for the lifetime of the returned buffer and
80
  /// that no other references to the data exist while the buffer is in use.
81
  ///
82
  /// ```
83
  /// static mut BUF: [u8; 1024] = [0; 1024];
84
  /// let _buffer = unsafe { envoy_proxy_dynamic_modules_rust_sdk::EnvoyMutBuffer::new(&raw mut BUF) };
85
  /// ```
86
  #[allow(unknown_lints, dangerous_implicit_autorefs)]
87
  pub unsafe fn new(static_buf: *mut [u8]) -> Self {
88
    Self {
89
      raw_ptr: static_buf as *mut u8,
90
      length: (*static_buf).len(),
91
      _marker: std::marker::PhantomData,
92
    }
93
  }
94

            
95
  /// This is a helper function to create an [`EnvoyMutBuffer`] from a raw pointer and length.
96
  ///
97
  /// # Safety
98
  ///
99
  /// This is not meant to be used by the end users, but rather by the SDK itself in the
100
  /// actual integration with Envoy.
101
  pub unsafe fn new_from_raw(raw_ptr: *mut u8, length: usize) -> Self {
102
    Self {
103
      raw_ptr,
104
      length,
105
      _marker: std::marker::PhantomData,
106
    }
107
  }
108

            
109
  /// This returns an immutable slice to the underlying memory region managed by Envoy.
110
  pub fn as_slice(&self) -> &[u8] {
111
    if self.raw_ptr.is_null() {
112
      return &[];
113
    }
114
    unsafe { std::slice::from_raw_parts(self.raw_ptr, self.length) }
115
  }
116

            
117
  /// This returns a mutable slice to the underlying memory region managed by Envoy.
118
  pub fn as_mut_slice(&mut self) -> &mut [u8] {
119
    if self.raw_ptr.is_null() {
120
      return &mut [];
121
    }
122
    unsafe { std::slice::from_raw_parts_mut(self.raw_ptr, self.length) }
123
  }
124
}
125

            
126
impl Default for EnvoyMutBuffer<'_> {
127
  fn default() -> Self {
128
    Self {
129
      raw_ptr: std::ptr::null_mut(),
130
      length: 0,
131
      _marker: std::marker::PhantomData,
132
    }
133
  }
134
}