@@ -5,6 +5,7 @@ use core::convert::TryFrom;
55pub struct Bytes < ' a > {
66 start : * const u8 ,
77 end : * const u8 ,
8+ /// INVARIANT: start <= cursor && cursor <= end
89 cursor : * const u8 ,
910 phantom : core:: marker:: PhantomData < & ' a ( ) > ,
1011}
@@ -14,6 +15,7 @@ impl<'a> Bytes<'a> {
1415 #[ inline]
1516 pub fn new ( slice : & ' a [ u8 ] ) -> Bytes < ' a > {
1617 let start = slice. as_ptr ( ) ;
18+ // SAFETY: obtain pointer to slice end; start points to slice start.
1719 let end = unsafe { start. add ( slice. len ( ) ) } ;
1820 let cursor = start;
1921 Bytes {
@@ -32,7 +34,7 @@ impl<'a> Bytes<'a> {
3234 #[ inline]
3335 pub fn peek ( & self ) -> Option < u8 > {
3436 if self . cursor < self . end {
35- // SAFETY: bounds checked
37+ // SAFETY: bounds checked
3638 Some ( unsafe { * self . cursor } )
3739 } else {
3840 None
@@ -41,9 +43,11 @@ impl<'a> Bytes<'a> {
4143
4244 #[ inline]
4345 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.
4448 let ptr = unsafe { self . cursor . add ( n) } ;
4549 if ptr < self . end {
46- // SAFETY: bounds checked
50+ // SAFETY: bounds checked pointer dereference is safe
4751 Some ( unsafe { * ptr } )
4852 } else {
4953 None
@@ -58,11 +62,21 @@ impl<'a> Bytes<'a> {
5862 self . as_ref ( ) . get ( ..n) ?. try_into ( ) . ok ( )
5963 }
6064
65+ /// Advance by 1, equivalent to calling `advance(1)`.
66+ ///
67+ /// # Safety
68+ ///
69+ /// Caller must ensure that Bytes hasn't been advanced/bumped by more than [`Bytes::len()`].
6170 #[ inline]
6271 pub unsafe fn bump ( & mut self ) {
6372 self . advance ( 1 )
6473 }
6574
75+ /// Advance cursor by `n`
76+ ///
77+ /// # Safety
78+ ///
79+ /// Caller must ensure that Bytes hasn't been advanced/bumped by more than [`Bytes::len()`].
6680 #[ inline]
6781 pub unsafe fn advance ( & mut self , n : usize ) {
6882 self . cursor = self . cursor . add ( n) ;
@@ -74,15 +88,25 @@ impl<'a> Bytes<'a> {
7488 self . end as usize - self . cursor as usize
7589 }
7690
91+ #[ inline]
92+ pub fn is_empty ( & self ) -> bool {
93+ self . len ( ) == 0
94+ }
95+
7796 #[ inline]
7897 pub fn slice ( & mut self ) -> & ' a [ u8 ] {
79- // not moving position at all, so it's safe
98+ // SAFETY: not moving position at all, so it's safe
8099 let slice = unsafe { slice_from_ptr_range ( self . start , self . cursor ) } ;
81100 self . commit ( ) ;
82101 slice
83102 }
84103
85104 // TODO: this is an anti-pattern, should be removed
105+ /// Deprecated. Do not use!
106+ /// # Safety
107+ ///
108+ /// Caller must ensure that `skip` is at most the number of advances (i.e., `bytes.advance(3)`
109+ /// implies a skip of at most 3).
86110 #[ inline]
87111 pub unsafe fn slice_skip ( & mut self , skip : usize ) -> & ' a [ u8 ] {
88112 debug_assert ! ( self . cursor. sub( skip) >= self . start) ;
@@ -96,6 +120,9 @@ impl<'a> Bytes<'a> {
96120 self . start = self . cursor
97121 }
98122
123+ /// # Safety
124+ ///
125+ /// see [`Bytes::advance`] safety comment.
99126 #[ inline]
100127 pub unsafe fn advance_and_commit ( & mut self , n : usize ) {
101128 self . advance ( n) ;
@@ -117,6 +144,9 @@ impl<'a> Bytes<'a> {
117144 self . end
118145 }
119146
147+ /// # Safety
148+ ///
149+ /// Must ensure invariant `bytes.start() <= ptr && ptr <= bytes.end()`.
120150 #[ inline]
121151 pub unsafe fn set_cursor ( & mut self , ptr : * const u8 ) {
122152 debug_assert ! ( ptr >= self . start) ;
@@ -128,10 +158,14 @@ impl<'a> Bytes<'a> {
128158impl < ' a > AsRef < [ u8 ] > for Bytes < ' a > {
129159 #[ inline]
130160 fn as_ref ( & self ) -> & [ u8 ] {
161+ // SAFETY: not moving position at all, so it's safe
131162 unsafe { slice_from_ptr_range ( self . cursor , self . end ) }
132163 }
133164}
134165
166+ /// # Safety
167+ ///
168+ /// Must ensure start and end point to the same memory object to uphold memory safety.
135169#[ inline]
136170unsafe fn slice_from_ptr_range < ' a > ( start : * const u8 , end : * const u8 ) -> & ' a [ u8 ] {
137171 debug_assert ! ( start <= end) ;
@@ -144,7 +178,7 @@ impl<'a> Iterator for Bytes<'a> {
144178 #[ inline]
145179 fn next ( & mut self ) -> Option < u8 > {
146180 if self . cursor < self . end {
147- // SAFETY: bounds checked
181+ // SAFETY: bounds checked dereference
148182 unsafe {
149183 let b = * self . cursor ;
150184 self . bump ( ) ;
0 commit comments