1// PortChannel.cpp 2 3#include <new> 4#include <string.h> 5 6#include "PortChannel.h" 7#include "Utils.h" 8 9static const int32 kMaxPortMessageSize = 102400; // 100 KB 10static const int32 kDefaultBufferSize = 10240; // 10 KB 11 12// constructor 13PortChannel::PortChannel() 14 : Channel(), 15 fSendPort(-1), 16 fReceivePort(-1), 17 fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]), 18 fBufferSize(kDefaultBufferSize), 19 fBufferOffset(0), 20 fBufferContentSize(0) 21{ 22 fSendPort = create_port(10, "port connection send port"); 23 fReceivePort = create_port(10, "port connection receive port"); 24} 25 26// constructor 27PortChannel::PortChannel(const Info* info, bool inverse) 28 : Channel(), 29 fSendPort(inverse ? info->receivePort : info->sendPort), 30 fReceivePort(inverse ? info->sendPort : info->receivePort), 31 fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]), 32 fBufferSize(kDefaultBufferSize), 33 fBufferOffset(0), 34 fBufferContentSize(0) 35{ 36} 37 38// constructor 39PortChannel::PortChannel(port_id sendPort, port_id receivePort) 40 : Channel(), 41 fSendPort(sendPort), 42 fReceivePort(receivePort), 43 fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]), 44 fBufferSize(kDefaultBufferSize), 45 fBufferOffset(0), 46 fBufferContentSize(0) 47{ 48} 49 50// destructor 51PortChannel::~PortChannel() 52{ 53 delete[] fBuffer; 54} 55 56// InitCheck 57status_t 58PortChannel::InitCheck() const 59{ 60 if (fSendPort < 0) 61 return fSendPort; 62 if (fReceivePort < 0) 63 return fReceivePort; 64 if (!fBuffer) 65 return B_NO_MEMORY; 66 return B_OK; 67} 68 69// GetInfo 70void 71PortChannel::GetInfo(Info* info) const 72{ 73 if (info) { 74 info->sendPort = fSendPort; 75 info->receivePort = fReceivePort; 76 } 77} 78 79// Close 80void 81PortChannel::Close() 82{ 83 if (fSendPort >= 0) { 84 delete_port(fSendPort); 85 fSendPort = -1; 86 } 87 if (fReceivePort >= 0) { 88 delete_port(fReceivePort); 89 fReceivePort = -1; 90 } 91} 92 93// Send 94status_t 95PortChannel::Send(const void* _buffer, int32 size) 96{ 97 if (size == 0) 98 return B_OK; 99 if (!_buffer || size < 0) 100 return B_BAD_VALUE; 101 const uint8* buffer = static_cast<const uint8*>(_buffer); 102 while (size > 0) { 103 int32 sendSize = min(size, fBufferSize); 104 status_t error = write_port(fSendPort, 0, buffer, size); 105 if (error != B_OK) 106 return error; 107 size -= sendSize; 108 buffer += sendSize; 109 } 110 return B_OK; 111} 112 113// Receive 114status_t 115PortChannel::Receive(void* _buffer, int32 size) 116{ 117 if (size == 0) 118 return B_OK; 119 if (!_buffer || size < 0) 120 return B_BAD_VALUE; 121 uint8* buffer = static_cast<uint8*>(_buffer); 122 while (size > 0) { 123 if (fBufferContentSize > 0) { 124 // there's something in our buffer: just read from there 125 int32 bytesRead = min(size, fBufferContentSize); 126 memcpy(buffer, fBuffer + fBufferOffset, bytesRead); 127 fBufferOffset += bytesRead; 128 fBufferContentSize -= bytesRead; 129 size -= bytesRead; 130 buffer += bytesRead; 131 } else { 132 // nothing left in the buffer: we read from the port 133 if (size > fBufferSize) { 134 // we shall read more than what would fit into our buffer, so 135 // we can directly read into the user buffer 136 ssize_t bytesRead = read_port(fReceivePort, 0, buffer, size); 137 if (bytesRead < 0) 138 return bytesRead; 139 size -= bytesRead; 140 buffer += bytesRead; 141 } else { 142 // we read into our buffer 143 ssize_t bytesRead = read_port(fReceivePort, 0, fBuffer, 144 fBufferSize); 145 if (bytesRead < 0) 146 return bytesRead; 147 fBufferOffset = 0; 148 fBufferContentSize = bytesRead; 149 } 150 } 151 } 152 return B_OK; 153} 154 155