• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tox-rs / tox / 5022320978

pending completion
5022320978

push

github

GitHub
Merge pull request #474 from tox-rs/fmt

3424 of 3424 new or added lines in 108 files covered. (100.0%)

16739 of 17643 relevant lines covered (94.88%)

1.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.87
/tox_core/src/net_crypto/packets_array.rs
1
/*! The implementation of packets buffer
2
*/
3

4
use std::iter;
5

6
use crate::net_crypto::errors::*;
7

8
/// Maximum size of receiving and sending packet buffers.
9
///
10
/// Must be a power of 2. The reason of this requirement is that `buffer_start`
11
/// and `buffer_end` indexes are unsigned 32 integers and might be overflowed.
12
/// When overflow happens the buffer should be used from the beginning but it's
13
/// possible only if `u32::MAX` is divided by buffer size, i.e. buffer size is a
14
/// power of 2.
15
pub const CRYPTO_PACKET_BUFFER_SIZE: u32 = 32768;
16

17
/// Calculate real index in the buffer by the packet index
18
fn real_index(index: u32) -> usize {
1✔
19
    (index % CRYPTO_PACKET_BUFFER_SIZE) as usize
1✔
20
}
21

22
/// Deque-like struct for packets queue that allows random writings by the
23
/// packet index
24
#[derive(Clone, Debug, Eq, PartialEq)]
25
pub struct PacketsArray<T> {
26
    /// Packets buffer of `CRYPTO_PACKET_BUFFER_SIZE` length
27
    pub buffer: Vec<Option<Box<T>>>,
28
    /// Start packet index.
29
    ///
30
    /// Can be any `u32` value regardless of the buffer size. Real index is
31
    /// calculated via `real_index` function.
32
    pub buffer_start: u32,
33
    /// End packet index.
34
    ///
35
    /// Can be any `u32` value regardless of the buffer size. Real index is
36
    /// calculated via `real_index` function.
37
    pub buffer_end: u32,
38
}
39

40
impl<T: Clone> Default for PacketsArray<T> {
41
    fn default() -> Self {
×
42
        PacketsArray::new()
×
43
    }
44
}
45

46
impl<T: Clone> PacketsArray<T> {
47
    /// Create new `PacketsArray`
48
    pub fn new() -> PacketsArray<T> {
3✔
49
        PacketsArray {
50
            buffer: iter::repeat(None).take(CRYPTO_PACKET_BUFFER_SIZE as usize).collect(),
3✔
51
            buffer_start: 0,
52
            buffer_end: 0,
53
        }
54
    }
55
}
56

