irox_tools/buf/
unlimited.rs1extern crate alloc;
6use crate::buf::{Buffer, RoundBuffer};
7use alloc::collections::LinkedList;
8use irox_bits::Bits;
9use irox_bits::{Error, MutBits};
10
11const PAGE_SIZE: usize = 0x1000; const PAGE_SHIFT: usize = 12;
13const DATA_MASK: usize = 0x0FFF;
14
15#[derive(Default, Clone)]
23pub struct UnlimitedBuffer<T: Clone> {
24 #[allow(clippy::linkedlist)]
25 data: LinkedList<RoundBuffer<PAGE_SIZE, T>>,
26 len: u64,
27}
28
29impl<T: Clone> UnlimitedBuffer<T> {
30 pub fn new() -> UnlimitedBuffer<T> {
31 UnlimitedBuffer {
32 data: LinkedList::new(),
33 len: 0,
34 }
35 }
36
37 pub fn get(&self, index: usize) -> Option<&T> {
38 let offset = index >> PAGE_SHIFT;
39 if let Some(block) = self.data.iter().nth(offset) {
40 let idx = index & DATA_MASK;
41 return block.get(idx);
42 }
43 None
44 }
45
46 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
47 let offset = index >> PAGE_SHIFT;
48 if let Some(block) = self.data.iter_mut().nth(offset) {
49 let idx = index & DATA_MASK;
50 return block.get_mut(idx);
51 }
52 None
53 }
54
55 #[allow(clippy::unused_self)]
56 pub fn capacity(&self) -> usize {
57 usize::MAX
58 }
59 pub fn is_empty(&self) -> bool {
60 self.len == 0
61 }
62 pub fn len(&self) -> u64 {
63 self.len
64 }
65
66 pub fn clear(&mut self) {
67 self.data.clear();
68 self.len = 0;
69 }
70
71 pub fn front(&self) -> Option<&T> {
72 self.data.front().and_then(|v| v.front())
73 }
74
75 pub fn front_mut(&mut self) -> Option<&mut T> {
76 self.data.front_mut().and_then(|v| v.front_mut())
77 }
78
79 pub fn back(&self) -> Option<&T> {
80 self.data.back().and_then(|v| v.back())
81 }
82
83 pub fn back_mut(&mut self) -> Option<&mut T> {
84 self.data.back_mut().and_then(|v| v.back_mut())
85 }
86
87 pub fn pop_front(&mut self) -> Option<T> {
90 while let Some(front) = self.data.front_mut() {
91 if front.is_empty() {
92 let _ = self.data.pop_front();
93 continue;
94 }
95 return if let Some(fr) = front.pop_front() {
96 self.len -= 1;
97 Some(fr)
98 } else {
99 None
100 };
101 }
102 None
103 }
104
105 pub fn pop_back(&mut self) -> Option<T> {
108 while let Some(back) = self.data.back_mut() {
109 if back.is_empty() {
110 let _ = self.data.pop_back();
111 continue;
112 }
113 return if let Some(back) = back.pop_back() {
114 self.len -= 1;
115 Some(back)
116 } else {
117 None
118 };
119 }
120 None
121 }
122
123 pub fn append_slice(&mut self, slice: &[T]) {
126 for v in slice {
127 self.push_back(v.clone());
128 }
129 }
130
131 pub fn push_front(&mut self, value: T) {
134 let mut buf = RoundBuffer::default();
135 let _ = buf.push_back(value);
136 self.data.push_front(buf);
137 self.len += 1;
138 }
139
140 pub fn push_back(&mut self, value: T) {
143 if let Some(back) = self.data.back_mut() {
144 if let Err(e) = back.push_back(value) {
145 let mut buf = RoundBuffer::new();
146 let _ = buf.push_back(e);
147 self.data.push_back(buf);
148 }
149 } else {
150 let mut buf = RoundBuffer::new();
151 let _ = buf.push_back(value);
152 self.data.push_back(buf);
153 }
154 self.len += 1;
155 }
156
157 pub fn iter_blocks<F: FnMut(&[Option<T>])>(&mut self, mut f: F) {
160 self.data.iter().for_each(|v| {
161 v.raw_buf(&mut f)
162 })
163 }
164}
165
166impl MutBits for UnlimitedBuffer<u8> {
167 fn write_u8(&mut self, val: u8) -> Result<(), Error> {
168 self.push_back(val);
169 Ok(())
170 }
171}
172
173impl Bits for UnlimitedBuffer<u8> {
174 fn next_u8(&mut self) -> Result<Option<u8>, Error> {
175 Ok(self.pop_front())
176 }
177}
178
179impl<T: Clone> Iterator for UnlimitedBuffer<T> {
180 type Item = T;
181
182 fn next(&mut self) -> Option<Self::Item> {
183 self.pop_front()
184 }
185}