1 // PortChannel.cpp 2 3 #include <new> 4 #include <string.h> 5 6 #include "PortChannel.h" 7 #include "Utils.h" 8 9 static const int32 kMaxPortMessageSize = 102400; // 100 KB 10 static const int32 kDefaultBufferSize = 10240; // 10 KB 11 12 // constructor 13 PortChannel::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 27 PortChannel::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 39 PortChannel::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 51 PortChannel::~PortChannel() 52 { 53 delete[] fBuffer; 54 } 55 56 // InitCheck 57 status_t 58 PortChannel::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 70 void 71 PortChannel::GetInfo(Info* info) const 72 { 73 if (info) { 74 info->sendPort = fSendPort; 75 info->receivePort = fReceivePort; 76 } 77 } 78 79 // Close 80 void 81 PortChannel::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 94 status_t 95 PortChannel::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 114 status_t 115 PortChannel::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