57
impl<T> PacketsArray<T> {
58
    /// Get difference between end and start indices of stored packets in this
59
    /// array.
60
    ///
61
    /// This value is equal to known gap between sent by one side and received
62
    /// by other side packets. Also note that this value is not necessary equal
63
    /// to count of packets that are stored in this array because packets are
64
    /// not necessary stored sequentially.
65
    pub fn len(&self) -> u32 {
3✔
66
        self.buffer_end.overflowing_sub(self.buffer_start).0
3✔
67
    }
68

69
    /// Insert packet to the array by its index
70
    ///
71
    /// Returns an error when index is too far and buffer can't hold it or when
72
    /// packet with this index already exists
73
    pub fn insert(&mut self, index: u32, packet: T) -> Result<(), PacketsArrayError> {
3✔
74
        if index.overflowing_sub(self.buffer_start).0 >= CRYPTO_PACKET_BUFFER_SIZE {
6✔
75
            return Err(PacketsArrayError::too_big(index));
2✔
76
        }
77

78
        let i = real_index(index);
6✔
79

80
        if self.buffer[i].is_some() {
3✔
81
            return Err(PacketsArrayError::already_exist(index));
1✔
82
        }
83

84
        self.buffer[i] = Some(Box::new(packet));
6✔
85
        if index.overflowing_sub(self.buffer_start).0 >= self.len() {
9✔
86
            self.buffer_end = index.overflowing_add(1).0;
3✔
87
        }
88

89
        Ok(())
3✔
90
    }
91

92
    /// Write packet at the end index and increment this index
93
    ///
94
    /// Returns an error when the buffer is full
95
    pub fn push_back(&mut self, packet: T) -> Result<(), PacketsArrayError> {
2✔
96
        if self.len() == CRYPTO_PACKET_BUFFER_SIZE {
4✔
97
            return Err(PacketsArrayError::ArrayFull);
1✔
98
        }
99

100
        self.buffer[real_index(self.buffer_end)] = Some(Box::new(packet));
4✔
101
        self.buffer_end = self.buffer_end.overflowing_add(1).0;
4✔
102

103
        Ok(())
2✔
104
    }
105

106
    /// Get packet at the start index and increment index if the packet exists
107
    pub fn pop_front(&mut self) -> Option<T> {
2✔
108
        if self.buffer_start == self.buffer_end {
2✔
109
            return None;
2✔
110
        }
111

112
        let i = real_index(self.buffer_start);
2✔
113
        let result = self.buffer[i].take();
2✔
114
        if result.is_some() {
6✔
115
            self.buffer_start = self.buffer_start.overflowing_add(1).0;
4✔
116
        };
117
        result.map(|packet| *packet)
7✔
118
    }
119

120
    /// Check if packet the index exists
121
    pub fn contains(&self, index: u32) -> bool {
2✔
122
        let len = self.len();
2✔
123

124
        if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len {
6✔
125
            return false;
1✔
126
        }
127

128
        self.buffer[real_index(index)].is_some()
2✔
129
    }
130

131
    /// Get reference to the packet by its index
132
    pub fn get(&self, index: u32) -> Option<&T> {
2✔
133
        let len = self.len();
2✔
134

135
        if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len {
6✔
136
            return None;
2✔
137
        }
138

139
        self.buffer[real_index(index)].as_deref()
2✔
140
    }
141

142
    /// Get mutable reference to the packet by its index
143
    pub fn get_mut(&mut self, index: u32) -> Option<&mut T> {
2✔
144
        let len = self.len();
2✔
145

146
        if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len {
6✔
147
            return None;
1✔
148
        }
149

150
        self.buffer[real_index(index)].as_deref_mut()
2✔
151
    }
152

153
    /// Remove packet by its index and return it if it was previously in the
154
    /// array
155
    pub fn remove(&mut self, index: u32) -> Option<T> {
2✔
156
        let len = self.len();
2✔
157

158
        if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len {
6✔
159
            return None;
1✔
160
        }
161

162
        self.buffer[real_index(index)].take().map(|packet| *packet)
6✔
163
    }
164

165
    /// Set end index when it gets known
166
    ///
167
    /// Returns an error when index is too far and buffer can't hold it or when
168
    /// index is lower then end index
169
    pub fn set_buffer_end(&mut self, index: u32) -> Result<(), PacketsArrayError> {
2✔
170
        if index.overflowing_sub(self.buffer_start).0 > CRYPTO_PACKET_BUFFER_SIZE {
4✔
171
            return Err(PacketsArrayError::too_big(index));
1✔
172
        }
173

174
        if index.overflowing_sub(self.buffer_end).0 > CRYPTO_PACKET_BUFFER_SIZE {
4✔
175
            return Err(PacketsArrayError::lower_index(index));
1✔
176
        }
177

178
        self.buffer_end = index;
2✔
179

180
        Ok(())
2✔
181
    }
182

183
    /// Set start index removing all packet before this index
184
    ///
185
    /// Returns an error when index is outside of buffer bounds
186
    pub fn set_buffer_start(&mut self, index: u32) -> Result<(), PacketsArrayError> {
2✔
187
        let len = self.len();
2✔
188

189
        if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 > len {
6✔
190
            return Err(PacketsArrayError::outside_index(index));
2✔
191
        }
192

193
        for packet in &mut self.buffer[real_index(self.buffer_start)..real_index(index)] {
8✔
194
            *packet = None;
4✔
195
        }
196

197
        self.buffer_start = index;
2✔
198

199
        Ok(())
2✔
200
    }
201

202
    /// Get mutable iterator over all stored packets with their index.
203
    pub fn iter_mut(&mut self) -> impl Iterator<Item = (u32, &mut T)> {
2✔
204
        let buffer_start = self.buffer_start;
2✔
205
        let start = real_index(buffer_start);
2✔
206
        let end = real_index(self.buffer_end);
2✔
207
        let iter = if start > end {
2✔
208
            let (first, second) = self.buffer.split_at_mut(start);
1✔
209
            second.iter_mut().chain(first.iter_mut().take(end))
1✔
210
        } else {
211
            [].iter_mut().chain(self.buffer[start..].iter_mut().take(end - start))
4✔
212
        };
213
        iter.enumerate().flat_map(move |(i, packet)| {
6✔
214
            packet
4✔
215
                .iter_mut()
×
216
                .map(move |packet| (buffer_start.overflowing_add(i as u32).0, &mut **packet))
8✔
217
        })
218
    }
219
}
220

