1use core::fmt;
2use std::error::Error;
3use std::iter::FusedIterator;
4use std::slice::Iter as SliceIter;
5
6use crate::asm::memory::MemoryRange;
7
8#[cfg(test)]
9mod test;
10
11#[derive(Clone, Debug)]
12struct MemorySegment
13{
14 range: MemoryRange,
15 data: Vec<u8>,
16}
17
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub enum Search
20{
21 Exact, Below, Above,
22}
23
24#[derive(Clone, Debug)]
25pub struct MemoryMap
26{
27 parts: Vec<MemorySegment>,
28}
29
30impl MemoryMap
31{
32 pub fn new() -> Self
33 {
34 Self{parts: Vec::new()}
35 }
36
37 pub fn len(&self) -> usize
38 {
39 self.parts.len()
40 }
41
42 fn locate(&self, addr: u32, search: Search) -> Option<usize>
43 {
44 if self.parts.is_empty() {return None;}
45 let mut first = 0;
46 let mut last = self.parts.len() - 1;
47 loop
48 {
49 let mid = first + (last - first) / 2;
50 let range = self.parts[mid].range;
51 if addr < range.first
52 {
53 if mid == first
54 {
55 return match search
56 {
57 Search::Exact => None,
58 Search::Below => if first > 0 {Some(first - 1)} else {None},
59 Search::Above => Some(first),
60 };
61 }
62 debug_assert!(mid > first);
63 last = mid - 1;
64 }
65 else if addr > range.last
66 {
67 if mid == last
68 {
69 return match search
70 {
71 Search::Exact => None,
72 Search::Below => Some(last),
73 Search::Above => if last < self.parts.len() - 1 {Some(last + 1)} else {None},
74 };
75 }
76 debug_assert!(mid < last);
77 first = mid + 1;
78 }
79 else {return Some(mid);}
80 }
81 }
82
83 pub fn find(&self, addr: u32, search: Search) -> Option<MemoryRange>
84 {
85 self.locate(addr, search).map(|i| self.parts[i].range)
86 }
87
88 pub fn get(&self, addr: u32, search: Search) -> Option<(MemoryRange, &[u8])>
89 {
90 self.locate(addr, search).map(|i| &self.parts[i]).map(|p| (p.range, &p.data[(addr - p.range.first) as usize..]))
91 }
92
93 pub fn get_mut(&mut self, addr: u32, search: Search) -> Option<(MemoryRange, &mut [u8])>
94 {
95 self.locate(addr, search).map(|i| &mut self.parts[i]).map(|p| (p.range, &mut p.data[(addr - p.range.first) as usize..]))
96 }
97
98 pub fn put(&mut self, addr: u32, data: &[u8]) -> Result<usize, PutError>
99 {
100 if !data.is_empty()
101 {
102 let have_last = usize::try_from(u32::MAX - addr).unwrap_or(usize::MAX);
103 if data.len() - 1 > have_last
104 {
105 return Err(PutError::Overflow{need: data.len(), have: have_last.saturating_add(1)})
106 }
107 let addr_last = addr + (data.len() - 1) as u32;
108
109 let idx_first = match self.locate(addr.saturating_sub(1), Search::Above)
111 {
112 None => self.parts.len(),
113 Some(idx) => idx,
114 };
115 let idx_last = match self.locate(addr_last.saturating_add(1), Search::Below)
117 {
118 None => None,
119 Some(idx) =>
120 {
121 if self.parts[idx].range.last >= addr.saturating_sub(1) {Some(idx)} else {None}
122 },
123 };
124
125 match idx_last
126 {
127 None =>
128 {
129 self.parts.insert(idx_first, MemorySegment{range: MemoryRange{first: addr, last: addr_last}, data: data.to_owned()});
130 Ok(data.len())
131 },
132 Some(idx_last) =>
133 {
134 let first = &mut self.parts[idx_first];
135 let mut added = data.len();
136 if addr <= first.range.first
137 {
138 if addr_last >= first.range.last
139 {
140 added -= first.data.len();
142 first.data.clear();
143 first.data.extend_from_slice(data);
144 }
145 else
146 {
147 let num_remove = data.len() - usize::try_from(first.range.first - addr).unwrap();
149 first.data.splice(..num_remove, data.iter().copied());
150 added -= num_remove;
151 }
152 }
153 else
154 {
155 let offset = usize::try_from(addr - first.range.first).unwrap();
156 if addr_last > first.range.last
157 {
158 let num_overwrite = first.data.len() - offset;
160 first.data.truncate(offset);
161 first.data.extend_from_slice(data);
162 added -= num_overwrite;
163 }
164 else
165 {
166 first.data[offset..offset + data.len()].copy_from_slice(data);
168 added = 0;
169 }
170 }
171
172 if idx_last > idx_first
173 {
174 for idx in idx_first + 1..idx_last
176 {
177 added -= self.parts[idx].data.len();
178 }
179 let (first, last) = {
181 let split = self.parts.split_at_mut(idx_last);
182 (&mut split.0[idx_first], &split.1[0])
183 };
184 if addr_last < last.range.last
185 {
186 let end_off = usize::try_from(last.range.last - addr_last).unwrap();
188 let overwritten = last.data.len() - end_off;
189 first.data.extend_from_slice(&last.data[last.data.len() - end_off..]);
190 first.range.last = last.range.last;
191 added -= overwritten;
192 }
193 else
194 {
195 added -= last.data.len();
197 first.range.last = addr_last;
198 }
199 first.range.first = first.range.first.min(addr);
200 self.parts.drain(idx_first + 1..=idx_last);
201 }
202 else
203 {
204 first.range.first = first.range.first.min(addr);
205 first.range.last = first.range.last.max(addr_last);
206 }
207 Ok(added)
208 },
209 }
210 }
211 else {Ok(0)}
212 }
213
214 pub fn count(&self) -> (u32, usize)
215 {
216 let mut addrs = 0;
217 for seg in self.parts.iter()
218 {
219 addrs += seg.range.last - seg.range.first;
221 }
222 addrs = addrs.saturating_add(self.parts.len() as u32);
224 (addrs, self.parts.len())
225 }
226
227 pub fn iter<'s>(&'s self) -> Iter<'s>
228 {
229 Iter(self.parts.iter())
230 }
231
232 pub fn count_range(&self, range: MemoryRange) -> (u32, usize)
233 {
234 let first = match self.locate(range.first, Search::Above)
235 {
236 None => self.parts.len(),
237 Some(idx) => idx,
238 };
239 let mut addrs = 0;
240 let mut cnt = 0;
241 for seg in self.parts[first..].iter().filter(|seg| seg.range.first <= range.last)
242 {
243 debug_assert!(seg.range.last >= range.first);
244 let min_addr = seg.range.first.max(range.first);
245 let max_addr = seg.range.last.min(range.last);
246 addrs += max_addr - min_addr;
248 cnt += 1;
249 }
250 addrs = addrs.saturating_add(cnt as u32);
252 (addrs, cnt)
253 }
254
255 pub fn iter_range<'s>(&'s self, range: MemoryRange) -> RangeIter<'s>
256 {
257 let first = match self.locate(range.first, Search::Above)
258 {
259 None => self.parts.len(),
260 Some(idx) => idx,
261 };
262 RangeIter{base: self, next: first, range}
263 }
264
265 pub fn remove(&mut self, addr: u32) -> Option<(MemoryRange, Vec<u8>)>
266 {
267 match self.locate(addr, Search::Exact)
268 {
269 None => None,
270 Some(idx) =>
271 {
272 let seg = self.parts.remove(idx);
273 Some((seg.range, seg.data))
274 },
275 }
276 }
277
278 pub fn remove_range(&mut self, range: MemoryRange)
279 {
280 match self.locate(range.first, Search::Above)
281 {
282 Some(first_idx) if range.last >= self.parts[first_idx].range.first =>
283 {
284 let first = &mut self.parts[first_idx];
285 if range.first > first.range.first && range.last < first.range.last
286 {
287 let start_off = (range.first - first.range.first) as usize;
290 let end_off = (first.range.last - range.last) as usize;
291
292 let end_range = MemoryRange{first: range.last + 1, last: first.range.last};
293 let end_data = first.data[first.data.len() - end_off..].to_owned();
294 first.range.last = range.first - 1;
295 first.data.truncate(start_off);
296 self.parts.insert(first_idx + 1, MemorySegment{range: end_range, data: end_data});
297 }
298 else
299 {
300 let remove_first = if range.first <= first.range.first
301 {
302 if range.last < first.range.last
303 {
304 first.data.drain(..(range.last + 1 - first.range.first) as usize);
306 first.range.first = range.last + 1;
307 false
308 }
309 else {true}
310 }
311 else
312 {
313 first.data.truncate((range.first - first.range.first) as usize);
315 first.range.last = range.first - 1;
316 false };
318
319 match self.locate(range.last, Search::Below)
321 {
322 None => assert!(!remove_first),
324 Some(last_idx) =>
325 {
326 if last_idx > first_idx
327 {
328 let last = &mut self.parts[last_idx];
329 let remove_last = if range.last < last.range.last
331 {
332 last.data.drain(..(range.last + 1 - last.range.first) as usize);
334 last.range.first = range.last + 1;
335 false
336 }
337 else {true};
338 self.parts.drain(first_idx + (!remove_first) as usize..last_idx + remove_last as usize);
339 }
340 else
341 {
342 if remove_first {self.parts.remove(first_idx);}
343 }
344 },
345 }
346 }
347 },
348 _ => return,
349 }
350 }
351
352 pub fn clear(&mut self)
353 {
354 self.parts.clear();
355 }
356}
357
358#[derive(Clone, Debug, Eq, PartialEq)]
359pub enum PutError
360{
361 Overflow{need: usize, have: usize},
362}
363
364impl fmt::Display for PutError
365{
366 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
367 {
368 match self
369 {
370 Self::Overflow{need, have} => write!(f, "segment overflow (expected {need} but got {have})"),
371 }
372 }
373}
374
375impl Error for PutError {}
376
377#[derive(Clone, Debug)]
378pub struct Iter<'l>(SliceIter<'l, MemorySegment>);
379
380impl<'l> Iterator for Iter<'l>
381{
382 type Item = (MemoryRange, &'l [u8]);
383
384 fn next(&mut self) -> Option<Self::Item>
385 {
386 self.0.next().map(|e| (e.range, e.data.as_ref()))
387 }
388}
389
390impl<'l> FusedIterator for Iter<'l> where SliceIter<'l, MemorySegment>: FusedIterator {}
391
392#[derive(Clone, Debug)]
393pub struct RangeIter<'l>
394{
395 base: &'l MemoryMap,
396 next: usize,
397 range: MemoryRange,
398}
399
400impl<'l> RangeIter<'l>
401{
402 pub fn range(&self) -> MemoryRange
403 {
404 self.range
405 }
406}
407
408impl<'l> Iterator for RangeIter<'l>
409{
410 type Item = (MemoryRange, &'l [u8]);
411
412 fn next(&mut self) -> Option<Self::Item>
413 {
414 match self.base.parts.get(self.next)
415 {
416 None => None,
417 Some(seg) =>
418 {
419 if seg.range.first <= self.range.last
420 {
421 self.next += 1;
422 let (start_off, first_addr) = if self.range.first <= seg.range.first {(0, seg.range.first)}
423 else {((self.range.first - seg.range.first) as usize, self.range.first)};
424 let (end_off, last_addr) = if self.range.last >= seg.range.last {(0, seg.range.last)}
425 else {((seg.range.last - self.range.last) as usize, self.range.last)};
426 Some((MemoryRange{first: first_addr, last: last_addr}, &seg.data[start_off..seg.data.len() - end_off]))
427 }
428 else
429 {
430 self.next = self.base.parts.len();
431 None
432 }
433 },
434 }
435 }
436}
437
438impl<'l> FusedIterator for RangeIter<'l> {}