oxihuman_core/
copy_buffer.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct CopyBuffer {
11 data: Vec<u8>,
12 capacity: usize,
13}
14
15#[allow(dead_code)]
16impl CopyBuffer {
17 pub fn new(capacity: usize) -> Self {
18 Self {
19 data: Vec::with_capacity(capacity),
20 capacity,
21 }
22 }
23
24 pub fn capacity(&self) -> usize {
25 self.capacity
26 }
27
28 pub fn len(&self) -> usize {
29 self.data.len()
30 }
31
32 pub fn is_empty(&self) -> bool {
33 self.data.is_empty()
34 }
35
36 pub fn remaining(&self) -> usize {
37 self.capacity.saturating_sub(self.data.len())
38 }
39
40 pub fn copy_in(&mut self, src: &[u8]) -> usize {
42 let avail = self.remaining();
43 let n = src.len().min(avail);
44 self.data.extend_from_slice(&src[..n]);
45 n
46 }
47
48 pub fn copy_out(&mut self, n: usize) -> Vec<u8> {
50 let take = n.min(self.data.len());
51 let out: Vec<u8> = self.data.drain(..take).collect();
52 out
53 }
54
55 pub fn peek(&self, n: usize) -> &[u8] {
57 let take = n.min(self.data.len());
58 &self.data[..take]
59 }
60
61 pub fn clear(&mut self) {
62 self.data.clear();
63 }
64
65 pub fn as_slice(&self) -> &[u8] {
66 &self.data
67 }
68
69 pub fn is_full(&self) -> bool {
71 self.data.len() >= self.capacity
72 }
73
74 pub fn fill(&mut self, byte: u8) {
76 let n = self.remaining();
77 for _ in 0..n {
78 self.data.push(byte);
79 }
80 }
81
82 pub fn set_byte(&mut self, pos: usize, byte: u8) -> bool {
84 if pos < self.data.len() {
85 self.data[pos] = byte;
86 true
87 } else {
88 false
89 }
90 }
91
92 pub fn get_byte(&self, pos: usize) -> Option<u8> {
93 self.data.get(pos).copied()
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn new_empty() {
103 let buf = CopyBuffer::new(64);
104 assert!(buf.is_empty());
105 assert_eq!(buf.capacity(), 64);
106 assert_eq!(buf.remaining(), 64);
107 }
108
109 #[test]
110 fn copy_in_basic() {
111 let mut buf = CopyBuffer::new(8);
112 let n = buf.copy_in(&[1, 2, 3, 4]);
113 assert_eq!(n, 4);
114 assert_eq!(buf.len(), 4);
115 }
116
117 #[test]
118 fn copy_in_clamped_to_capacity() {
119 let mut buf = CopyBuffer::new(4);
120 let n = buf.copy_in(&[0u8; 10]);
121 assert_eq!(n, 4);
122 assert!(buf.is_full());
123 }
124
125 #[test]
126 fn copy_out_removes_front() {
127 let mut buf = CopyBuffer::new(16);
128 buf.copy_in(&[10, 20, 30, 40]);
129 let out = buf.copy_out(2);
130 assert_eq!(out, vec![10, 20]);
131 assert_eq!(buf.len(), 2);
132 }
133
134 #[test]
135 fn peek_does_not_consume() {
136 let mut buf = CopyBuffer::new(16);
137 buf.copy_in(&[1, 2, 3]);
138 let peeked = buf.peek(2);
139 assert_eq!(peeked, &[1, 2]);
140 assert_eq!(buf.len(), 3);
141 }
142
143 #[test]
144 fn fill_to_capacity() {
145 let mut buf = CopyBuffer::new(4);
146 buf.fill(0xFF);
147 assert!(buf.is_full());
148 assert_eq!(buf.as_slice(), &[0xFF, 0xFF, 0xFF, 0xFF]);
149 }
150
151 #[test]
152 fn set_and_get_byte() {
153 let mut buf = CopyBuffer::new(8);
154 buf.copy_in(&[0u8; 4]);
155 assert!(buf.set_byte(2, 99));
156 assert_eq!(buf.get_byte(2), Some(99));
157 assert!(!buf.set_byte(100, 0));
158 }
159
160 #[test]
161 fn clear_resets() {
162 let mut buf = CopyBuffer::new(8);
163 buf.copy_in(&[1, 2, 3]);
164 buf.clear();
165 assert!(buf.is_empty());
166 assert_eq!(buf.remaining(), 8);
167 }
168
169 #[test]
170 fn remaining_decreases() {
171 let mut buf = CopyBuffer::new(10);
172 buf.copy_in(&[0u8; 7]);
173 assert_eq!(buf.remaining(), 3);
174 }
175
176 #[test]
177 fn copy_out_partial_when_short() {
178 let mut buf = CopyBuffer::new(8);
179 buf.copy_in(&[5, 6]);
180 let out = buf.copy_out(10);
181 assert_eq!(out, vec![5, 6]);
182 assert!(buf.is_empty());
183 }
184}