@@ -58,6 +58,9 @@ pub struct RustBuffer {
58
58
len : i32 ,
59
59
/// The pointer to the allocated buffer of the `Vec<u8>`.
60
60
data : * mut u8 ,
61
+ /// This forces the struct to be larger than 16 bytes, as a temporary workaround for a bug in JNA.
62
+ /// See https://github.com/mozilla/uniffi-rs/issues/334 for details.
63
+ padding : i64 ,
61
64
}
62
65
63
66
impl RustBuffer {
@@ -69,6 +72,23 @@ impl RustBuffer {
69
72
Self :: from_vec ( Vec :: new ( ) )
70
73
}
71
74
75
+ /// Creates a `RustBuffer` from its constituent fields.
76
+ ///
77
+ /// This is intended mainly as an internal convenience function and should not
78
+ /// be used outside of this module.
79
+ ///
80
+ /// # Safety
81
+ ///
82
+ /// You must ensure that the raw parts uphold the documented invariants of this class.
83
+ pub unsafe fn from_raw_parts ( data : * mut u8 , len : i32 , capacity : i32 ) -> Self {
84
+ Self {
85
+ capacity,
86
+ len,
87
+ data,
88
+ padding : 0 ,
89
+ }
90
+ }
91
+
72
92
/// Get the current length of the buffer, as a `usize`.
73
93
///
74
94
/// This is mostly a helper function to convert the `i32` length field
@@ -119,11 +139,7 @@ impl RustBuffer {
119
139
let capacity = i32:: try_from ( v. capacity ( ) ) . expect ( "buffer capacity cannot fit into a i32." ) ;
120
140
let len = i32:: try_from ( v. len ( ) ) . expect ( "buffer length cannot fit into a i32." ) ;
121
141
let mut v = std:: mem:: ManuallyDrop :: new ( v) ;
122
- Self {
123
- capacity,
124
- len,
125
- data : v. as_mut_ptr ( ) ,
126
- }
142
+ unsafe { Self :: from_raw_parts ( v. as_mut_ptr ( ) , len, capacity) }
127
143
}
128
144
129
145
/// Converts this `RustBuffer` back into an owned `Vec<u8>`.
@@ -177,11 +193,7 @@ impl Default for RustBuffer {
177
193
unsafe impl crate :: deps:: ffi_support:: IntoFfi for RustBuffer {
178
194
type Value = Self ;
179
195
fn ffi_default ( ) -> Self {
180
- Self {
181
- capacity : 0 ,
182
- len : 0 ,
183
- data : std:: ptr:: null_mut ( ) ,
184
- }
196
+ unsafe { Self :: from_raw_parts ( std:: ptr:: null_mut ( ) , 0 , 0 ) }
185
197
}
186
198
fn into_ffi_value ( self ) -> Self :: Value {
187
199
self
@@ -220,34 +232,22 @@ mod test {
220
232
#[ test]
221
233
fn test_rustbuffer_null_means_empty ( ) {
222
234
// This is how foreign-language code might cheaply indicate an empty buffer.
223
- let rbuf = RustBuffer {
224
- capacity : 0 ,
225
- len : 0 ,
226
- data : std:: ptr:: null_mut ( ) ,
227
- } ;
235
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( std:: ptr:: null_mut ( ) , 0 , 0 ) } ;
228
236
assert_eq ! ( rbuf. destroy_into_vec( ) . as_slice( ) , & [ 0u8 ; 0 ] ) ;
229
237
}
230
238
231
239
#[ test]
232
240
#[ should_panic]
233
241
fn test_rustbuffer_null_must_have_no_capacity ( ) {
234
242
// We guard against foreign-language code providing this kind of invalid struct.
235
- let rbuf = RustBuffer {
236
- capacity : 1 ,
237
- len : 0 ,
238
- data : std:: ptr:: null_mut ( ) ,
239
- } ;
243
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( std:: ptr:: null_mut ( ) , 0 , 1 ) } ;
240
244
rbuf. destroy_into_vec ( ) ;
241
245
}
242
246
#[ test]
243
247
#[ should_panic]
244
248
fn test_rustbuffer_null_must_have_zero_length ( ) {
245
249
// We guard against foreign-language code providing this kind of invalid struct.
246
- let rbuf = RustBuffer {
247
- capacity : 0 ,
248
- len : 12 ,
249
- data : std:: ptr:: null_mut ( ) ,
250
- } ;
250
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( std:: ptr:: null_mut ( ) , 12 , 0 ) } ;
251
251
rbuf. destroy_into_vec ( ) ;
252
252
}
253
253
@@ -256,11 +256,7 @@ mod test {
256
256
fn test_rustbuffer_provided_capacity_must_be_non_negative ( ) {
257
257
// We guard against foreign-language code providing this kind of invalid struct.
258
258
let mut v = vec ! [ 0u8 , 1 , 2 ] ;
259
- let rbuf = RustBuffer {
260
- capacity : -7 ,
261
- len : 3 ,
262
- data : v. as_mut_ptr ( ) ,
263
- } ;
259
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( v. as_mut_ptr ( ) , 3 , -7 ) } ;
264
260
rbuf. destroy_into_vec ( ) ;
265
261
}
266
262
@@ -269,11 +265,7 @@ mod test {
269
265
fn test_rustbuffer_provided_len_must_be_non_negative ( ) {
270
266
// We guard against foreign-language code providing this kind of invalid struct.
271
267
let mut v = vec ! [ 0u8 , 1 , 2 ] ;
272
- let rbuf = RustBuffer {
273
- capacity : 3 ,
274
- len : -1 ,
275
- data : v. as_mut_ptr ( ) ,
276
- } ;
268
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( v. as_mut_ptr ( ) , -1 , 3 ) } ;
277
269
rbuf. destroy_into_vec ( ) ;
278
270
}
279
271
@@ -282,11 +274,7 @@ mod test {
282
274
fn test_rustbuffer_provided_len_must_not_exceed_capacity ( ) {
283
275
// We guard against foreign-language code providing this kind of invalid struct.
284
276
let mut v = vec ! [ 0u8 , 1 , 2 ] ;
285
- let rbuf = RustBuffer {
286
- capacity : 2 ,
287
- len : 3 ,
288
- data : v. as_mut_ptr ( ) ,
289
- } ;
277
+ let rbuf = unsafe { RustBuffer :: from_raw_parts ( v. as_mut_ptr ( ) , 3 , 2 ) } ;
290
278
rbuf. destroy_into_vec ( ) ;
291
279
}
292
280
0 commit comments