• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "mojo/public/cpp/system/message_pipe.h"
6 
7 #include "base/numerics/safe_math.h"
8 
9 namespace mojo {
10 
WriteMessageRaw(MessagePipeHandle message_pipe,const void * bytes,size_t num_bytes,const MojoHandle * handles,size_t num_handles,MojoWriteMessageFlags flags)11 MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
12                            const void* bytes,
13                            size_t num_bytes,
14                            const MojoHandle* handles,
15                            size_t num_handles,
16                            MojoWriteMessageFlags flags) {
17   ScopedMessageHandle message_handle;
18   MojoResult rv = CreateMessage(&message_handle);
19   DCHECK_EQ(MOJO_RESULT_OK, rv);
20 
21   MojoAppendMessageDataOptions append_options;
22   append_options.struct_size = sizeof(append_options);
23   append_options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
24   void* buffer;
25   uint32_t buffer_size;
26   rv = MojoAppendMessageData(message_handle->value(),
27                              base::checked_cast<uint32_t>(num_bytes), handles,
28                              base::checked_cast<uint32_t>(num_handles),
29                              &append_options, &buffer, &buffer_size);
30   if (rv != MOJO_RESULT_OK)
31     return MOJO_RESULT_ABORTED;
32 
33   DCHECK(buffer);
34   DCHECK_GE(buffer_size, base::checked_cast<uint32_t>(num_bytes));
35   memcpy(buffer, bytes, num_bytes);
36 
37   MojoWriteMessageOptions write_options;
38   write_options.struct_size = sizeof(write_options);
39   write_options.flags = flags;
40   return MojoWriteMessage(message_pipe.value(),
41                           message_handle.release().value(), &write_options);
42 }
43 
ReadMessageRaw(MessagePipeHandle message_pipe,std::vector<uint8_t> * payload,std::vector<ScopedHandle> * handles,MojoReadMessageFlags flags)44 MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
45                           std::vector<uint8_t>* payload,
46                           std::vector<ScopedHandle>* handles,
47                           MojoReadMessageFlags flags) {
48   ScopedMessageHandle message_handle;
49   MojoResult rv = ReadMessageNew(message_pipe, &message_handle, flags);
50   if (rv != MOJO_RESULT_OK)
51     return rv;
52 
53   rv = MojoSerializeMessage(message_handle->value(), nullptr);
54   if (rv != MOJO_RESULT_OK && rv != MOJO_RESULT_FAILED_PRECONDITION)
55     return MOJO_RESULT_ABORTED;
56 
57   void* buffer = nullptr;
58   uint32_t num_bytes = 0;
59   uint32_t num_handles = 0;
60   rv = MojoGetMessageData(message_handle->value(), nullptr, &buffer, &num_bytes,
61                           nullptr, &num_handles);
62   if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
63     DCHECK(handles);
64     handles->resize(num_handles);
65     rv = MojoGetMessageData(
66         message_handle->value(), nullptr, &buffer, &num_bytes,
67         reinterpret_cast<MojoHandle*>(handles->data()), &num_handles);
68   }
69 
70   if (num_bytes) {
71     DCHECK(buffer);
72     uint8_t* payload_data = reinterpret_cast<uint8_t*>(buffer);
73     payload->resize(num_bytes);
74     std::copy(payload_data, payload_data + num_bytes, payload->begin());
75   } else if (payload) {
76     payload->clear();
77   }
78 
79   if (handles && !num_handles)
80     handles->clear();
81 
82   if (rv != MOJO_RESULT_OK)
83     return MOJO_RESULT_ABORTED;
84 
85   return MOJO_RESULT_OK;
86 }
87 
88 }  // namespace mojo
89