• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 // This file provides a C++ wrapping around the Mojo C API for data pipes,
6 // replacing the prefix of "Mojo" with a "mojo" namespace, and using more
7 // strongly-typed representations of |MojoHandle|s.
8 //
9 // Please see "mojo/public/c/system/data_pipe.h" for complete documentation of
10 // the API.
11 
12 #ifndef MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
13 #define MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
14 
15 #include <stdint.h>
16 
17 #include "base/compiler_specific.h"
18 #include "base/logging.h"
19 #include "mojo/public/c/system/data_pipe.h"
20 #include "mojo/public/cpp/system/handle.h"
21 
22 namespace mojo {
23 
24 // A strongly-typed representation of a |MojoHandle| to the producer end of a
25 // data pipe.
26 class DataPipeProducerHandle : public Handle {
27  public:
DataPipeProducerHandle()28   DataPipeProducerHandle() {}
DataPipeProducerHandle(MojoHandle value)29   explicit DataPipeProducerHandle(MojoHandle value) : Handle(value) {}
30 
31   // Writes to a data pipe. See |MojoWriteData| for complete documentation.
WriteData(const void * elements,uint32_t * num_bytes,MojoWriteDataFlags flags)32   MojoResult WriteData(const void* elements,
33                        uint32_t* num_bytes,
34                        MojoWriteDataFlags flags) const {
35     MojoWriteDataOptions options;
36     options.struct_size = sizeof(options);
37     options.flags = flags;
38     return MojoWriteData(value(), elements, num_bytes, &options);
39   }
40 
41   // Begins a two-phase write to a data pipe. See |MojoBeginWriteData()| for
42   // complete documentation.
BeginWriteData(void ** buffer,uint32_t * buffer_num_bytes,MojoBeginWriteDataFlags flags)43   MojoResult BeginWriteData(void** buffer,
44                             uint32_t* buffer_num_bytes,
45                             MojoBeginWriteDataFlags flags) const {
46     MojoBeginWriteDataOptions options;
47     options.struct_size = sizeof(options);
48     options.flags = flags;
49     return MojoBeginWriteData(value(), &options, buffer, buffer_num_bytes);
50   }
51 
52   // Completes a two-phase write to a data pipe. See |MojoEndWriteData()| for
53   // complete documentation.
EndWriteData(uint32_t num_bytes_written)54   MojoResult EndWriteData(uint32_t num_bytes_written) const {
55     return MojoEndWriteData(value(), num_bytes_written, nullptr);
56   }
57 
58   // Copying and assignment allowed.
59 };
60 
61 static_assert(sizeof(DataPipeProducerHandle) == sizeof(Handle),
62               "Bad size for C++ DataPipeProducerHandle");
63 
64 typedef ScopedHandleBase<DataPipeProducerHandle> ScopedDataPipeProducerHandle;
65 static_assert(sizeof(ScopedDataPipeProducerHandle) ==
66                   sizeof(DataPipeProducerHandle),
67               "Bad size for C++ ScopedDataPipeProducerHandle");
68 
69 // A strongly-typed representation of a |MojoHandle| to the consumer end of a
70 // data pipe.
71 class DataPipeConsumerHandle : public Handle {
72  public:
DataPipeConsumerHandle()73   DataPipeConsumerHandle() {}
DataPipeConsumerHandle(MojoHandle value)74   explicit DataPipeConsumerHandle(MojoHandle value) : Handle(value) {}
75 
76   // Reads from a data pipe. See |MojoReadData()| for complete documentation.
ReadData(void * elements,uint32_t * num_bytes,MojoReadDataFlags flags)77   MojoResult ReadData(void* elements,
78                       uint32_t* num_bytes,
79                       MojoReadDataFlags flags) const {
80     MojoReadDataOptions options;
81     options.struct_size = sizeof(options);
82     options.flags = flags;
83     return MojoReadData(value(), &options, elements, num_bytes);
84   }
85 
86   // Begins a two-phase read from a data pipe. See |MojoBeginReadData()| for
87   // complete documentation.
BeginReadData(const void ** buffer,uint32_t * buffer_num_bytes,MojoBeginReadDataFlags flags)88   MojoResult BeginReadData(const void** buffer,
89                            uint32_t* buffer_num_bytes,
90                            MojoBeginReadDataFlags flags) const {
91     MojoBeginReadDataOptions options;
92     options.struct_size = sizeof(options);
93     options.flags = flags;
94     return MojoBeginReadData(value(), &options, buffer, buffer_num_bytes);
95   }
96 
97   // Completes a two-phase read from a data pipe. See |MojoEndReadData()| for
98   // complete documentation.
EndReadData(uint32_t num_bytes_read)99   MojoResult EndReadData(uint32_t num_bytes_read) const {
100     return MojoEndReadData(value(), num_bytes_read, nullptr);
101   }
102 
103   // Copying and assignment allowed.
104 };
105 
106 static_assert(sizeof(DataPipeConsumerHandle) == sizeof(Handle),
107               "Bad size for C++ DataPipeConsumerHandle");
108 
109 typedef ScopedHandleBase<DataPipeConsumerHandle> ScopedDataPipeConsumerHandle;
110 static_assert(sizeof(ScopedDataPipeConsumerHandle) ==
111                   sizeof(DataPipeConsumerHandle),
112               "Bad size for C++ ScopedDataPipeConsumerHandle");
113 
114 // Creates a new data pipe. See |MojoCreateDataPipe()| for complete
115 // documentation.
CreateDataPipe(const MojoCreateDataPipeOptions * options,ScopedDataPipeProducerHandle * data_pipe_producer,ScopedDataPipeConsumerHandle * data_pipe_consumer)116 inline MojoResult CreateDataPipe(
117     const MojoCreateDataPipeOptions* options,
118     ScopedDataPipeProducerHandle* data_pipe_producer,
119     ScopedDataPipeConsumerHandle* data_pipe_consumer) {
120   DCHECK(data_pipe_producer);
121   DCHECK(data_pipe_consumer);
122   DataPipeProducerHandle producer_handle;
123   DataPipeConsumerHandle consumer_handle;
124   MojoResult rv = MojoCreateDataPipe(options,
125                                      producer_handle.mutable_value(),
126                                      consumer_handle.mutable_value());
127   // Reset even on failure (reduces the chances that a "stale"/incorrect handle
128   // will be used).
129   data_pipe_producer->reset(producer_handle);
130   data_pipe_consumer->reset(consumer_handle);
131   return rv;
132 }
133 
134 // A wrapper class that automatically creates a data pipe and owns both handles.
135 // TODO(vtl): Make an even more friendly version? (Maybe templatized for a
136 // particular type instead of some "element"? Maybe functions that take
137 // vectors?)
138 class DataPipe {
139  public:
140   DataPipe();
141   explicit DataPipe(uint32_t capacity_num_bytes);
142   explicit DataPipe(const MojoCreateDataPipeOptions& options);
143   ~DataPipe();
144 
145   ScopedDataPipeProducerHandle producer_handle;
146   ScopedDataPipeConsumerHandle consumer_handle;
147 };
148 
DataPipe()149 inline DataPipe::DataPipe() {
150   MojoResult result =
151       CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
152   ALLOW_UNUSED_LOCAL(result);
153   DCHECK_EQ(MOJO_RESULT_OK, result);
154 }
155 
DataPipe(uint32_t capacity_num_bytes)156 inline DataPipe::DataPipe(uint32_t capacity_num_bytes) {
157   MojoCreateDataPipeOptions options;
158   options.struct_size = sizeof(MojoCreateDataPipeOptions);
159   options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
160   options.element_num_bytes = 1;
161   options.capacity_num_bytes = capacity_num_bytes;
162   mojo::DataPipe data_pipe(options);
163   MojoResult result =
164       CreateDataPipe(&options, &producer_handle, &consumer_handle);
165   ALLOW_UNUSED_LOCAL(result);
166   DCHECK_EQ(MOJO_RESULT_OK, result);
167 }
168 
DataPipe(const MojoCreateDataPipeOptions & options)169 inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
170   MojoResult result =
171       CreateDataPipe(&options, &producer_handle, &consumer_handle);
172   ALLOW_UNUSED_LOCAL(result);
173   DCHECK_EQ(MOJO_RESULT_OK, result);
174 }
175 
~DataPipe()176 inline DataPipe::~DataPipe() {
177 }
178 
179 }  // namespace mojo
180 
181 #endif  // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
182