@@ -21,20 +21,25 @@ wrapper! {
2121 copy => |ptr| ffi:: g_string_new( ( * ptr) . str ) ,
2222 free => |ptr| ffi:: g_string_free( ptr, ffi:: GTRUE ) ,
2323 init => |ptr| unsafe {
24- * ptr = ffi:: GString {
25- str : ffi:: g_malloc0 ( 64 ) as * mut _,
24+ let inner = ffi:: GString {
25+ str : ffi:: g_malloc ( 64 ) as * mut _,
2626 len: 0 ,
2727 allocated_len: 64 ,
2828 } ;
29+ ptr:: write( inner. str , 0 ) ;
30+
31+ * ptr = inner;
2932 } ,
3033 copy_into => |dest, src| {
34+ assert!( ( * src) . allocated_len > ( * src) . len) ;
3135 let allocated_len = ( * src) . allocated_len;
32- let mut inner = ffi:: GString {
33- str : ffi:: g_malloc0 ( allocated_len) as * mut _,
36+ let inner = ffi:: GString {
37+ str : ffi:: g_malloc ( allocated_len) as * mut _,
3438 len: 0 ,
3539 allocated_len,
3640 } ;
37- ffi:: g_string_append_len( & mut inner, ( * src) . str , ( * src) . len as isize ) ;
41+ // +1 to also copy the NUL-terminator
42+ ptr:: copy_nonoverlapping( ( * src) . str , inner. str , ( * src) . len + 1 ) ;
3843 * dest = inner;
3944 } ,
4045 clear => |ptr| {
@@ -56,19 +61,16 @@ impl GStringBuilder {
5661 let allocated_len = usize:: next_power_of_two ( std:: cmp:: max ( data. len ( ) , 64 ) + 1 ) ;
5762 assert_ne ! ( allocated_len, 0 ) ;
5863
59- let mut inner = ffi:: GString {
64+ let inner = ffi:: GString {
6065 str : ffi:: g_malloc ( allocated_len) as * mut _ ,
61- len : 0 ,
66+ len : data . len ( ) ,
6267 allocated_len,
6368 } ;
6469 if data. is_empty ( ) {
6570 ptr:: write ( inner. str , 0 ) ;
6671 } else {
67- ffi:: g_string_append_len (
68- & mut inner,
69- data. as_ptr ( ) as * const _ ,
70- data. len ( ) as isize ,
71- ) ;
72+ ptr:: copy_nonoverlapping ( data. as_ptr ( ) as * const _ , inner. str , data. len ( ) ) ;
73+ ptr:: write ( inner. str . add ( data. len ( ) ) , 0 ) ;
7274 }
7375 Self { inner }
7476 }
@@ -116,10 +118,6 @@ impl GStringBuilder {
116118
117119 // rustdoc-stripper-ignore-next
118120 /// Returns `&str` slice.
119- ///
120- /// # Panics
121- ///
122- /// If the string builder contains invalid UTF-8 this function panics.
123121 pub fn as_str ( & self ) -> & str {
124122 unsafe {
125123 let ptr: * const u8 = self . inner . str as _ ;
@@ -128,21 +126,17 @@ impl GStringBuilder {
128126 return "" ;
129127 }
130128 let slice = slice:: from_raw_parts ( ptr, len) ;
131- std:: str:: from_utf8 ( slice) . unwrap ( )
129+ std:: str:: from_utf8_unchecked ( slice)
132130 }
133131 }
134132
135133 // rustdoc-stripper-ignore-next
136134 /// Returns `&str` slice.
137- ///
138- /// # Panics
139- ///
140- /// If the string builder contains invalid UTF-8 this function panics.
141135 #[ must_use = "String returned from the builder should probably be used" ]
142136 pub fn into_string ( self ) -> crate :: GString {
143137 unsafe {
144138 let s = mem:: ManuallyDrop :: new ( self ) ;
145- crate :: GString :: from_glib_full_num ( s. inner . str , s. inner . len )
139+ crate :: GString :: from_ptr_and_len_unchecked ( s. inner . str , s. inner . len )
146140 }
147141 }
148142}
@@ -257,6 +251,7 @@ mod tests {
257251 #[ test]
258252 fn append ( ) {
259253 let mut s = crate :: GStringBuilder :: new ( "" ) ;
254+ assert_eq ! ( & * s, "" ) ;
260255 s. append ( "Hello" ) ;
261256 s. append ( " " ) ;
262257 s. append ( "there!" ) ;
@@ -267,6 +262,7 @@ mod tests {
267262 #[ test]
268263 fn prepend ( ) {
269264 let mut s = crate :: GStringBuilder :: new ( "456" ) ;
265+ assert_eq ! ( & * s, "456" ) ;
270266 s. prepend ( "123" ) ;
271267 assert_eq ! ( & * s, "123456" ) ;
272268 }
0 commit comments