| // 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 |