1
- use core:: convert:: TryInto ;
2
1
use core:: convert:: TryFrom ;
2
+ use core:: convert:: TryInto ;
3
3
4
4
#[ allow( missing_docs) ]
5
5
pub struct Bytes < ' a > {
@@ -41,19 +41,27 @@ impl<'a> Bytes<'a> {
41
41
}
42
42
}
43
43
44
- #[ inline]
45
- pub fn peek_ahead ( & self , n : usize ) -> Option < u8 > {
46
- // SAFETY: obtain a potentially OOB pointer that is later compared against the `self.end`
47
- // pointer.
48
- let ptr = self . cursor . wrapping_add ( n) ;
49
- if ptr < self . end {
50
- // SAFETY: bounds checked pointer dereference is safe
51
- Some ( unsafe { * ptr } )
44
+ /// Peek at byte `n` ahead of cursor
45
+ ///
46
+ /// # Safety
47
+ ///
48
+ /// Caller must ensure that `n <= self.len()`, otherwise `self.cursor.add(n)` is UB.
49
+ /// That means there are at least `n-1` bytes between `self.cursor` and `self.end`
50
+ /// and `self.cursor.add(n)` is either `self.end` or points to a valid byte.
51
+ #[ inline]
52
+ pub unsafe fn peek_ahead ( & self , n : usize ) -> Option < u8 > {
53
+ debug_assert ! ( n <= self . len( ) ) ;
54
+ // SAFETY: by preconditions
55
+ let p = unsafe { self . cursor . add ( n) } ;
56
+ if p < self . end {
57
+ // SAFETY: by preconditions, if this is not `self.end`,
58
+ // then it is safe to dereference
59
+ Some ( unsafe { * p } )
52
60
} else {
53
61
None
54
62
}
55
63
}
56
-
64
+
57
65
#[ inline]
58
66
pub fn peek_n < ' b : ' a , U : TryFrom < & ' a [ u8 ] > > ( & ' b self , n : usize ) -> Option < U > {
59
67
// TODO: once we bump MSRC, use const generics to allow only [u8; N] reads
@@ -65,7 +73,7 @@ impl<'a> Bytes<'a> {
65
73
/// Advance by 1, equivalent to calling `advance(1)`.
66
74
///
67
75
/// # Safety
68
- ///
76
+ ///
69
77
/// Caller must ensure that Bytes hasn't been advanced/bumped by more than [`Bytes::len()`].
70
78
#[ inline]
71
79
pub unsafe fn bump ( & mut self ) {
@@ -75,7 +83,7 @@ impl<'a> Bytes<'a> {
75
83
/// Advance cursor by `n`
76
84
///
77
85
/// # Safety
78
- ///
86
+ ///
79
87
/// Caller must ensure that Bytes hasn't been advanced/bumped by more than [`Bytes::len()`].
80
88
#[ inline]
81
89
pub unsafe fn advance ( & mut self , n : usize ) {
@@ -104,7 +112,7 @@ impl<'a> Bytes<'a> {
104
112
// TODO: this is an anti-pattern, should be removed
105
113
/// Deprecated. Do not use!
106
114
/// # Safety
107
- ///
115
+ ///
108
116
/// Caller must ensure that `skip` is at most the number of advances (i.e., `bytes.advance(3)`
109
117
/// implies a skip of at most 3).
110
118
#[ inline]
@@ -114,21 +122,21 @@ impl<'a> Bytes<'a> {
114
122
self . commit ( ) ;
115
123
head
116
124
}
117
-
125
+
118
126
#[ inline]
119
127
pub fn commit ( & mut self ) {
120
128
self . start = self . cursor
121
129
}
122
130
123
131
/// # Safety
124
- ///
132
+ ///
125
133
/// see [`Bytes::advance`] safety comment.
126
134
#[ inline]
127
135
pub unsafe fn advance_and_commit ( & mut self , n : usize ) {
128
136
self . advance ( n) ;
129
137
self . commit ( ) ;
130
138
}
131
-
139
+
132
140
#[ inline]
133
141
pub fn as_ptr ( & self ) -> * const u8 {
134
142
self . cursor
@@ -138,14 +146,14 @@ impl<'a> Bytes<'a> {
138
146
pub fn start ( & self ) -> * const u8 {
139
147
self . start
140
148
}
141
-
149
+
142
150
#[ inline]
143
151
pub fn end ( & self ) -> * const u8 {
144
152
self . end
145
153
}
146
-
154
+
147
155
/// # Safety
148
- ///
156
+ ///
149
157
/// Must ensure invariant `bytes.start() <= ptr && ptr <= bytes.end()`.
150
158
#[ inline]
151
159
pub unsafe fn set_cursor ( & mut self , ptr : * const u8 ) {
0 commit comments