#include #include #include #include "control_port.hpp" ControlPort::ControlPort(){ QObject::connect(&socket, &QTcpSocket::readyRead, this, &ControlPort::readReady); QObject::connect(&socket, &QTcpSocket::connected, this, &ControlPort::connected); QObject::connect(&socket, &QTcpSocket::disconnected, this, &ControlPort::disconnected); } void ControlPort::connect(int local_port){ /* Prevents failure in case the socket is alredy connecting. This also * discards pending data in the send buffer, but we don't care about * that.*/ socket.abort(); socket.connectToHost(QHostAddress::LocalHost, local_port); } void ControlPort::parseLine(std::string_view line){ constexpr std::string_view prefix = "Control socket listening on port"; if(line.substr(0, prefix.length()) != prefix) return; auto tmp = std::string(line.substr(prefix.length())); int port = 0; sscanf(tmp.c_str(), " %d", &port); connect(port); } QAbstractSocket::SocketState ControlPort::getState() const{ return socket.state(); } void ControlPort::writeLine(std::string_view line){ int toWrite = line.length(); const char *data = line.data(); while(toWrite > 0){ auto ret = socket.write(data, toWrite); if(ret < 0){ break; } data += ret; toWrite -= ret; } } void ControlPort::readReady(){ char buf[512]; while(true){ int ret = socket.read(buf, sizeof(buf)); if(ret == 0 || ret == -1) break; lineBuf.write(std::string_view(buf, ret)); while(lineBuf.hasLine()){ for(auto& c : lineCallbacks){ c(lineBuf.peek()); } lineBuf.pop(); } } }