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: 28 DataPipeProducerHandle() {} 29 explicit DataPipeProducerHandle(MojoHandle value) : Handle(value) {} 30 31 // Writes to a data pipe. See |MojoWriteData| for complete documentation. 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. 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. 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: 73 DataPipeConsumerHandle() {} 74 explicit DataPipeConsumerHandle(MojoHandle value) : Handle(value) {} 75 76 // Reads from a data pipe. See |MojoReadData()| for complete documentation. 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. 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. 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. 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 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 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 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 176 inline DataPipe::~DataPipe() { 177 } 178 179 } // namespace mojo 180 181 #endif // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_ 182