1#![allow(clippy::unwrap_used)]
7#![allow(clippy::expect_used)]
8#![allow(clippy::indexing_slicing)]
9#![allow(clippy::panic)]
10
11use super::*;
12use crate::ule::*;
13use alloc::vec::Vec;
14use core::any;
15use core::convert::TryInto;
16use core::marker::PhantomData;
17use core::ops::Deref;
18use core::ops::Range;
19use core::{fmt, ptr, slice};
20
21use super::components::IntegerULE;
22
23pub struct VarZeroVecOwned<T: ?Sized, F = Index16> {
32 marker1: PhantomData<T>,
33 marker2: PhantomData<F>,
34 entire_slice: Vec<u8>,
36}
37
38impl<T: ?Sized, F> Clone for VarZeroVecOwned<T, F> {
39 fn clone(&self) -> Self {
40 VarZeroVecOwned {
41 marker1: PhantomData,
42 marker2: PhantomData,
43 entire_slice: self.entire_slice.clone(),
44 }
45 }
46}
47
48#[derive(PartialEq)]
50enum ShiftType {
51 Insert,
52 Replace,
53 Remove,
54}
55
56impl<T: VarULE + ?Sized, F: VarZeroVecFormat> Deref for VarZeroVecOwned<T, F> {
57 type Target = VarZeroSlice<T, F>;
58 fn deref(&self) -> &VarZeroSlice<T, F> {
59 self.as_slice()
60 }
61}
62
63impl<T: VarULE + ?Sized, F> VarZeroVecOwned<T, F> {
64 pub fn new() -> Self {
66 Self {
67 marker1: PhantomData,
68 marker2: PhantomData,
69 entire_slice: Vec::new(),
70 }
71 }
72}
73
74impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
75 pub fn from_slice(slice: &VarZeroSlice<T, F>) -> Self {
77 Self {
78 marker1: PhantomData,
79 marker2: PhantomData,
80 entire_slice: slice.as_bytes().into(),
81 }
82 }
83
84 pub fn try_from_elements<A>(elements: &[A]) -> Result<Self, &'static str>
86 where
87 A: EncodeAsVarULE<T>,
88 {
89 Ok(if elements.is_empty() {
90 Self::from_slice(VarZeroSlice::new_empty())
91 } else {
92 Self {
93 marker1: PhantomData,
94 marker2: PhantomData,
95 entire_slice: components::get_serializable_bytes_non_empty::<T, A, F>(elements)
97 .ok_or(F::Index::TOO_LARGE_ERROR)?,
98 }
99 })
100 }
101
102 pub fn as_slice(&self) -> &VarZeroSlice<T, F> {
104 let slice: &[u8] = &self.entire_slice;
105 unsafe {
106 VarZeroSlice::from_bytes_unchecked(slice)
108 }
109 }
110
111 pub(crate) fn with_capacity(capacity: usize) -> Self {
115 Self {
116 marker1: PhantomData,
117 marker2: PhantomData,
118 entire_slice: Vec::with_capacity(capacity * (F::Index::SIZE + 4)),
119 }
120 }
121
122 pub(crate) fn reserve(&mut self, capacity: usize) {
126 self.entire_slice.reserve(capacity * (F::Index::SIZE + 4))
127 }
128
129 unsafe fn element_position_unchecked(&self, idx: usize) -> usize {
136 let len = self.len();
137 if len == 0 {
138 return 0;
139 }
140 let out = if idx == len {
141 let indices_size = F::Index::SIZE
142 .checked_mul(len - 1)
143 .expect(F::Index::TOO_LARGE_ERROR);
144 self.entire_slice.len() - F::Len::SIZE - indices_size
145 } else if let Some(idx) = self.index_data(idx) {
146 idx.iule_to_usize()
147 } else {
148 0
149 };
150 let indices_size = F::Index::SIZE
151 .checked_mul(len - 1)
152 .expect(F::Index::TOO_LARGE_ERROR);
153 debug_assert!(out + F::Len::SIZE + indices_size <= self.entire_slice.len());
154 out
155 }
156
157 unsafe fn element_range_unchecked(&self, idx: usize) -> Range<usize> {
162 let start = self.element_position_unchecked(idx);
163 let end = self.element_position_unchecked(idx + 1);
164 debug_assert!(start <= end, "{start} > {end}");
165 start..end
166 }
167
168 unsafe fn set_len(&mut self, len: usize) {
173 assert!(len <= F::Len::MAX_VALUE as usize);
174 let len_bytes = len.to_le_bytes();
175 let len_ule = F::Len::iule_from_usize(len).expect(F::Len::TOO_LARGE_ERROR);
176 self.entire_slice[0..F::Len::SIZE].copy_from_slice(ULE::slice_as_bytes(&[len_ule]));
177 assert_eq!(len_bytes[F::Len::SIZE..].iter().sum::<u8>(), 0);
179 }
180
181 fn index_range(index: usize) -> Option<Range<usize>> {
184 let index_minus_one = index.checked_sub(1)?;
185 let pos = F::Len::SIZE
186 + F::Index::SIZE
187 .checked_mul(index_minus_one)
188 .expect(F::Index::TOO_LARGE_ERROR);
189 Some(pos..pos + F::Index::SIZE)
190 }
191
192 unsafe fn index_data(&self, index: usize) -> Option<&F::Index> {
197 let index_range = Self::index_range(index)?;
198 Some(&F::Index::slice_from_bytes_unchecked(&self.entire_slice[index_range])[0])
199 }
200
201 unsafe fn index_data_mut(&mut self, index: usize) -> Option<&mut F::Index> {
207 let ptr = self.entire_slice.as_mut_ptr();
208 let range = Self::index_range(index)?;
209
210 let data = slice::from_raw_parts_mut(ptr.add(range.start), F::Index::SIZE);
214 Some(&mut F::Index::iule_from_bytes_unchecked_mut(data)[0])
215 }
216
217 unsafe fn shift_indices(&mut self, starting_index: usize, amount: i32) {
226 let normalized_idx = starting_index
227 .checked_sub(1)
228 .expect("shift_indices called with a 0 starting index");
229 let len = self.len();
230 let indices_size = F::Index::SIZE
231 .checked_mul(len - 1)
232 .expect(F::Index::TOO_LARGE_ERROR);
233 let indices = F::Index::iule_from_bytes_unchecked_mut(
234 &mut self.entire_slice[F::Len::SIZE..F::Len::SIZE + indices_size],
235 );
236 for idx in &mut indices[normalized_idx..] {
237 let mut new_idx = idx.iule_to_usize();
238 if amount > 0 {
239 new_idx = new_idx.checked_add(amount.try_into().unwrap()).unwrap();
240 } else {
241 new_idx = new_idx.checked_sub((-amount).try_into().unwrap()).unwrap();
242 }
243 *idx = F::Index::iule_from_usize(new_idx).expect(F::Index::TOO_LARGE_ERROR);
244 }
245 }
246
247 pub fn as_varzerovec<'a>(&'a self) -> VarZeroVec<'a, T, F> {
252 self.as_slice().into()
253 }
254
255 pub fn clear(&mut self) {
257 self.entire_slice.clear()
258 }
259
260 #[inline]
262 pub fn into_bytes(self) -> Vec<u8> {
263 self.entire_slice
264 }
265
266 unsafe fn shift(&mut self, index: usize, new_size: usize, shift_type: ShiftType) -> &mut [u8] {
277 let len = self.len();
286 let slice_len = self.entire_slice.len();
287
288 let prev_element = match shift_type {
289 ShiftType::Insert => {
290 let pos = self.element_position_unchecked(index);
291 pos..pos
294 }
295 _ => self.element_range_unchecked(index),
296 };
297
298 let index_shift: i64 = match shift_type {
300 ShiftType::Insert => F::Index::SIZE as i64,
301 ShiftType::Replace => 0,
302 ShiftType::Remove => -(F::Index::SIZE as i64),
303 };
304 let shift: i64 =
306 new_size as i64 - (prev_element.end - prev_element.start) as i64 + index_shift;
307 let new_slice_len = slice_len.wrapping_add(shift as usize);
308 if shift > 0 {
309 if new_slice_len > F::Index::MAX_VALUE as usize {
310 panic!(
311 "Attempted to grow VarZeroVec to an encoded size that does not fit within the length size used by {}",
312 any::type_name::<F>()
313 );
314 }
315 self.entire_slice.resize(new_slice_len, 0);
316 }
317
318 {
320 let slice_range = self.entire_slice.as_mut_ptr_range();
323 let indices_start = slice_range.start.add(F::Len::SIZE);
325 let old_slice_end = slice_range.start.add(slice_len);
326 let indices_size = F::Index::SIZE
327 .checked_mul(len - 1)
328 .expect(F::Index::TOO_LARGE_ERROR);
329 let data_start = indices_start.add(indices_size);
330 let prev_element_p =
331 data_start.add(prev_element.start)..data_start.add(prev_element.end);
332
333 let index_range = if let Some(index_minus_one) = index.checked_sub(1) {
339 let index_offset = F::Index::SIZE
340 .checked_mul(index_minus_one)
341 .expect(F::Index::TOO_LARGE_ERROR);
342 let index_start = indices_start.add(index_offset);
343 Some(index_start..index_start.add(F::Index::SIZE))
344 } else {
345 None
346 };
347
348 unsafe fn shift_bytes(block: Range<*const u8>, to: *mut u8) {
349 debug_assert!(block.end >= block.start);
350 ptr::copy(block.start, to, block.end.offset_from(block.start) as usize);
351 }
352
353 if shift_type == ShiftType::Remove {
354 if let Some(ref index_range) = index_range {
355 shift_bytes(index_range.end..prev_element_p.start, index_range.start);
356 } else {
357 shift_bytes(
360 indices_start.add(F::Index::SIZE)..prev_element_p.start,
361 indices_start,
362 )
363 }
364 }
365
366 shift_bytes(
368 prev_element_p.end..old_slice_end,
369 prev_element_p
370 .start
371 .offset((new_size as i64 + index_shift) as isize),
372 );
373
374 let first_affected_index = match shift_type {
375 ShiftType::Insert => {
376 if let Some(index_range) = index_range {
377 shift_bytes(index_range.start..prev_element_p.start, index_range.end);
379 let index_data = self
380 .index_data_mut(index)
381 .expect("If index_range is some, index is > 0 and should not panic in index_data_mut");
382 *index_data = F::Index::iule_from_usize(prev_element.start)
383 .expect(F::Index::TOO_LARGE_ERROR);
384 } else {
385 shift_bytes(
389 indices_start..prev_element_p.start,
390 indices_start.add(F::Index::SIZE),
391 );
392 let index_data = self
394 .index_data_mut(1)
395 .expect("Should be able to write to index 1");
396 *index_data = F::Index::iule_from_usize(0).expect("0 is always valid!");
397 }
398
399 self.set_len(len + 1);
400 index + 1
401 }
402 ShiftType::Remove => {
403 self.set_len(len - 1);
404 if index == 0 {
405 index + 1
407 } else {
408 index
409 }
410 }
411 ShiftType::Replace => index + 1,
412 };
413 self.entire_slice.set_len(new_slice_len);
417 self.shift_indices(first_affected_index, (shift - index_shift) as i32);
419 };
420
421 debug_assert!(self.verify_integrity());
422
423 let indices_size = F::Index::SIZE
425 .checked_mul(self.len() - 1)
426 .expect(F::Index::TOO_LARGE_ERROR);
427 let element_pos = F::Len::SIZE + indices_size + self.element_position_unchecked(index);
428 &mut self.entire_slice[element_pos..element_pos + new_size]
429 }
430
431 fn verify_integrity(&self) -> bool {
437 if self.is_empty() {
438 if self.entire_slice.is_empty() {
439 return true;
440 } else {
441 panic!(
442 "VarZeroVecOwned integrity: Found empty VarZeroVecOwned with a nonempty slice"
443 );
444 }
445 }
446 let len = unsafe {
447 <F::Len as ULE>::slice_from_bytes_unchecked(&self.entire_slice[..F::Len::SIZE])[0]
448 .iule_to_usize()
449 };
450 if len == 0 {
451 panic!("VarZeroVecOwned integrity: Found empty VarZeroVecOwned with a nonempty slice");
453 }
454 let indices_size = F::Index::SIZE
455 .checked_mul(len - 1)
456 .expect(F::Index::TOO_LARGE_ERROR);
457 if self.entire_slice.len() < F::Len::SIZE + indices_size {
458 panic!("VarZeroVecOwned integrity: Not enough room for the indices");
459 }
460 let data_len = self.entire_slice.len() - F::Len::SIZE - indices_size;
461 if data_len > F::Index::MAX_VALUE as usize {
462 panic!("VarZeroVecOwned integrity: Data segment is too long");
463 }
464
465 let indices = unsafe {
467 F::Index::slice_from_bytes_unchecked(
468 &self.entire_slice[F::Len::SIZE..F::Len::SIZE + indices_size],
469 )
470 };
471 for idx in indices {
472 if idx.iule_to_usize() > data_len {
473 panic!("VarZeroVecOwned integrity: Indices must not point past the data segment");
474 }
475 }
476 for window in indices.windows(2) {
477 if window[0].iule_to_usize() > window[1].iule_to_usize() {
478 panic!("VarZeroVecOwned integrity: Indices must be in non-decreasing order");
479 }
480 }
481 true
482 }
483
484 pub fn push<A: EncodeAsVarULE<T> + ?Sized>(&mut self, element: &A) {
486 self.insert(self.len(), element)
487 }
488
489 pub fn insert<A: EncodeAsVarULE<T> + ?Sized>(&mut self, index: usize, element: &A) {
491 let len = self.len();
492 if index > len {
493 panic!("Called out-of-bounds insert() on VarZeroVec, index {index} len {len}");
494 }
495
496 let value_len = element.encode_var_ule_len();
497
498 if len == 0 {
499 let header_len = F::Len::SIZE; let cap = header_len + value_len;
501 self.entire_slice.resize(cap, 0);
502 self.entire_slice[0] = 1; element.encode_var_ule_write(&mut self.entire_slice[header_len..]);
504 return;
505 }
506
507 assert!(value_len < F::Index::MAX_VALUE as usize);
508 unsafe {
509 let place = self.shift(index, value_len, ShiftType::Insert);
510 element.encode_var_ule_write(place);
511 }
512 }
513
514 pub fn remove(&mut self, index: usize) {
516 let len = self.len();
517 if index >= len {
518 panic!("Called out-of-bounds remove() on VarZeroVec, index {index} len {len}");
519 }
520 if len == 1 {
521 self.entire_slice.clear();
523 return;
524 }
525 unsafe {
526 self.shift(index, 0, ShiftType::Remove);
527 }
528 }
529
530 pub fn replace<A: EncodeAsVarULE<T> + ?Sized>(&mut self, index: usize, element: &A) {
532 let len = self.len();
533 if index >= len {
534 panic!("Called out-of-bounds replace() on VarZeroVec, index {index} len {len}");
535 }
536
537 let value_len = element.encode_var_ule_len();
538
539 assert!(value_len < F::Index::MAX_VALUE as usize);
540 unsafe {
541 let place = self.shift(index, value_len, ShiftType::Replace);
542 element.encode_var_ule_write(place);
543 }
544 }
545}
546
547impl<T: VarULE + ?Sized, F: VarZeroVecFormat> fmt::Debug for VarZeroVecOwned<T, F>
548where
549 T: fmt::Debug,
550{
551 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552 VarZeroSlice::fmt(self, f)
553 }
554}
555
556impl<T: VarULE + ?Sized, F> Default for VarZeroVecOwned<T, F> {
557 fn default() -> Self {
558 Self::new()
559 }
560}
561
562impl<T, A, F> PartialEq<&'_ [A]> for VarZeroVecOwned<T, F>
563where
564 T: VarULE + ?Sized,
565 T: PartialEq,
566 A: AsRef<T>,
567 F: VarZeroVecFormat,
568{
569 #[inline]
570 fn eq(&self, other: &&[A]) -> bool {
571 self.iter().eq(other.iter().map(|t| t.as_ref()))
572 }
573}
574
575impl<'a, T: ?Sized + VarULE, F: VarZeroVecFormat> From<&'a VarZeroSlice<T, F>>
576 for VarZeroVecOwned<T, F>
577{
578 fn from(other: &'a VarZeroSlice<T, F>) -> Self {
579 Self::from_slice(other)
580 }
581}
582
583#[cfg(test)]
584mod test {
585 use super::VarZeroVecOwned;
586 #[test]
587 fn test_insert_integrity() {
588 let mut items: Vec<String> = Vec::new();
589 let mut zerovec = VarZeroVecOwned::<str>::new();
590
591 items.insert(0, "1234567890".into());
593 zerovec.insert(0, "1234567890");
594 assert_eq!(zerovec, &*items);
595
596 zerovec.insert(1, "foo3");
597 items.insert(1, "foo3".into());
598 assert_eq!(zerovec, &*items);
599
600 items.insert(items.len(), "qwertyuiop".into());
602 zerovec.insert(zerovec.len(), "qwertyuiop");
603 assert_eq!(zerovec, &*items);
604
605 items.insert(0, "asdfghjkl;".into());
606 zerovec.insert(0, "asdfghjkl;");
607 assert_eq!(zerovec, &*items);
608
609 items.insert(2, "".into());
610 zerovec.insert(2, "");
611 assert_eq!(zerovec, &*items);
612 }
613
614 #[test]
615 fn test_empty_inserts() {
617 let mut items: Vec<String> = Vec::new();
618 let mut zerovec = VarZeroVecOwned::<str>::new();
619
620 items.insert(0, "".into());
622 zerovec.insert(0, "");
623 assert_eq!(zerovec, &*items);
624
625 items.insert(0, "".into());
626 zerovec.insert(0, "");
627 assert_eq!(zerovec, &*items);
628
629 items.insert(0, "1234567890".into());
630 zerovec.insert(0, "1234567890");
631 assert_eq!(zerovec, &*items);
632
633 items.insert(0, "".into());
634 zerovec.insert(0, "");
635 assert_eq!(zerovec, &*items);
636 }
637
638 #[test]
639 fn test_small_insert_integrity() {
640 let mut items: Vec<String> = Vec::new();
643 let mut zerovec = VarZeroVecOwned::<str>::new();
644
645 items.insert(0, "abc".into());
647 zerovec.insert(0, "abc");
648 assert_eq!(zerovec, &*items);
649
650 zerovec.insert(1, "def");
651 items.insert(1, "def".into());
652 assert_eq!(zerovec, &*items);
653 }
654
655 #[test]
656 #[should_panic]
657 fn test_insert_past_end() {
658 VarZeroVecOwned::<str>::new().insert(1, "");
659 }
660
661 #[test]
662 fn test_remove_integrity() {
663 let mut items: Vec<&str> = vec!["apples", "bananas", "eeples", "", "baneenees", "five", ""];
664 let mut zerovec = VarZeroVecOwned::<str>::try_from_elements(&items).unwrap();
665
666 for index in [0, 2, 4, 0, 1, 1, 0] {
667 items.remove(index);
668 zerovec.remove(index);
669 assert_eq!(zerovec, &*items, "index {}, len {}", index, items.len());
670 }
671 }
672
673 #[test]
674 fn test_removing_last_element_clears() {
675 let mut zerovec = VarZeroVecOwned::<str>::try_from_elements(&["buy some apples"]).unwrap();
676 assert!(!zerovec.as_bytes().is_empty());
677 zerovec.remove(0);
678 assert!(zerovec.as_bytes().is_empty());
679 }
680
681 #[test]
682 #[should_panic]
683 fn test_remove_past_end() {
684 VarZeroVecOwned::<str>::new().remove(0);
685 }
686
687 #[test]
688 fn test_replace_integrity() {
689 let mut items: Vec<&str> = vec!["apples", "bananas", "eeples", "", "baneenees", "five", ""];
690 let mut zerovec = VarZeroVecOwned::<str>::try_from_elements(&items).unwrap();
691
692 items[0] = "blablah";
694 zerovec.replace(0, "blablah");
695 assert_eq!(zerovec, &*items);
696
697 items[1] = "twily";
699 zerovec.replace(1, "twily");
700 assert_eq!(zerovec, &*items);
701
702 items[3] = "aoeuidhtns";
704 zerovec.replace(3, "aoeuidhtns");
705 assert_eq!(zerovec, &*items);
706
707 items[6] = "0123456789";
709 zerovec.replace(6, "0123456789");
710 assert_eq!(zerovec, &*items);
711
712 items[2] = "";
714 zerovec.replace(2, "");
715 assert_eq!(zerovec, &*items);
716 }
717
718 #[test]
719 #[should_panic]
720 fn test_replace_past_end() {
721 VarZeroVecOwned::<str>::new().replace(0, "");
722 }
723}