diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h index 2df3447d23d..4fba9091634 100644 --- a/bindings/c/include/opendal.h +++ b/bindings/c/include/opendal.h @@ -99,6 +99,10 @@ typedef struct opendal_bytes { * The length of the byte array */ uintptr_t len; + /** + * The capacity of the byte array + */ + uintptr_t capacity; } opendal_bytes; /** diff --git a/bindings/c/src/types.rs b/bindings/c/src/types.rs index 051724a671e..795c7a73b5c 100644 --- a/bindings/c/src/types.rs +++ b/bindings/c/src/types.rs @@ -34,25 +34,37 @@ pub struct opendal_bytes { pub data: *const u8, /// The length of the byte array pub len: usize, + /// The capacity of the byte array + pub capacity: usize, } impl opendal_bytes { /// Construct a [`opendal_bytes`] from the Rust [`Vec`] of bytes pub(crate) fn new(buf: Buffer) -> Self { let vec = buf.to_vec(); - let data = vec.as_ptr(); - let len = vec.len(); - std::mem::forget(vec); - Self { data, len } + let mut buf = std::mem::ManuallyDrop::new(vec); + let data = buf.as_mut_ptr(); + let len = buf.len(); + let capacity = buf.capacity(); + Self { + data, + len, + capacity, + } } /// \brief Frees the heap memory used by the opendal_bytes #[no_mangle] pub unsafe extern "C" fn opendal_bytes_free(ptr: *mut opendal_bytes) { if !ptr.is_null() { - let data_mut = (*ptr).data as *mut u8; - drop(Vec::from_raw_parts(data_mut, (*ptr).len, (*ptr).len)); - drop(Box::from_raw(ptr)); + // transmuting `*const u8` to `*mut u8` is undefined behavior in any cases + // however, fields type of `opendal_bytes` is already related to the zig binding + // it should be fixed later + let _ = Vec::from_raw_parts((*ptr).data as *mut u8, (*ptr).len, (*ptr).capacity); + // it is too weird that call `Box::new` outside `opendal_bytes::new` but dealloc it here + // also, boxing `opendal_bytes` might not be necessary + // `data` points to heap, so `opendal_bytes` could be passed as a stack value + let _ = Box::from_raw(ptr); } } } diff --git a/bindings/go/types.go b/bindings/go/types.go index 59583a94afd..6ff8b2d606a 100644 --- a/bindings/go/types.go +++ b/bindings/go/types.go @@ -257,8 +257,9 @@ type resultStat struct { type opendalMetadata struct{} type opendalBytes struct { - data *byte - len uintptr + data *byte + len uintptr + capacity uintptr } type opendalError struct { @@ -285,6 +286,7 @@ type opendalEntry struct{} func toOpendalBytes(data []byte) opendalBytes { var ptr *byte l := len(data) + c := cap(data) if l > 0 { ptr = &data[0] } else { @@ -292,8 +294,9 @@ func toOpendalBytes(data []byte) opendalBytes { ptr = &b } return opendalBytes{ - data: ptr, - len: uintptr(l), + data: ptr, + len: uintptr(l), + capacity: uintptr(c), } }