annotate vamp-client/PipedQProcessTransport.h @ 91:c897c9a8daf1

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