@@ -15,11 +15,31 @@ wrapper! {
1515 /// A mutable text buffer that grows automatically.
1616 #[ doc( alias = "GString" ) ]
1717 #[ must_use = "The builder must be built to be used" ]
18- pub struct GStringBuilder ( Boxed <ffi:: GString >) ;
18+ pub struct GStringBuilder ( BoxedInline <ffi:: GString >) ;
1919
2020 match fn {
2121 copy => |ptr| ffi:: g_string_new( ( * ptr) . str ) ,
2222 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+ } ,
2343 type_ => || ffi:: g_gstring_get_type( ) ,
2444 }
2545}
@@ -29,13 +49,28 @@ unsafe impl Sync for GStringBuilder {}
2949
3050impl GStringBuilder {
3151 #[ 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 ) ;
3455 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 }
3974 }
4075 }
4176
@@ -107,10 +142,7 @@ impl GStringBuilder {
107142 pub fn into_string ( self ) -> crate :: GString {
108143 unsafe {
109144 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 )
114146 }
115147 }
116148}
@@ -119,7 +151,7 @@ impl Default for GStringBuilder {
119151 // rustdoc-stripper-ignore-next
120152 /// Creates a new empty string.
121153 fn default ( ) -> Self {
122- unsafe { from_glib_full ( ffi :: g_string_new ( ptr :: null ( ) ) ) }
154+ Self :: new ( "" )
123155 }
124156}
125157
0 commit comments