@@ -15,11 +15,31 @@ wrapper! {
15
15
/// A mutable text buffer that grows automatically.
16
16
#[ doc( alias = "GString" ) ]
17
17
#[ must_use = "The builder must be built to be used" ]
18
- pub struct GStringBuilder ( Boxed <ffi:: GString >) ;
18
+ pub struct GStringBuilder ( BoxedInline <ffi:: GString >) ;
19
19
20
20
match fn {
21
21
copy => |ptr| ffi:: g_string_new( ( * ptr) . str ) ,
22
22
free => |ptr| ffi:: g_string_free( ptr, ffi:: GTRUE ) ,
23
+ init => |ptr| unsafe {
24
+ * ptr = ffi:: GString {
25
+ str : ffi:: g_malloc0( 64 ) as * mut _,
26
+ len: 0 ,
27
+ allocated_len: 64 ,
28
+ } ;
29
+ } ,
30
+ copy_into => |dest, src| {
31
+ let allocated_len = ( * src) . allocated_len;
32
+ let mut inner = ffi:: GString {
33
+ str : ffi:: g_malloc0( allocated_len) as * mut _,
34
+ len: 0 ,
35
+ allocated_len,
36
+ } ;
37
+ ffi:: g_string_append_len( & mut inner, ( * src) . str , ( * src) . len as isize ) ;
38
+ * dest = inner;
39
+ } ,
40
+ clear => |ptr| {
41
+ ffi:: g_free( ( * ptr) . str as * mut _) ;
42
+ } ,
23
43
type_ => || ffi:: g_gstring_get_type( ) ,
24
44
}
25
45
}
@@ -29,13 +49,28 @@ unsafe impl Sync for GStringBuilder {}
29
49
30
50
impl GStringBuilder {
31
51
#[ doc( alias = "g_string_new_len" ) ]
32
- pub fn new < T : AsRef < [ u8 ] > > ( data : T ) -> GStringBuilder {
33
- let bytes = data. as_ref ( ) ;
52
+ pub fn new < T : AsRef < str > > ( data : T ) -> GStringBuilder {
53
+ let data = data. as_ref ( ) ;
54
+ assert ! ( data. len( ) < usize :: MAX - 1 ) ;
34
55
unsafe {
35
- from_glib_full ( ffi:: g_string_new_len (
36
- bytes. as_ptr ( ) as * const _ ,
37
- bytes. len ( ) as isize ,
38
- ) )
56
+ let allocated_len = usize:: next_power_of_two ( std:: cmp:: max ( data. len ( ) , 64 ) + 1 ) ;
57
+ assert_ne ! ( allocated_len, 0 ) ;
58
+
59
+ let mut inner = ffi:: GString {
60
+ str : ffi:: g_malloc ( allocated_len) as * mut _ ,
61
+ len : 0 ,
62
+ allocated_len,
63
+ } ;
64
+ if data. is_empty ( ) {
65
+ ptr:: write ( inner. str , 0 ) ;
66
+ } else {
67
+ ffi:: g_string_append_len (
68
+ & mut inner,
69
+ data. as_ptr ( ) as * const _ ,
70
+ data. len ( ) as isize ,
71
+ ) ;
72
+ }
73
+ Self { inner }
39
74
}
40
75
}
41
76
@@ -107,10 +142,7 @@ impl GStringBuilder {
107
142
pub fn into_string ( self ) -> crate :: GString {
108
143
unsafe {
109
144
let s = mem:: ManuallyDrop :: new ( self ) ;
110
- from_glib_full ( ffi:: g_string_free (
111
- mut_override ( s. to_glib_none ( ) . 0 ) ,
112
- ffi:: GFALSE ,
113
- ) )
145
+ crate :: GString :: from_glib_full_num ( s. inner . str , s. inner . len )
114
146
}
115
147
}
116
148
}
@@ -119,7 +151,7 @@ impl Default for GStringBuilder {
119
151
// rustdoc-stripper-ignore-next
120
152
/// Creates a new empty string.
121
153
fn default ( ) -> Self {
122
- unsafe { from_glib_full ( ffi :: g_string_new ( ptr :: null ( ) ) ) }
154
+ Self :: new ( "" )
123
155
}
124
156
}
125
157
0 commit comments