1use core::ops::Range;
7use core::convert::{TryFrom, TryInto};
8
9pub trait FromData: Sized {
13 const SIZE: usize;
17
18 fn parse(data: &[u8]) -> Option<Self>;
20}
21
22pub trait FromSlice<'a>: Sized {
26 fn parse(data: &'a [u8]) -> Option<Self>;
28}
29
30impl FromData for () {
31 const SIZE: usize = 0;
32
33 #[inline]
34 fn parse(_: &[u8]) -> Option<Self> {
35 Some(())
36 }
37}
38
39impl FromData for u8 {
40 const SIZE: usize = 1;
41
42 #[inline]
43 fn parse(data: &[u8]) -> Option<Self> {
44 data.get(0).copied()
45 }
46}
47
48impl FromData for i8 {
49 const SIZE: usize = 1;
50
51 #[inline]
52 fn parse(data: &[u8]) -> Option<Self> {
53 data.get(0).copied().map(|n| n as i8)
54 }
55}
56
57impl FromData for u16 {
58 const SIZE: usize = 2;
59
60 #[inline]
61 fn parse(data: &[u8]) -> Option<Self> {
62 data.try_into().ok().map(u16::from_be_bytes)
63 }
64}
65
66impl FromData for i16 {
67 const SIZE: usize = 2;
68
69 #[inline]
70 fn parse(data: &[u8]) -> Option<Self> {
71 data.try_into().ok().map(i16::from_be_bytes)
72 }
73}
74
75impl FromData for u32 {
76 const SIZE: usize = 4;
77
78 #[inline]
79 fn parse(data: &[u8]) -> Option<Self> {
80 data.try_into().ok().map(u32::from_be_bytes)
81 }
82}
83
84impl FromData for i32 {
85 const SIZE: usize = 4;
86
87 #[inline]
88 fn parse(data: &[u8]) -> Option<Self> {
89 data.try_into().ok().map(i32::from_be_bytes)
90 }
91}
92
93impl FromData for u64 {
94 const SIZE: usize = 8;
95
96 #[inline]
97 fn parse(data: &[u8]) -> Option<Self> {
98 data.try_into().ok().map(u64::from_be_bytes)
99 }
100}
101
102#[derive(Clone, Copy, Debug)]
108pub struct U24(pub u32);
109
110impl FromData for U24 {
111 const SIZE: usize = 3;
112
113 #[inline]
114 fn parse(data: &[u8]) -> Option<Self> {
115 let data: [u8; 3] = data.try_into().ok()?;
116 Some(U24(u32::from_be_bytes([0, data[0], data[1], data[2]])))
117 }
118}
119
120
121#[derive(Clone, Copy, Debug)]
123pub struct F2DOT14(pub i16);
124
125impl F2DOT14 {
126 #[inline]
128 pub fn to_f32(&self) -> f32 {
129 f32::from(self.0) / 16384.0
130 }
131}
132
133impl FromData for F2DOT14 {
134 const SIZE: usize = 2;
135
136 #[inline]
137 fn parse(data: &[u8]) -> Option<Self> {
138 i16::parse(data).map(F2DOT14)
139 }
140}
141
142
143#[derive(Clone, Copy, Debug)]
145pub struct Fixed(pub f32);
146
147impl FromData for Fixed {
148 const SIZE: usize = 4;
149
150 #[inline]
151 fn parse(data: &[u8]) -> Option<Self> {
152 i32::parse(data).map(|n| Fixed(n as f32 / 65536.0))
154 }
155}
156
157
158pub trait NumFrom<T>: Sized {
164 fn num_from(_: T) -> Self;
166}
167
168impl NumFrom<u32> for usize {
169 #[inline]
170 fn num_from(v: u32) -> Self {
171 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
172 {
173 v as usize
174 }
175
176 }
178}
179
180impl NumFrom<char> for usize {
181 #[inline]
182 fn num_from(v: char) -> Self {
183 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
184 {
185 v as usize
186 }
187
188 }
190}
191
192
193pub trait TryNumFrom<T>: Sized {
195 fn try_num_from(_: T) -> Option<Self>;
197}
198
199impl TryNumFrom<f32> for u8 {
200 #[inline]
201 fn try_num_from(v: f32) -> Option<Self> {
202 i32::try_num_from(v).and_then(|v| u8::try_from(v).ok())
203 }
204}
205
206impl TryNumFrom<f32> for i16 {
207 #[inline]
208 fn try_num_from(v: f32) -> Option<Self> {
209 i32::try_num_from(v).and_then(|v| i16::try_from(v).ok())
210 }
211}
212
213impl TryNumFrom<f32> for u16 {
214 #[inline]
215 fn try_num_from(v: f32) -> Option<Self> {
216 i32::try_num_from(v).and_then(|v| u16::try_from(v).ok())
217 }
218}
219
220impl TryNumFrom<f32> for i32 {
221 #[inline]
222 fn try_num_from(v: f32) -> Option<Self> {
223 const MIN: f32 = core::i32::MIN as f32;
231 const MAX_P1: f32 = core::i32::MAX as f32;
234 if v >= MIN && v < MAX_P1 {
235 Some(v as i32)
236 } else {
237 None
238 }
239 }
240}
241
242
243#[derive(Clone, Copy)]
247pub struct LazyArray16<'a, T> {
248 data: &'a [u8],
249 data_type: core::marker::PhantomData<T>,
250}
251
252impl<T> Default for LazyArray16<'_, T> {
253 #[inline]
254 fn default() -> Self {
255 LazyArray16 {
256 data: &[],
257 data_type: core::marker::PhantomData,
258 }
259 }
260}
261
262impl<'a, T: FromData> LazyArray16<'a, T> {
263 #[inline]
265 pub fn new(data: &'a [u8]) -> Self {
266 LazyArray16 {
267 data,
268 data_type: core::marker::PhantomData,
269 }
270 }
271
272 #[inline]
274 pub fn get(&self, index: u16) -> Option<T> {
275 if index < self.len() {
276 let start = usize::from(index) * T::SIZE;
277 let end = start + T::SIZE;
278 self.data.get(start..end).and_then(T::parse)
279 } else {
280 None
281 }
282 }
283
284 #[inline]
286 pub fn last(&self) -> Option<T> {
287 if !self.is_empty() {
288 self.get(self.len() - 1)
289 } else {
290 None
291 }
292 }
293
294 #[inline]
296 pub fn slice(&self, range: Range<u16>) -> Option<Self> {
297 let start = usize::from(range.start) * T::SIZE;
298 let end = usize::from(range.end) * T::SIZE;
299 Some(LazyArray16 {
300 data: self.data.get(start..end)?,
301 ..LazyArray16::default()
302 })
303 }
304
305 #[inline]
307 pub fn len(&self) -> u16 {
308 (self.data.len() / T::SIZE) as u16
309 }
310
311 #[inline]
313 pub fn is_empty(&self) -> bool {
314 self.len() == 0
315 }
316
317 #[inline]
319 pub fn binary_search(&self, key: &T) -> Option<(u16, T)>
320 where T: Ord
321 {
322 self.binary_search_by(|p| p.cmp(key))
323 }
324
325 #[inline]
327 pub fn binary_search_by<F>(&self, mut f: F) -> Option<(u16, T)>
328 where F: FnMut(&T) -> core::cmp::Ordering
329 {
330 use core::cmp::Ordering;
333
334 let mut size = self.len();
335 if size == 0 {
336 return None;
337 }
338
339 let mut base = 0;
340 while size > 1 {
341 let half = size / 2;
342 let mid = base + half;
343 let cmp = f(&self.get(mid)?);
347 base = if cmp == Ordering::Greater { base } else { mid };
348 size -= half;
349 }
350
351 let value = self.get(base)?;
353 if f(&value) == Ordering::Equal { Some((base, value)) } else { None }
354 }
355}
356
357impl<'a, T: FromData + core::fmt::Debug + Copy> core::fmt::Debug for LazyArray16<'a, T> {
358 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
359 f.debug_list().entries(self.into_iter()).finish()
360 }
361}
362
363impl<'a, T: FromData> IntoIterator for LazyArray16<'a, T> {
364 type Item = T;
365 type IntoIter = LazyArrayIter16<'a, T>;
366
367 #[inline]
368 fn into_iter(self) -> Self::IntoIter {
369 LazyArrayIter16 {
370 data: self,
371 index: 0,
372 }
373 }
374}
375
376
377#[derive(Clone, Copy)]
379#[allow(missing_debug_implementations)]
380pub struct LazyArrayIter16<'a, T> {
381 data: LazyArray16<'a, T>,
382 index: u16,
383}
384
385impl<T: FromData> Default for LazyArrayIter16<'_, T> {
386 #[inline]
387 fn default() -> Self {
388 LazyArrayIter16 {
389 data: LazyArray16::new(&[]),
390 index: 0,
391 }
392 }
393}
394
395impl<'a, T: FromData> Iterator for LazyArrayIter16<'a, T> {
396 type Item = T;
397
398 #[inline]
399 fn next(&mut self) -> Option<Self::Item> {
400 self.index += 1; self.data.get(self.index - 1)
402 }
403
404 #[inline]
405 fn count(self) -> usize {
406 usize::from(self.data.len().checked_sub(self.index).unwrap_or(0))
407 }
408}
409
410
411#[derive(Clone, Copy)]
415pub struct LazyArray32<'a, T> {
416 data: &'a [u8],
417 data_type: core::marker::PhantomData<T>,
418}
419
420impl<T> Default for LazyArray32<'_, T> {
421 #[inline]
422 fn default() -> Self {
423 LazyArray32 {
424 data: &[],
425 data_type: core::marker::PhantomData,
426 }
427 }
428}
429
430impl<'a, T: FromData> LazyArray32<'a, T> {
431 #[inline]
433 pub fn new(data: &'a [u8]) -> Self {
434 LazyArray32 {
435 data,
436 data_type: core::marker::PhantomData,
437 }
438 }
439
440 #[inline]
442 pub fn get(&self, index: u32) -> Option<T> {
443 if index < self.len() {
444 let start = usize::num_from(index) * T::SIZE;
445 let end = start + T::SIZE;
446 self.data.get(start..end).and_then(T::parse)
447 } else {
448 None
449 }
450 }
451
452 #[inline]
454 pub fn len(&self) -> u32 {
455 (self.data.len() / T::SIZE) as u32
456 }
457
458 #[inline]
460 pub fn binary_search(&self, key: &T) -> Option<(u32, T)>
461 where T: Ord
462 {
463 self.binary_search_by(|p| p.cmp(key))
464 }
465
466 #[inline]
468 pub fn binary_search_by<F>(&self, mut f: F) -> Option<(u32, T)>
469 where F: FnMut(&T) -> core::cmp::Ordering
470 {
471 use core::cmp::Ordering;
474
475 let mut size = self.len();
476 if size == 0 {
477 return None;
478 }
479
480 let mut base = 0;
481 while size > 1 {
482 let half = size / 2;
483 let mid = base + half;
484 let cmp = f(&self.get(mid)?);
488 base = if cmp == Ordering::Greater { base } else { mid };
489 size -= half;
490 }
491
492 let value = self.get(base)?;
494 if f(&value) == Ordering::Equal { Some((base, value)) } else { None }
495 }
496}
497
498impl<'a, T: FromData + core::fmt::Debug + Copy> core::fmt::Debug for LazyArray32<'a, T> {
499 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
500 f.debug_list().entries(self.into_iter()).finish()
501 }
502}
503
504impl<'a, T: FromData> IntoIterator for LazyArray32<'a, T> {
505 type Item = T;
506 type IntoIter = LazyArrayIter32<'a, T>;
507
508 #[inline]
509 fn into_iter(self) -> Self::IntoIter {
510 LazyArrayIter32 {
511 data: self,
512 index: 0,
513 }
514 }
515}
516
517
518#[derive(Clone, Copy)]
520#[allow(missing_debug_implementations)]
521pub struct LazyArrayIter32<'a, T> {
522 data: LazyArray32<'a, T>,
523 index: u32,
524}
525
526impl<'a, T: FromData> Iterator for LazyArrayIter32<'a, T> {
527 type Item = T;
528
529 #[inline]
530 fn next(&mut self) -> Option<Self::Item> {
531 self.index += 1; self.data.get(self.index - 1)
533 }
534
535 #[inline]
536 fn count(self) -> usize {
537 usize::num_from(self.data.len().checked_sub(self.index).unwrap_or(0))
538 }
539}
540
541
542#[derive(Clone, Copy)]
548pub struct LazyOffsetArray16<'a, T: FromSlice<'a>> {
549 data: &'a [u8],
550 offsets: LazyArray16<'a, Option<Offset16>>,
552 data_type: core::marker::PhantomData<T>,
553}
554
555impl<'a, T: FromSlice<'a>> LazyOffsetArray16<'a, T> {
556 #[allow(dead_code)]
558 pub fn new(data: &'a [u8], offsets: LazyArray16<'a, Option<Offset16>>) -> Self {
559 Self { data, offsets, data_type: core::marker::PhantomData }
560 }
561
562 #[allow(dead_code)]
564 pub fn parse(data: &'a [u8]) -> Option<Self> {
565 let mut s = Stream::new(data);
566 let count = s.read::<u16>()?;
567 let offsets = s.read_array16(count)?;
568 Some(Self { data, offsets, data_type: core::marker::PhantomData })
569 }
570
571 #[inline]
573 pub fn get(&self, index: u16) -> Option<T> {
574 let offset = self.offsets.get(index)??.to_usize();
575 self.data.get(offset..).and_then(T::parse)
576 }
577
578 #[inline]
580 pub fn len(&self) -> u16 {
581 self.offsets.len()
582 }
583
584 #[inline]
586 #[allow(dead_code)]
587 pub fn is_empty(&self) -> bool {
588 self.len() == 0
589 }
590}
591
592impl<'a, T: FromSlice<'a> + core::fmt::Debug + Copy> core::fmt::Debug for LazyOffsetArray16<'a, T> {
593 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
594 f.debug_list().entries(self.into_iter()).finish()
595 }
596}
597
598#[derive(Clone, Copy)]
600#[allow(missing_debug_implementations)]
601pub struct LazyOffsetArrayIter16<'a, T: FromSlice<'a>> {
602 array: LazyOffsetArray16<'a, T>,
603 index: u16,
604}
605
606impl<'a, T: FromSlice<'a>> IntoIterator for LazyOffsetArray16<'a, T> {
607 type Item = T;
608 type IntoIter = LazyOffsetArrayIter16<'a, T>;
609
610 #[inline]
611 fn into_iter(self) -> Self::IntoIter {
612 LazyOffsetArrayIter16 {
613 array: self,
614 index: 0,
615 }
616 }
617}
618
619impl<'a, T: FromSlice<'a>> Iterator for LazyOffsetArrayIter16<'a, T> {
620 type Item = T;
621
622 fn next(&mut self) -> Option<Self::Item> {
623 if self.index < self.array.len() {
624 self.index += 1;
625 self.array.get(self.index - 1)
626 } else {
627 None
628 }
629 }
630
631 #[inline]
632 fn count(self) -> usize {
633 usize::from(self.array.len().checked_sub(self.index).unwrap_or(0))
634 }
635}
636
637
638#[derive(Clone, Copy, Default, Debug)]
640pub struct Stream<'a> {
641 data: &'a [u8],
642 offset: usize,
643}
644
645impl<'a> Stream<'a> {
646 #[inline]
648 pub fn new(data: &'a [u8]) -> Self {
649 Stream { data, offset: 0 }
650 }
651
652 #[inline]
656 pub fn new_at(data: &'a [u8], offset: usize) -> Option<Self> {
657 if offset <= data.len() {
658 Some(Stream { data, offset })
659 } else {
660 None
661 }
662 }
663
664 #[inline]
666 pub fn at_end(&self) -> bool {
667 self.offset >= self.data.len()
668 }
669
670 #[inline]
674 pub fn jump_to_end(&mut self) {
675 self.offset = self.data.len();
676 }
677
678 #[inline]
680 pub fn offset(&self) -> usize {
681 self.offset
682 }
683
684 #[inline]
688 pub fn tail(&self) -> Option<&'a [u8]> {
689 self.data.get(self.offset..)
690 }
691
692 #[inline]
696 pub fn skip<T: FromData>(&mut self) {
697 self.advance(T::SIZE);
698 }
699
700 #[inline]
704 pub fn advance(&mut self, len: usize) {
705 self.offset += len;
706 }
707
708 #[inline]
710 pub fn advance_checked(&mut self, len: usize) -> Option<()> {
711 if self.offset + len <= self.data.len() {
712 self.advance(len);
713 Some(())
714 } else {
715 None
716 }
717 }
718
719 #[inline]
724 pub fn read<T: FromData>(&mut self) -> Option<T> {
725 self.read_bytes(T::SIZE).and_then(T::parse)
726 }
727
728 #[inline]
730 pub fn read_at<T: FromData>(data: &[u8], offset: usize) -> Option<T> {
731 data.get(offset..offset + T::SIZE).and_then(T::parse)
732 }
733
734 #[inline]
736 pub fn read_bytes(&mut self, len: usize) -> Option<&'a [u8]> {
737 let v = self.data.get(self.offset..self.offset + len)?;
738 self.advance(len);
739 Some(v)
740 }
741
742 #[inline]
744 pub fn read_array16<T: FromData>(&mut self, count: u16) -> Option<LazyArray16<'a, T>> {
745 let len = usize::from(count) * T::SIZE;
746 self.read_bytes(len).map(LazyArray16::new)
747 }
748
749 #[inline]
751 pub fn read_array32<T: FromData>(&mut self, count: u32) -> Option<LazyArray32<'a, T>> {
752 let len = usize::num_from(count) * T::SIZE;
753 self.read_bytes(len).map(LazyArray32::new)
754 }
755
756 #[allow(dead_code)]
757 #[inline]
758 pub(crate) fn read_at_offset16(&mut self, data: &'a [u8]) -> Option<&'a [u8]> {
759 let offset = self.read::<Offset16>()?.to_usize();
760 data.get(offset..)
761 }
762
763 #[allow(dead_code)]
764 #[inline]
765 pub(crate) fn read_at_offset32(&mut self, data: &'a [u8]) -> Option<&'a [u8]> {
766 let offset = self.read::<Offset32>()?.to_usize();
767 data.get(offset..)
768 }
769}
770
771
772pub trait Offset {
774 fn to_usize(&self) -> usize;
776
777 fn is_null(&self) -> bool { self.to_usize() == 0 }
779}
780
781
782#[derive(Clone, Copy, Debug)]
784pub struct Offset16(pub u16);
785
786impl Offset for Offset16 {
787 #[inline]
788 fn to_usize(&self) -> usize {
789 usize::from(self.0)
790 }
791}
792
793impl FromData for Offset16 {
794 const SIZE: usize = 2;
795
796 #[inline]
797 fn parse(data: &[u8]) -> Option<Self> {
798 u16::parse(data).map(Offset16)
799 }
800}
801
802impl FromData for Option<Offset16> {
803 const SIZE: usize = Offset16::SIZE;
804
805 #[inline]
806 fn parse(data: &[u8]) -> Option<Self> {
807 let offset = Offset16::parse(data)?;
808 if offset.0 != 0 { Some(Some(offset)) } else { Some(None) }
809 }
810}
811
812
813#[derive(Clone, Copy, Debug)]
815pub struct Offset32(pub u32);
816
817impl Offset for Offset32 {
818 #[inline]
819 fn to_usize(&self) -> usize {
820 usize::num_from(self.0)
821 }
822}
823
824impl FromData for Offset32 {
825 const SIZE: usize = 4;
826
827 #[inline]
828 fn parse(data: &[u8]) -> Option<Self> {
829 u32::parse(data).map(Offset32)
830 }
831}
832
833
834impl FromData for Option<Offset32> {
835 const SIZE: usize = Offset32::SIZE;
836
837 #[inline]
838 fn parse(data: &[u8]) -> Option<Self> {
839 let offset = Offset32::parse(data)?;
840 if offset.0 != 0 { Some(Some(offset)) } else { Some(None) }
841 }
842}
843
844
845#[inline]
846pub(crate) fn i16_bound(min: i16, val: i16, max: i16) -> i16 {
847 use core::cmp;
848 cmp::max(min, cmp::min(max, val))
849}
850
851#[inline]
852pub(crate) fn f32_bound(min: f32, val: f32, max: f32) -> f32 {
853 debug_assert!(min.is_finite());
854 debug_assert!(val.is_finite());
855 debug_assert!(max.is_finite());
856
857 if val > max {
858 return max;
859 } else if val < min {
860 return min;
861 }
862
863 val
864}