blob: 09f5de36316b88abaaa32674fc2765a526905412 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/indexed_db/instance/sqlite/blob_writer.h"
#include "content/browser/indexed_db/indexed_db_external_object.h"
#include "mojo/public/cpp/system/data_pipe.h"
namespace content::indexed_db::sqlite {
// static
std::unique_ptr<BlobWriter> BlobWriter::WriteBlobIntoDatabase(
IndexedDBExternalObject& external_object,
sql::StreamingBlobHandle blob_handle,
base::OnceCallback<void(bool)> on_complete) {
mojo::ScopedDataPipeProducerHandle producer_handle;
mojo::ScopedDataPipeConsumerHandle consumer_handle;
MojoResult result =
CreateDataPipe(/*options=*/nullptr, producer_handle, consumer_handle);
if (result != MOJO_RESULT_OK) {
return nullptr;
}
external_object.remote()->ReadAll(std::move(producer_handle),
mojo::NullRemote());
auto sink = base::WrapUnique(
new BlobWriter(std::move(blob_handle), std::move(on_complete)));
sink->Start(std::move(consumer_handle));
return sink;
}
BlobWriter::BlobWriter(sql::StreamingBlobHandle blob_handle,
base::OnceCallback<void(bool)> on_complete)
: target_(std::move(blob_handle)), on_complete_(std::move(on_complete)) {}
BlobWriter::~BlobWriter() = default;
void BlobWriter::Start(mojo::ScopedDataPipeConsumerHandle consumer_handle) {
drainer_ =
std::make_unique<mojo::DataPipeDrainer>(this, std::move(consumer_handle));
}
void BlobWriter::OnDataAvailable(base::span<const uint8_t> data) {
if (!target_) {
return;
}
if (target_->Write(bytes_written_so_far_, data)) {
bytes_written_so_far_ += data.size();
} else {
target_.reset();
// Reporting an error deletes `this`, but `drainer_` doesn't like being
// deleted inside `OnDataAvailable`.
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(std::move(on_complete_), /*success=*/false));
}
}
void BlobWriter::OnDataComplete() {
if (target_ && on_complete_) {
std::move(on_complete_).Run(/*success=*/true);
}
}
} // namespace content::indexed_db::sqlite