blob: f8b47f36e65253448daed9b056d03214f466e802 [file] [log] [blame]
// Copyright 2018 The Chromium OS 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 "arc/vm/vsock_proxy/vsock_stream.h"
#include <string>
#include <utility>
#include <vector>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/safe_strerror.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
namespace arc {
VSockStream::VSockStream(base::ScopedFD vsock_fd)
: vsock_fd_(std::move(vsock_fd)) {}
VSockStream::~VSockStream() = default;
bool VSockStream::Read(arc_proxy::VSockMessage* message) {
uint64_t size = 0;
if (!base::ReadFromFD(vsock_fd_.get(), reinterpret_cast<char*>(&size),
sizeof(size))) {
PLOG(ERROR) << "Failed to read message size";
return false;
}
std::vector<char> buf(size);
if (!base::ReadFromFD(vsock_fd_.get(), buf.data(), buf.size())) {
PLOG(ERROR) << "Failed to read a proto";
return false;
}
if (!message->ParseFromArray(buf.data(), buf.size())) {
LOG(ERROR) << "Failed to parse proto message";
return false;
}
if (VLOG_IS_ON(1)) {
std::string text;
google::protobuf::TextFormat::PrintToString(*message, &text);
LOG(INFO) << "Reading: " << text;
}
return true;
}
bool VSockStream::Write(const arc_proxy::VSockMessage& message) {
if (VLOG_IS_ON(1)) {
std::string text;
google::protobuf::TextFormat::PrintToString(message, &text);
LOG(INFO) << "Writing: " << text;
}
uint64_t size = message.ByteSize();
if (!base::WriteFileDescriptor(
vsock_fd_.get(), reinterpret_cast<char*>(&size), sizeof(size))) {
PLOG(ERROR) << "Failed to write buffer size";
return false;
}
google::protobuf::io::FileOutputStream stream(vsock_fd_.get());
if (!message.SerializeToZeroCopyStream(&stream) || !stream.Flush()) {
const int error = stream.GetErrno();
LOG(ERROR) << "Failed to "
<< (error ? "write proto: " + base::safe_strerror(error)
: "serialize proto.");
return false;
}
return true;
}
} // namespace arc