1
#![allow(missing_docs)]
2

            
3
//! Parse binary data
4
//!
5
//! The is module provides the basis for all font parsing in Allsorts. The parsing approach
6
//! is inspired by the paper,
7
//! [The next 700 data description languages](https://collaborate.princeton.edu/en/publications/the-next-700-data-description-languages) by Kathleen Fisher, Yitzhak Mandelbaum, David P. Walker.
8

            
9
use crate::binary::{I16Be, I32Be, I64Be, U16Be, U24Be, U32Be, U64Be, I8, U8};
10
use crate::error::ParseError;
11
use crate::layout::{LayoutCache, LayoutTableType};
12
use crate::{size, SafeFrom};
13
use std::borrow::Cow;
14
use std::cmp;
15
use std::cmp::Ordering;
16
// [azul web-lift] BTreeMap not HashMap for ReadCache: this cache (coverages/classdefs etc.) starts
17
// EMPTY (cap-0) and the FIRST insert during GSUB/GPOS shaping hits the lifted hashbrown EMPTY-INSERT
18
// mis-lift (reserve_rehash-from-0) → the remill-lifted web backend HANGS in shape_text. BTreeMap has
19
// no ctrl-group/empty-static → immune. Key is `usize` (Ord); entry API is identical.
20
use std::collections::btree_map::Entry;
21
use std::collections::BTreeMap;
22
use std::fmt;
23
use std::marker::PhantomData;
24
use std::sync::Arc;
25

            
26
#[derive(Debug, Copy, Clone)]
27
pub struct ReadEof {}
28

            
29
pub struct ReadBuf<'a> {
30
    data: Cow<'a, [u8]>,
31
}
32

            
33
#[derive(Copy, Clone, PartialEq)]
34
pub struct ReadScope<'a> {
35
    base: usize,
36
    data: &'a [u8],
37
}
38

            
39
pub struct ReadScopeOwned {
40
    base: usize,
41
    data: Box<[u8]>,
42
}
43

            
44
impl ReadScopeOwned {
45
11016
    pub fn new(scope: ReadScope<'_>) -> ReadScopeOwned {
46
11016
        ReadScopeOwned {
47
11016
            base: scope.base,
48
11016
            data: Box::from(scope.data),
49
11016
        }
50
11016
    }
51

            
52
61506
    pub fn scope(&self) -> ReadScope<'_> {
53
61506
        ReadScope {
54
61506
            base: self.base,
55
61506
            data: &self.data,
56
61506
        }
57
61506
    }
58
}
59

            
60
#[derive(Clone)]
61
pub struct ReadCtxt<'a> {
62
    scope: ReadScope<'a>,
63
    offset: usize,
64
}
65

            
66
pub struct ReadCache<T> {
67
    map: BTreeMap<usize, Arc<T>>,
68
}
69

            
70
pub trait ReadBinary {
71
    type HostType<'a>: Sized; // default = Self
72

            
73
    fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self::HostType<'a>, ParseError>;
74
}
75

            
76
pub trait ReadBinaryDep {
77
    type Args<'a>: Copy;
78
    type HostType<'a>: Sized; // default = Self
79

            
80
    fn read_dep<'a>(
81
        ctxt: &mut ReadCtxt<'a>,
82
        args: Self::Args<'a>,
83
    ) -> Result<Self::HostType<'a>, ParseError>;
84
}
85

            
86
pub trait ReadFixedSizeDep: ReadBinaryDep {
87
    /// The number of bytes consumed by `ReadBinaryDep::read`.
88
    fn size(args: Self::Args<'_>) -> usize;
89
}
90

            
91
/// Read will always succeed if sufficient bytes are available.
92
pub trait ReadUnchecked {
93
    type HostType: Sized; // default = Self
94

            
95
    /// The number of bytes consumed by `read_unchecked`.
96
    const SIZE: usize;
97

            
98
    /// Must read exactly `SIZE` bytes.
99
    /// Unsafe as it avoids prohibitively expensive per-byte bounds checking.
100
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> Self::HostType;
101
}
102

            
103
pub trait ReadFrom {
104
    type ReadType: ReadUnchecked;
105
    fn read_from(value: <Self::ReadType as ReadUnchecked>::HostType) -> Self;
106
}
107

            
108
impl<T> ReadUnchecked for T
109
where
110
    T: ReadFrom,
111
{
112
    type HostType = T;
113

            
114
    const SIZE: usize = T::ReadType::SIZE;
115

            
116
20324196
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> Self::HostType {
117
20324196
        let t = T::ReadType::read_unchecked(ctxt);
118
20324196
        T::read_from(t)
119
20324196
    }
120
}
121

            
122
impl<T> ReadBinary for T
123
where
124
    T: ReadUnchecked,
125
{
126
    type HostType<'a> = T::HostType;
127

            
128
6281982
    fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self::HostType<'a>, ParseError> {
129
6281982
        ctxt.check_avail(T::SIZE)?;
130
6281982
        Ok(unsafe { T::read_unchecked(ctxt) })
131
        // Safe because we have `SIZE` bytes available.
132
6281982
    }
133
}
134

            
135
impl<T> ReadBinaryDep for T
136
where
137
    T: ReadBinary,
138
{
139
    type Args<'a> = ();
140
    type HostType<'a> = T::HostType<'a>;
141

            
142
10550742
    fn read_dep<'a>(
143
10550742
        ctxt: &mut ReadCtxt<'a>,
144
10550742
        (): Self::Args<'_>,
145
10550742
    ) -> Result<Self::HostType<'a>, ParseError> {
