Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions bindings/c/include/opendal.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,47 @@ typedef struct opendal_list_options {
bool deleted;
} opendal_list_options;

/**
* \brief The options for copy operations.
*
* Use `opendal_copy_options_new()` to construct and
* `opendal_copy_options_free()` to free.
*/
typedef struct opendal_copy_options {
/**
* Only copy if target does not exist; default false.
*/
bool if_not_exists;
/**
* If-Match condition; NULL means unset.
*/
const char *if_match;
/**
* Source version; NULL means unset.
*/
const char *source_version;
/**
* Whether `source_content_length_hint` has been set.
*/
bool has_source_content_length_hint;
/**
* Known content length of the source object.
*/
uint64_t source_content_length_hint;
/**
* Concurrent copy operations. `0` means sequential copy.
*/
uintptr_t concurrent;
/**
* Whether `chunk` has been set.
*/
bool has_chunk;
/**
* Chunk size for segmented copy operations.
*/
uintptr_t chunk;
} opendal_copy_options;

/**
* \brief Metadata for **operator**, users can use this metadata to get information
* of operator.
Expand Down Expand Up @@ -915,6 +956,34 @@ typedef struct opendal_capability {
* If operator supports copy.
*/
bool copy;
/**
* If operator supports copy with if not exists.
*/
bool copy_with_if_not_exists;
/**
* If operator supports copy with if match.
*/
bool copy_with_if_match;
/**
* If operator supports copy with source version.
*/
bool copy_with_source_version;
/**
* If operator supports copy can be split into multiple server-side tasks.
*/
bool copy_can_multi;
/**
* copy_multi_max_size is the max size supported for segmented copy tasks.
*
* If it is not set, this will be zero
*/
uintptr_t copy_multi_max_size;
/**
* copy_multi_min_size is the min size required for segmented copy tasks.
*
* If it is not set, this will be zero
*/
uintptr_t copy_multi_min_size;
/**
* If operator supports rename.
*/
Expand Down Expand Up @@ -1964,6 +2033,64 @@ struct opendal_error *opendal_operator_copy(const struct opendal_operator *op,
const char *src,
const char *dest);

/**
* \brief Blocking copy the object in `path` with options.
*
* Copy the object from `src` to `dest` blocking by `op`, using the provided
* `opendal_copy_options` to control the behavior, e.g. `if_not_exists` or
* `if_match` conditions.
*
* @param op The opendal_operator created previously
* @param src The designated source path you want to copy
* @param dest The designated destination path you want to copy
* @param opts The options for the copy operation; pass NULL to use defaults
* @see opendal_operator
* @see opendal_copy_options
* @see opendal_error
* @return NULL if succeeds, otherwise it contains the error code and error message.
*
* # Example
*
* Following is an example
* ```C
* //...prepare your opendal_operator, named op for example
*
* // prepare your data
* char* data = "Hello, World!";
* opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
* opendal_error *error = opendal_operator_write(op, "/testpath", bytes);
*
* assert(error == NULL);
*
* // prepare options
* opendal_copy_options *opts = opendal_copy_options_new();
* opendal_copy_options_set_if_not_exists(opts, true);
*
* // now you can copy with options!
* opendal_error *error = opendal_operator_copy_with(op, "/testpath", "/testpath2", opts);
*
* // Assert that this succeeds
* assert(error == NULL);
*
* // remember to free the options
* opendal_copy_options_free(opts);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `src` and `dest` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `src` or `dest` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_error *opendal_operator_copy_with(const struct opendal_operator *op,
const char *src,
const char *dest,
const struct opendal_copy_options *opts);

struct opendal_error *opendal_operator_check(const struct opendal_operator *op);

/**
Expand Down Expand Up @@ -2386,6 +2513,48 @@ void opendal_read_options_set_override_cache_control(struct opendal_read_options
void opendal_read_options_set_override_content_disposition(struct opendal_read_options *opts,
const char *override_content_disposition);

/**
* \brief Construct a heap-allocated opendal_copy_options with default values.
*/
struct opendal_copy_options *opendal_copy_options_new(void);

/**
* \brief Free the heap memory used by opendal_copy_options.
*/
void opendal_copy_options_free(struct opendal_copy_options *opts);

/**
* \brief Set if_not_exists.
*/
void opendal_copy_options_set_if_not_exists(struct opendal_copy_options *opts, bool if_not_exists);

/**
* \brief Set If-Match.
*/
void opendal_copy_options_set_if_match(struct opendal_copy_options *opts, const char *if_match);

/**
* \brief Set source version.
*/
void opendal_copy_options_set_source_version(struct opendal_copy_options *opts,
const char *source_version);

/**
* \brief Set source_content_length_hint.
*/
void opendal_copy_options_set_source_content_length_hint(struct opendal_copy_options *opts,
uint64_t source_content_length_hint);

/**
* \brief Set concurrent.
*/
void opendal_copy_options_set_concurrent(struct opendal_copy_options *opts, uintptr_t concurrent);

