@@ -21,20 +21,25 @@ wrapper! {
21
21
copy => |ptr| ffi:: g_string_new( ( * ptr) . str ) ,
22
22
free => |ptr| ffi:: g_string_free( ptr, ffi:: GTRUE ) ,
23
23
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 _,
26
26
len: 0 ,
27
27
allocated_len: 64 ,
28
28
} ;
29
+ ptr:: write( inner. str , 0 ) ;
30
+
31
+ * ptr = inner;
29
32
} ,
30
33
copy_into => |dest, src| {
34
+ assert!( ( * src) . allocated_len > ( * src) . len) ;
31
35
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 _,
34
38
len: 0 ,
35
39
allocated_len,
36
40
} ;
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 ) ;
38
43
* dest = inner;
39
44
} ,
40
45
clear => |ptr| {
@@ -56,19 +61,16 @@ impl GStringBuilder {
56
61
let allocated_len = usize:: next_power_of_two ( std:: cmp:: max ( data. len ( ) , 64 ) + 1 ) ;
57
62
assert_ne ! ( allocated_len, 0 ) ;
58
63
59
- let mut inner = ffi:: GString {
64
+ let inner = ffi:: GString {
60
65
str : ffi:: g_malloc ( allocated_len) as * mut _ ,
61
- len : 0 ,
66
+ len : data . len ( ) ,
62
67
allocated_len,
63
68
} ;
64
69
if data. is_empty ( ) {
65
70
ptr:: write ( inner. str , 0 ) ;
66
71
} 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 ) ;
72
74
}
73
75
Self { inner }
74
76
}
@@ -116,10 +118,6 @@ impl GStringBuilder {
116
118
117
119
// rustdoc-stripper-ignore-next
118
120
/// Returns `&str` slice.
119
- ///
120
- /// # Panics
121
- ///
122
- /// If the string builder contains invalid UTF-8 this function panics.
123
121
pub fn as_str ( & self ) -> & str {
124
122
unsafe {
125
123
let ptr: * const u8 = self . inner . str as _ ;
@@ -128,21 +126,17 @@ impl GStringBuilder {
128
126
return "" ;
129
127
}
130
128
let slice = slice:: from_raw_parts ( ptr, len) ;
131
- std:: str:: from_utf8 ( slice) . unwrap ( )
129
+ std:: str:: from_utf8_unchecked ( slice)
132
130
}
133
131
}
134
132
135
133
// rustdoc-stripper-ignore-next
136
134
/// Returns `&str` slice.
137
- ///
138
- /// # Panics
139
- ///
140
- /// If the string builder contains invalid UTF-8 this function panics.
141
135
#[ must_use = "String returned from the builder should probably be used" ]
142
136
pub fn into_string ( self ) -> crate :: GString {
143
137
unsafe {
144
138
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 )
146
140
}
147
141
}
148
142
}
@@ -257,6 +251,7 @@ mod tests {
257
251
#[ test]
258
252
fn append ( ) {
259
253
let mut s = crate :: GStringBuilder :: new ( "" ) ;
254
+ assert_eq ! ( & * s, "" ) ;
260
255
s. append ( "Hello" ) ;
261
256
s. append ( " " ) ;
262
257
s. append ( "there!" ) ;
@@ -267,6 +262,7 @@ mod tests {
267
262
#[ test]
268
263
fn prepend ( ) {
269
264
let mut s = crate :: GStringBuilder :: new ( "456" ) ;
265
+ assert_eq ! ( & * s, "456" ) ;
270
266
s. prepend ( "123" ) ;
271
267
assert_eq ! ( & * s, "123456" ) ;
272
268
}
0 commit comments