media_core/
circular_buffer.rs

1use crate::{Error, Result};
2
3pub struct CircularBuffer<T = u8> {
4    buffer: Vec<T>,
5    read_pos: usize,
6    write_pos: usize,
7    len: usize,
8}
9
10impl<T: Default + Copy> CircularBuffer<T> {
11    pub fn new(capacity: usize) -> Self {
12        Self {
13            buffer: vec![T::default(); capacity],
14            read_pos: 0,
15            write_pos: 0,
16            len: 0,
17        }
18    }
19
20    #[inline]
21    pub fn len(&self) -> usize {
22        self.len
23    }
24
25    #[inline]
26    pub fn is_empty(&self) -> bool {
27        self.len == 0
28    }
29
30    #[inline]
31    pub fn capacity(&self) -> usize {
32        self.buffer.len()
33    }
34
35    #[inline]
36    pub fn available(&self) -> usize {
37        self.capacity() - self.len
38    }
39
40    pub fn grow(&mut self, capacity: usize) -> Result<()> {
41        if self.capacity() >= capacity {
42            return Ok(());
43        }
44
45        let new_capacity = capacity.max(self.capacity() * 2);
46
47        if self.read_pos + self.len <= self.capacity() {
48            if self.write_pos == 0 && self.len > 0 {
49                let pos = self.capacity();
50                self.buffer.resize(new_capacity, T::default());
51                self.write_pos = pos;
52            } else {
53                self.buffer.resize(new_capacity, T::default());
54            }
55        } else {
56            let mut new_buffer = vec![T::default(); new_capacity];
57            let len = self.len;
58
59            if len > 0 {
60                self.read_to_slice(&mut new_buffer[..len]);
61            }
62
63            self.buffer = new_buffer;
64            self.read_pos = 0;
65            self.write_pos = len;
66            self.len = len;
67        }
68
69        Ok(())
70    }
71
72    pub fn write(&mut self, buf: &[T]) -> Result<usize> {
73        if buf.is_empty() {
74            return Err(Error::WriteFailed("input buffer is empty".to_string()));
75        }
76
77        if self.available() < buf.len() {
78            self.grow(self.len + buf.len())?;
79        }
80
81        let write_len = buf.len().min(self.available());
82        let end_pos = self.write_pos + write_len;
83
84        if end_pos <= self.capacity() {
85            self.buffer[self.write_pos..end_pos].copy_from_slice(&buf[..write_len]);
86            self.write_pos = end_pos % self.capacity();
87        } else {
88            let chunk_len = self.capacity() - self.write_pos;
89            self.buffer[self.write_pos..].copy_from_slice(&buf[..chunk_len]);
90            self.buffer[..write_len - chunk_len].copy_from_slice(&buf[chunk_len..write_len]);
91            self.write_pos = (write_len - chunk_len) % self.capacity();
92        }
93
94        self.len += write_len;
95
96        Ok(write_len)
97    }
98
99    pub fn read(&mut self, buf: &mut [T]) -> Result<usize> {
100        if buf.is_empty() {
101            return Err(Error::ReadFailed("output buffer is empty".to_string()));
102        }
103
104        let read_len = buf.len().min(self.len);
105        if read_len == 0 {
106            return Ok(0);
107        }
108
109        self.read_to_slice(&mut buf[..read_len]);
110        Ok(read_len)
111    }
112
113    fn read_to_slice(&mut self, buf: &mut [T]) {
114        let read_len = buf.len();
115        let end_pos = self.read_pos + read_len;
116
117        if end_pos <= self.capacity() {
118            buf.copy_from_slice(&self.buffer[self.read_pos..end_pos]);
119            self.read_pos = end_pos % self.capacity();
120        } else {
121            let chunk_len = self.capacity() - self.read_pos;
122            buf[..chunk_len].copy_from_slice(&self.buffer[self.read_pos..]);
123            buf[chunk_len..].copy_from_slice(&self.buffer[..read_len - chunk_len]);
124            self.read_pos = (read_len - chunk_len) % self.capacity();
125        }
126
127        self.len -= read_len;
128    }
129
130    pub fn peek(&self, buf: &mut [T]) -> Result<usize> {
131        if buf.is_empty() {
132            return Err(Error::ReadFailed("output buffer is empty".to_string()));
133        }
134
135        let peek_len = buf.len().min(self.len);
136        if peek_len == 0 {
137            return Ok(0);
138        }
139
140        let end_pos = self.read_pos + peek_len;
141
142        if end_pos <= self.capacity() {
143            buf.copy_from_slice(&self.buffer[self.read_pos..end_pos]);
144        } else {
145            let chunk_len = self.capacity() - self.read_pos;
146            buf[..chunk_len].copy_from_slice(&self.buffer[self.read_pos..]);
147            buf[chunk_len..].copy_from_slice(&self.buffer[..peek_len - chunk_len]);
148        }
149
150        Ok(peek_len)
151    }
152
153    pub fn consume(&mut self, len: usize) -> usize {
154        let consume_len = len.min(self.len);
155        self.read_pos = (self.read_pos + consume_len) % self.capacity();
156        self.len -= consume_len;
157        consume_len
158    }
159
160    pub fn clear(&mut self) {
161        self.read_pos = 0;
162        self.write_pos = 0;
163        self.len = 0;
164    }
165}