bindings/c/include/opendal.h (207 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _OPENDAL_H
#define _OPENDAL_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define OPENDAL_SEEK_SET 0
#define OPENDAL_SEEK_CUR 1
#define OPENDAL_SEEK_END 2
/**
* \brief The error code for all opendal APIs in C binding.
* \todo The error handling is not complete, the error with error message will be
* added in the future.
*/
typedef enum opendal_code {
/**
* returning it back. For example, s3 returns an internal service error.
*/
OPENDAL_UNEXPECTED,
/**
* Underlying service doesn't support this operation.
*/
OPENDAL_UNSUPPORTED,
/**
* The config for backend is invalid.
*/
OPENDAL_CONFIG_INVALID,
/**
* The given path is not found.
*/
OPENDAL_NOT_FOUND,
/**
* The given path doesn't have enough permission for this operation
*/
OPENDAL_PERMISSION_DENIED,
/**
* The given path is a directory.
*/
OPENDAL_IS_A_DIRECTORY,
/**
* The given path is not a directory.
*/
OPENDAL_NOT_A_DIRECTORY,
/**
* The given path already exists thus we failed to the specified operation on it.
*/
OPENDAL_ALREADY_EXISTS,
/**
* Requests that sent to this path is over the limit, please slow down.
*/
OPENDAL_RATE_LIMITED,
/**
* The given file paths are same.
*/
OPENDAL_IS_SAME_FILE,
/**
* The condition of this operation is not match.
*/
OPENDAL_CONDITION_NOT_MATCH,
/**
* The range of the content is not satisfied.
*/
OPENDAL_RANGE_NOT_SATISFIED,
} opendal_code;
/**
* \brief opendal_bytes carries raw-bytes with its length
*
* The opendal_bytes type is a C-compatible substitute for Vec type
* in Rust, it has to be manually freed. You have to call opendal_bytes_free()
* to free the heap memory to avoid memory leak.
*
* @see opendal_bytes_free
*/
typedef struct opendal_bytes {
/**
* Pointing to the byte array on heap
*/
uint8_t *data;
/**
* The length of the byte array
*/
uintptr_t len;
/**
* The capacity of the byte array
*/
uintptr_t capacity;
} opendal_bytes;
/**
* \brief The opendal error type for C binding, containing an error code and corresponding error
* message.
*
* The normal operations returns a pointer to the opendal_error, and the **nullptr normally
* represents no error has taken placed**. If any error has taken place, the caller should check
* the error code and print the error message.
*
* The error code is represented in opendal_code, which is an enum on different type of errors.
* The error messages is represented in opendal_bytes, which is a non-null terminated byte array.
*
* \note 1. The error message is on heap, so the error needs to be freed by the caller, by calling
* opendal_error_free. 2. The error message is not null terminated, so the caller should
* never use "%s" to print the error message.
*
* @see opendal_code
* @see opendal_bytes
* @see opendal_error_free
*/
typedef struct opendal_error {
enum opendal_code code;
struct opendal_bytes message;
} opendal_error;
/**
* \brief opendal_list_entry is the entry under a path, which is listed from the opendal_lister
*
* For examples, please see the comment section of opendal_operator_list()
* @see opendal_operator_list()
* @see opendal_list_entry_path()
* @see opendal_list_entry_name()
*/
typedef struct opendal_entry {
/**
* The pointer to the opendal::Entry in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_entry;
/**
* \brief The result type returned by opendal_lister_next().
* The list entry is the list result of the list operation, the error field is the error code and error message.
* If the operation succeeds, the error should be NULL.
*
* \note Please notice if the lister reaches the end, both the list_entry and error will be NULL.
*/
typedef struct opendal_result_lister_next {
/**
* The next object name
*/
struct opendal_entry *entry;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_lister_next;
/**
* \brief BlockingLister is designed to list entries at given path in a blocking
* manner.
*
* Users can construct Lister by `blocking_list` or `blocking_scan`(currently not supported in C binding)
*
* For examples, please see the comment section of opendal_operator_list()
* @see opendal_operator_list()
*/
typedef struct opendal_lister {
/**
* The pointer to the opendal::BlockingLister in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_lister;
/**
* \brief Carries all metadata associated with a **path**.
*
* The metadata of the "thing" under a path. Please **only** use the opendal_metadata
* with our provided API, e.g. opendal_metadata_content_length().
*
* \note The metadata is also heap-allocated, please call opendal_metadata_free() on this
* to free the heap memory.
*
* @see opendal_metadata_free
*/
typedef struct opendal_metadata {
/**
* The pointer to the opendal::Metadata in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_metadata;
/**
* \brief Used to access almost all OpenDAL APIs. It represents an
* operator that provides the unified interfaces provided by OpenDAL.
*
* @see opendal_operator_new This function construct the operator
* @see opendal_operator_free This function frees the heap memory of the operator
*
* \note The opendal_operator actually owns a pointer to
* an opendal::BlockingOperator, which is inside the Rust core code.
*
* \remark You may use the field `ptr` to check whether this is a NULL
* operator.
*/
typedef struct opendal_operator {
/**
* The pointer to the opendal::BlockingOperator in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_operator;
/**
* \brief The result type returned by opendal_operator_new() operation.
*
* If the init logic is successful, the `op` field will be set to a valid
* pointer, and the `error` field will be set to null. If the init logic fails, the
* `op` field will be set to null, and the `error` field will be set to a
* valid pointer with error code and error message.
*
* @see opendal_operator_new()
* @see opendal_operator
* @see opendal_error
*/
typedef struct opendal_result_operator_new {
/**
* The pointer for operator.
*/
struct opendal_operator *op;
/**
* The error pointer for error.
*/
struct opendal_error *error;
} opendal_result_operator_new;
/**
* \brief The configuration for the initialization of opendal_operator.
*
* \note This is also a heap-allocated struct, please free it after you use it
*
* @see opendal_operator_new has an example of using opendal_operator_options
* @see opendal_operator_options_new This function construct the operator
* @see opendal_operator_options_free This function frees the heap memory of the operator
* @see opendal_operator_options_set This function allow you to set the options
*/
typedef struct opendal_operator_options {
/**
* The pointer to the HashMap<String, String> in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_operator_options;
/**
* \brief The result type returned by opendal's read operation.
*
* The result type of read operation in opendal C binding, it contains
* the data that the read operation returns and an NULL error.
* If the read operation failed, the `data` fields should be a nullptr
* and the error is not NULL.
*/
typedef struct opendal_result_read {
/**
* The byte array with length returned by read operations
*/
struct opendal_bytes data;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_read;
/**
* \brief The result type returned by opendal's reader operation.
*
* \note The opendal_reader actually owns a pointer to
* a opendal::BlockingReader, which is inside the Rust core code.
*/
typedef struct opendal_reader {
/**
* The pointer to the opendal::StdReader in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_reader;
/**
* \brief The result type returned by opendal_operator_reader().
* The result type for opendal_operator_reader(), the field `reader` contains the reader
* of the path, which is an iterator of the objects under the path. the field `code` represents
* whether the stat operation is successful.
*/
typedef struct opendal_result_operator_reader {
/**
* The pointer for opendal_reader
*/
struct opendal_reader *reader;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_operator_reader;
/**
* \brief The result type returned by opendal's writer operation.
* \note The opendal_writer actually owns a pointer to
* an opendal::BlockingWriter, which is inside the Rust core code.
*/
typedef struct opendal_writer {
/**
* The pointer to the opendal::BlockingWriter in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_writer;
/**
* \brief The result type returned by opendal_operator_writer().
* The result type for opendal_operator_writer(), the field `writer` contains the writer
* of the path, which is an iterator of the objects under the path. the field `code` represents
*/
typedef struct opendal_result_operator_writer {
/**
* The pointer for opendal_writer
*/
struct opendal_writer *writer;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_operator_writer;
/**
* \brief The result type returned by opendal_operator_is_exist().
*
* The result type for opendal_operator_is_exist(), the field `is_exist`
* contains whether the path exists, and the field `error` contains the
* corresponding error. If successful, the `error` field is null.
*
* \note If the opendal_operator_is_exist() fails, the `is_exist` field
* will be set to false.
*/
typedef struct opendal_result_is_exist {
/**
* Whether the path exists
*/
bool is_exist;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_is_exist;
/**
* \brief The result type returned by opendal_operator_exists().
*
* The result type for opendal_operator_exists(), the field `exists`
* contains whether the path exists, and the field `error` contains the
* corresponding error. If successful, the `error` field is null.
*
* \note If the opendal_operator_exists() fails, the `exists` field
* will be set to false.
*/
typedef struct opendal_result_exists {
/**
* Whether the path exists
*/
bool exists;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_exists;
/**
* \brief The result type returned by opendal_operator_stat().
*
* The result type for opendal_operator_stat(), the field `meta` contains the metadata
* of the path, the field `error` represents whether the stat operation is successful.
* If successful, the `error` field is null.
*/
typedef struct opendal_result_stat {
/**
* The metadata output of the stat
*/
struct opendal_metadata *meta;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_stat;
/**
* \brief The result type returned by opendal_operator_list().
*
* The result type for opendal_operator_list(), the field `lister` contains the lister
* of the path, which is an iterator of the objects under the path. the field `error` represents
* whether the stat operation is successful. If successful, the `error` field is null.
*/
typedef struct opendal_result_list {
/**
* The lister, used for further listing operations
*/
struct opendal_lister *lister;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_list;
/**
* \brief Metadata for **operator**, users can use this metadata to get information
* of operator.
*/
typedef struct opendal_operator_info {
/**
* The pointer to the opendal::OperatorInfo in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_operator_info;
/**
* \brief Capability is used to describe what operations are supported
* by current Operator.
*/
typedef struct opendal_capability {
/**
* If operator supports stat.
*/
bool stat;
/**
* If operator supports stat with if match.
*/
bool stat_with_if_match;
/**
* If operator supports stat with if none match.
*/
bool stat_with_if_none_match;
/**
* If operator supports read.
*/
bool read;
/**
* If operator supports read with if match.
*/
bool read_with_if_match;
/**
* If operator supports read with if none match.
*/
bool read_with_if_none_match;
/**
* if operator supports read with override cache control.
*/
bool read_with_override_cache_control;
/**
* if operator supports read with override content disposition.
*/
bool read_with_override_content_disposition;
/**
* if operator supports read with override content type.
*/
bool read_with_override_content_type;
/**
* If operator supports write.
*/
bool write;
/**
* If operator supports write can be called in multi times.
*/
bool write_can_multi;
/**
* If operator supports write with empty content.
*/
bool write_can_empty;
/**
* If operator supports write by append.
*/
bool write_can_append;
/**
* If operator supports write with content type.
*/
bool write_with_content_type;
/**
* If operator supports write with content disposition.
*/
bool write_with_content_disposition;
/**
* If operator supports write with cache control.
*/
bool write_with_cache_control;
/**
* write_multi_max_size is the max size that services support in write_multi.
*
* For example, AWS S3 supports 5GiB as max in write_multi.
*
* If it is not set, this will be zero
*/
uintptr_t write_multi_max_size;
/**
* write_multi_min_size is the min size that services support in write_multi.
*
* For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
*
* If it is not set, this will be zero
*/
uintptr_t write_multi_min_size;
/**
* write_total_max_size is the max size that services support in write_total.
*
* For example, Cloudflare D1 supports 1MB as max in write_total.
*
* If it is not set, this will be zero
*/
uintptr_t write_total_max_size;
/**
* If operator supports create dir.
*/
bool create_dir;
/**
* If operator supports delete.
*/
bool delete_;
/**
* If operator supports copy.
*/
bool copy;
/**
* If operator supports rename.
*/
bool rename;
/**
* If operator supports list.
*/
bool list;
/**
* If backend supports list with limit.
*/
bool list_with_limit;
/**
* If backend supports list with start after.
*/
bool list_with_start_after;
/**
* If backend supports list without delimiter.
*/
bool list_with_recursive;
/**
* If operator supports presign.
*/
bool presign;
/**
* If operator supports presign read.
*/
bool presign_read;
/**
* If operator supports presign stat.
*/
bool presign_stat;
/**
* If operator supports presign write.
*/
bool presign_write;
/**
* If operator supports shared.
*/
bool shared;
/**
* If operator supports blocking.
*/
bool blocking;
} opendal_capability;
/**
* \brief The is the result type returned by opendal_reader_read().
* The result type contains a size field, which is the size of the data read,
* which is zero on error. The error field is the error code and error message.
*/
typedef struct opendal_result_reader_read {
/**
* The read size if succeed.
*/
uintptr_t size;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_reader_read;
/**
* \brief The result type returned by opendal_writer_write().
* The result type contains a size field, which is the size of the data written,
* which is zero on error. The error field is the error code and error message.
*/
typedef struct opendal_result_writer_write {
/**
* The write size if succeed.
*/
uintptr_t size;
/**
* The error, if ok, it is null
*/
struct opendal_error *error;
} opendal_result_writer_write;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* \brief Frees the opendal_error, ok to call on NULL
*/
void opendal_error_free(struct opendal_error *ptr);
/**
* \brief Return the next object to be listed
*
* Lister is an iterator of the objects under its path, this method is the same as
* calling next() on the iterator
*
* For examples, please see the comment section of opendal_operator_list()
* @see opendal_operator_list()
*/
struct opendal_result_lister_next opendal_lister_next(struct opendal_lister *self);
/**
* \brief Free the heap-allocated metadata used by opendal_lister
*/
void opendal_lister_free(struct opendal_lister *ptr);
/**
* \brief Free the heap-allocated metadata used by opendal_metadata
*/
void opendal_metadata_free(struct opendal_metadata *ptr);
/**
* \brief Return the content_length of the metadata
*
* # Example
* ```C
* // ... previously you wrote "Hello, World!" to path "/testpath"
* opendal_result_stat s = opendal_operator_stat(op, "/testpath");
* assert(s.error == NULL);
*
* opendal_metadata *meta = s.meta;
* assert(opendal_metadata_content_length(meta) == 13);
* ```
*/
uint64_t opendal_metadata_content_length(const struct opendal_metadata *self);
/**
* \brief Return whether the path represents a file
*
* # Example
* ```C
* // ... previously you wrote "Hello, World!" to path "/testpath"
* opendal_result_stat s = opendal_operator_stat(op, "/testpath");
* assert(s.error == NULL);
*
* opendal_metadata *meta = s.meta;
* assert(opendal_metadata_is_file(meta));
* ```
*/
bool opendal_metadata_is_file(const struct opendal_metadata *self);
/**
* \brief Return whether the path represents a directory
*
* # Example
* ```C
* // ... previously you wrote "Hello, World!" to path "/testpath"
* opendal_result_stat s = opendal_operator_stat(op, "/testpath");
* assert(s.error == NULL);
*
* opendal_metadata *meta = s.meta;
*
* // this is not a directory
* assert(!opendal_metadata_is_dir(meta));
* ```
*
* \todo This is not a very clear example. A clearer example will be added
* after we support opendal_operator_mkdir()
*/
bool opendal_metadata_is_dir(const struct opendal_metadata *self);
/**
* \brief Return the last_modified of the metadata, in milliseconds
*
* # Example
* ```C
* // ... previously you wrote "Hello, World!" to path "/testpath"
* opendal_result_stat s = opendal_operator_stat(op, "/testpath");
* assert(s.error == NULL);
*
* opendal_metadata *meta = s.meta;
* assert(opendal_metadata_last_modified_ms(meta) != -1);
* ```
*/
int64_t opendal_metadata_last_modified_ms(const struct opendal_metadata *self);
/**
* \brief Free the heap-allocated operator pointed by opendal_operator.
*
* Please only use this for a pointer pointing at a valid opendal_operator.
* Calling this function on NULL does nothing, but calling this function on pointers
* of other type will lead to segfault.
*
* # Example
*
* ```C
* opendal_operator *op = opendal_operator_new("fs", NULL);
* // ... use this op, maybe some reads and writes
*
* // free this operator
* opendal_operator_free(op);
* ```
*/
void opendal_operator_free(const struct opendal_operator *ptr);
/**
* \brief Construct an operator based on `scheme` and `options`
*
* Uses an array of key-value pairs to initialize the operator based on provided `scheme`
* and `options`. For each scheme, i.e. Backend, different options could be set, you may
* reference the [documentation](https://opendal.apache.org/docs/category/services/) for
* each service, especially for the **Configuration Part**.
*
* @param scheme the service scheme you want to specify, e.g. "fs", "s3"
* @param options the pointer to the options for this operator, it could be NULL, which means no
* option is set
* @see opendal_operator_options
* @return A valid opendal_result_operator_new setup with the `scheme` and `options` is the construction
* succeeds. On success the operator field is a valid pointer to a newly allocated opendal_operator,
* and the error field is NULL. Otherwise, the operator field is a NULL pointer and the error field.
*
* # Example
*
* Following is an example.
* ```C
* // Allocate a new options
* opendal_operator_options *options = opendal_operator_options_new();
* // Set the options you need
* opendal_operator_options_set(options, "root", "/myroot");
*
* // Construct the operator based on the options and scheme
* opendal_result_operator_new result = opendal_operator_new("memory", options);
* opendal_operator* op = result.op;
*
* // you could free the options right away since the options is not used afterwards
* opendal_operator_options_free(options);
*
* // ... your operations
* ```
*
* # Safety
*
* The only unsafe case is passing an invalid c string pointer to the `scheme` argument.
*/
struct opendal_result_operator_new opendal_operator_new(const char *scheme,
const struct opendal_operator_options *options);
/**
* \brief Blocking write raw bytes to `path`.
*
* Write the `bytes` into the `path` blocking by `op_ptr`.
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* \note It is important to notice that the `bytes` that is passes in will be consumed by this
* function. Therefore, you should not use the `bytes` after this function returns.
*
* @param op The opendal_operator created previously
* @param path The designated path you want to write your bytes in
* @param bytes The opendal_byte typed bytes to be written
* @see opendal_operator
* @see opendal_bytes
* @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 };
*
* // now you can write!
* opendal_error *err = opendal_operator_write(op, "/testpath", bytes);
*
* // Assert that this succeeds
* assert(err == NULL);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
* * The `bytes` provided has valid byte in the `data` field and the `len` field is set
* correctly.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_error *opendal_operator_write(const struct opendal_operator *op,
const char *path,
const struct opendal_bytes *bytes);
/**
* \brief Blocking read the data from `path`.
*
* Read the data out from `path` blocking by operator.
*
* @param op The opendal_operator created previously
* @param path The path you want to read the data out
* @see opendal_operator
* @see opendal_result_read
* @see opendal_error
* @return Returns opendal_result_read, the `data` field is a pointer to a newly allocated
* opendal_bytes, the `error` field contains the error. If the `error` is not NULL, then
* the operation failed and the `data` field is a nullptr.
*
* \note If the read operation succeeds, the returned opendal_bytes is newly allocated on heap.
* After your usage of that, please call opendal_bytes_free() to free the space.
*
* # Example
*
* Following is an example
* ```C
* // ... you have write "Hello, World!" to path "/testpath"
*
* opendal_result_read r = opendal_operator_read(op, "testpath");
* assert(r.error == NULL);
*
* opendal_bytes bytes = r.data;
* assert(bytes.len == 13);
* opendal_bytes_free(&bytes);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_read opendal_operator_read(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking read the data from `path`.
*
* Read the data out from `path` blocking by operator, returns
* an opendal_result_read with error code.
*
* @param op The opendal_operator created previously
* @param path The path you want to read the data out
* @see opendal_operator
* @see opendal_result_read
* @see opendal_code
* @return Returns opendal_code
*
* \note If the read operation succeeds, the returned opendal_bytes is newly allocated on heap.
* After your usage of that, please call opendal_bytes_free() to free the space.
*
* # Example
*
* Following is an example
* ```C
* // ... you have created an operator named op
*
* opendal_result_operator_reader result = opendal_operator_reader(op, "/testpath");
* assert(result.error == NULL);
* // The reader is in result.reader
* opendal_reader *reader = result.reader;
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_operator_reader opendal_operator_reader(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking create a writer for the specified path.
*
* This function prepares a writer that can be used to write data to the specified path
* using the provided operator. If successful, it returns a valid writer; otherwise, it
* returns an error.
*
* @param op The opendal_operator created previously
* @param path The designated path where the writer will be used
* @see opendal_operator
* @see opendal_result_operator_writer
* @see opendal_error
* @return Returns opendal_result_operator_writer, containing a writer and an opendal_error.
* If the operation succeeds, the `writer` field holds a valid writer and the `error` field
* is null. Otherwise, the `writer` will be null and the `error` will be set correspondingly.
*
* # Example
*
* Following is an example
* ```C
* //...prepare your opendal_operator, named op for example
*
* opendal_result_operator_writer result = opendal_operator_writer(op, "/testpath");
* assert(result.error == NULL);
* opendal_writer *writer = result.writer;
* // Use the writer to write data...
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_operator_writer opendal_operator_writer(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking delete the object in `path`.
*
* Delete the object in `path` blocking by `op_ptr`.
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* @param op The opendal_operator created previously
* @param path The designated path you want to delete
* @see opendal_operator
* @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);
*
* // now you can delete!
* opendal_error *error = opendal_operator_delete(op, "/testpath");
*
* // Assert that this succeeds
* assert(error == NULL);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_error *opendal_operator_delete(const struct opendal_operator *op, const char *path);
/**
* \brief Check whether the path exists.
*
* If the operation succeeds, no matter the path exists or not,
* the error should be a nullptr. Otherwise, the field `is_exist`
* is filled with false, and the error is set
*
* @param op The opendal_operator created previously
* @param path The path you want to check existence
* @see opendal_operator
* @see opendal_result_is_exist
* @see opendal_error
* @return Returns opendal_result_is_exist, the `is_exist` field contains whether the path exists.
* However, it the operation fails, the `is_exist` will contain false and the error will be set.
*
* # Example
*
* ```C
* // .. you previously wrote some data to path "/mytest/obj"
* opendal_result_is_exist e = opendal_operator_is_exist(op, "/mytest/obj");
* assert(e.error == NULL);
* assert(e.is_exist);
*
* // but you previously did **not** write any data to path "/yourtest/obj"
* opendal_result_is_exist e = opendal_operator_is_exist(op, "/yourtest/obj");
* assert(e.error == NULL);
* assert(!e.is_exist);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
__attribute__((deprecated("Use opendal_operator_exists() instead.")))
struct opendal_result_is_exist opendal_operator_is_exist(const struct opendal_operator *op,
const char *path);
/**
* \brief Check whether the path exists.
*
* If the operation succeeds, no matter the path exists or not,
* the error should be a nullptr. Otherwise, the field `exists`
* is filled with false, and the error is set
*
* @param op The opendal_operator created previously
* @param path The path you want to check existence
* @see opendal_operator
* @see opendal_result_exists
* @see opendal_error
* @return Returns opendal_result_exists, the `exists` field contains whether the path exists.
* However, it the operation fails, the `exists` will contain false and the error will be set.
*
* # Example
*
* ```C
* // .. you previously wrote some data to path "/mytest/obj"
* opendal_result_exists e = opendal_operator_exists(op, "/mytest/obj");
* assert(e.error == NULL);
* assert(e.exists);
*
* // but you previously did **not** write any data to path "/yourtest/obj"
* opendal_result_exists e = opendal_operator_exists(op, "/yourtest/obj");
* assert(e.error == NULL);
* assert(!e.exists);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_exists opendal_operator_exists(const struct opendal_operator *op,
const char *path);
/**
* \brief Stat the path, return its metadata.
*
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* @param op The opendal_operator created previously
* @param path The path you want to stat
* @see opendal_operator
* @see opendal_result_stat
* @see opendal_metadata
* @return Returns opendal_result_stat, containing a metadata and an opendal_error.
* If the operation succeeds, the `meta` field would hold a valid metadata and
* the `error` field should hold nullptr. Otherwise, the metadata will contain a
* NULL pointer, i.e. invalid, and the `error` will be set correspondingly.
*
* # Example
*
* ```C
* // ... previously you wrote "Hello, World!" to path "/testpath"
* opendal_result_stat s = opendal_operator_stat(op, "/testpath");
* assert(s.error == NULL);
*
* const opendal_metadata *meta = s.meta;
*
* // ... you could now use your metadata, notice that please only access metadata
* // using the APIs provided by OpenDAL
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_stat opendal_operator_stat(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking list the objects in `path`.
*
* List the object in `path` blocking by `op_ptr`, return a result with an
* opendal_lister. Users should call opendal_lister_next() on the
* lister.
*
* @param op The opendal_operator created previously
* @param path The designated path you want to list
* @see opendal_lister
* @return Returns opendal_result_list, containing a lister and an opendal_error.
* If the operation succeeds, the `lister` field would hold a valid lister and
* the `error` field should hold nullptr. Otherwise, the `lister`` will contain a
* NULL pointer, i.e. invalid, and the `error` will be set correspondingly.
*
* # Example
*
* Following is an example
* ```C
* // You have written some data into some files path "root/dir1"
* // Your opendal_operator was called op
* opendal_result_list l = opendal_operator_list(op, "root/dir1");
* assert(l.error == ERROR);
*
* opendal_lister *lister = l.lister;
* opendal_list_entry *entry;
*
* while ((entry = opendal_lister_next(lister)) != NULL) {
* const char* de_path = opendal_list_entry_path(entry);
* const char* de_name = opendal_list_entry_name(entry);
* // ...... your operations
*
* // remember to free the entry after you are done using it
* opendal_list_entry_free(entry);
* }
*
* // and remember to free the lister
* opendal_lister_free(lister);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_result_list opendal_operator_list(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking create the directory in `path`.
*
* Create the directory in `path` blocking by `op_ptr`.
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* @param op The opendal_operator created previously
* @param path The designated directory you want to create
* @see opendal_operator
* @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
*
* // create your directory
* opendal_error *error = opendal_operator_create_dir(op, "/testdir/");
*
* // Assert that this succeeds
* assert(error == NULL);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` must contain a valid nul terminator at the end of
* the string.
*
* # Panic
*
* * If the `path` points to NULL, this function panics, i.e. exits with information
*/
struct opendal_error *opendal_operator_create_dir(const struct opendal_operator *op,
const char *path);
/**
* \brief Blocking rename the object in `path`.
*
* Rename the object in `src` to `dest` blocking by `op`.
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* @param op The opendal_operator created previously
* @param src The designated source path you want to rename
* @param dest The designated destination path you want to rename
* @see opendal_operator
* @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);
*
* // now you can rename!
* opendal_error *error = opendal_operator_rename(op, "/testpath", "/testpath2");
*
* // Assert that this succeeds
* assert(error == NULL);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` 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_rename(const struct opendal_operator *op,
const char *src,
const char *dest);
/**
* \brief Blocking copy the object in `path`.
*
* Copy the object in `src` to `dest` blocking by `op`.
* Error is NULL if successful, otherwise it contains the error code and error message.
*
* @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
* @see opendal_operator
* @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);
*
* // now you can rename!
* opendal_error *error = opendal_operator_copy(op, "/testpath", "/testpath2");
*
* // Assert that this succeeds
* assert(error == NULL);
* ```
*
* # Safety
*
* It is **safe** under the cases below
* * The memory pointed to by `path` 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(const struct opendal_operator *op,
const char *src,
const char *dest);
struct opendal_error *opendal_operator_check(const struct opendal_operator *op);
/**
* \brief Get information of underlying accessor.
*
* # Example
*
* ```C
* /// suppose you have a memory-backed opendal_operator* named op
* char *scheme;
* opendal_operator_info *info = opendal_operator_info_new(op);
*
* scheme = opendal_operator_info_get_scheme(info);
* assert(!strcmp(scheme, "memory"));
*
* /// free the heap memory
* free(scheme);
* opendal_operator_info_free(info);
* ```
*/
struct opendal_operator_info *opendal_operator_info_new(const struct opendal_operator *op);
/**
* \brief Free the heap-allocated opendal_operator_info
*/
void opendal_operator_info_free(struct opendal_operator_info *ptr);
/**
* \brief Return the nul-terminated operator's scheme, i.e. service
*
* \note: The string is on heap, remember to free it
*/
char *opendal_operator_info_get_scheme(const struct opendal_operator_info *self);
/**
* \brief Return the nul-terminated operator's working root path
*
* \note: The string is on heap, remember to free it
*/
char *opendal_operator_info_get_root(const struct opendal_operator_info *self);
/**
* \brief Return the nul-terminated operator backend's name, could be empty if underlying backend has no
* namespace concept.
*
* \note: The string is on heap, remember to free it
*/
char *opendal_operator_info_get_name(const struct opendal_operator_info *self);
/**
* \brief Return the operator's full capability
*/
struct opendal_capability opendal_operator_info_get_full_capability(const struct opendal_operator_info *self);
/**
* \brief Return the operator's native capability
*/
struct opendal_capability opendal_operator_info_get_native_capability(const struct opendal_operator_info *self);
/**
* \brief Frees the heap memory used by the opendal_bytes
*/
void opendal_bytes_free(struct opendal_bytes *ptr);
/**
* \brief Construct a heap-allocated opendal_operator_options
*
* @return An empty opendal_operator_option, which could be set by
* opendal_operator_option_set().
*
* @see opendal_operator_option_set
*/
struct opendal_operator_options *opendal_operator_options_new(void);
/**
* \brief Set a Key-Value pair inside opendal_operator_options
*
* # Safety
*
* This function is unsafe because it dereferences and casts the raw pointers
* Make sure the pointer of `key` and `value` point to a valid string.
*
* # Example
*
* ```C
* opendal_operator_options *options = opendal_operator_options_new();
* opendal_operator_options_set(options, "root", "/myroot");
*
* // .. use your opendal_operator_options
*
* opendal_operator_options_free(options);
* ```
*/
void opendal_operator_options_set(struct opendal_operator_options *self,
const char *key,
const char *value);
/**
* \brief Free the allocated memory used by [`opendal_operator_options`]
*/
void opendal_operator_options_free(struct opendal_operator_options *ptr);
/**
* \brief Path of entry.
*
* Path is relative to operator's root. Only valid in current operator.
*
* \note To free the string, you can directly call free()
*/
char *opendal_entry_path(const struct opendal_entry *self);
/**
* \brief Name of entry.
*
* Name is the last segment of path.
* If this entry is a dir, `Name` MUST endswith `/`
* Otherwise, `Name` MUST NOT endswith `/`.
*
* \note To free the string, you can directly call free()
*/
char *opendal_entry_name(const struct opendal_entry *self);
/**
* \brief Frees the heap memory used by the opendal_list_entry
*/
void opendal_entry_free(struct opendal_entry *ptr);
/**
* \brief Read data from the reader.
*/
struct opendal_result_reader_read opendal_reader_read(struct opendal_reader *self,
uint8_t *buf,
uintptr_t len);
/**
* \brief Seek to an offset, in bytes, in a stream.
*/
struct opendal_error *opendal_reader_seek(struct opendal_reader *self,
int64_t offset,
int32_t whence);
/**
* \brief Frees the heap memory used by the opendal_reader.
*/
void opendal_reader_free(struct opendal_reader *ptr);
/**
* \brief Write data to the writer.
*/
struct opendal_result_writer_write opendal_writer_write(struct opendal_writer *self,
const struct opendal_bytes *bytes);
/**
* \brief Close the writer and make sure all data have been stored.
*/
struct opendal_error *opendal_writer_close(struct opendal_writer *ptr);
/**
* \brief Frees the heap memory used by the opendal_writer.
*/
void opendal_writer_free(struct opendal_writer *ptr);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif /* _OPENDAL_H */