221
#[cfg(test)]
222
mod tests {
223
    use super::*;
224

225
    #[test]
226
    fn len() {
3✔
227
        let mut array = PacketsArray::<()>::new();
1✔
228
        assert_eq!(array.len(), 0);
2✔
229
        array.buffer_end = 1;
1✔
230
        assert_eq!(array.len(), 1);
2✔
231
        array.buffer_start = u32::max_value();
1✔
232
        assert_eq!(array.len(), 2);
1✔
233
    }
234

235
    #[test]
236
    fn insert() {
3✔
237
        let mut array = PacketsArray::<()>::new();
1✔
238
        assert!(array.insert(0, ()).is_ok());
2✔
239
        assert_eq!(array.buffer_start, 0);
1✔
240
        assert_eq!(array.buffer_end, 1);
1✔
241
        assert!(array.get(0).is_some());
2✔
242
        assert!(array.get(1).is_none());
2✔
243
        assert!(array.insert(7, ()).is_ok());
2✔
244
        assert_eq!(array.buffer_start, 0);
1✔
245
        assert_eq!(array.buffer_end, 8);
1✔
246
        assert!(array.get(7).is_some());
2✔
247
        assert!(array.get(6).is_none());
2✔
248
        assert!(array.get(8).is_none());
2✔
249
    }
250

251
    #[test]
252
    fn insert_exists() {
3✔
253
        let mut array = PacketsArray::<()>::new();
1✔
254
        assert!(array.insert(7, ()).is_ok());
2✔
255
        let res = array.insert(7, ());
2✔
256
        assert!(res.is_err());
1✔
257
        assert_eq!(res.err().unwrap(), PacketsArrayError::AlreadyExist { index: 7 });
2✔
258
        assert!(array.insert(6, ()).is_ok());
2✔
259
        assert!(array.insert(8, ()).is_ok());
2✔
260
    }
261

262
    #[test]
263
    fn insert_too_big_index() {
3✔
264
        let mut array = PacketsArray::<()>::new();
1✔
265
        let res = array.insert(CRYPTO_PACKET_BUFFER_SIZE, ());
2✔
266
        assert!(res.is_err());
1✔
267
        assert_eq!(
1✔
268
            res.err().unwrap(),
2✔
269
            PacketsArrayError::TooBig {
270
                index: CRYPTO_PACKET_BUFFER_SIZE
271
            }
272
        );
273
        assert_eq!(array.buffer_start, 0);
1✔
274
        assert_eq!(array.buffer_end, 0);
1✔
275
        array.buffer_start = u32::max_value();
1✔
276
        let res = array.insert(CRYPTO_PACKET_BUFFER_SIZE - 1, ());
1✔
277
        assert!(res.is_err());
1✔
278
        assert_eq!(
1✔
279
            res.err().unwrap(),
2✔
280
            PacketsArrayError::TooBig {
281
                index: CRYPTO_PACKET_BUFFER_SIZE - 1
282
            }
283
        );
284
        assert_eq!(array.buffer_start, u32::max_value());
1✔
285
        assert_eq!(array.buffer_end, 0);
1✔
286
    }
287

288
    #[test]
289
    fn push_back() {
3✔
290
        let mut array = PacketsArray::<()>::new();
1✔
291
        assert!(array.push_back(()).is_ok());
2✔
292
        assert_eq!(array.buffer_start, 0);
1✔
293
        assert_eq!(array.buffer_end, 1);
1✔
294
        assert!(array.get(0).is_some());
2✔
295
    }
296

297
    #[test]
298
    fn push_back_overflow() {
3✔
299
        let mut array = PacketsArray::<()>::new();
1✔
300
        array.buffer_start = u32::max_value();
1✔
301
        array.buffer_end = u32::max_value();
1✔
302
        assert!(array.push_back(()).is_ok());
1✔
303
        assert_eq!(array.buffer_start, u32::max_value());
1✔
304
        assert_eq!(array.buffer_end, 0);
1✔
305
        assert!(array.get(u32::max_value()).is_some());
1✔
306
    }
307

308
    #[test]
309
    fn push_back_full() {
3✔
310
        let mut array = PacketsArray::<()>::new();
1✔
311
        array.buffer_end = CRYPTO_PACKET_BUFFER_SIZE;
1✔
312
        let res = array.push_back(());
2✔
313
        assert!(res.is_err());
1✔
314
        assert_eq!(res.err().unwrap(), PacketsArrayError::ArrayFull);
2✔
315
        assert_eq!(array.buffer_start, 0);
1✔
316
        assert_eq!(array.buffer_end, CRYPTO_PACKET_BUFFER_SIZE);
1✔
317
    }
318

319
    #[test]
320
    fn pop_front_some() {
3✔
321
        let mut array = PacketsArray::<()>::new();
1✔
322
        assert!(array.push_back(()).is_ok());
2✔
323
        assert!(array.pop_front().is_some());
2✔
324
        assert_eq!(array.buffer_start, 1);
1✔
325
        assert_eq!(array.buffer_end, 1);
1✔
326
        assert!(array.get(0).is_none());
2✔
327
    }
328

329
    #[test]
330
    fn pop_front_none() {
3✔
331
        let mut array = PacketsArray::<()>::new();
1✔
332
        array.buffer_end = 1;
1✔
333
        assert!(array.pop_front().is_none());
2✔
334
        assert_eq!(array.buffer_start, 0);
1✔
335
        assert_eq!(array.buffer_end, 1);
1✔
336
    }
337

338
    #[test]
339
    fn pop_front_empty() {
3✔
340
        let mut array = PacketsArray::<()>::new();
1✔
341
        assert!(array.pop_front().is_none());
2✔
342
        assert_eq!(array.buffer_start, 0);
1✔
343
        assert_eq!(array.buffer_end, 0);
1✔
344
    }
345

346
    #[test]
347
    fn contains() {
3✔
348
        let mut array = PacketsArray::<()>::new();
1✔
349
        assert!(array.push_back(()).is_ok());
2✔
350
        assert!(array.contains(0));
2✔
351
        assert!(!array.contains(1));
2✔
352
        assert!(!array.contains(2));
2✔
353
    }
354

355
    #[test]
356
    fn get() {
3✔
357
        let mut array = PacketsArray::<()>::new();
1✔
358
        assert!(array.push_back(()).is_ok());
2✔
359
        assert!(array.get(0).is_some());
2✔
360
        assert!(array.get(1).is_none());
2✔
361
        assert!(array.get(2).is_none());
2✔
362
    }
363

364
    #[test]
365
    fn get_mut() {
3✔
366
        let mut array = PacketsArray::<()>::new();
1✔
367
        assert!(array.push_back(()).is_ok());
2✔
368
        assert!(array.get_mut(0).is_some());
2✔
369
        assert!(array.get_mut(1).is_none());
2✔
370
        assert!(array.get_mut(2).is_none());
2✔
371
    }
372

373
    #[test]
374
    fn remove() {
3✔
375
        let mut array = PacketsArray::<()>::new();
1✔
376
        assert!(array.push_back(()).is_ok());
2✔
377
        assert!(array.remove(0).is_some());
2✔
378
        assert!(array.remove(0).is_none());
2✔
379
        assert!(array.remove(1).is_none());
2✔
380
        assert!(array.remove(2).is_none());
2✔
381
        assert!(array.get(0).is_none());
2✔
382
        assert_eq!(array.buffer_start, 0);
1✔
383
        assert_eq!(array.buffer_end, 1);
1✔
384
    }
385

386
    #[test]
387
    fn set_buffer_end() {
3✔
388
        let mut array = PacketsArray::<()>::new();
1✔
389
        assert!(array.set_buffer_end(7).is_ok());
2✔
390
        assert_eq!(array.buffer_start, 0);
1✔
391
        assert_eq!(array.buffer_end, 7);
1✔
392
        assert!(array.set_buffer_end(CRYPTO_PACKET_BUFFER_SIZE).is_ok());
2✔
393
        assert_eq!(array.buffer_start, 0);
1✔
394
        assert_eq!(array.buffer_end, CRYPTO_PACKET_BUFFER_SIZE);
1✔
395
    }
396

397
    #[test]
398
    fn set_buffer_end_too_big_index() {
3✔
399
        let mut array = PacketsArray::<()>::new();
1✔
400
        let res = array.set_buffer_end(CRYPTO_PACKET_BUFFER_SIZE + 1);
2✔
401
        assert!(res.is_err());
1✔
402
        assert_eq!(
1✔
403
            res.err().unwrap(),
2✔
404
            PacketsArrayError::TooBig {
405
                index: CRYPTO_PACKET_BUFFER_SIZE + 1
406
            }
407
        );
408
        assert_eq!(array.buffer_start, 0);
1✔
409
        assert_eq!(array.buffer_end, 0);
1✔
410
    }
411

412
    #[test]
413
    fn set_buffer_end_lower_than_end_index() {
3✔
414
        let mut array = PacketsArray::<()>::new();
1✔
415
        array.buffer_end = 7;
1✔
416
        let res = array.set_buffer_end(6);
2✔
417
        assert!(res.is_err());
1✔
418
        assert_eq!(res.err().unwrap(), PacketsArrayError::LowerIndex { index: 6 });
2✔
419
        assert_eq!(array.buffer_start, 0);
1✔
420
        assert_eq!(array.buffer_end, 7);
1✔
421
    }
422

423
    #[test]
424
    fn set_buffer_start() {
3✔
425
        let mut array = PacketsArray::<()>::new();
1✔
426
        assert!(array.push_back(()).is_ok());
2✔
427
        assert!(array.push_back(()).is_ok());
2✔
428
        assert!(array.set_buffer_start(1).is_ok());
2✔
429
        assert!(array.set_buffer_start(1).is_ok());
2✔
430
        assert!(array.get(0).is_none());
2✔
431
        assert!(array.get(1).is_some());
2✔
432
        assert_eq!(array.buffer_start, 1);
1✔
433
        assert_eq!(array.buffer_end, 2);
1✔
434
        assert!(array.set_buffer_start(2).is_ok());
2✔
435
        assert!(array.set_buffer_start(2).is_ok());
2✔
436
        assert!(array.get(0).is_none());
2✔
437
        assert!(array.get(1).is_none());
2✔
438
        assert_eq!(array.buffer_start, 2);
1✔
439
        assert_eq!(array.buffer_end, 2);
1✔
440
    }
441

442
    #[test]
443
    fn set_buffer_start_too_big_index() {
3✔
444
        let mut array = PacketsArray::<()>::new();
1✔
445
        let res = array.set_buffer_start(1);
2✔
446
        assert!(res.is_err());
1✔
447
        assert_eq!(res.err().unwrap(), PacketsArrayError::OutsideIndex { index: 1 });
2✔
448
        assert_eq!(array.buffer_start, 0);
1✔
449
        assert_eq!(array.buffer_end, 0);
1✔
450
    }
451

452
    #[test]
453
    fn set_buffer_start_lower_than_start_index() {
3✔
454
        let mut array = PacketsArray::<()>::new();
1✔
455
        array.buffer_start = 7;
1✔
456
        array.buffer_end = 7;
1✔
457
        let res = array.set_buffer_start(1);
2✔
458
        assert!(res.is_err());
1✔
459
        assert_eq!(res.err().unwrap(), PacketsArrayError::OutsideIndex { index: 1 });
2✔
460
        assert_eq!(array.buffer_start, 7);
1✔
461
        assert_eq!(array.buffer_end, 7);
1✔
462
    }
463

464
    #[test]
465
    fn iter_mut_empty() {
3✔
466
        let mut array = PacketsArray::<()>::new();
1✔
467
        assert!(array.iter_mut().next().is_none());
2✔
468
    }
469

470
    #[test]
471
    fn iter_mut_single_part() {
3✔
472
        let mut array = PacketsArray::<()>::new();
1✔
473
        assert!(array.insert(0, ()).is_ok());
2✔
474
        assert!(array.insert(2, ()).is_ok());
2✔
475
        assert!(array.insert(5, ()).is_ok());
2✔
476
        assert_eq!(array.iter_mut().map(|(i, _)| i).collect::<Vec<_>>(), vec![0, 2, 5]);
5✔
477
    }
478

479
    #[test]
480
    fn iter_mut_two_parts() {
3✔
481
        let mut array = PacketsArray::<()>::new();
1✔
482
        array.buffer_start = CRYPTO_PACKET_BUFFER_SIZE - 1;
1✔
483
        array.buffer_end = CRYPTO_PACKET_BUFFER_SIZE + 3;
1✔
484
        assert!(array.insert(CRYPTO_PACKET_BUFFER_SIZE - 1, ()).is_ok());
2✔
485
        assert!(array.insert(CRYPTO_PACKET_BUFFER_SIZE, ()).is_ok());
2✔
486
        assert!(array.insert(CRYPTO_PACKET_BUFFER_SIZE + 2, ()).is_ok());
2✔
487
        assert_eq!(
2✔
488
            array.iter_mut().map(|(i, _)| i).collect::<Vec<_>>(),
4✔
489
            vec![
2✔
490
                CRYPTO_PACKET_BUFFER_SIZE - 1,
491
                CRYPTO_PACKET_BUFFER_SIZE,
492
                CRYPTO_PACKET_BUFFER_SIZE + 2,
493
            ]
494
        );
495
    }
496
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc