11//! Buffer management for same-process client<->server communication.
22
3- use std:: io :: { self , Write } ;
4- use std:: mem :: { self , ManuallyDrop } ;
5- use std:: ops :: { Deref , DerefMut } ;
6- use std:: slice;
3+ use std:: alloc :: { self , Layout } ;
4+ use std:: ops :: Deref ;
5+ use std:: ptr :: null_mut ;
6+ use std:: { mem , slice} ;
77
88#[ repr( C ) ]
99pub struct Buffer {
1010 data : * mut u8 ,
1111 len : usize ,
1212 capacity : usize ,
13- reserve : extern "C" fn ( Buffer , usize ) -> Buffer ,
14- drop : extern "C" fn ( Buffer ) ,
1513}
1614
1715unsafe impl Sync for Buffer { }
@@ -20,7 +18,7 @@ unsafe impl Send for Buffer {}
2018impl Default for Buffer {
2119 #[ inline]
2220 fn default ( ) -> Self {
23- Self :: from ( vec ! [ ] )
21+ Self { data : null_mut ( ) , len : 0 , capacity : 0 }
2422 }
2523}
2624
@@ -32,13 +30,6 @@ impl Deref for Buffer {
3230 }
3331}
3432
35- impl DerefMut for Buffer {
36- #[ inline]
37- fn deref_mut ( & mut self ) -> & mut [ u8 ] {
38- unsafe { slice:: from_raw_parts_mut ( self . data , self . len ) }
39- }
40- }
41-
4233impl Buffer {
4334 #[ inline]
4435 pub ( super ) fn new ( ) -> Self {
@@ -55,27 +46,10 @@ impl Buffer {
5546 mem:: take ( self )
5647 }
5748
58- // We have the array method separate from extending from a slice. This is
59- // because in the case of small arrays, codegen can be more efficient
60- // (avoiding a memmove call). With extend_from_slice, LLVM at least
61- // currently is not able to make that optimization.
62- #[ inline]
63- pub ( super ) fn extend_from_array < const N : usize > ( & mut self , xs : & [ u8 ; N ] ) {
64- if xs. len ( ) > ( self . capacity - self . len ) {
65- let b = self . take ( ) ;
66- * self = ( b. reserve ) ( b, xs. len ( ) ) ;
67- }
68- unsafe {
69- xs. as_ptr ( ) . copy_to_nonoverlapping ( self . data . add ( self . len ) , xs. len ( ) ) ;
70- self . len += xs. len ( ) ;
71- }
72- }
73-
7449 #[ inline]
7550 pub ( super ) fn extend_from_slice ( & mut self , xs : & [ u8 ] ) {
7651 if xs. len ( ) > ( self . capacity - self . len ) {
77- let b = self . take ( ) ;
78- * self = ( b. reserve ) ( b, xs. len ( ) ) ;
52+ self . reserve ( xs. len ( ) ) ;
7953 }
8054 unsafe {
8155 xs. as_ptr ( ) . copy_to_nonoverlapping ( self . data . add ( self . len ) , xs. len ( ) ) ;
@@ -89,67 +63,42 @@ impl Buffer {
8963 // will panic if we're exceeding isize::MAX bytes and so there's no need
9064 // to check for overflow.
9165 if self . len == self . capacity {
92- let b = self . take ( ) ;
93- * self = ( b. reserve ) ( b, 1 ) ;
66+ self . reserve ( 1 ) ;
9467 }
9568 unsafe {
9669 * self . data . add ( self . len ) = v;
9770 self . len += 1 ;
9871 }
9972 }
100- }
101-
102- impl Write for Buffer {
103- #[ inline]
104- fn write ( & mut self , xs : & [ u8 ] ) -> io:: Result < usize > {
105- self . extend_from_slice ( xs) ;
106- Ok ( xs. len ( ) )
107- }
10873
10974 #[ inline]
110- fn write_all ( & mut self , xs : & [ u8 ] ) -> io:: Result < ( ) > {
111- self . extend_from_slice ( xs) ;
112- Ok ( ( ) )
75+ fn layout ( & self ) -> Layout {
76+ Layout :: array :: < u8 > ( self . capacity ) . unwrap ( )
11377 }
11478
115- #[ inline]
116- fn flush ( & mut self ) -> io:: Result < ( ) > {
117- Ok ( ( ) )
79+ fn reserve ( & mut self , amount : usize ) {
80+ debug_assert ! ( amount > 0 ) ;
81+ self . capacity += amount;
82+ assert ! ( self . capacity < isize :: MAX as usize ) ;
83+ let layout = self . layout ( ) ;
84+ self . data = if self . data . is_null ( ) {
85+ unsafe { alloc:: alloc ( layout) }
86+ } else {
87+ unsafe { alloc:: realloc ( self . data , layout, self . capacity ) }
88+ } ;
89+ if self . data . is_null ( ) {
90+ alloc:: handle_alloc_error ( layout) ;
91+ }
11892 }
11993}
12094
12195impl Drop for Buffer {
12296 #[ inline]
12397 fn drop ( & mut self ) {
124- let b = self . take ( ) ;
125- ( b. drop ) ( b) ;
126- }
127- }
128-
129- impl From < Vec < u8 > > for Buffer {
130- fn from ( v : Vec < u8 > ) -> Self {
131- let mut v = ManuallyDrop :: new ( v) ;
132- let ( data, len, capacity) = ( v. as_mut_ptr ( ) , v. len ( ) , v. capacity ( ) ) ;
133-
134- // This utility function is nested in here because it can *only*
135- // be safely called on `Buffer`s created by *this* `proc_macro`.
136- fn to_vec ( b : Buffer ) -> Vec < u8 > {
98+ if !self . data . is_null ( ) {
13799 unsafe {
138- let b = ManuallyDrop :: new ( b) ;
139- Vec :: from_raw_parts ( b. data , b. len , b. capacity )
100+ alloc:: dealloc ( self . data , self . layout ( ) ) ;
140101 }
141102 }
142-
143- extern "C" fn reserve ( b : Buffer , additional : usize ) -> Buffer {
144- let mut v = to_vec ( b) ;
145- v. reserve ( additional) ;
146- Buffer :: from ( v)
147- }
148-
149- extern "C" fn drop ( b : Buffer ) {
150- mem:: drop ( to_vec ( b) ) ;
151- }
152-
153- Buffer { data, len, capacity, reserve, drop }
154103 }
155104}
0 commit comments