// Copyright 2017 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 "mojo/public/cpp/system/message_pipe.h"
#include "base/numerics/safe_math.h"
namespace mojo {
MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
const void* bytes,
size_t num_bytes,
const MojoHandle* handles,
size_t num_handles,
MojoWriteMessageFlags flags) {
ScopedMessageHandle message_handle;
MojoResult rv = CreateMessage(&message_handle);
DCHECK_EQ(MOJO_RESULT_OK, rv);
MojoAppendMessageDataOptions append_options;
append_options.struct_size = sizeof(append_options);
append_options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
void* buffer;
uint32_t buffer_size;
rv = MojoAppendMessageData(message_handle->value(),
base::checked_cast<uint32_t>(num_bytes), handles,
base::checked_cast<uint32_t>(num_handles),
&append_options, &buffer, &buffer_size);
if (rv != MOJO_RESULT_OK)
return MOJO_RESULT_ABORTED;
DCHECK(buffer);
DCHECK_GE(buffer_size, base::checked_cast<uint32_t>(num_bytes));
memcpy(buffer, bytes, num_bytes);
MojoWriteMessageOptions write_options;
write_options.struct_size = sizeof(write_options);
write_options.flags = flags;
return MojoWriteMessage(message_pipe.value(),
message_handle.release().value(), &write_options);
}
MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
std::vector<uint8_t>* payload,
std::vector<ScopedHandle>* handles,
MojoReadMessageFlags flags) {
ScopedMessageHandle message_handle;
MojoResult rv = ReadMessageNew(message_pipe, &message_handle, flags);
if (rv != MOJO_RESULT_OK)
return rv;
rv = MojoSerializeMessage(message_handle->value(), nullptr);
if (rv != MOJO_RESULT_OK && rv != MOJO_RESULT_FAILED_PRECONDITION)
return MOJO_RESULT_ABORTED;
void* buffer = nullptr;
uint32_t num_bytes = 0;
uint32_t num_handles = 0;
rv = MojoGetMessageData(message_handle->value(), nullptr, &buffer, &num_bytes,
nullptr, &num_handles);
if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
DCHECK(handles);
handles->resize(num_handles);
rv = MojoGetMessageData(
message_handle->value(), nullptr, &buffer, &num_bytes,
reinterpret_cast<MojoHandle*>(handles->data()), &num_handles);
}
if (num_bytes) {
DCHECK(buffer);
uint8_t* payload_data = reinterpret_cast<uint8_t*>(buffer);
payload->resize(num_bytes);
std::copy(payload_data, payload_data + num_bytes, payload->begin());
} else if (payload) {
payload->clear();
}
if (handles && !num_handles)
handles->clear();
if (rv != MOJO_RESULT_OK)
return MOJO_RESULT_ABORTED;
return MOJO_RESULT_OK;
}
} // namespace mojo