146
10550742
        T::read(ctxt)
147
10550742
    }
148
}
149

            
150
impl<T> ReadFixedSizeDep for T
151
where
152
    T: ReadUnchecked,
153
{
154
    fn size((): ()) -> usize {
155
        T::SIZE
156
    }
157
}
158

            
159
pub trait CheckIndex {
160
    fn check_index(&self, index: usize) -> Result<(), ParseError>;
161
}
162

            
163
/// Wrapper type for Debug impl of byte slices
164
pub(crate) struct DebugData<'a>(pub(crate) &'a [u8]);
165

            
166
pub struct ReadArray<'a, T: ReadFixedSizeDep> {
167
    scope: ReadScope<'a>,
168
    length: usize,
169
    stride: usize,
170
    args: T::Args<'a>,
171
}
172

            
173
impl<T: ReadFixedSizeDep> Clone for ReadArray<'_, T> {
174
29214
    fn clone(&self) -> Self {
175
29214
        *self
176
29214
    }
177
}
178

            
179
impl<T: ReadFixedSizeDep> Copy for ReadArray<'_, T> {}
180

            
181
pub struct ReadArrayIter<'a, T: ReadUnchecked> {
182
    scope: ReadScope<'a>,
183
    index: usize,
184
    end: usize,
185
    stride: usize,
186
    phantom: PhantomData<T>,
187
}
188

            
189
pub struct ReadArrayDepIter<'a, 'b, T: ReadFixedSizeDep> {
190
    array: &'b ReadArray<'a, T>,
191
    index: usize,
192
}
193

            
194
#[derive(Clone)]
195
pub enum ReadArrayCow<'a, T>
196
where
197
    T: ReadUnchecked,
198
{
199
    Owned(Vec<T::HostType>),
200
    Borrowed(ReadArray<'a, T>),
201
}
202

            
203
pub struct ReadArrayCowIter<'a, 'b, T: ReadUnchecked> {
204
    array: &'b ReadArrayCow<'a, T>,
205
    index: usize,
206
}
207

            
208
impl<'a, T: ReadUnchecked> ReadArrayCow<'a, T> {
209
29160
    pub fn len(&self) -> usize {
210
29160
        match self {
211
29160
            ReadArrayCow::Borrowed(array) => array.len(),
212
            ReadArrayCow::Owned(vec) => vec.len(),
213
        }
214
29160
    }
215

            
216
    pub fn is_empty(&self) -> bool {
217
        match self {
218
            ReadArrayCow::Borrowed(array) => array.is_empty(),
219
            ReadArrayCow::Owned(vec) => vec.is_empty(),
220
        }
221
    }
222

            
223
    pub fn read_item(&self, index: usize) -> Result<T::HostType, ParseError>
224
    where
225
        T::HostType: Copy,
226
    {
227
        match self {
228
            ReadArrayCow::Borrowed(array) => array.read_item(index),
229
            ReadArrayCow::Owned(vec) => vec.get(index).copied().ok_or(ParseError::BadIndex),
230
        }
231
    }
232

            
233
3249720
    pub fn get_item(&self, index: usize) -> Option<<T as ReadUnchecked>::HostType>
234
3249720
    where
235
3249720
        T: ReadUnchecked,
236
3249720
        <T as ReadUnchecked>::HostType: Copy,
237
    {
238
3249720
        match self {
239
3249720
            ReadArrayCow::Borrowed(array) => array.get_item(index),
240
            ReadArrayCow::Owned(vec) => vec.get(index).copied(),
241
        }
242
3249720
    }
243

            
244
    // subarray and iter_res are not yet implemented
245

            
246
    pub fn iter<'b>(&'b self) -> ReadArrayCowIter<'a, 'b, T> {
247
        ReadArrayCowIter {
248
            array: self,
249
            index: 0,
250
        }
251
    }
252
}
253

            
254
impl<T: ReadUnchecked> CheckIndex for ReadArrayCow<'_, T> {
255
    fn check_index(&self, index: usize) -> Result<(), ParseError> {
256
        if index < self.len() {
257
            Ok(())
258
        } else {
259
            Err(ParseError::BadIndex)
260
        }
261
    }
262
}
263

            
264
impl<'a> ReadScope<'a> {
265
1002240
    pub fn new(data: &'a [u8]) -> ReadScope<'a> {
266
1002240
        let base = 0;
267
1002240
        ReadScope { base, data }
268
1002240
    }
269

            
270
196128
    pub fn data(&self) -> &'a [u8] {
271
196128
        self.data
272
196128
    }
273

            
274
68616882
    pub fn offset(&self, offset: usize) -> ReadScope<'a> {
275
68616882
        let base = self.base + offset;
276
68616882
        let data = self.data.get(offset..).unwrap_or(&[]);
277
68616882
        ReadScope { base, data }
278
68616882
    }
279

            
280
150649146
    pub fn offset_length(&self, offset: usize, length: usize) -> Result<ReadScope<'a>, ParseError> {
281
150649146
        if offset < self.data.len() || length == 0 {
282
150626736
            let data = self.data.get(offset..).unwrap_or(&[]);
283
150626736
            if length <= data.len() {
284
150626736
                let base = self.base + offset;
285
150626736
                let data = &data[0..length];
286
150626736
                Ok(ReadScope { base, data })
287
            } else {
288
                Err(ParseError::BadEof)
289
            }
290
        } else {
291
22410
            Err(ParseError::BadOffset)
292
        }
