1use std::{cmp::min, io, ptr};
2
3pub trait AsBuffer {
8 fn as_buffer(&self) -> &[u8];
9 fn as_mut_buffer(&mut self) -> &mut [u8];
10}
11
12pub struct Buffer<T: AsBuffer> {
48 pub start: usize,
49 pub head: usize,
50 pub end: usize,
51 pub buffer: T,
52}
53
54impl<T: AsBuffer + Clone> Clone for Buffer<T> {
55 fn clone(&self) -> Self {
56 Self {
57 start: self.start,
58 head: self.head,
59 end: self.end,
60 buffer: self.buffer.clone(),
61 }
62 }
63}
64
65impl<T: AsBuffer> Buffer<T> {
66 pub fn new(buffer: T) -> Self {
67 Self {
68 start: 0,
69 head: 0,
70 end: 0,
71 buffer,
72 }
73 }
74
75 pub fn meter(&self, half: usize) -> String {
76 let size = half * 2 + 1;
77 let len = self.capacity();
78 (0..size + 2)
79 .map(|i| {
80 if i == 0 {
81 '['
82 } else if i - 1 == half {
83 ':'
84 } else if i - 1 < (self.start * size / len) {
85 ' '
86 } else if i - 1 < (self.head * size / len) {
87 '█'
88 } else if i - 1 < (self.end * size / len) {
89 '░'
90 } else if i - 1 < size {
91 ' '
92 } else {
93 ']'
94 }
95 })
96 .collect()
97 }
98
99 pub fn available_data(&self) -> usize {
100 self.end - self.start
101 }
102
103 pub fn available_space(&self) -> usize {
104 self.capacity() - self.end
105 }
106
107 pub fn capacity(&self) -> usize {
108 self.buffer().len()
109 }
110
111 pub fn is_empty(&self) -> bool {
112 self.start == self.end
113 }
114
115 pub fn is_full(&self) -> bool {
116 self.end == self.capacity()
117 }
118
119 pub fn fill(&mut self, count: usize) -> usize {
120 let count = min(count, self.available_space());
121 self.end += count;
122 count
123 }
124
125 pub fn consume(&mut self, count: usize) -> usize {
126 let count = min(count, self.available_data());
127 self.start += count;
128 count
129 }
130
131 pub fn clear(&mut self) {
132 self.start = 0;
133 self.head = 0;
134 self.end = 0;
135 }
136
137 pub fn buffer(&self) -> &[u8] {
138 self.buffer.as_buffer()
139 }
140
141 pub fn mut_buffer(&mut self) -> &mut [u8] {
142 self.buffer.as_mut_buffer()
143 }
144
145 pub fn data(&self) -> &[u8] {
146 let range = self.start..self.end;
147 &self.buffer()[range]
148 }
149
150 pub fn unparsed_data(&self) -> &[u8] {
151 let range = self.head..self.end;
152 &self.buffer()[range]
153 }
154
155 pub fn space(&mut self) -> &mut [u8] {
156 let range = self.end..self.capacity();
157 &mut self.mut_buffer()[range]
158 }
159
160 pub fn used(&self) -> &[u8] {
161 let range = ..self.end;
162 &self.buffer()[range]
163 }
164
165 pub fn should_shift(&self) -> bool {
166 self.start > self.capacity() / 2 || (self.start > 0 && self.is_empty())
167 }
168
169 pub fn shift(&mut self) -> usize {
170 let start = self.start;
171 let end = self.end;
172 if start > 0 {
173 unsafe {
174 let len = end - start;
175 ptr::copy(
176 self.buffer()[start..end].as_ptr(),
177 self.mut_buffer()[..len].as_mut_ptr(),
178 len,
179 );
180 self.start = 0;
181 self.head -= start;
182 self.end = len;
183 }
184 }
185 start
186 }
187}
188
189impl<T: AsBuffer> io::Write for Buffer<T> {
190 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
191 match self.space().write(buf) {
192 Ok(size) => {
193 self.fill(size);
194 Ok(size)
195 }
196 err => err,
197 }
198 }
199
200 fn flush(&mut self) -> io::Result<()> {
201 Ok(())
202 }
203}
204
205impl<T: AsBuffer> io::Read for Buffer<T> {
206 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
207 let len = min(self.available_data(), buf.len());
208 unsafe {
209 ptr::copy(
210 self.buffer()[self.start..self.start + len].as_ptr(),
211 buf.as_mut_ptr(),
212 len,
213 );
214 self.start += len;
215 }
216 Ok(len)
217 }
218}