blob: cb1ed8937c4e2751e3dfca6de936ada32254816f [file] [log] [blame]
// Copyright 2016 The Fuchsia 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 "upload_element_reader.h"
#include <utility>
#include "lib/fxl/logging.h"
namespace http {
UploadElementReader::UploadElementReader() : err_(ZX_OK) {}
UploadElementReader::~UploadElementReader() = default;
SocketUploadElementReader::SocketUploadElementReader(zx::socket socket)
: socket_(std::move(socket)) {}
SocketUploadElementReader::~SocketUploadElementReader() {}
size_t SocketUploadElementReader::size() { return kUnknownSize; }
bool SocketUploadElementReader::ReadAvailable(std::ostream* os) {
while (true) {
size_t num_bytes = buf_.size();
err_ = socket_.read(0u, buf_.data(), num_bytes, &num_bytes);
if (err_ == ZX_ERR_SHOULD_WAIT) {
err_ = socket_.wait_one(ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
zx::time::infinite(), nullptr);
if (err_ == ZX_OK)
continue; // retry now that the socket is ready
}
if (err_ != ZX_OK) {
// If the other end closes the socket, we get MX_ERR_PEER_CLOSED.
if (err_ == ZX_ERR_PEER_CLOSED) {
err_ = ZX_OK;
return false;
}
FXL_VLOG(1) << "SocketUploadElementReader: result=" << err_;
return false;
}
os->write(buf_.data(), num_bytes);
if (!*os) {
// TODO(toshik): better result code?
err_ = ZX_ERR_BUFFER_TOO_SMALL;
FXL_VLOG(1) << "SocketUploadElementReader: result=" << err_;
return false;
} else {
return true;
}
}
}
VmoUploadElementReader::VmoUploadElementReader(zx::vmo vmo)
: vmo_(std::move(vmo)), offset_(0) {
err_ = vmo_.get_size(&size_);
}
VmoUploadElementReader::VmoUploadElementReader(zx::vmo vmo, uint64_t size)
: vmo_(std::move(vmo)), size_(size), offset_(0) {}
VmoUploadElementReader::~VmoUploadElementReader() {}
size_t VmoUploadElementReader::size() { return size_; }
bool VmoUploadElementReader::ReadAvailable(std::ostream* os) {
const size_t remaining_bytes = size_ - offset_;
const size_t bytes_to_process = std::min(remaining_bytes, buf_.size());
err_ = vmo_.read(buf_.data(), offset_, bytes_to_process);
if (err_ != ZX_OK) {
FXL_VLOG(1) << "VmoUploadElementReader: result=" << err_;
return false;
}
if (bytes_to_process > 0) {
os->write(buf_.data(), bytes_to_process);
if (!*os) {
FXL_VLOG(1) << "VmoUploadElementReader: Unable to write to stream.";
// TODO(toshik): better result code?
err_ = ZX_ERR_BUFFER_TOO_SMALL;
return false;
}
offset_ += bytes_to_process;
return true;
} else {
return false;
}
}
} // namespace http