293
150649146
    }
294

            
295
205470324
    pub fn ctxt(&self) -> ReadCtxt<'a> {
296
205470324
        ReadCtxt::new(*self)
297
205470324
    }
298

            
299
3801390
    pub fn read<T: ReadBinaryDep<Args<'a> = ()>>(&self) -> Result<T::HostType<'a>, ParseError> {
300
3801390
        self.ctxt().read::<T>()
301
3801390
    }
302

            
303
4409154
    pub fn read_dep<T: ReadBinaryDep>(
304
4409154
        &self,
305
4409154
        args: T::Args<'a>,
306
4409154
    ) -> Result<T::HostType<'a>, ParseError> {
307
4409154
        self.ctxt().read_dep::<T>(args)
308
4409154
    }
309

            
310
513648
    pub fn read_cache<T>(
311
513648
        &self,
312
513648
        cache: &mut ReadCache<T::HostType<'a>>,
313
513648
    ) -> Result<Arc<T::HostType<'a>>, ParseError>
314
513648
    where
315
513648
        T: 'static + ReadBinaryDep<Args<'a> = ()>,
316
    {
317
513648
        match cache.map.entry(self.base) {
318
421308
            Entry::Vacant(entry) => {
319
421308
                let t = Arc::new(self.read::<T>()?);
320
421308
                Ok(Arc::clone(entry.insert(t)))
321
            }
322
92340
            Entry::Occupied(entry) => Ok(Arc::clone(entry.get())),
323
        }
324
513648
    }
325

            
326
    pub fn read_cache_state<T, Table>(
327
        &self,
328
        cache: &mut ReadCache<T::HostType<'a>>,
329
        state: LayoutCache<Table>,
330
    ) -> Result<Arc<T::HostType<'a>>, ParseError>
331
    where
332
        T: 'static + ReadBinaryDep<Args<'a> = LayoutCache<Table>>,
333
        Table: LayoutTableType,
334
    {
335
        match cache.map.entry(self.base) {
336
            Entry::Vacant(entry) => {
337
                let t = Arc::new(self.read_dep::<T>(state)?);
338
                Ok(Arc::clone(entry.insert(t)))
339
            }
340
            Entry::Occupied(entry) => Ok(Arc::clone(entry.get())),
341
        }
342
    }
343

            
344
    pub(crate) fn read_optional_array<T>(
345
        &self,
346
        offset: u32,
347
        num: u16,
348
    ) -> Result<Option<ReadArray<'a, T>>, ParseError>
349
    where
350
        T: ReadUnchecked,
351
    {
352
        (num > 0 && offset != 0)
353
            .then(|| {
354
                self.offset(usize::safe_from(offset))
355
                    .ctxt()
356
                    .read_array(usize::from(num))
357
            })
358
            .transpose()
359
    }
360
}
361

            
362
impl fmt::Debug for ReadScope<'_> {
363
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364
        let ReadScope { base, data } = self;
365
        f.debug_struct("ReadScope")
366
            .field("base", base)
367
            .field("data", &DebugData(data))
368
            .finish()
369
    }
370
}
371

            
372
impl<T> ReadCache<T> {
373
21624
    pub fn new() -> Self {
374
21624
        let map = BTreeMap::new();
375
21624
        ReadCache { map }
376
21624
    }
377
}
378

            
379
impl<'a> ReadCtxt<'a> {
380
    /// ReadCtxt is constructed by calling `ReadScope::ctxt`.
381
205470324
    fn new(scope: ReadScope<'a>) -> ReadCtxt<'a> {
382
205470324
        ReadCtxt { scope, offset: 0 }
383
205470324
    }
384

            
385
3827250
    pub fn check(&self, cond: bool) -> Result<(), ParseError> {
386
3827250
        match cond {
387
3827250
            true => Ok(()),
388
            false => Err(ParseError::BadValue),
389
        }
390
3827250
    }
391

            
392
    /// Check a condition, returning `ParseError::BadIndex` if `false`.
393
    ///
394
    /// ```
395
    /// use allsorts::binary::read::ReadScope;
396
    /// use allsorts::error::ParseError;
397
    ///
398
    /// # fn main() -> Result<(), ParseError> {
399
    /// let ctxt = ReadScope::new(b"some data").ctxt();
400
    ///
401
    /// // Demonstration values
402
    /// let count = 3;
403
    /// let index = 1;
404
    /// ctxt.check_index(index < count)?;
405
    /// # Ok(())
406
    /// # }
407
    /// ```
408
    pub fn check_index(&self, cond: bool) -> Result<(), ParseError> {
409
        match cond {
410
            true => Ok(()),
411
            false => Err(ParseError::BadIndex),
412
        }
413
    }
414

            
415
    /// Check a condition, returning `ParseError::BadVersion` if `false`.
416
    ///
417
    /// Intended for use in checking versions read from data. Example:
418
    ///
419
    /// ```
420
    /// use allsorts::binary::read::ReadScope;
421
    /// use allsorts::error::ParseError;
422
    ///
423
    /// let scope = ReadScope::new(&[0, 2]);
424
    /// let mut ctxt = scope.ctxt();
425
    /// let major_version = ctxt.read_u16be().expect("unable to read version");
426
    ///
427
    /// assert!(ctxt.check_version(major_version == 2).is_ok());
428
    /// assert_eq!(
429
    ///     ctxt.check_version(major_version == 1),
430
    ///     Err(ParseError::BadVersion)
431
    /// );
432
    /// ```
433
    pub fn check_version(&self, cond: bool) -> Result<(), ParseError> {
434
        match cond {
435
            true => Ok(()),
436
            false => Err(ParseError::BadVersion),
437
        }
438
    }
439

            
440
4236570
    pub fn scope(&self) -> ReadScope<'a> {
441
4236570
        self.scope.offset(self.offset)
442
4236570
    }
443

            
444
10550742
    pub fn read<T: ReadBinaryDep<Args<'a> = ()>>(&mut self) -> Result<T::HostType<'a>, ParseError> {
445
10550742
        T::read_dep(self, ())
446
10550742
    }
447

            
448
232367832
    pub fn read_dep<T: ReadBinaryDep>(
449
232367832
        &mut self,
450
232367832
        args: T::Args<'a>,
451
232367832
    ) -> Result<T::HostType<'a>, ParseError> {
452
232367832
        T::read_dep(self, args)
453
232367832
    }
