use crate::callback::{c_callback, with_libstorage_lock, CallbackFuture};
use crate::error::{Result, StorageError};
use crate::ffi::{storage_upload_chunk, string_to_c_string};
use crate::node::lifecycle::StorageNode;
pub async fn upload_chunk(node: &StorageNode, session_id: &str, chunk: Vec<u8>) -> Result<()> {
if session_id.is_empty() {
return Err(StorageError::invalid_parameter(
"session_id",
"Session ID cannot be empty",
));
}
if chunk.is_empty() {
return Err(StorageError::invalid_parameter(
"chunk",
"Chunk cannot be empty",
));
}
let future = CallbackFuture::new();
let context_ptr = future.context_ptr();
let chunk_ptr = chunk.as_ptr() as *mut u8;
let chunk_len = chunk.len();
let result = with_libstorage_lock(|| unsafe {
node.with_ctx(|ctx| {
let c_session_id = string_to_c_string(session_id);
storage_upload_chunk(
ctx as *mut _,
c_session_id.as_ptr(),
chunk_ptr,
chunk_len,
Some(c_callback),
context_ptr.as_ptr(),
)
})
});
if result != 0 {
return Err(StorageError::upload_error("Failed to upload chunk"));
}
future.await?;
Ok(())
}
pub async fn upload_chunks(
node: &StorageNode,
session_id: &str,
chunks: Vec<Vec<u8>>,
) -> Result<()> {
for (index, chunk) in chunks.into_iter().enumerate() {
upload_chunk(node, session_id, chunk).await.map_err(|e| {
StorageError::upload_error(format!("Failed to upload chunk {}: {}", index, e))
})?;
}
Ok(())
}