commonware_codec/
buffer.rs

1//! Buffer implementation of codec types.
2//!
3//! Numeric types are encoded in big-endian byte order.
4//!
5//! Prefixes varints for length-encoded data.
6
7use crate::{error::Error, varint};
8use bytes::{Buf, BufMut, Bytes, BytesMut};
9
10/// A buffer for reading codec data with safety checks
11#[derive(Debug)]
12pub struct ReadBuffer {
13    /// The underlying bytes
14    inner: Bytes,
15}
16
17impl ReadBuffer {
18    /// Creates a new reader from bytes
19    pub fn new(bytes: Bytes) -> Self {
20        Self { inner: bytes }
21    }
22
23    /// Reads a varint-encoded unsigned integer
24    #[inline]
25    pub fn read_varint(&mut self) -> Result<u64, Error> {
26        varint::decode_varint(&mut self.inner)
27    }
28
29    /// Gets a byte from the buffer
30    #[inline]
31    pub fn get_u8(&mut self) -> Result<u8, Error> {
32        if !self.has_remaining() {
33            return Err(Error::EndOfBuffer);
34        }
35        Ok(self.inner.get_u8())
36    }
37
38    /// Gets remaining bytes
39    #[inline]
40    pub fn remaining(&self) -> usize {
41        self.inner.remaining()
42    }
43
44    /// Checks if the buffer has any remaining bytes
45    #[inline]
46    pub fn has_remaining(&self) -> bool {
47        self.remaining() > 0
48    }
49
50    /// Ensures the buffer has at least `size` bytes remaining
51    #[inline]
52    pub fn at_least(&self, size: usize) -> Result<(), Error> {
53        if self.remaining() < size {
54            return Err(Error::EndOfBuffer);
55        }
56        Ok(())
57    }
58
59    /// Advance the buffer by `cnt` bytes
60    #[inline]
61    pub fn advance(&mut self, cnt: usize) {
62        self.inner.advance(cnt);
63    }
64
65    // Implement methods from Buf trait with safety checks
66    #[inline]
67    pub fn get_u16(&mut self) -> Result<u16, Error> {
68        self.at_least(2)?;
69        Ok(self.inner.get_u16())
70    }
71
72    #[inline]
73    pub fn get_u32(&mut self) -> Result<u32, Error> {
74        self.at_least(4)?;
75        Ok(self.inner.get_u32())
76    }
77
78    #[inline]
79    pub fn get_u64(&mut self) -> Result<u64, Error> {
80        self.at_least(8)?;
81        Ok(self.inner.get_u64())
82    }
83
84    #[inline]
85    pub fn get_u128(&mut self) -> Result<u128, Error> {
86        self.at_least(16)?;
87        Ok(self.inner.get_u128())
88    }
89
90    #[inline]
91    pub fn get_i8(&mut self) -> Result<i8, Error> {
92        self.at_least(1)?;
93        Ok(self.inner.get_i8())
94    }
95
96    #[inline]
97    pub fn get_i16(&mut self) -> Result<i16, Error> {
98        self.at_least(2)?;
99        Ok(self.inner.get_i16())
100    }
101
102    #[inline]
103    pub fn get_i32(&mut self) -> Result<i32, Error> {
104        self.at_least(4)?;
105        Ok(self.inner.get_i32())
106    }
107
108    #[inline]
109    pub fn get_i64(&mut self) -> Result<i64, Error> {
110        self.at_least(8)?;
111        Ok(self.inner.get_i64())
112    }
113
114    #[inline]
115    pub fn get_i128(&mut self) -> Result<i128, Error> {
116        self.at_least(16)?;
117        Ok(self.inner.get_i128())
118    }
119
120    #[inline]
121    pub fn get_f32(&mut self) -> Result<f32, Error> {
122        self.at_least(4)?;
123        Ok(self.inner.get_f32())
124    }
125
126    #[inline]
127    pub fn get_f64(&mut self) -> Result<f64, Error> {
128        self.at_least(8)?;
129        Ok(self.inner.get_f64())
130    }
131
132    #[inline]
133    pub fn copy_to_slice(&mut self, dst: &mut [u8]) -> Result<(), Error> {
134        self.at_least(dst.len())?;
135        self.inner.copy_to_slice(dst);
136        Ok(())
137    }
138
139    #[inline]
140    pub fn split_to(&mut self, size: usize) -> Result<Bytes, Error> {
141        self.at_least(size)?;
142        Ok(self.inner.split_to(size))
143    }
144
145    /// Returns a reference to the internal buffer
146    pub fn inner(&self) -> &Bytes {
147        &self.inner
148    }
149}
150
151/// A buffer for writing codec data
152#[derive(Debug)]
153pub struct WriteBuffer {
154    /// The underlying buffer
155    inner: BytesMut,
156}
157
158impl WriteBuffer {
159    /// Creates a new write buffer
160    pub fn new(capacity: usize) -> Self {
161        Self {
162            inner: BytesMut::with_capacity(capacity),
163        }
164    }
165
166    /// Writes a varint-encoded unsigned integer
167    #[inline]
168    pub fn write_varint(&mut self, value: u64) {
169        varint::encode_varint(value, &mut self.inner);
170    }
171
172    /// Returns the current length of the buffer
173    #[inline]
174    pub fn len(&self) -> usize {
175        self.inner.len()
176    }
177
178    /// Returns the total capacity of the buffer
179    #[inline]
180    pub fn capacity(&self) -> usize {
181        self.inner.capacity()
182    }
183
184    #[inline]
185    pub fn remaining_mut(&mut self) -> usize {
186        self.inner.remaining_mut()
187    }
188
189    /// Checks if the buffer is empty
190    #[inline]
191    pub fn is_empty(&self) -> bool {
192        self.inner.is_empty()
193    }
194
195    /// Freezes the buffer and returns the bytes
196    pub fn freeze(self) -> Bytes {
197        self.inner.freeze()
198    }
199
200    /// Resets the buffer
201    pub fn clear(&mut self) {
202        self.inner.clear();
203    }
204
205    // Delegate to inner buffer's BufMut implementation
206    #[inline]
207    pub fn put_u8(&mut self, v: u8) {
208        self.inner.put_u8(v);
209    }
210
211    #[inline]
212    pub fn put_u16(&mut self, v: u16) {
213        self.inner.put_u16(v);
214    }
215
216    #[inline]
217    pub fn put_u32(&mut self, v: u32) {
218        self.inner.put_u32(v);
219    }
220
221    #[inline]
222    pub fn put_u64(&mut self, v: u64) {
223        self.inner.put_u64(v);
224    }
225
226    #[inline]
227    pub fn put_u128(&mut self, v: u128) {
228        self.inner.put_u128(v);
229    }
230
231    #[inline]
232    pub fn put_i8(&mut self, v: i8) {
233        self.inner.put_i8(v);
234    }
235
236    #[inline]
237    pub fn put_i16(&mut self, v: i16) {
238        self.inner.put_i16(v);
239    }
240
241    #[inline]
242    pub fn put_i32(&mut self, v: i32) {
243        self.inner.put_i32(v);
244    }
245
246    #[inline]
247    pub fn put_i64(&mut self, v: i64) {
248        self.inner.put_i64(v);
249    }
250
251    #[inline]
252    pub fn put_i128(&mut self, v: i128) {
253        self.inner.put_i128(v);
254    }
255
256    #[inline]
257    pub fn put_f32(&mut self, v: f32) {
258        self.inner.put_f32(v);
259    }
260
261    #[inline]
262    pub fn put_f64(&mut self, v: f64) {
263        self.inner.put_f64(v);
264    }
265
266    #[inline]
267    pub fn put_slice(&mut self, src: &[u8]) {
268        self.inner.put_slice(src);
269    }
270}
271
272impl From<WriteBuffer> for Vec<u8> {
273    fn from(buffer: WriteBuffer) -> Self {
274        buffer.inner.to_vec()
275    }
276}
277
278impl From<WriteBuffer> for Bytes {
279    fn from(buffer: WriteBuffer) -> Self {
280        buffer.freeze()
281    }
282}
283
284impl AsRef<[u8]> for WriteBuffer {
285    fn as_ref(&self) -> &[u8] {
286        &self.inner
287    }
288}
289
290#[cfg(test)]
291mod tests {
292    use super::*;
293    use crate::Reader;
294    use bytes::Bytes;
295
296    #[test]
297    fn test_read_buffer_split() {
298        let mut buffer = ReadBuffer::new(Bytes::from_static(&[0x01, 0x02, 0x03]));
299        let split = buffer.split_to(2).unwrap();
300        assert_eq!(split, Bytes::from_static(&[0x01, 0x02]));
301        assert_eq!(buffer.remaining(), 1);
302        assert_eq!(buffer.read_n_bytes(1).unwrap(), Bytes::from_static(&[0x03]));
303    }
304
305    #[test]
306    fn test_write_buffer_append() {
307        let mut writer = WriteBuffer::new(4);
308        writer.put_u32(0x01020304);
309        let frozen = writer.freeze();
310        assert_eq!(frozen, Bytes::from_static(&[0x01, 0x02, 0x03, 0x04]));
311    }
312
313    #[test]
314    fn test_buffer_remaining() {
315        let mut buffer = ReadBuffer::new(Bytes::from_static(&[0x01, 0x02, 0x03]));
316        assert_eq!(buffer.remaining(), 3);
317        let _ = buffer.read_n_bytes(2).unwrap();
318        assert_eq!(buffer.remaining(), 1);
319    }
320}