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 22namespace mojo { 23 24// A strongly-typed representation of a |MojoHandle| to the producer end of a 25// data pipe. 26class DataPipeProducerHandle : public Handle { 27 public: 28 DataPipeProducerHandle() {} 29 explicit DataPipeProducerHandle(MojoHandle value) : Handle(value) {} 30 31 // Copying and assignment allowed. 32}; 33 34static_assert(sizeof(DataPipeProducerHandle) == sizeof(Handle), 35 "Bad size for C++ DataPipeProducerHandle"); 36 37typedef ScopedHandleBase<DataPipeProducerHandle> ScopedDataPipeProducerHandle; 38static_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. 44class DataPipeConsumerHandle : public Handle { 45 public: 46 DataPipeConsumerHandle() {} 47 explicit DataPipeConsumerHandle(MojoHandle value) : Handle(value) {} 48 49 // Copying and assignment allowed. 50}; 51 52static_assert(sizeof(DataPipeConsumerHandle) == sizeof(Handle), 53 "Bad size for C++ DataPipeConsumerHandle"); 54 55typedef ScopedHandleBase<DataPipeConsumerHandle> ScopedDataPipeConsumerHandle; 56static_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. 62inline 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. 81inline 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. 90inline 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. 100inline 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. 106inline 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. 115inline 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. 125inline 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?) 134class DataPipe { 135 public: 136 DataPipe(); 137 explicit DataPipe(const MojoCreateDataPipeOptions& options); 138 ~DataPipe(); 139 140 ScopedDataPipeProducerHandle producer_handle; 141 ScopedDataPipeConsumerHandle consumer_handle; 142}; 143 144inline 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 151inline 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 158inline DataPipe::~DataPipe() { 159} 160 161} // namespace mojo 162 163#endif // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_ 164