annotate vamp-client/ProcessQtTransport.h @ 95:b6ac26b72b59

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