454

            
455
    pub fn bytes_available(&self) -> bool {
456
        self.offset < self.scope.data.len()
457
    }
458

            
459
226961082
    fn check_avail(&self, length: usize) -> Result<(), ReadEof> {
460
226961082
        match self.offset.checked_add(length) {
461
226961082
            Some(endpos) if endpos <= self.scope.data.len() => Ok(()),
462
            _ => Err(ReadEof {}),
463
        }
464
226961082
    }
465

            
466
3967920
    unsafe fn read_unchecked_u8(&mut self) -> u8 {
467
3967920
        let byte = *self.scope.data.get_unchecked(self.offset);
468
3967920
        self.offset += 1;
469
3967920
        byte
470
3967920
    }
471

            
472
1080
    unsafe fn read_unchecked_i8(&mut self) -> i8 {
473
1080
        self.read_unchecked_u8() as i8
474
1080
    }
475

            
476
261374148
    unsafe fn read_unchecked_u16be(&mut self) -> u16 {
477
261374148
        let hi = u16::from(*self.scope.data.get_unchecked(self.offset));
478
261374148
        let lo = u16::from(*self.scope.data.get_unchecked(self.offset + 1));
479
261374148
        self.offset += 2;
480
261374148
        (hi << 8) | lo
481
261374148
    }
482

            
483
122362974
    unsafe fn read_unchecked_i16be(&mut self) -> i16 {
484
122362974
        self.read_unchecked_u16be() as i16
485
122362974
    }
486

            
487
    unsafe fn read_unchecked_u24be(&mut self) -> u32 {
488
        let b0 = u32::from(*self.scope.data.get_unchecked(self.offset));
489
        let b1 = u32::from(*self.scope.data.get_unchecked(self.offset + 1));
490
        let b2 = u32::from(*self.scope.data.get_unchecked(self.offset + 2));
491
        self.offset += 3;
492
        (b0 << 16) | (b1 << 8) | b2
493
    }
494

            
495
22938822
    unsafe fn read_unchecked_u32be(&mut self) -> u32 {
496
22938822
        let b0 = u32::from(*self.scope.data.get_unchecked(self.offset));
497
22938822
        let b1 = u32::from(*self.scope.data.get_unchecked(self.offset + 1));
498
22938822
        let b2 = u32::from(*self.scope.data.get_unchecked(self.offset + 2));
499
22938822
        let b3 = u32::from(*self.scope.data.get_unchecked(self.offset + 3));
500
22938822
        self.offset += 4;
501
22938822
        (b0 << 24) | (b1 << 16) | (b2 << 8) | b3
502
22938822
    }
503

            
504
58104
    unsafe fn read_unchecked_i32be(&mut self) -> i32 {
505
58104
        self.read_unchecked_u32be() as i32
506
58104
    }
507

            
508
116208
    unsafe fn read_unchecked_u64be(&mut self) -> u64 {
509
116208
        let hi = u64::from(self.read_unchecked_u32be());
510
116208
        let lo = u64::from(self.read_unchecked_u32be());
511
116208
        (hi << 32) | lo
512
116208
    }
513

            
514
116208
    unsafe fn read_unchecked_i64be(&mut self) -> i64 {
515
116208
        self.read_unchecked_u64be() as i64
516
116208
    }
517

            
518
    pub fn read_u8(&mut self) -> Result<u8, ReadEof> {
519
        self.check_avail(1)?;
520
        Ok(unsafe { self.read_unchecked_u8() })
521
        // Safe because we have 1 byte available.
522
    }
523

            
524
1080
    pub fn read_i8(&mut self) -> Result<i8, ReadEof> {
525
1080
        self.check_avail(1)?;
526
1080
        Ok(unsafe { self.read_unchecked_i8() })
527
        // Safe because we have 1 byte available.
528
1080
    }
529

            
530
46828260
    pub fn read_u16be(&mut self) -> Result<u16, ReadEof> {
531
46828260
        self.check_avail(2)?;
532
46828260
        Ok(unsafe { self.read_unchecked_u16be() })
533
        // Safe because we have 2 bytes available.
534
46828260
    }
535

            
536
115761906
    pub fn read_i16be(&mut self) -> Result<i16, ReadEof> {
537
115761906
        self.check_avail(2)?;
538
115761906
        Ok(unsafe { self.read_unchecked_i16be() })
539
        // Safe because we have 2 bytes available.
540
115761906
    }
