annotate vamp-client/PiperQProcessTransport.h @ 93:fbce91785d35

Having a class called PipedXX is too confusing with all the Piper classes; give up and rename it
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 13 Oct 2016 12:07:41 +0100
parents
children
rev   line source
c@93 1
c@93 2 #ifndef PIPER_QPROCESS_TRANSPORT_H
c@93 3 #define PIPER_QPROCESS_TRANSPORT_H
c@93 4
c@93 5 #include "SynchronousTransport.h"
c@93 6
c@93 7 #include <QProcess>
c@93 8 #include <QString>
c@93 9
c@93 10 #include <iostream>
c@93 11
c@93 12 namespace piper { //!!! change
c@93 13
c@93 14 class PiperQProcessTransport : public SynchronousTransport
c@93 15 {
c@93 16 public:
c@93 17 PiperQProcessTransport(QString processName) :
c@93 18 m_completenessChecker(0) {
c@93 19 m_process = new QProcess();
c@93 20 m_process->setReadChannel(QProcess::StandardOutput);
c@93 21 m_process->setProcessChannelMode(QProcess::ForwardedErrorChannel);
c@93 22 m_process->start(processName);
c@93 23 if (!m_process->waitForStarted()) {
c@93 24 std::cerr << "server failed to start" << std::endl;
c@93 25 delete m_process;
c@93 26 m_process = nullptr;
c@93 27 }
c@93 28 }
c@93 29
c@93 30 ~PiperQProcessTransport() {
c@93 31 if (m_process) {
c@93 32 if (m_process->state() != QProcess::NotRunning) {
c@93 33 m_process->closeWriteChannel();
c@93 34 m_process->waitForFinished(200);
c@93 35 m_process->close();
c@93 36 m_process->waitForFinished();
c@93 37 std::cerr << "server exited" << std::endl;
c@93 38 }
c@93 39 delete m_process;
c@93 40 }
c@93 41 }
c@93 42
c@93 43 void
c@93 44 setCompletenessChecker(MessageCompletenessChecker *checker) {
c@93 45 //!!! ownership?
c@93 46 m_completenessChecker = checker;
c@93 47 }
c@93 48
c@93 49 bool
c@93 50 isOK() const override {
c@93 51 return m_process != nullptr;
c@93 52 }
c@93 53
c@93 54 std::vector<char>
c@93 55 call(const char *ptr, size_t size) override {
c@93 56
c@93 57 if (!m_completenessChecker) {
c@93 58 throw std::logic_error("No completeness checker set on transport");
c@93 59 }
c@93 60
c@93 61 m_process->write(ptr, size);
c@93 62
c@93 63 std::vector<char> buffer;
c@93 64 bool complete = false;
c@93 65
c@93 66 while (!complete) {
c@93 67
c@93 68 m_process->waitForReadyRead(1000);
c@93 69 qint64 byteCount = m_process->bytesAvailable();
c@93 70
c@93 71 if (!byteCount) {
c@93 72 if (m_process->state() == QProcess::NotRunning) {
c@93 73 std::cerr << "ERROR: Subprocess exited: Load failed" << std::endl;
c@93 74 throw std::runtime_error("Piper server exited unexpectedly");
c@93 75 }
c@93 76 } else {
c@93 77 size_t formerSize = buffer.size();
c@93 78 buffer.resize(formerSize + byteCount);
c@93 79 m_process->read(buffer.data() + formerSize, byteCount);
c@93 80 complete = m_completenessChecker->isComplete(buffer);
c@93 81 }
c@93 82 }
c@93 83
c@93 84 return buffer;
c@93 85 }
c@93 86
c@93 87 private:
c@93 88 MessageCompletenessChecker *m_completenessChecker; //!!! I don't own this (currently)
c@93 89 QProcess *m_process; // I own this
c@93 90 };
c@93 91
c@93 92 }
c@93 93
c@93 94 #endif