@@ -235,7 +235,7 @@ impl ByteView {
235235 }
236236 }
237237
238- /// Returns a mutable reference into the given Byteview , if there are no other pointers to the same allocation.
238+ /// Returns a mutable reference into the given byteview , if there are no other pointers to the same allocation.
239239 pub fn get_mut ( & mut self ) -> Option < Mutator < ' _ > > {
240240 if self . ref_count ( ) == 1 {
241241 Some ( Mutator ( self ) )
@@ -244,7 +244,7 @@ impl ByteView {
244244 }
245245 }
246246
247- /// Creates a slice and populates it with `len` bytes
247+ /// Creates a byteview and populates it with `len` bytes
248248 /// from the given reader.
249249 ///
250250 /// # Errors
@@ -274,98 +274,128 @@ impl ByteView {
274274 Self :: with_size_zeroed ( slice_len)
275275 }
276276
277+ /// Creates a new zeroed, fixed-length byteview.
278+ ///
279+ /// # Panics
280+ ///
281+ /// Panics if the length does not fit in a u32 (4 GiB).
277282 fn with_size_zeroed ( slice_len : usize ) -> Self {
278- let Ok ( len) = u32:: try_from ( slice_len) else {
279- panic ! ( "byte slice too long" ) ;
280- } ;
281-
282- let mut builder = Self {
283- trailer : Trailer {
284- short : ManuallyDrop :: new ( ShortRepr {
285- len,
286- data : [ 0 ; INLINE_SIZE ] ,
287- } ) ,
288- } ,
289- } ;
283+ let view = if slice_len <= INLINE_SIZE {
284+ Self {
285+ trailer : Trailer {
286+ short : ManuallyDrop :: new ( ShortRepr {
287+ // SAFETY: We know slice_len is INLINE_SIZE or less, so it must be
288+ // a valid u32
289+ #[ allow( clippy:: cast_possible_truncation) ]
290+ len : slice_len as u32 ,
291+ data : [ 0 ; INLINE_SIZE ] ,
292+ } ) ,
293+ } ,
294+ }
295+ } else {
296+ let Ok ( len) = u32:: try_from ( slice_len) else {
297+ panic ! ( "byte slice too long" ) ;
298+ } ;
290299
291- if !builder. is_inline ( ) {
292300 unsafe {
293- let header_size = std:: mem:: size_of :: < HeapAllocationHeader > ( ) ;
294- let alignment = std:: mem:: align_of :: < HeapAllocationHeader > ( ) ;
295- let total_size = header_size + slice_len;
296- let layout = std:: alloc:: Layout :: from_size_align ( total_size, alignment) . unwrap ( ) ;
301+ const HEADER_SIZE : usize = std:: mem:: size_of :: < HeapAllocationHeader > ( ) ;
302+ const ALIGNMENT : usize = std:: mem:: align_of :: < HeapAllocationHeader > ( ) ;
303+
304+ let total_size = HEADER_SIZE + slice_len;
305+ let layout = std:: alloc:: Layout :: from_size_align ( total_size, ALIGNMENT ) . unwrap ( ) ;
297306
298307 // IMPORTANT: Zero-allocate the region
299308 let heap_ptr = std:: alloc:: alloc_zeroed ( layout) ;
300309 if heap_ptr. is_null ( ) {
301310 std:: alloc:: handle_alloc_error ( layout) ;
302311 }
303312
304- // Set pointer to heap allocation address
305- ( * builder. trailer . long ) . heap = heap_ptr;
306- ( * builder. trailer . long ) . offset = 0 ;
307- ( * builder. trailer . long ) . original_len = slice_len as u32 ;
308-
309313 // Set ref count
310314 let heap_region = heap_ptr as * const HeapAllocationHeader ;
311315 let heap_region = & * heap_region;
312316 heap_region. ref_count . store ( 1 , Ordering :: Release ) ;
317+
318+ Self {
319+ trailer : Trailer {
320+ long : ManuallyDrop :: new ( LongRepr {
321+ len,
322+ prefix : [ 0 ; PREFIX_SIZE ] ,
323+ heap : heap_ptr,
324+ original_len : len,
325+ offset : 0 ,
326+ } ) ,
327+ } ,
328+ }
313329 }
314- }
330+ } ;
315331
316- debug_assert_eq ! ( 1 , builder . ref_count( ) ) ;
332+ debug_assert_eq ! ( 1 , view . ref_count( ) ) ;
317333
318- builder
334+ view
319335 }
320336
337+ /// Creates a new fixed-length byteview, with uninitialized contents.
338+ ///
339+ /// # Panics
340+ ///
341+ /// Panics if the length does not fit in a u32 (4 GiB).
321342 fn with_size_unchecked ( slice_len : usize ) -> Self {
322- let Ok ( len) = u32:: try_from ( slice_len) else {
323- panic ! ( "byte slice too long" ) ;
324- } ;
325-
326- let mut builder = Self {
327- trailer : Trailer {
328- short : ManuallyDrop :: new ( ShortRepr {
329- len,
330- data : [ 0 ; INLINE_SIZE ] ,
331- } ) ,
332- } ,
333- } ;
343+ let view = if slice_len <= INLINE_SIZE {
344+ Self {
345+ trailer : Trailer {
346+ short : ManuallyDrop :: new ( ShortRepr {
347+ // SAFETY: We know slice_len is INLINE_SIZE or less, so it must be
348+ // a valid u32
349+ #[ allow( clippy:: cast_possible_truncation) ]
350+ len : slice_len as u32 ,
351+ data : [ 0 ; INLINE_SIZE ] ,
352+ } ) ,
353+ } ,
354+ }
355+ } else {
356+ let Ok ( len) = u32:: try_from ( slice_len) else {
357+ panic ! ( "byte slice too long" ) ;
358+ } ;
334359
335- if !builder. is_inline ( ) {
336360 unsafe {
337361 const HEADER_SIZE : usize = std:: mem:: size_of :: < HeapAllocationHeader > ( ) ;
338362 const ALIGNMENT : usize = std:: mem:: align_of :: < HeapAllocationHeader > ( ) ;
339363
340364 let total_size = HEADER_SIZE + slice_len;
341365 let layout = std:: alloc:: Layout :: from_size_align ( total_size, ALIGNMENT ) . unwrap ( ) ;
342366
343- // IMPORTANT: Zero-allocate the region
344367 let heap_ptr = std:: alloc:: alloc ( layout) ;
345368 if heap_ptr. is_null ( ) {
346369 std:: alloc:: handle_alloc_error ( layout) ;
347370 }
348371
349- // Set pointer to heap allocation address
350- ( * builder. trailer . long ) . heap = heap_ptr;
351- ( * builder. trailer . long ) . offset = 0 ;
352- ( * builder. trailer . long ) . original_len = slice_len as u32 ;
353-
354372 // Set ref count
355373 let heap_region = heap_ptr as * const HeapAllocationHeader ;
356374 let heap_region = & * heap_region;
357375 heap_region. ref_count . store ( 1 , Ordering :: Release ) ;
376+
377+ Self {
378+ trailer : Trailer {
379+ long : ManuallyDrop :: new ( LongRepr {
380+ len,
381+ prefix : [ 0 ; PREFIX_SIZE ] ,
382+ heap : heap_ptr,
383+ original_len : len,
384+ offset : 0 ,
385+ } ) ,
386+ } ,
387+ }
358388 }
359- }
389+ } ;
360390
361- debug_assert_eq ! ( 1 , builder . ref_count( ) ) ;
391+ debug_assert_eq ! ( 1 , view . ref_count( ) ) ;
362392
363- builder
393+ view
364394 }
365395
366- /// Creates a new slice from an existing byte slice.
396+ /// Creates a new byteview from an existing byte slice.
367397 ///
368- /// Will heap-allocate the slice if it has at least length 13 .
398+ /// Will heap-allocate the slice if it has at least length 21 .
369399 ///
370400 /// # Panics
371401 ///
@@ -455,7 +485,7 @@ impl ByteView {
455485 Self :: new ( self )
456486 }
457487
458- /// Clones the given range of the existing slice without heap allocation.
488+ /// Clones the given range of the existing byteview without heap allocation.
459489 ///
460490 /// # Examples
461491 ///
0 commit comments