541

            
542
1077408
    pub fn read_u32be(&mut self) -> Result<u32, ReadEof> {
543
1077408
        self.check_avail(4)?;
544
1077408
        Ok(unsafe { self.read_unchecked_u32be() })
545
        // Safe because we have 4 bytes available.
546
1077408
    }
547

            
548
    pub fn read_i32be(&mut self) -> Result<i32, ReadEof> {
549
        self.check_avail(4)?;
550
        Ok(unsafe { self.read_unchecked_i32be() })
551
        // Safe because we have 4 bytes available.
552
    }
553

            
554
    pub fn read_u64be(&mut self) -> Result<u64, ReadEof> {
555
        self.check_avail(8)?;
556
        Ok(unsafe { self.read_unchecked_u64be() })
557
        // Safe because we have 8 bytes available.
558
    }
559

            
560
    pub fn read_i64be(&mut self) -> Result<i64, ReadEof> {
561
        self.check_avail(8)?;
562
        Ok(unsafe { self.read_unchecked_i64be() })
563
        // Safe because we have 8 bytes available.
564
    }
565

            
566
4845594
    pub fn read_array<T: ReadUnchecked>(
567
4845594
        &mut self,
568
4845594
        length: usize,
569
4845594
    ) -> Result<ReadArray<'a, T>, ParseError> {
570
4845594
        let scope = self.read_scope(length * T::SIZE)?;
571
4823184
        let args = ();
572
4823184
        Ok(ReadArray {
573
4823184
            scope,
574
4823184
            length,
575
4823184
            stride: T::SIZE,
576
4823184
            args,
577
4823184
        })
578
4845594
    }
579

            
580
    pub fn read_array_stride<T: ReadUnchecked>(
581
        &mut self,
582
        length: usize,
583
        stride: usize,
584
    ) -> Result<ReadArray<'a, T>, ParseError> {
585
        if T::SIZE > stride {
586
            return Err(ParseError::BadValue);
587
        }
588
        let scope = self.read_scope(length * stride)?;
589
        let args = ();
590
        Ok(ReadArray {
591
            scope,
592
            length,
593
            stride,
594
            args,
595
        })
596
    }
597

            
598
    pub fn read_array_upto_hack<T: ReadUnchecked>(
599
        &mut self,
600
        length: usize,
601
    ) -> Result<ReadArray<'a, T>, ParseError> {
602
        let start_pos = self.offset;
603
        let buf_size = self.scope.data.len();
604
        let avail_bytes = cmp::max(0, buf_size - start_pos);
605
        let max_length = avail_bytes / T::SIZE;
606
        let length = cmp::min(length, max_length);
607
        self.read_array(length)
608
    }
609

            
610
    /// Read up to and including the supplied nibble.
611
    pub fn read_until_nibble(&mut self, nibble: u8) -> Result<&'a [u8], ReadEof> {
612
        let end = self.scope.data[self.offset..]
613
            .iter()
614
            .position(|&b| (b >> 4) == nibble || (b & 0xF) == nibble)
615
            .ok_or(ReadEof {})?;
616
        self.read_slice(end + 1)
617
    }
618

            
619
5489802
    pub fn read_array_dep<T: ReadFixedSizeDep>(
620
5489802
        &mut self,
621
5489802
        length: usize,
622
5489802
        args: T::Args<'a>,
623
5489802
    ) -> Result<ReadArray<'a, T>, ParseError> {
624
5489802
        let stride = T::size(args);
625
5489802
        let scope = self.read_scope(length * stride)?;
626
5489802
        Ok(ReadArray {
627
5489802
            scope,
628
5489802
            length,
629
5489802
            stride,
630
5489802
            args,
631
5489802
        })
632
5489802
    }
633

            
634
10424106
    pub fn read_scope(&mut self, length: usize) -> Result<ReadScope<'a>, ReadEof> {
635
10424106
        if let Ok(scope) = self.scope.offset_length(self.offset, length) {
636
10401696
            self.offset += length;
637
10401696
            Ok(scope)
638
        } else {
639
22410
            Err(ReadEof {})
640
        }
641
10424106
    }
642

            
643
88506
    pub fn read_slice(&mut self, length: usize) -> Result<&'a [u8], ReadEof> {
644
88506
        let scope = self.read_scope(length)?;
645
88506
        Ok(scope.data)
646
88506
    }
647
}
648

            
649
impl<'a> ReadBuf<'a> {
650
    pub fn scope(&'a self) -> ReadScope<'a> {
651
        ReadScope::new(&self.data)
652
    }
653

            
654
    pub fn into_data(self) -> Cow<'a, [u8]> {
655
        self.data
656
    }
657
}
658

            
659
impl<'a> From<&'a [u8]> for ReadBuf<'a> {
660
    fn from(data: &'a [u8]) -> ReadBuf<'a> {
661
        ReadBuf {
662
            data: Cow::Borrowed(data),
663
        }
664
    }
665
}
666

            
667
impl<'a> From<Vec<u8>> for ReadBuf<'a> {
668
    fn from(data: Vec<u8>) -> ReadBuf<'a> {
669
        ReadBuf {
670
            data: Cow::Owned(data),
671
        }
672
    }
673
}
674

            
675
impl<'a, T: ReadFixedSizeDep> ReadArray<'a, T> {
676
123251598
    pub fn len(&self) -> usize {
677
123251598
        self.length
678
123251598
    }
679

            
680
    pub fn is_empty(&self) -> bool {
681
        self.length == 0
682
    }
683

            
684
    pub fn args(&self) -> &T::Args<'a> {
685
        &self.args
686
    }
