c@93: c@93: #ifndef PIPER_QPROCESS_TRANSPORT_H c@93: #define PIPER_QPROCESS_TRANSPORT_H c@93: c@93: #include "SynchronousTransport.h" c@93: c@93: #include c@93: #include c@93: c@93: #include c@93: c@93: namespace piper { //!!! change c@93: c@93: class PiperQProcessTransport : public SynchronousTransport c@93: { c@93: public: c@93: PiperQProcessTransport(QString processName) : c@93: m_completenessChecker(0) { c@93: m_process = new QProcess(); c@93: m_process->setReadChannel(QProcess::StandardOutput); c@93: m_process->setProcessChannelMode(QProcess::ForwardedErrorChannel); c@93: m_process->start(processName); c@93: if (!m_process->waitForStarted()) { c@93: std::cerr << "server failed to start" << std::endl; c@93: delete m_process; c@93: m_process = nullptr; c@93: } c@93: } c@93: c@93: ~PiperQProcessTransport() { c@93: if (m_process) { c@93: if (m_process->state() != QProcess::NotRunning) { c@93: m_process->closeWriteChannel(); c@93: m_process->waitForFinished(200); c@93: m_process->close(); c@93: m_process->waitForFinished(); c@93: std::cerr << "server exited" << std::endl; c@93: } c@93: delete m_process; c@93: } c@93: } c@93: c@93: void c@93: setCompletenessChecker(MessageCompletenessChecker *checker) { c@93: //!!! ownership? c@93: m_completenessChecker = checker; c@93: } c@93: c@93: bool c@93: isOK() const override { c@93: return m_process != nullptr; c@93: } c@93: c@93: std::vector c@93: call(const char *ptr, size_t size) override { c@93: c@93: if (!m_completenessChecker) { c@93: throw std::logic_error("No completeness checker set on transport"); c@93: } c@93: c@93: m_process->write(ptr, size); c@93: c@93: std::vector buffer; c@93: bool complete = false; c@93: c@93: while (!complete) { c@93: c@93: m_process->waitForReadyRead(1000); c@93: qint64 byteCount = m_process->bytesAvailable(); c@93: c@93: if (!byteCount) { c@93: if (m_process->state() == QProcess::NotRunning) { c@93: std::cerr << "ERROR: Subprocess exited: Load failed" << std::endl; c@93: throw std::runtime_error("Piper server exited unexpectedly"); c@93: } c@93: } else { c@93: size_t formerSize = buffer.size(); c@93: buffer.resize(formerSize + byteCount); c@93: m_process->read(buffer.data() + formerSize, byteCount); c@93: complete = m_completenessChecker->isComplete(buffer); c@93: } c@93: } c@93: c@93: return buffer; c@93: } c@93: c@93: private: c@93: MessageCompletenessChecker *m_completenessChecker; //!!! I don't own this (currently) c@93: QProcess *m_process; // I own this c@93: }; c@93: c@93: } c@93: c@93: #endif