/* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012 Symless Ltd. * * This package is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * found in the file LICENSE that should have accompanied this file. * * This package is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "IpcReader.h" #include "Logger.h" #include "byte_utils.h" #include "common/ipc.h" #include #include #include using namespace synergy::gui; IpcReader::IpcReader(QTcpSocket *socket) : m_Socket(socket) {} void IpcReader::start() const { connect( m_Socket, &QTcpSocket::readyRead, this, &IpcReader::onSocketReadyRead); } void IpcReader::stop() const { disconnect( m_Socket, &QTcpSocket::readyRead, this, &IpcReader::onSocketReadyRead); } void IpcReader::onSocketReadyRead() { QMutexLocker locker(&m_Mutex); logVerbose("ready read"); while (m_Socket->bytesAvailable()) { logVerbose("bytes available"); char codeBuf[5]; readStream(codeBuf, 4); codeBuf[4] = 0; logVerbose(QString("ipc read: %1").arg(codeBuf)); if (memcmp(codeBuf, kIpcMsgLogLine, 4) == 0) { logVerbose("reading log line"); char lenBuf[4]; readStream(lenBuf, 4); int len = bytesToInt(lenBuf, 4); std::vector dataBuf(len); readStream(dataBuf.data(), len); QString text = QString::fromUtf8(dataBuf.data(), len); emit read(text); } else if (memcmp(codeBuf, kIpcMsgHelloBack, 4) == 0) { logVerbose("reading hello back"); emit helloBack(); } else { qCritical("aborting ipc read, message invalid"); return; } } logVerbose("read done"); } bool IpcReader::readStream(char *buffer, int length) { logVerbose("reading stream"); int read = 0; while (read < length) { int ask = length - read; if (m_Socket->bytesAvailable() < ask) { logVerbose("buffer too short, waiting"); m_Socket->waitForReadyRead(-1); } auto got = m_Socket->read(buffer, ask); read += got; logVerbose(QString("ask=%1 got=%2 read=%3").arg(ask).arg(got).arg(read)); if (got == -1) { logVerbose("socket ended, aborting"); return false; } else if (length - read > 0) { logVerbose(QString("more remains, seek to %1").arg(got)); buffer += got; } } return true; }