687

            
688
116962434
    pub fn read_item(&self, index: usize) -> Result<T::HostType<'a>, ParseError> {
689
116962434
        if index < self.length {
690
116962434
            let size = T::size(self.args);
691
116962434
            let offset = index * size;
692
116962434
            let scope = self.scope.offset_length(offset, size).unwrap();
693
116962434
            let mut ctxt = scope.ctxt();
694
116962434
            T::read_dep(&mut ctxt, self.args)
695
        } else {
696
            Err(ParseError::BadIndex)
697
        }
698
116962434
    }
699

            
700
23236524
    pub fn get_item(&self, index: usize) -> Option<<T as ReadUnchecked>::HostType>
701
23236524
    where
702
23236524
        T: ReadUnchecked,
703
    {
704
23236524
        if index < self.length {
705
23175018
            let offset = index * self.stride;
706
23175018
            let scope = self.scope.offset_length(offset, self.stride).unwrap();
707
23175018
            let mut ctxt = scope.ctxt();
708
23175018
            Some(unsafe { T::read_unchecked(&mut ctxt) }) // Safe because we have `SIZE` bytes available.
709
        } else {
710
61506
            None
711
        }
712
23236524
    }
713

            
714
    pub fn last(&self) -> Option<<T as ReadUnchecked>::HostType>
715
    where
716
        T: ReadUnchecked,
717
    {
718
        let index = self.length.checked_sub(1)?;
719
        self.get_item(index)
720
    }
721

            
722
2885826
    pub fn to_vec(&self) -> Vec<<T as ReadUnchecked>::HostType>
723
2885826
    where
724
2885826
        T: ReadUnchecked,
725
    {
726
2885826
        let mut vec = Vec::with_capacity(self.length);
727
51118267
        for t in self.iter() {
728
51118267
            vec.push(t);
729
51118267
        }
730
2885826
        vec
731
2885826
    }
732

            
733
5489802
    pub fn read_to_vec(&self) -> Result<Vec<T::HostType<'a>>, ParseError> {
734
5489802
        let mut vec = Vec::with_capacity(self.length);
735
116962434
        for res in self.iter_res() {
736
116962434
            let t = res?;
737
116962434
            vec.push(t);
738
        }
739
5489802
        Ok(vec)
740
5489802
    }
741

            
742
3672660
    pub fn iter(&self) -> ReadArrayIter<'a, T>
743
3672660
    where
744
3672660
        T: ReadUnchecked,
745
    {
746
3672660
        ReadArrayIter {
747
3672660
            scope: self.scope,
748
3672660
            index: 0,
749
3672660
            end: self.length,
750
3672660
            stride: self.stride,
751
3672660
            phantom: PhantomData,
752
3672660
        }
753
3672660
    }
754

            
755
5489802
    pub fn iter_res<'b>(&'b self) -> ReadArrayDepIter<'a, 'b, T> {
756
5489802
        ReadArrayDepIter {
757
5489802
            array: self,
758
5489802
            index: 0,
759
5489802
        }
760
5489802
    }
761

            
762
    // This is derived from the function on slice in the standard library
763
35964
    pub fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize>
764
35964
    where
765
35964
        F: FnMut(<T as ReadUnchecked>::HostType) -> Ordering,
766
35964
        T: ReadUnchecked,
767
    {
768
        // INVARIANTS:
769
        // - 0 <= left <= left + size = right <= self.len()
770
        // - f returns Less for everything in self[..left]
771
        // - f returns Greater for everything in self[right..]
772
35964
        let mut size = self.len();
773
35964
        let mut left = 0;
774
35964
        let mut right = size;
775
100980
        while left < right {
776
65124
            let mid = left + size / 2;
777

            
778
65124
            let offset = mid * self.stride;
779
            // NOTE(unwrap): the while condition means `size` is strictly positive, so
780
            // `size/2 < size`. Thus `left + size/2 < left + size`, which
781
            // coupled with the `left + size <= self.len()` invariant means
782
            // we have `left + size/2 < self.len()`, and this is in-bounds.
783
65124
            let scope = self.scope.offset_length(offset, self.stride).unwrap();
784
65124
            let mut ctxt = scope.ctxt();
785
            // SAFTEY: Safe because we have checked that we have `SIZE` bytes available in the
786
            // offset_length call.
787
65124
            let cmp = f(unsafe { T::read_unchecked(&mut ctxt) });
788
            // let cmp = f(unsafe { self.get_unchecked(mid) });
789

            
790
            // The reason why we use if/else control flow rather than match
791
            // is because match reorders comparison operations, which is perf sensitive.
792
            // This is x86 asm for u8: https://rust.godbolt.org/z/8Y8Pra.
793
65124
            if cmp == Ordering::Less {
794
6750
                left = mid + 1;
795
58374
            } else if cmp == Ordering::Greater {
796
58266
                right = mid;
797
58266
            } else {
798
108
                return Ok(mid);
799
            }
800

            
801
65016
            size = right - left;
802
        }
803

            
804
35856
        Err(left)
805
35964
    }
806
}
807

            
808
impl<T: ReadFixedSizeDep> CheckIndex for ReadArray<'_, T> {
809
    fn check_index(&self, index: usize) -> Result<(), ParseError> {
810
        if index < self.len() {
811
            Ok(())
812
        } else {
813
            Err(ParseError::BadIndex)
814
        }
815
    }
