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 // Copying and assignment allowed. 32 }; 33 34 static_assert(sizeof(DataPipeProducerHandle) == sizeof(Handle), 35 "Bad size for C++ DataPipeProducerHandle"); 36 37 typedef ScopedHandleBase<DataPipeProducerHandle> ScopedDataPipeProducerHandle; 38 static_assert(sizeof(ScopedDataPipeProducerHandle) == 39 sizeof(DataPipeProducerHandle), 40 "Bad size for C++ ScopedDataPipeProducerHandle"); 41 42 // A strongly-typed representation of a |MojoHandle| to the consumer end of a 43 // data pipe. 44 class DataPipeConsumerHandle : public Handle { 45 public: 46 DataPipeConsumerHandle() {} 47 explicit DataPipeConsumerHandle(MojoHandle value) : Handle(value) {} 48 49 // Copying and assignment allowed. 50 }; 51 52 static_assert(sizeof(DataPipeConsumerHandle) == sizeof(Handle), 53 "Bad size for C++ DataPipeConsumerHandle"); 54 55 typedef ScopedHandleBase<DataPipeConsumerHandle> ScopedDataPipeConsumerHandle; 56 static_assert(sizeof(ScopedDataPipeConsumerHandle) == 57 sizeof(DataPipeConsumerHandle), 58 "Bad size for C++ ScopedDataPipeConsumerHandle"); 59 60 // Creates a new data pipe. See |MojoCreateDataPipe()| for complete 61 // documentation. 62 inline MojoResult CreateDataPipe( 63 const MojoCreateDataPipeOptions* options, 64 ScopedDataPipeProducerHandle* data_pipe_producer, 65 ScopedDataPipeConsumerHandle* data_pipe_consumer) { 66 DCHECK(data_pipe_producer); 67 DCHECK(data_pipe_consumer); 68 DataPipeProducerHandle producer_handle; 69 DataPipeConsumerHandle consumer_handle; 70 MojoResult rv = MojoCreateDataPipe(options, 71 producer_handle.mutable_value(), 72 consumer_handle.mutable_value()); 73 // Reset even on failure (reduces the chances that a "stale"/incorrect handle 74 // will be used). 75 data_pipe_producer->reset(producer_handle); 76 data_pipe_consumer->reset(consumer_handle); 77 return rv; 78 } 79 80 // Writes to a data pipe. See |MojoWriteData| for complete documentation. 81 inline MojoResult WriteDataRaw(DataPipeProducerHandle data_pipe_producer, 82 const void* elements, 83 uint32_t* num_bytes, 84 MojoWriteDataFlags flags) { 85 return MojoWriteData(data_pipe_producer.value(), elements, num_bytes, flags); 86 } 87 88 // Begins a two-phase write to a data pipe. See |MojoBeginWriteData()| for 89 // complete documentation. 90 inline MojoResult BeginWriteDataRaw(DataPipeProducerHandle data_pipe_producer, 91 void** buffer, 92 uint32_t* buffer_num_bytes, 93 MojoWriteDataFlags flags) { 94 return MojoBeginWriteData( 95 data_pipe_producer.value(), buffer, buffer_num_bytes, flags); 96 } 97 98 // Completes a two-phase write to a data pipe. See |MojoEndWriteData()| for 99 // complete documentation. 100 inline MojoResult EndWriteDataRaw(DataPipeProducerHandle data_pipe_producer, 101 uint32_t num_bytes_written) { 102 return MojoEndWriteData(data_pipe_producer.value(), num_bytes_written); 103 } 104 105 // Reads from a data pipe. See |MojoReadData()| for complete documentation. 106 inline MojoResult ReadDataRaw(DataPipeConsumerHandle data_pipe_consumer, 107 void* elements, 108 uint32_t* num_bytes, 109 MojoReadDataFlags flags) { 110 return MojoReadData(data_pipe_consumer.value(), elements, num_bytes, flags); 111 } 112 113 // Begins a two-phase read from a data pipe. See |MojoBeginReadData()| for 114 // complete documentation. 115 inline MojoResult BeginReadDataRaw(DataPipeConsumerHandle data_pipe_consumer, 116 const void** buffer, 117 uint32_t* buffer_num_bytes, 118 MojoReadDataFlags flags) { 119 return MojoBeginReadData( 120 data_pipe_consumer.value(), buffer, buffer_num_bytes, flags); 121 } 122 123 // Completes a two-phase read from a data pipe. See |MojoEndReadData()| for 124 // complete documentation. 125 inline MojoResult EndReadDataRaw(DataPipeConsumerHandle data_pipe_consumer, 126 uint32_t num_bytes_read) { 127 return MojoEndReadData(data_pipe_consumer.value(), num_bytes_read); 128 } 129 130 // A wrapper class that automatically creates a data pipe and owns both handles. 131 // TODO(vtl): Make an even more friendly version? (Maybe templatized for a 132 // particular type instead of some "element"? Maybe functions that take 133 // vectors?) 134 class DataPipe { 135 public: 136 DataPipe(); 137 explicit DataPipe(const MojoCreateDataPipeOptions& options); 138 ~DataPipe(); 139 140 ScopedDataPipeProducerHandle producer_handle; 141 ScopedDataPipeConsumerHandle consumer_handle; 142 }; 143 144 inline DataPipe::DataPipe() { 145 MojoResult result = 146 CreateDataPipe(nullptr, &producer_handle, &consumer_handle); 147 ALLOW_UNUSED_LOCAL(result); 148 DCHECK_EQ(MOJO_RESULT_OK, result); 149 } 150 151 inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) { 152 MojoResult result = 153 CreateDataPipe(&options, &producer_handle, &consumer_handle); 154 ALLOW_UNUSED_LOCAL(result); 155 DCHECK_EQ(MOJO_RESULT_OK, result); 156 } 157 158 inline DataPipe::~DataPipe() { 159 } 160 161 } // namespace mojo 162 163 #endif // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_ 164