@@ -438,19 +438,37 @@ tuple_abomonate!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD
438
438
tuple_abomonate ! ( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE ) ;
439
439
tuple_abomonate ! ( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF ) ;
440
440
441
+ unsafe impl < ' bytes , T : Abomonation < ' bytes > > Abomonation < ' bytes > for [ T ] {
442
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
443
+ for element in self { T :: entomb ( element, write) ?; }
444
+ Ok ( ( ) )
445
+ }
446
+
447
+ unsafe fn exhume ( self_ : NonNull < Self > , bytes : & ' bytes mut [ u8 ] ) -> Option < & ' bytes mut [ u8 ] > {
448
+ // FIXME: This constructs an &[T] to invalid data, which is UB.
449
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
450
+ let self_len = self_. as_ref ( ) . len ( ) ;
451
+ exhume_slice ( self_. as_ptr ( ) as * mut T , self_len, bytes)
452
+ }
453
+
454
+ fn extent ( & self ) -> usize {
455
+ self . iter ( ) . map ( T :: extent) . sum ( )
456
+ }
457
+ }
458
+
441
459
macro_rules! array_abomonate {
442
460
( $size: expr) => (
443
461
unsafe impl <' bytes, T : Abomonation <' bytes>> Abomonation <' bytes> for [ T ; $size] {
444
462
unsafe fn entomb<W : Write >( & self , write: & mut W ) -> IOResult <( ) > {
445
- entomb_slice ( & self [ ..] , write)
463
+ < [ T ] > :: entomb ( & self [ ..] , write)
446
464
}
447
465
448
466
unsafe fn exhume( self_: NonNull <Self >, bytes: & ' bytes mut [ u8 ] ) -> Option <& ' bytes mut [ u8 ] > {
449
467
exhume_slice( self_. as_ptr( ) as * mut T , $size, bytes)
450
468
}
451
469
452
470
fn extent( & self ) -> usize {
453
- slice_extent ( & self [ ..] )
471
+ < [ T ] > :: extent ( & self [ ..] )
454
472
}
455
473
}
456
474
)
@@ -550,30 +568,64 @@ unsafe impl<'bytes> Abomonation<'bytes> for String {
550
568
}
551
569
}
552
570
553
- unsafe impl < ' bytes , T : Abomonation < ' bytes > > Abomonation < ' bytes > for Vec < T > {
571
+ unsafe impl < ' target , ' bytes : ' target , T : Abomonation < ' bytes > > Abomonation < ' bytes > for & ' target [ T ] {
554
572
unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
555
573
write. write_all ( typed_to_bytes ( & self [ ..] ) ) ?;
556
- entomb_slice ( & self [ ..] , write)
574
+ <[ T ] >:: entomb ( & self [ ..] , write)
575
+ }
576
+
577
+ #[ inline]
578
+ unsafe fn exhume ( self_ : NonNull < Self > , bytes : & ' bytes mut [ u8 ] ) -> Option < & ' bytes mut [ u8 ] > {
579
+ // FIXME: This (briefly) constructs an &[T] to invalid data, which is UB.
580
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
581
+ let self_len = self_. as_ref ( ) . len ( ) ;
582
+ let ( s, rest) = exhume_slice_ref ( self_len, bytes) ?;
583
+ self_. as_ptr ( ) . write ( s) ;
584
+ Some ( rest)
585
+ }
586
+
587
+ fn extent ( & self ) -> usize {
588
+ mem:: size_of :: < T > ( ) * self . len ( ) + <[ T ] >:: extent ( & self [ ..] )
589
+ }
590
+ }
591
+
592
+ unsafe impl < ' target , ' bytes : ' target , T : Abomonation < ' bytes > > Abomonation < ' bytes > for & ' target mut [ T ] {
593
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
594
+ <& [ T ] >:: entomb ( & & self [ ..] , write)
595
+ }
596
+
597
+ #[ inline]
598
+ unsafe fn exhume ( self_ : NonNull < Self > , bytes : & ' bytes mut [ u8 ] ) -> Option < & ' bytes mut [ u8 ] > {
599
+ // FIXME: This (briefly) constructs an &mut [T] to invalid data, which is UB.
600
+ // I'm not sure if this can be fully resolved without relying on slice implementation details.
601
+ let self_len = self_. as_ref ( ) . len ( ) ;
602
+ let ( s, rest) = exhume_slice_ref ( self_len, bytes) ?;
603
+ self_. as_ptr ( ) . write ( s) ;
604
+ Some ( rest)
605
+ }
606
+
607
+ fn extent ( & self ) -> usize {
608
+ <& [ T ] >:: extent ( & & self [ ..] )
609
+ }
610
+ }
611
+
612
+ unsafe impl < ' bytes , T : Abomonation < ' bytes > > Abomonation < ' bytes > for Vec < T > {
613
+ unsafe fn entomb < W : Write > ( & self , write : & mut W ) -> IOResult < ( ) > {
614
+ <& [ T ] >:: entomb ( & & self [ ..] , write)
557
615
}
558
616
559
617
#[ inline]
560
618
unsafe fn exhume ( self_ : NonNull < Self > , bytes : & ' bytes mut [ u8 ] ) -> Option < & ' bytes mut [ u8 ] > {
561
619
// FIXME: This (briefly) constructs an &Vec<T> to invalid data, which is UB.
562
620
// I'm not sure if this can be fully resolved without relying on Vec implementation details.
563
621
let self_len = self_. as_ref ( ) . len ( ) ;
564
- let binary_len = self_len * mem:: size_of :: < T > ( ) ;
565
- if binary_len > bytes. len ( ) { None }
566
- else {
567
- let ( mine, mut rest) = bytes. split_at_mut ( binary_len) ;
568
- let first_ptr = mine. as_mut_ptr ( ) as * mut T ;
569
- rest = exhume_slice ( first_ptr, self_len, rest) ?;
570
- self_. as_ptr ( ) . write ( Vec :: from_raw_parts ( first_ptr, self_len, self_len) ) ;
571
- Some ( rest)
572
- }
622
+ let ( s, rest) = exhume_slice_ref ( self_len, bytes) ?;
623
+ self_. as_ptr ( ) . write ( Vec :: from_raw_parts ( s. as_mut_ptr ( ) , self_len, self_len) ) ;
624
+ Some ( rest)
573
625
}
574
626
575
627
fn extent ( & self ) -> usize {
576
- mem :: size_of :: < T > ( ) * self . len ( ) + slice_extent ( & self [ ..] )
628
+ < & [ T ] > :: extent ( & & self [ ..] )
577
629
}
578
630
}
579
631
@@ -631,14 +683,8 @@ unsafe fn typed_to_bytes<T>(slice: &[T]) -> &[u8] {
631
683
std:: slice:: from_raw_parts ( slice. as_ptr ( ) as * const u8 , slice. len ( ) * mem:: size_of :: < T > ( ) )
632
684
}
633
685
634
- // Common subset of "entomb" for all [T]-like types
635
- unsafe fn entomb_slice < ' a , T : Abomonation < ' a > , W : Write > ( slice : & [ T ] , write : & mut W ) -> IOResult < ( ) > {
636
- for element in slice { T :: entomb ( element, write) ?; }
637
- Ok ( ( ) )
638
- }
639
-
640
686
// Common subset of "exhume" for all [T]-like types
641
- // (I'd gladly take a NonNull< [T]> , but it is too difficult to build raw pointers to slices )
687
+ // (I'd gladly move this to [T]::exhume , but building a NonNull<[T]> is currently too difficult )
642
688
#[ inline]
643
689
unsafe fn exhume_slice < ' bytes , T : Abomonation < ' bytes > > (
644
690
first_ptr : * mut T ,
@@ -652,9 +698,17 @@ unsafe fn exhume_slice<'bytes, T: Abomonation<'bytes>>(
652
698
Some ( bytes)
653
699
}
654
700
655
- // Common subset of "extent" for all [T]-like types
656
- fn slice_extent < ' a , T : Abomonation < ' a > > ( slice : & [ T ] ) -> usize {
657
- slice. iter ( ) . map ( T :: extent) . sum ( )
701
+ // Common subset of "exhume" for all &[T]-like types
702
+ #[ inline]
703
+ unsafe fn exhume_slice_ref < ' target , ' bytes : ' target , T : Abomonation < ' bytes > > ( length : usize , bytes : & ' bytes mut [ u8 ] ) -> Option < ( & ' target mut [ T ] , & ' bytes mut [ u8 ] ) > {
704
+ let binary_len = length * mem:: size_of :: < T > ( ) ;
705
+ if binary_len > bytes. len ( ) { None }
706
+ else {
707
+ let ( mine, mut rest) = bytes. split_at_mut ( binary_len) ;
708
+ let first_ptr = mine. as_mut_ptr ( ) as * mut T ;
709
+ rest = exhume_slice ( first_ptr, length, rest) ?;
710
+ Some ( ( std:: slice:: from_raw_parts_mut ( first_ptr, length) . into ( ) , rest) )
711
+ }
658
712
}
659
713
660
714
// Common subset of "exhume" for all &mut T-like types
0 commit comments