From 74934472d69b42a90f0f3826169224096654303c Mon Sep 17 00:00:00 2001 From: Vaibhav Pratap Date: Mon, 3 Aug 2026 07:21:48 +0000 Subject: [PATCH 1/5] docs(storage): update async samples to use PrecomputedChecksumsOption Use the new PrecomputedChecksumsOption instead of UseCrc32cValueOption in the async upload sample. --- google/cloud/storage/examples/storage_async_samples.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/google/cloud/storage/examples/storage_async_samples.cc b/google/cloud/storage/examples/storage_async_samples.cc index 902855efcdfe4..43089f5f78a09 100644 --- a/google/cloud/storage/examples/storage_async_samples.cc +++ b/google/cloud/storage/examples/storage_async_samples.cc @@ -751,10 +751,10 @@ void CreateAndWriteAppendableObjectWithChecksum( // Set the expected CRC32C checksum in the current options scope // just before calling Finalize(). - // Note: 548262564U is the pre-computed CRC32C checksum for the string "Some - // data\n". If the data changes, this checksum must be updated to match. google::cloud::internal::OptionsSpan span( - google::cloud::Options{}.set(548262564U)); + google::cloud::Options{}.set( + gcs::PrecomputedChecksums{ + gcs::ComputeCrc32cChecksum("Some data\n"), ""})); co_return (co_await writer.Finalize(std::move(token))).value(); }; // [END storage_create_and_write_appendable_object_with_checksum] From b0764fc13befc3556b85a071740109a76a6557b2 Mon Sep 17 00:00:00 2001 From: Vaibhav Pratap Date: Mon, 3 Aug 2026 07:26:25 +0000 Subject: [PATCH 2/5] docs(storage): add sync samples for PrecomputedChecksumsOption Added and examples to demonstrate how to provide precomputed hashes to synchronous client calls. --- .../examples/storage_object_samples.cc | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/google/cloud/storage/examples/storage_object_samples.cc b/google/cloud/storage/examples/storage_object_samples.cc index b805107bb8ec4..cd45dc4fe3be0 100644 --- a/google/cloud/storage/examples/storage_object_samples.cc +++ b/google/cloud/storage/examples/storage_object_samples.cc @@ -145,6 +145,29 @@ void InsertObject(google::cloud::storage::Client client, (std::move(client), argv.at(0), argv.at(1), argv.at(2)); } +void InsertObjectWithChecksum(google::cloud::storage::Client client, + std::vector const& argv) { + //! [insert-object-with-checksum] + namespace gcs = ::google::cloud::storage; + using ::google::cloud::StatusOr; + [](gcs::Client client, std::string const& bucket_name, + std::string const& object_name, std::string const& contents) { + StatusOr object_metadata = client.InsertObject( + bucket_name, object_name, std::move(contents), + google::cloud::Options{}.set( + gcs::PrecomputedChecksums{ + gcs::ComputeCrc32cChecksum(contents), ""})); + + if (!object_metadata) throw std::move(object_metadata).status(); + + std::cout << "The object " << object_metadata->name() + << " was created in bucket " << object_metadata->bucket() + << " with precomputed checksums.\n"; + } + //! [insert-object-with-checksum] + (std::move(client), argv.at(0), argv.at(1), argv.at(2)); +} + // NOLINTNEXTLINE(performance-unnecessary-value-param) void InsertObjectStrictIdempotency(google::cloud::storage::Client, std::vector const& argv) { @@ -394,6 +417,34 @@ void WriteObject(google::cloud::storage::Client client, (std::move(client), argv.at(0), argv.at(1), std::stoi(argv.at(2))); } +void WriteObjectWithChecksum(google::cloud::storage::Client client, + std::vector const& argv) { + //! [write-object-with-checksum] + namespace gcs = ::google::cloud::storage; + using ::google::cloud::StatusOr; + [](gcs::Client client, std::string const& bucket_name, + std::string const& object_name) { + std::string const text = "Some data\n"; + gcs::ObjectWriteStream stream = client.WriteObject( + bucket_name, object_name, + google::cloud::Options{}.set( + gcs::PrecomputedChecksums{ + gcs::ComputeCrc32cChecksum(text), ""})); + + stream << text; + stream.Close(); + + StatusOr metadata = std::move(stream).metadata(); + if (!metadata) throw std::move(metadata).status(); + + std::cout << "The object " << metadata->name() + << " was created in bucket " << metadata->bucket() + << " with precomputed checksums.\n"; + } + //! [write-object-with-checksum] + (std::move(client), argv.at(0), argv.at(1)); +} + void WriteObjectFromMemory(google::cloud::storage::Client client, std::vector const& argv) { //! [write object from memory] [START storage_file_upload_from_memory] @@ -677,6 +728,9 @@ void RunAll(std::vector const& argv) { std::cout << "\nRunning InsertObject() example [1]" << std::endl; InsertObject(client, {bucket_name, object_name, object_media}); + std::cout << "\nRunning InsertObjectWithChecksum() example" << std::endl; + InsertObjectWithChecksum(client, {bucket_name, object_name + "_with_checksum", object_media}); + std::cout << "\nRunning ListObjects() example" << std::endl; ListObjects(client, {bucket_name}); @@ -725,6 +779,9 @@ void RunAll(std::vector const& argv) { std::cout << "\nRunning WriteObject() example" << std::endl; WriteObject(client, {bucket_name, object_name, "100000"}); + std::cout << "\nRunning WriteObjectWithChecksum() example" << std::endl; + WriteObjectWithChecksum(client, {bucket_name, object_name + "_write_checksum"}); + std::cout << "\nRunning ReadObjectRange() example" << std::endl; ReadObjectRange(client, {bucket_name, object_name, "1000", "2000"}); @@ -830,6 +887,9 @@ int main(int argc, char* argv[]) { ListObjectsAndFolders), make_entry("insert-object", {"", ""}, InsertObject), + make_entry("insert-object-with-checksum", + {"", ""}, + InsertObjectWithChecksum), make_entry("insert-object-strict-idempotency", {"", ""}, InsertObjectStrictIdempotency), @@ -855,6 +915,8 @@ int main(int argc, char* argv[]) { make_entry("delete-object", {""}, DeleteObject), make_entry("write-object", {"", ""}, WriteObject), + make_entry("write-object-with-checksum", {""}, + WriteObjectWithChecksum), make_entry("write-object-from-memory", {""}, WriteObjectFromMemory), make_entry("update-object-metadata", From c447204d0f1e605fe0b94c240e4e86a991d072a0 Mon Sep 17 00:00:00 2001 From: Vaibhav Pratap Date: Mon, 3 Aug 2026 07:59:49 +0000 Subject: [PATCH 3/5] docs(storage): address PR review comments - Remove empty string explicitly passed for MD5 hash in precomputed checksums. - Add an example demonstrating . --- .../storage/examples/storage_async_samples.cc | 3 +- .../examples/storage_object_samples.cc | 44 +++++++++++++++---- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/google/cloud/storage/examples/storage_async_samples.cc b/google/cloud/storage/examples/storage_async_samples.cc index 43089f5f78a09..be6fc05cd5149 100644 --- a/google/cloud/storage/examples/storage_async_samples.cc +++ b/google/cloud/storage/examples/storage_async_samples.cc @@ -753,8 +753,7 @@ void CreateAndWriteAppendableObjectWithChecksum( // just before calling Finalize(). google::cloud::internal::OptionsSpan span( google::cloud::Options{}.set( - gcs::PrecomputedChecksums{ - gcs::ComputeCrc32cChecksum("Some data\n"), ""})); + gcs::PrecomputedChecksums{gcs::ComputeCrc32cChecksum("Some data\n")})); co_return (co_await writer.Finalize(std::move(token))).value(); }; // [END storage_create_and_write_appendable_object_with_checksum] diff --git a/google/cloud/storage/examples/storage_object_samples.cc b/google/cloud/storage/examples/storage_object_samples.cc index cd45dc4fe3be0..0c350f5105e95 100644 --- a/google/cloud/storage/examples/storage_object_samples.cc +++ b/google/cloud/storage/examples/storage_object_samples.cc @@ -155,8 +155,7 @@ void InsertObjectWithChecksum(google::cloud::storage::Client client, StatusOr object_metadata = client.InsertObject( bucket_name, object_name, std::move(contents), google::cloud::Options{}.set( - gcs::PrecomputedChecksums{ - gcs::ComputeCrc32cChecksum(contents), ""})); + gcs::PrecomputedChecksums{gcs::ComputeCrc32cChecksum(contents)})); if (!object_metadata) throw std::move(object_metadata).status(); @@ -168,6 +167,26 @@ void InsertObjectWithChecksum(google::cloud::storage::Client client, (std::move(client), argv.at(0), argv.at(1), argv.at(2)); } +void InsertObjectWithBadChecksum(google::cloud::storage::Client client, + std::vector const& argv) { + //! [insert-object-with-bad-checksum] + namespace gcs = ::google::cloud::storage; + [](gcs::Client client, std::string const& bucket_name, + std::string const& object_name, std::string const& contents) { + try { + client.InsertObject( + bucket_name, object_name, std::move(contents), + google::cloud::Options{}.set( + gcs::PrecomputedChecksums{"bad_crc32c"})); + } catch (google::cloud::Status const& status) { + std::cout << "The object was not created because the checksum was bad. " + << "Status: " << status << "\n"; + } + } + //! [insert-object-with-bad-checksum] + (std::move(client), argv.at(0), argv.at(1), argv.at(2)); +} + // NOLINTNEXTLINE(performance-unnecessary-value-param) void InsertObjectStrictIdempotency(google::cloud::storage::Client, std::vector const& argv) { @@ -428,8 +447,7 @@ void WriteObjectWithChecksum(google::cloud::storage::Client client, gcs::ObjectWriteStream stream = client.WriteObject( bucket_name, object_name, google::cloud::Options{}.set( - gcs::PrecomputedChecksums{ - gcs::ComputeCrc32cChecksum(text), ""})); + gcs::PrecomputedChecksums{gcs::ComputeCrc32cChecksum(text)})); stream << text; stream.Close(); @@ -437,9 +455,8 @@ void WriteObjectWithChecksum(google::cloud::storage::Client client, StatusOr metadata = std::move(stream).metadata(); if (!metadata) throw std::move(metadata).status(); - std::cout << "The object " << metadata->name() - << " was created in bucket " << metadata->bucket() - << " with precomputed checksums.\n"; + std::cout << "The object " << metadata->name() << " was created in bucket " + << metadata->bucket() << " with precomputed checksums.\n"; } //! [write-object-with-checksum] (std::move(client), argv.at(0), argv.at(1)); @@ -729,7 +746,12 @@ void RunAll(std::vector const& argv) { InsertObject(client, {bucket_name, object_name, object_media}); std::cout << "\nRunning InsertObjectWithChecksum() example" << std::endl; - InsertObjectWithChecksum(client, {bucket_name, object_name + "_with_checksum", object_media}); + InsertObjectWithChecksum( + client, {bucket_name, object_name + "_with_checksum", object_media}); + + std::cout << "\nRunning InsertObjectWithBadChecksum() example" << std::endl; + InsertObjectWithBadChecksum( + client, {bucket_name, object_name + "_with_bad_checksum", object_media}); std::cout << "\nRunning ListObjects() example" << std::endl; ListObjects(client, {bucket_name}); @@ -780,7 +802,8 @@ void RunAll(std::vector const& argv) { WriteObject(client, {bucket_name, object_name, "100000"}); std::cout << "\nRunning WriteObjectWithChecksum() example" << std::endl; - WriteObjectWithChecksum(client, {bucket_name, object_name + "_write_checksum"}); + WriteObjectWithChecksum(client, + {bucket_name, object_name + "_write_checksum"}); std::cout << "\nRunning ReadObjectRange() example" << std::endl; ReadObjectRange(client, {bucket_name, object_name, "1000", "2000"}); @@ -890,6 +913,9 @@ int main(int argc, char* argv[]) { make_entry("insert-object-with-checksum", {"", ""}, InsertObjectWithChecksum), + make_entry("insert-object-with-bad-checksum", + {"", ""}, + InsertObjectWithBadChecksum), make_entry("insert-object-strict-idempotency", {"", ""}, InsertObjectStrictIdempotency), From 3fcab6af02850b5c157219718e831f2b679b9f25 Mon Sep 17 00:00:00 2001 From: Vaibhav Pratap Date: Mon, 3 Aug 2026 10:17:41 +0000 Subject: [PATCH 4/5] docs(storage): address more PR review comments - Fixed a silent failure bug in InsertObjectWithBadChecksum where the try-catch block was hiding the fact that StatusOr doesn't throw by default. - Removed the std::move(const&) anti-pattern in the sample lambda inputs. - Formatted storage_async_samples.cc properly to resolve the CI failure. --- .../storage/examples/storage_async_samples.cc | 3 +- .../examples/storage_object_samples.cc | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/google/cloud/storage/examples/storage_async_samples.cc b/google/cloud/storage/examples/storage_async_samples.cc index be6fc05cd5149..b185e387f4b7d 100644 --- a/google/cloud/storage/examples/storage_async_samples.cc +++ b/google/cloud/storage/examples/storage_async_samples.cc @@ -753,7 +753,8 @@ void CreateAndWriteAppendableObjectWithChecksum( // just before calling Finalize(). google::cloud::internal::OptionsSpan span( google::cloud::Options{}.set( - gcs::PrecomputedChecksums{gcs::ComputeCrc32cChecksum("Some data\n")})); + gcs::PrecomputedChecksums{ + gcs::ComputeCrc32cChecksum("Some data\n")})); co_return (co_await writer.Finalize(std::move(token))).value(); }; // [END storage_create_and_write_appendable_object_with_checksum] diff --git a/google/cloud/storage/examples/storage_object_samples.cc b/google/cloud/storage/examples/storage_object_samples.cc index 0c350f5105e95..526abad140c49 100644 --- a/google/cloud/storage/examples/storage_object_samples.cc +++ b/google/cloud/storage/examples/storage_object_samples.cc @@ -132,7 +132,7 @@ void InsertObject(google::cloud::storage::Client client, namespace gcs = ::google::cloud::storage; using ::google::cloud::StatusOr; [](gcs::Client client, std::string const& bucket_name, - std::string const& object_name, std::string const& contents) { + std::string const& object_name, std::string contents) { StatusOr object_metadata = client.InsertObject(bucket_name, object_name, std::move(contents)); if (!object_metadata) throw std::move(object_metadata).status(); @@ -151,11 +151,12 @@ void InsertObjectWithChecksum(google::cloud::storage::Client client, namespace gcs = ::google::cloud::storage; using ::google::cloud::StatusOr; [](gcs::Client client, std::string const& bucket_name, - std::string const& object_name, std::string const& contents) { + std::string const& object_name, std::string contents) { + auto checksum = gcs::ComputeCrc32cChecksum(contents); StatusOr object_metadata = client.InsertObject( bucket_name, object_name, std::move(contents), google::cloud::Options{}.set( - gcs::PrecomputedChecksums{gcs::ComputeCrc32cChecksum(contents)})); + gcs::PrecomputedChecksums{std::move(checksum)})); if (!object_metadata) throw std::move(object_metadata).status(); @@ -172,16 +173,19 @@ void InsertObjectWithBadChecksum(google::cloud::storage::Client client, //! [insert-object-with-bad-checksum] namespace gcs = ::google::cloud::storage; [](gcs::Client client, std::string const& bucket_name, - std::string const& object_name, std::string const& contents) { - try { - client.InsertObject( - bucket_name, object_name, std::move(contents), - google::cloud::Options{}.set( - gcs::PrecomputedChecksums{"bad_crc32c"})); - } catch (google::cloud::Status const& status) { + std::string const& object_name, std::string contents) { + auto object_metadata = client.InsertObject( + bucket_name, object_name, std::move(contents), + google::cloud::Options{}.set( + gcs::PrecomputedChecksums{"bad_crc32c"})); + + if (!object_metadata) { std::cout << "The object was not created because the checksum was bad. " - << "Status: " << status << "\n"; + << "Status: " << object_metadata.status() << "\n"; + return; } + throw std::runtime_error( + "The object was created, but it shouldn't have been!"); } //! [insert-object-with-bad-checksum] (std::move(client), argv.at(0), argv.at(1), argv.at(2)); @@ -194,7 +198,7 @@ void InsertObjectStrictIdempotency(google::cloud::storage::Client, namespace gcs = ::google::cloud::storage; using ::google::cloud::StatusOr; [](std::string const& bucket_name, std::string const& object_name, - std::string const& contents) { + std::string contents) { // Create a client that only retries idempotent operations, the default is // to retry all operations. auto client = From 4ad8c594fbea071478f428a3bd7bd71cf5d40fcb Mon Sep 17 00:00:00 2001 From: Vaibhav Pratap Date: Mon, 3 Aug 2026 10:21:05 +0000 Subject: [PATCH 5/5] docs(storage): remove remaining anti-pattern in other InsertObject snippets --- google/cloud/storage/examples/storage_object_samples.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/cloud/storage/examples/storage_object_samples.cc b/google/cloud/storage/examples/storage_object_samples.cc index 526abad140c49..1936bb9c846c9 100644 --- a/google/cloud/storage/examples/storage_object_samples.cc +++ b/google/cloud/storage/examples/storage_object_samples.cc @@ -224,7 +224,7 @@ void InsertObjectModifiedRetry(google::cloud::storage::Client, namespace gcs = ::google::cloud::storage; using ::google::cloud::StatusOr; [](std::string const& bucket_name, std::string const& object_name, - std::string const& contents) { + std::string contents) { // Create a client that only gives up on the third error. The default policy // is to retry for several minutes. auto client = @@ -251,7 +251,7 @@ void InsertObjectMultipart(google::cloud::storage::Client client, using ::google::cloud::StatusOr; [](gcs::Client client, std::string const& bucket_name, std::string const& object_name, std::string const& content_type, - std::string const& contents) { + std::string contents) { // Setting the object metadata (via the `gcs::WithObjectMadata` option) // requires a multipart upload, the library prefers simple uploads unless // required as in this case.