| Index: chromeos/dbus/pipe_string_writer.cc
|
| diff --git a/chromeos/dbus/pipe_string_writer.cc b/chromeos/dbus/pipe_string_writer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..793546550dc255526fc9f93d1e25a205db550a1d
|
| --- /dev/null
|
| +++ b/chromeos/dbus/pipe_string_writer.cc
|
| @@ -0,0 +1,76 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chromeos/dbus/pipe_string_writer.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/posix/eintr_wrapper.h"
|
| +#include "base/task_runner.h"
|
| +#include "net/base/file_stream.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/net_errors.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +PipeStringWriter::PipeStringWriter(
|
| + const std::string& data,
|
| + const scoped_refptr<base::TaskRunner>& task_runner,
|
| + const IOCompleteCallback& callback)
|
| + : string_io_buffer_(new net::StringIOBuffer(data)),
|
| + drainable_io_buffer_(
|
| + new net::DrainableIOBuffer(string_io_buffer_.get(),
|
| + string_io_buffer_->size())),
|
| + task_runner_(task_runner),
|
| + callback_(callback),
|
| + weak_ptr_factory_(this) {}
|
| +
|
| +PipeStringWriter::~PipeStringWriter() {}
|
| +
|
| +base::ScopedFD PipeStringWriter::StartIO() {
|
| + // Use a pipe to send data
|
| + int pipe_fds[2];
|
| + const int status = HANDLE_EINTR(pipe(pipe_fds));
|
| + if (status < 0) {
|
| + PLOG(ERROR) << "pipe";
|
| + return base::ScopedFD();
|
| + }
|
| + base::ScopedFD pipe_read_end(pipe_fds[0]);
|
| + // Pass ownership of pipe_fds[1] to data_stream_, which will close it.
|
| + data_stream_.reset(
|
| + new net::FileStream(base::File(pipe_fds[1]), task_runner_));
|
| +
|
| + // Post an initial async write to setup data streaming
|
| + int rv = data_stream_->Write(drainable_io_buffer_.get(),
|
| + drainable_io_buffer_->BytesRemaining(),
|
| + base::Bind(&PipeStringWriter::OnDataWritten,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + if (rv != net::ERR_IO_PENDING) {
|
| + LOG(ERROR) << "Unable to post initial write";
|
| + return base::ScopedFD();
|
| + }
|
| + return pipe_read_end;
|
| +}
|
| +
|
| +void PipeStringWriter::OnDataWritten(int byte_count) {
|
| + DVLOG(1) << "OnDataWritten byte_count " << byte_count;
|
| + if (byte_count < 0) {
|
| + callback_.Run(byte_count); // signal creator of an error.
|
| + return;
|
| + }
|
| + drainable_io_buffer_->DidConsume(byte_count);
|
| + if (drainable_io_buffer_->BytesRemaining() > 0) {
|
| + // Post another write
|
| + int rv = data_stream_->Write(drainable_io_buffer_.get(),
|
| + drainable_io_buffer_->BytesRemaining(),
|
| + base::Bind(&PipeStringWriter::OnDataWritten,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + if (rv != net::ERR_IO_PENDING) {
|
| + LOG(ERROR) << "Unable to post another write";
|
| + }
|
| + } else {
|
| + callback_.Run(0); // success.
|
| + }
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|