816
}
817

            
818
impl<T> CheckIndex for Vec<T> {
819
513000
    fn check_index(&self, index: usize) -> Result<(), ParseError> {
820
513000
        if index < self.len() {
821
513000
            Ok(())
822
        } else {
823
            Err(ParseError::BadIndex)
824
        }
825
513000
    }
826
}
827

            
828
impl<'a, T: ReadUnchecked> IntoIterator for &ReadArray<'a, T> {
829
    type Item = T::HostType;
830
    type IntoIter = ReadArrayIter<'a, T>;
831
721062
    fn into_iter(self) -> ReadArrayIter<'a, T> {
832
721062
        self.iter()
833
721062
    }
834
}
835

            
836
impl<T: ReadUnchecked> Iterator for ReadArrayIter<'_, T> {
837
    type Item = T::HostType;
838

            
839
60633187
    fn next(&mut self) -> Option<T::HostType> {
840
        // From the docs:
841
        // It is important to note that both back and forth work on the same range,
842
        // and do not cross: iteration is over when they meet in the middle.
843
60633187
        if self.index >= self.end {
844
3627732
            return None;
845
57005455
        }
846
57005455
        let mut ctxt = self.scope.offset(self.index * self.stride).ctxt();
847
57005455
        ctxt.check_avail(self.stride).ok()?;
848
        // SAFETY: Ok because we have (at least) `stride` bytes available and T::SIZE is <= stride.
849
57005455
        self.index += 1;
850
57005455
        Some(unsafe { T::read_unchecked(&mut ctxt) })
851
60633187
    }
852

            
853
    fn size_hint(&self) -> (usize, Option<usize>) {
854
        let remaining = self.scope.data().len() / self.stride;
855
        (remaining, Some(remaining))
856
    }
857
}
858

            
859
impl<T: ReadUnchecked> DoubleEndedIterator for ReadArrayIter<'_, T> {
860
    fn next_back(&mut self) -> Option<T::HostType> {
861
        let index = self.end.checked_sub(1)?;
862
        // From the docs:
863
        // It is important to note that both back and forth work on the same range,
864
        // and do not cross: iteration is over when they meet in the middle.
865
        if index < self.index {
866
            return None;
867
        }
868
        let mut ctxt = self.scope.offset(index * self.stride).ctxt();
869
        ctxt.check_avail(self.stride).ok()?;
870
        // SAFETY: Ok because we have (at least) `stride` bytes available and T::SIZE is <= stride.
871
        self.end -= 1;
872
        Some(unsafe { T::read_unchecked(&mut ctxt) })
873
    }
874
}
875

            
876
impl<T: ReadUnchecked> ExactSizeIterator for ReadArrayIter<'_, T> {}
877

            
878
impl<'a, 'b, T: ReadUnchecked> IntoIterator for &'b ReadArrayCow<'a, T>
879
where
880
    T::HostType: Copy,
881
{
882
    type Item = T::HostType;
883
    type IntoIter = ReadArrayCowIter<'a, 'b, T>;
884

            
885
    fn into_iter(self) -> ReadArrayCowIter<'a, 'b, T> {
886
        self.iter()
887
    }
888
}
889

            
890
impl<T: ReadUnchecked> Iterator for ReadArrayCowIter<'_, '_, T>
891
where
892
    T::HostType: Copy,
893
{
894
    type Item = T::HostType;
895

            
896
    fn next(&mut self) -> Option<T::HostType> {
897
        let item = self.array.get_item(self.index)?;
898
        self.index += 1;
899
        Some(item)
900
    }
901

            
902
    fn size_hint(&self) -> (usize, Option<usize>) {
903
        if self.index < self.array.len() {
904
            let length = self.array.len() - self.index;
905
            (length, Some(length))
906
        } else {
907
            (0, Some(0))
908
        }
909
    }
910
}
911

            
912
impl<'a, T: ReadFixedSizeDep> Iterator for ReadArrayDepIter<'a, '_, T> {
913
    type Item = Result<T::HostType<'a>, ParseError>;
914

            
915
122452236
    fn next(&mut self) -> Option<Result<T::HostType<'a>, ParseError>> {
916
122452236
        if self.index < self.array.len() {
917
116962434
            let result = self.array.read_item(self.index);
918
116962434
            self.index += 1;
919
116962434
            Some(result)
920
        } else {
921
5489802
            None
922
        }
923
122452236
    }
924

            
925
    fn size_hint(&self) -> (usize, Option<usize>) {
926
        if self.index < self.array.len() {
927
            let length = self.array.len() - self.index;
928
            (length, Some(length))
929
        } else {
930
            (0, Some(0))
931
        }
932
    }
933
}
934

            
935
impl<'a, T: ReadUnchecked> ReadArray<'a, T> {
936
    pub fn empty() -> ReadArray<'a, T> {
937
        ReadArray {
938
            scope: ReadScope::new(&[]),
939
            length: 0,
940
            stride: T::SIZE,
941
            args: (),
942
        }
943
    }
