[OpenDocString] kdeconnect-kde (cpp)
multiplexchannel.cpp
MultiplexChannel::MultiplexChannel(QSharedPointer state)
    : state{state}
{
    QIODevice::open(QIODevice::ReadWrite);

    connect(this, &QIODevice::aboutToClose, state.data(), &MultiplexChannelState::requestClose);
    connect(state.data(), &MultiplexChannelState::readyRead, this, &QIODevice::readyRead);
    connect(state.data(), &MultiplexChannelState::bytesWritten, this, &QIODevice::bytesWritten);
    connect(state.data(), &MultiplexChannelState::disconnected, this, &MultiplexChannel::disconnect);
}
This constructor builds a multiplex channel object from a given state object. It takes the state object of the channel, and connects the read and write methods to the device and the channel data channels.
MultiplexChannel::~MultiplexChannel()
{
}
This removes all events of the channel.
bool MultiplexChannel::atEnd() const
{
    return !isOpen() || (!state->connected && state->read_buffer.isEmpty());
}
This implements checking if the channel is open and is connected and there is data available to read.
void MultiplexChannel::disconnect()
{
    state->connected = false;
    setOpenMode(QIODevice::ReadOnly);
    Q_EMIT state->readyRead();
    Q_EMIT state->requestClose();
    if (state->read_buffer.isEmpty()) {
        close();
    }
}
This disconnects from the network and sets the open mode to readonly and requests a close if the read buffer is empty.
qint64 MultiplexChannel::bytesAvailable() const
{
    return state->read_buffer.size() + QIODevice::bytesAvailable();
}
Returns the number of bytes available in the current read buffer.
qint64 MultiplexChannel::bytesToWrite() const
{
    return state->write_buffer.size() + QIODevice::bytesToWrite();
}
Returns the number of bytes that can be written, in bytes.
qint64 MultiplexChannel::readData(char *data, qint64 maxlen)
{
    if (maxlen <= state->read_buffer.size()) {
        for (int i = 0; i < maxlen; ++i) {
            data[i] = state->read_buffer[i];
        }
        state->read_buffer.remove(0, maxlen);
        Q_EMIT state->readAvailable();
        if (!state->connected && state->read_buffer.isEmpty()) {
            close();
        }
        return maxlen;
    } else if (state->read_buffer.size() > 0) {
        auto num_to_read = state->read_buffer.size();
        for (int i = 0; i < num_to_read; ++i) {
            data[i] = state->read_buffer[i];
        }
        state->read_buffer.remove(0, num_to_read);
        Q_EMIT state->readAvailable();
        if (!state->connected && state->read_buffer.isEmpty()) {
            close();
        }
        return num_to_read;
    } else if (isOpen() && state->connected) {
        if (state->requestedReadAmount < BUFFER_SIZE) {
            Q_EMIT state->readAvailable();
        }
        return 0;
    } else {
        close();
        return -1;
    }
}
This removes the first maxlen bytes from the read buffer, and returns the number of bytes read. If the buffer is full, it returns the number of bytes read, and closes the connection. If the channel is not open, it returns -1.
qint64 MultiplexChannel::writeData(const char *data, qint64 len)
{
    state->write_buffer.append(data, len);
    Q_EMIT state->writeAvailable();
    return len;
}
This adds len bytes of data to the internal write buffer and emits the signal writeAvailable.
bool MultiplexChannel::canReadLine() const
{
    return isReadable() && (QIODevice::canReadLine() || state->read_buffer.contains('\n'));
}
This implements checking if the channel is readable and is readable by reading a line of data. If the device is not readable, the function returns false.
bool MultiplexChannel::isSequential() const
{
    return true;
}
This implements checking if the channel is sequential.