File indexing completed on 2024-05-12 04:58:51
0001 /** 0002 * SPDX-FileCopyrightText: 2019 Matthijs Tijink <matthijstijink@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "multiplexchannel.h" 0008 #include "core_debug.h" 0009 #include "multiplexchannelstate.h" 0010 0011 MultiplexChannel::MultiplexChannel(QSharedPointer<MultiplexChannelState> state) 0012 : state{state} 0013 { 0014 QIODevice::open(QIODevice::ReadWrite); 0015 0016 connect(this, &QIODevice::aboutToClose, state.data(), &MultiplexChannelState::requestClose); 0017 connect(state.data(), &MultiplexChannelState::readyRead, this, &QIODevice::readyRead); 0018 connect(state.data(), &MultiplexChannelState::bytesWritten, this, &QIODevice::bytesWritten); 0019 connect(state.data(), &MultiplexChannelState::disconnected, this, &MultiplexChannel::disconnect); 0020 } 0021 0022 MultiplexChannel::~MultiplexChannel() 0023 { 0024 } 0025 0026 bool MultiplexChannel::atEnd() const 0027 { 0028 return !isOpen() || (!state->connected && state->read_buffer.isEmpty()); 0029 } 0030 0031 void MultiplexChannel::disconnect() 0032 { 0033 state->connected = false; 0034 setOpenMode(QIODevice::ReadOnly); 0035 Q_EMIT state->readyRead(); 0036 Q_EMIT state->requestClose(); 0037 if (state->read_buffer.isEmpty()) { 0038 close(); 0039 } 0040 } 0041 0042 qint64 MultiplexChannel::bytesAvailable() const 0043 { 0044 return state->read_buffer.size() + QIODevice::bytesAvailable(); 0045 } 0046 0047 qint64 MultiplexChannel::bytesToWrite() const 0048 { 0049 return state->write_buffer.size() + QIODevice::bytesToWrite(); 0050 } 0051 0052 qint64 MultiplexChannel::readData(char *data, qint64 maxlen) 0053 { 0054 if (maxlen <= state->read_buffer.size()) { 0055 for (int i = 0; i < maxlen; ++i) { 0056 data[i] = state->read_buffer[i]; 0057 } 0058 state->read_buffer.remove(0, maxlen); 0059 Q_EMIT state->readAvailable(); 0060 if (!state->connected && state->read_buffer.isEmpty()) { 0061 close(); 0062 } 0063 return maxlen; 0064 } else if (state->read_buffer.size() > 0) { 0065 auto num_to_read = state->read_buffer.size(); 0066 for (int i = 0; i < num_to_read; ++i) { 0067 data[i] = state->read_buffer[i]; 0068 } 0069 state->read_buffer.remove(0, num_to_read); 0070 Q_EMIT state->readAvailable(); 0071 if (!state->connected && state->read_buffer.isEmpty()) { 0072 close(); 0073 } 0074 return num_to_read; 0075 } else if (isOpen() && state->connected) { 0076 if (state->requestedReadAmount < BUFFER_SIZE) { 0077 Q_EMIT state->readAvailable(); 0078 } 0079 return 0; 0080 } else { 0081 close(); 0082 return -1; 0083 } 0084 } 0085 0086 qint64 MultiplexChannel::writeData(const char *data, qint64 len) 0087 { 0088 state->write_buffer.append(data, len); 0089 Q_EMIT state->writeAvailable(); 0090 return len; 0091 } 0092 0093 bool MultiplexChannel::canReadLine() const 0094 { 0095 return isReadable() && (QIODevice::canReadLine() || state->read_buffer.contains('\n')); 0096 } 0097 0098 bool MultiplexChannel::isSequential() const 0099 { 0100 return true; 0101 } 0102 0103 #include "moc_multiplexchannel.cpp"