/**
* \brief Set chunk.
*/
void opendal_copy_options_set_chunk(struct opendal_copy_options *opts, uintptr_t chunk);

/**
* \brief Construct a heap-allocated opendal_operator_options
*
Expand Down
1 change: 1 addition & 0 deletions bindings/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub use result::opendal_result_writer_write;

mod types;
pub use types::opendal_bytes;
pub use types::opendal_copy_options;
pub use types::opendal_delete_options;
pub use types::opendal_list_options;
pub use types::opendal_operator_options;
Expand Down
78 changes: 78 additions & 0 deletions bindings/c/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,84 @@ pub unsafe extern "C" fn opendal_operator_copy(
}
}

/// \brief Blocking copy the object in `path` with options.
///
/// Copy the object from `src` to `dest` blocking by `op`, using the provided
/// `opendal_copy_options` to control the behavior, e.g. `if_not_exists` or
/// `if_match` conditions.
///
/// @param op The opendal_operator created previously
/// @param src The designated source path you want to copy
/// @param dest The designated destination path you want to copy
/// @param opts The options for the copy operation; pass NULL to use defaults
/// @see opendal_operator
/// @see opendal_copy_options
/// @see opendal_error
/// @return NULL if succeeds, otherwise it contains the error code and error message.
///
/// # Example
///
/// Following is an example
/// ```C
/// //...prepare your opendal_operator, named op for example
///
/// // prepare your data
/// char* data = "Hello, World!";
/// opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
/// opendal_error *error = opendal_operator_write(op, "/testpath", bytes);
///
/// assert(error == NULL);
///
/// // prepare options
/// opendal_copy_options *opts = opendal_copy_options_new();
/// opendal_copy_options_set_if_not_exists(opts, true);
///
/// // now you can copy with options!
/// opendal_error *error = opendal_operator_copy_with(op, "/testpath", "/testpath2", opts);
///
/// // Assert that this succeeds
/// assert(error == NULL);
///
/// // remember to free the options
/// opendal_copy_options_free(opts);
/// ```
///
/// # Safety
///
/// It is **safe** under the cases below
/// * The memory pointed to by `src` and `dest` must contain a valid nul terminator at the end of
/// the string.
///
/// # Panic
///
/// * If the `src` or `dest` points to NULL, this function panics, i.e. exits with information
#[no_mangle]
pub unsafe extern "C" fn opendal_operator_copy_with(
op: &opendal_operator,
src: *const c_char,
dest: *const c_char,
opts: *const opendal_copy_options,
) -> *mut opendal_error {
assert!(!src.is_null());
assert!(!dest.is_null());
let src = std::ffi::CStr::from_ptr(src)
.to_str()
.expect("malformed src");
let dest = std::ffi::CStr::from_ptr(dest)
.to_str()
.expect("malformed dest");
let copy_opts = if opts.is_null() {
core::options::CopyOptions::default()
} else {
core::options::CopyOptions::from(&*opts)
};
if let Err(err) = op.deref().copy_options(src, dest, copy_opts) {
opendal_error::new(err)
} else {
std::ptr::null_mut()
}
}

#[no_mangle]
pub unsafe extern "C" fn opendal_operator_check(op: &opendal_operator) -> *mut opendal_error {
if let Err(err) = op.deref().check() {
Expand Down
22 changes: 22 additions & 0 deletions bindings/c/src/operator_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,22 @@ pub struct opendal_capability {

/// If operator supports copy.
pub copy: bool,
/// If operator supports copy with if not exists.
pub copy_with_if_not_exists: bool,
/// If operator supports copy with if match.
pub copy_with_if_match: bool,
/// If operator supports copy with source version.
pub copy_with_source_version: bool,
/// If operator supports copy can be split into multiple server-side tasks.
pub copy_can_multi: bool,
/// copy_multi_max_size is the max size supported for segmented copy tasks.
///
/// If it is not set, this will be zero
pub copy_multi_max_size: usize,
/// copy_multi_min_size is the min size required for segmented copy tasks.
///
/// If it is not set, this will be zero
pub copy_multi_min_size: usize,

/// If operator supports rename.
pub rename: bool,
Expand Down Expand Up @@ -298,6 +314,12 @@ impl From<core::Capability> for opendal_capability {
delete_with_version: value.delete_with_version,
delete_with_recursive: value.delete_with_recursive,
copy: value.copy,
copy_with_if_not_exists: value.copy_with_if_not_exists,
copy_with_if_match: value.copy_with_if_match,
copy_with_source_version: value.copy_with_source_version,
copy_can_multi: value.copy_can_multi,
copy_multi_max_size: value.copy_multi_max_size.unwrap_or(0),
copy_multi_min_size: value.copy_multi_min_size.unwrap_or(0),
rename: value.rename,
list: value.list,
list_with_limit: value.list_with_limit,
Expand Down
Loading