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
7 changes: 4 additions & 3 deletions include/miniocpp/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ struct CreateMultipartUploadArgs : public ObjectArgs {
}; // struct CreateMultipartUploadArgs

struct PutObjectBaseArgs : public ObjectWriteArgs {
long object_size = -1;
std::optional<uint64_t> object_size;
size_t part_size = 0;
long part_count = 0;
std::optional<size_t> part_count;
std::string content_type;

PutObjectBaseArgs() = default;
Expand Down Expand Up @@ -348,7 +348,8 @@ struct PutObjectArgs : public PutObjectBaseArgs {
std::string checksum_crc64nvme; // CRC64NVME checksum for multipart uploads

PutObjectArgs() = default;
PutObjectArgs(std::istream& stream, long object_size, long part_size);
PutObjectArgs(std::istream& stream, std::optional<uint64_t> object_size,
size_t part_size);
~PutObjectArgs() = default;

error::Error Validate();
Expand Down
5 changes: 3 additions & 2 deletions include/miniocpp/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <ios>
#include <list>
#include <map>
#include <optional>
#include <set>
#include <streambuf>
#include <string>
Expand Down Expand Up @@ -121,8 +122,8 @@ std::string Crc64NvmeBase64(const char* data, size_t len);
error::Error CheckBucketName(std::string_view bucket_name, bool strict = false);
error::Error ReadPart(std::istream& stream, char* buf, size_t size,
size_t& bytes_read);
error::Error CalcPartInfo(long object_size, size_t& part_size,
long& part_count);
error::Error CalcPartInfo(std::optional<uint64_t> object_size,
size_t& part_size, std::optional<size_t>& part_count);

/**
* UtcTime represents date and time in UTC timezone.
Expand Down
10 changes: 5 additions & 5 deletions src/args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,9 @@ ListObjectVersionsArgs& ListObjectVersionsArgs::operator=(
return this->operator=(ListObjectVersionsArgs(args));
}

PutObjectArgs::PutObjectArgs(std::istream& istream, long object_size,
long part_size)
PutObjectArgs::PutObjectArgs(std::istream& istream,
std::optional<uint64_t> object_size,
size_t part_size)
: stream(&istream) {
this->object_size = object_size;
this->part_size = part_size;
Expand All @@ -317,7 +318,7 @@ error::Error PutObjectArgs::Validate() {
if (!size.has_value()) {
return error::Error("size must be set when buf is set");
}
if (object_size < 0) object_size = static_cast<long>(*size);
if (!object_size.has_value()) object_size = static_cast<uint64_t>(*size);
}
return utils::CalcPartInfo(object_size, part_size, part_count);
}
Expand Down Expand Up @@ -440,8 +441,7 @@ error::Error UploadObjectArgs::Validate() {
}

std::filesystem::path file_path = filename;
size_t obj_size = std::filesystem::file_size(file_path);
object_size = static_cast<long>(obj_size);
object_size = static_cast<uint64_t>(std::filesystem::file_size(file_path));
return utils::CalcPartInfo(object_size, part_size, part_count);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

Expand Down
22 changes: 12 additions & 10 deletions src/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -542,24 +542,24 @@ PutObjectResponse Client::PutObject(PutObjectArgs args, std::string& upload_id,
}
}

long object_size = args.object_size;
std::optional<uint64_t> object_size = args.object_size;
size_t part_size = args.part_size;
size_t uploaded_size = 0;
unsigned int part_number = 0;
std::string one_byte;
bool stop = false;
std::list<Part> parts;
long part_count = args.part_count;
std::optional<size_t> part_count = args.part_count;
double uploaded_bytes = 0; // for progress
double upload_speed = -1; // for progress

while (!stop) {
part_number++;

size_t bytes_read = 0;
if (part_count > 0) {
if (part_number == part_count) {
part_size = object_size - uploaded_size;
if (part_count.has_value()) {
if (part_number == *part_count) {
part_size = *object_size - uploaded_size;
stop = true;
}

Expand Down Expand Up @@ -596,7 +596,7 @@ PutObjectResponse Client::PutObject(PutObjectArgs args, std::string& upload_id,
// If bytes read is less than or equals to part size, then we have reached
// last part.
if (bytes_read <= part_size) {
part_count = part_number;
part_count = std::optional<size_t>(part_number);
part_size = bytes_read;
stop = true;
} else {
Expand All @@ -608,7 +608,7 @@ PutObjectResponse Client::PutObject(PutObjectArgs args, std::string& upload_id,

uploaded_size += part_size;

if (part_count == 1) {
if (part_count.has_value() && *part_count == 1) {
PutObjectApiArgs api_args;
api_args.extra_query_params = args.extra_query_params;
api_args.bucket = args.bucket;
Expand Down Expand Up @@ -679,7 +679,8 @@ PutObjectResponse Client::PutObject(PutObjectArgs args, std::string& upload_id,
}

http::ProgressFunctionArgs actual_args;
actual_args.upload_total_bytes = static_cast<double>(object_size);
actual_args.upload_total_bytes =
object_size ? static_cast<double>(*object_size) : -1.0;
actual_args.uploaded_bytes = uploaded_bytes + args.uploaded_bytes;
actual_args.userdata = progress_userdata;
return progressfunc(actual_args);
Expand All @@ -702,7 +703,8 @@ PutObjectResponse Client::PutObject(PutObjectArgs args, std::string& upload_id,
if (args.progressfunc != nullptr) {
uploaded_bytes += static_cast<double>(data.length());
http::ProgressFunctionArgs actual_args;
actual_args.upload_total_bytes = static_cast<double>(object_size);
actual_args.upload_total_bytes =
object_size ? static_cast<double>(*object_size) : -1.0;
actual_args.uploaded_bytes = uploaded_bytes;
actual_args.userdata = args.progress_userdata;
if (!args.progressfunc(actual_args)) {
Expand Down Expand Up @@ -989,7 +991,7 @@ PutObjectResponse Client::PutObject(PutObjectArgs args) {
std::stringstream ss(std::ios_base::in | std::ios_base::out);
ss.rdbuf()->pubsetbuf(args.buf, size);

PutObjectArgs http_args(ss, static_cast<long>(size), 16 * 1024 * 1024L);
PutObjectArgs http_args(ss, static_cast<uint64_t>(size), 16 * 1024 * 1024L);
http_args.bucket = args.bucket;
http_args.object = args.object;
http_args.region = region;
Expand Down
28 changes: 15 additions & 13 deletions src/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "miniocpp/utils.h"

#include <charconv>
#include <optional>

#include "miniocpp/error.h"

Expand Down Expand Up @@ -662,8 +663,9 @@ error::Error ReadPart(std::istream& stream, char* buf, size_t size,
return error::SUCCESS;
}

error::Error CalcPartInfo(long object_size, size_t& part_size,
long& part_count) {
error::Error CalcPartInfo(std::optional<uint64_t> object_size,
size_t& part_size,
std::optional<size_t>& part_count) {
if (part_size > 0) {
if (part_size < kMinPartSize) {
return error::Error("part size " + std::to_string(part_size) +
Expand All @@ -676,33 +678,33 @@ error::Error CalcPartInfo(long object_size, size_t& part_size,
}
}

if (object_size >= 0) {
if (static_cast<uint64_t>(object_size) > kMaxObjectSize) {
return error::Error("object size " + std::to_string(object_size) +
if (object_size.has_value()) {
if (*object_size > kMaxObjectSize) {
return error::Error("object size " + std::to_string(*object_size) +
" is not supported; maximum allowed 5TiB");
}
} else if (part_size <= 0) {
return error::Error(
"valid part size must be provided when object size is unknown");
}

if (object_size < 0) {
part_count = -1;
if (!object_size.has_value()) {
part_count.reset();
return error::SUCCESS;
}

if (part_size <= 0) {
// Calculate part size by multiple of kOptPartSize.
double psize = std::ceil((double)object_size / kMaxMultipartCount);
double psize = std::ceil((double)*object_size / kMaxMultipartCount);
part_size = (size_t)std::ceil(psize / kMinPartSize) * kMinPartSize;
}

if (static_cast<long>(part_size) > object_size) part_size = object_size;
part_count = static_cast<long>(
(part_size > 0) ? ((object_size + part_size - 1) / part_size) : 1);
if (part_count > kMaxMultipartCount) {
if (part_size > *object_size) part_size = *object_size;
part_count = static_cast<size_t>(
(part_size > 0) ? ((*object_size + part_size - 1) / part_size) : 1);
if (*part_count > kMaxMultipartCount) {
return error::Error(
"object size " + std::to_string(object_size) + " and part size " +
"object size " + std::to_string(*object_size) + " and part size " +
std::to_string(part_size) + " make more than " +
std::to_string(kMaxMultipartCount) + "parts for upload");
}
Expand Down
21 changes: 12 additions & 9 deletions tests/tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class Tests {

std::string data = "StatObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()), 0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down Expand Up @@ -309,7 +309,7 @@ class Tests {
std::string object_name = RandObjectName();
std::string data = "RemoveObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()), 0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand All @@ -326,7 +326,7 @@ class Tests {

std::string data = "DownloadObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()), 0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down Expand Up @@ -372,7 +372,7 @@ class Tests {

std::string data = "GetObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()), 0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down Expand Up @@ -461,7 +461,8 @@ class Tests {
std::string object_name = RandObjectName();
std::string data = "PutObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, data.length(), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()),
0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand All @@ -475,7 +476,7 @@ class Tests {
std::string object_name = RandObjectName();
size_t size = 67108865; // (64MiB + 1) bytes
RandCharStream stream(size);
minio::s3::PutObjectArgs args(stream, size, 0);
minio::s3::PutObjectArgs args(stream, static_cast<uint64_t>(size), 0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand All @@ -497,7 +498,7 @@ class Tests {
std::string src_object_name = RandObjectName();
std::string data = "CopyObject()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()), 0);
args.bucket = bucket_name_;
args.object = src_object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down Expand Up @@ -584,7 +585,8 @@ class Tests {
"1996,Jeep,Grand Cherokee,\"MUST SELL!\n"
"air, moon roof, loaded\",4799.00\n";
std::stringstream ss("Year,Make,Model,Description,Price\n" + data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(ss.str().length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(ss.str().length()),
0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down Expand Up @@ -664,7 +666,8 @@ class Tests {
try {
std::string data = "ListenBucketNotification()";
std::stringstream ss(data);
minio::s3::PutObjectArgs args(ss, static_cast<long>(data.length()), 0);
minio::s3::PutObjectArgs args(ss, static_cast<uint64_t>(data.length()),
0);
args.bucket = bucket_name_;
args.object = object_name;
minio::s3::PutObjectResponse resp = client_.PutObject(args);
Expand Down
Loading