944
}
945

            
946
impl ReadUnchecked for U8 {
947
    type HostType = u8;
948

            
949
    const SIZE: usize = size::U8;
950

            
951
3966840
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> u8 {
952
3966840
        ctxt.read_unchecked_u8()
953
3966840
    }
954
}
955

            
956
impl ReadUnchecked for I8 {
957
    type HostType = i8;
958

            
959
    const SIZE: usize = size::I8;
960

            
961
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> i8 {
962
        ctxt.read_unchecked_i8()
963
    }
964
}
965

            
966
impl ReadUnchecked for U16Be {
967
    type HostType = u16;
968

            
969
    const SIZE: usize = size::U16;
970

            
971
92182914
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> u16 {
972
92182914
        ctxt.read_unchecked_u16be()
973
92182914
    }
974
}
975

            
976
impl ReadUnchecked for I16Be {
977
    type HostType = i16;
978

            
979
    const SIZE: usize = size::I16;
980

            
981
6601068
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> i16 {
982
6601068
        ctxt.read_unchecked_i16be()
983
6601068
    }
984
}
985

            
986
impl ReadUnchecked for U24Be {
987
    type HostType = u32;
988

            
989
    const SIZE: usize = size::U24;
990

            
991
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> u32 {
992
        ctxt.read_unchecked_u24be()
993
    }
994
}
995

            
996
impl ReadUnchecked for U32Be {
997
    type HostType = u32;
998

            
999
    const SIZE: usize = size::U32;
21570894
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> u32 {
21570894
        ctxt.read_unchecked_u32be()
21570894
    }
}
impl ReadUnchecked for I32Be {
    type HostType = i32;
    const SIZE: usize = size::I32;
58104
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> i32 {
58104
        ctxt.read_unchecked_i32be()
58104
    }
}
impl ReadUnchecked for U64Be {
    type HostType = u64;
    const SIZE: usize = size::U64;
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> u64 {
        ctxt.read_unchecked_u64be()
    }
}
impl ReadUnchecked for I64Be {
    type HostType = i64;
    const SIZE: usize = size::I64;
116208
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> i64 {
116208
        ctxt.read_unchecked_i64be()
116208
    }
}
impl<T1, T2> ReadUnchecked for (T1, T2)
where
    T1: ReadUnchecked,
    T2: ReadUnchecked,
{
    type HostType = (T1::HostType, T2::HostType);
    const SIZE: usize = T1::SIZE + T2::SIZE;
887598
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> Self::HostType {
887598
        let t1 = T1::read_unchecked(ctxt);
887598
        let t2 = T2::read_unchecked(ctxt);
887598
        (t1, t2)
887598
    }
}
impl<T1, T2, T3> ReadUnchecked for (T1, T2, T3)
where
    T1: ReadUnchecked,
    T2: ReadUnchecked,
    T3: ReadUnchecked,
{
    type HostType = (T1::HostType, T2::HostType, T3::HostType);
    const SIZE: usize = T1::SIZE + T2::SIZE + T3::SIZE;
18537930
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> Self::HostType {
18537930
        let t1 = T1::read_unchecked(ctxt);
18537930
        let t2 = T2::read_unchecked(ctxt);
18537930
        let t3 = T3::read_unchecked(ctxt);
18537930
        (t1, t2, t3)
18537930
    }
}
impl<T1, T2, T3, T4> ReadUnchecked for (T1, T2, T3, T4)
where
    T1: ReadUnchecked,
    T2: ReadUnchecked,
    T3: ReadUnchecked,
    T4: ReadUnchecked,
{
    type HostType = (T1::HostType, T2::HostType, T3::HostType, T4::HostType);
    const SIZE: usize = T1::SIZE + T2::SIZE + T3::SIZE + T4::SIZE;
    unsafe fn read_unchecked(ctxt: &mut ReadCtxt<'_>) -> Self::HostType {
        let t1 = T1::read_unchecked(ctxt);
        let t2 = T2::read_unchecked(ctxt);
        let t3 = T3::read_unchecked(ctxt);
        let t4 = T4::read_unchecked(ctxt);
        (t1, t2, t3, t4)
    }
}
impl<T> fmt::Debug for ReadArrayCow<'_, T>
where
    T: ReadUnchecked,
    <T as ReadUnchecked>::HostType: Copy + fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        f.debug_list().entries(self.iter()).finish()
    }
}
impl<'a, T> fmt::Debug for ReadArray<'a, T>
where
    T: ReadFixedSizeDep,
    T::HostType<'a>: Copy + fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        let mut list = f.debug_list();
        for item in self.iter_res() {
            list.entry(&item.map_err(|_| fmt::Error)?);
        }
        list.finish()
    }
}
impl fmt::Debug for DebugData<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "[<{} bytes>]", self.0.len())
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    use crate::binary::write::{WriteBuffer, WriteContext};
    #[test]
    fn test_read_u24be() {
        let scope = ReadScope::new(&[1, 2, 3]);
        assert_eq!(scope.read::<U24Be>().unwrap(), 0x10203);
    }
    // Tests that offset_length does not panic when length is 0 but offset is out-of-bounds
    #[test]
    fn test_offset_length_oob() {
        let scope = ReadScope::new(&[1, 2, 3]);
        assert!(scope.offset_length(99, 0).is_ok());
    }
    #[test]
    fn double_ended_read_array_iter() {
        let numbers = [1i32, 2, 3, 4, 5, 6];
        let mut w = WriteBuffer::new();
        w.write_iter::<I32Be, _>(numbers.iter().copied()).unwrap();
        let data = w.into_inner();
        let array = ReadScope::new(&data).ctxt().read_array::<I32Be>(6).unwrap();
        let mut iter = array.iter();
        assert_eq!(Some(1), iter.next());
        assert_eq!(Some(6), iter.next_back());
        assert_eq!(Some(5), iter.next_back());
        assert_eq!(Some(2), iter.next());
        assert_eq!(Some(3), iter.next());
        assert_eq!(Some(4), iter.next());
        assert_eq!(None, iter.next());
        assert_eq!(None, iter.next_back());
    }
}