@@ -20,7 +20,8 @@ use serde::Serialize;
2020/// Immutable bytes type with zero copy cloning and slicing.
2121#[ derive( Clone ) ]
2222pub struct Bytes {
23- slice : & ' static [ u8 ] ,
23+ ptr : NonNull < u8 > ,
24+ len : usize ,
2425 // The `bytes`` field is used to ensure that the underlying bytes are freed when there are no
2526 // more references to the `Bytes` object. For static buffers the field is `None`.
2627 bytes : Option < RefCountedCell > ,
@@ -48,10 +49,9 @@ impl Bytes {
4849 len : usize ,
4950 refcount : RefCountedCell ,
5051 ) -> Self {
51- // SAFETY: The caller must ensure that the pointer is valid and that the length is correct.
52- let slice = unsafe { std:: slice:: from_raw_parts ( ptr. as_ptr ( ) , len) } ;
5352 Self {
54- slice,
53+ ptr,
54+ len,
5555 bytes : Some ( refcount) ,
5656 }
5757 }
@@ -65,8 +65,12 @@ impl Bytes {
6565 /// Creates `Bytes` from a static slice.
6666 #[ inline]
6767 pub const fn from_static ( value : & ' static [ u8 ] ) -> Self {
68- let slice: & [ u8 ] = value;
69- Self { slice, bytes : None }
68+ Self {
69+ // SAFETY: static slice always have a valid pointer and length
70+ ptr : unsafe { NonNull :: new_unchecked ( value. as_ptr ( ) . cast_mut ( ) ) } ,
71+ len : value. len ( ) ,
72+ bytes : None ,
73+ }
7074 }
7175
7276 /// Creates `Bytes` from a slice, by copying.
@@ -77,13 +81,13 @@ impl Bytes {
7781 /// Returns the length of the `Bytes`.
7882 #[ inline]
7983 pub const fn len ( & self ) -> usize {
80- self . slice . len ( )
84+ self . len
8185 }
8286
8387 /// Returns `true` if the `Bytes` is empty.
8488 #[ inline]
8589 pub const fn is_empty ( & self ) -> bool {
86- self . slice . is_empty ( )
90+ self . len == 0
8791 }
8892
8993 /// Returns a slice of self for the provided range.
@@ -178,54 +182,58 @@ impl Bytes {
178182
179183 let subset_start = subset. as_ptr ( ) as usize ;
180184 let subset_end = subset_start + subset. len ( ) ;
181- let self_start = self . slice . as_ptr ( ) as usize ;
182- let self_end = self_start + self . slice . len ( ) ;
185+ let self_start = self . ptr . as_ptr ( ) as usize ;
186+ let self_end = self_start + self . len ;
183187 if subset_start >= self_start && subset_end <= self_end {
184188 Some ( self . safe_slice_ref ( subset_start - self_start, subset_end - self_start) )
185189 } else {
186190 None
187191 }
188192 }
189193
190- /// Returns a mutable reference to the slice of self.
191- /// Allows for fast unchecked shrinking of the slice.
192- ///
193- /// # Safety
194- ///
195- /// Callers of that function must make sure that they only put subslices of the slice into the
196- /// returned reference.
197- /// They also need to make sure to not persist the slice reference for longer than the struct
198- /// lives.
199- #[ inline]
200- pub unsafe fn as_mut_slice ( & mut self ) -> & mut & ' static [ u8 ] {
201- & mut self . slice
202- }
203-
204- pub fn from_underlying ( value : impl UnderlyingBytes ) -> Self {
194+ pub fn from_underlying < T : UnderlyingBytes > ( value : T ) -> Self {
205195 unsafe {
196+ let refcounted = make_refcounted ( value) ;
197+ let a = refcounted. data . cast :: < CustomArc < T > > ( ) . as_ptr ( ) ;
198+
206199 // SAFETY:
207200 // * the pointer associated with a slice is non null and valid for the length of the
208201 // slice
209- // * it stays valid as long as value is not dopped
202+ // * it stays valid as long as value is not dropped
203+ let data: & T = & ( * a) . data ;
210204 let ( ptr, len) = {
211- let s = value . as_ref ( ) ;
205+ let s = data . as_ref ( ) ;
212206 ( NonNull :: new_unchecked ( s. as_ptr ( ) . cast_mut ( ) ) , s. len ( ) )
213207 } ;
214- Self :: from_raw_refcount ( ptr, len, make_refcounted ( value ) )
208+ Self :: from_raw_refcount ( ptr, len, refcounted )
215209 }
216210 }
217211
218212 #[ inline]
219213 fn safe_slice_ref ( & self , start : usize , end : usize ) -> Self {
214+ if !( start <= end && end <= self . len ) {
215+ #[ allow( clippy:: panic) ]
216+ {
217+ panic ! ( "Out of bound slicing of Bytes instance" )
218+ }
219+ }
220+ // SAFETY:
221+ // * start is less than len, so the resulting pointer is
222+ // going either inside the allocation or one past
223+ // * we have 0 <= start <= end <= len so 0 <= end - start <= len - start. Since the new ptr
224+ // points to ptr + start, then memory span is between ptr + start and (ptr + start) + (len -
225+ // start) = ptr + len
220226 Self {
221- slice : & self . slice [ start..end] ,
227+ ptr : unsafe { self . ptr . add ( start) } ,
228+ len : end - start,
222229 bytes : self . bytes . clone ( ) ,
223230 }
224231 }
225232
226233 #[ inline]
227234 fn as_slice ( & self ) -> & [ u8 ] {
228- self . slice
235+ // SAFETY: ptr is valid for the associated length
236+ unsafe { std:: slice:: from_raw_parts ( self . ptr . as_ptr ( ) . cast_const ( ) , self . len ( ) ) }
229237 }
230238}
231239
@@ -357,21 +365,21 @@ pub struct RefCountedCellVTable {
357365 pub drop : unsafe fn ( NonNull < ( ) > ) ,
358366}
359367
368+ /// A custom Arc implementation that contains only the strong count
369+ ///
370+ /// This struct is not exposed to the outside of this functions and is
371+ /// only interacted with through the `RefCountedCell` API.
372+ struct CustomArc < T > {
373+ rc : AtomicUsize ,
374+ #[ allow( unused) ]
375+ data : T ,
376+ }
377+
360378/// Creates a refcounted cell.
361379///
362380/// The data passed to this cell will only be dopped when the last
363381/// clone of the cell is dropped.
364382fn make_refcounted < T : Send + Sync + ' static > ( data : T ) -> RefCountedCell {
365- /// A custom Arc implementation that contains only the strong count
366- ///
367- /// This struct is not exposed to the outside of this functions and is
368- /// only interacted with through the `RefCountedCell` API.
369- struct CustomArc < T > {
370- rc : AtomicUsize ,
371- #[ allow( unused) ]
372- data : T ,
373- }
374-
375383 unsafe fn custom_arc_clone < T > ( data : NonNull < ( ) > ) -> RefCountedCell {
376384 let custom_arc = data. cast :: < CustomArc < T > > ( ) . as_ref ( ) ;
377385 custom_arc
0 commit comments