c@31: c@31: #include "VampnProto.h" c@31: c@31: #include "bits/RequestOrResponse.h" c@31: c@31: #include c@31: #include c@31: #include c@31: c@31: using namespace std; c@31: using namespace vampipe; c@31: c@31: void usage() c@31: { c@31: string myname = "vampipe-server"; c@31: cerr << "\n" << myname << c@31: ": Load and run Vamp plugins in response to messages from stdin\n\n" c@31: " Usage: " << myname << "\n\n" c@31: "Expects Vamp request messages in Cap'n Proto packed format on stdin,\n" c@31: "and writes Vamp response messages in the same format to stdout.\n\n"; c@31: c@31: exit(2); c@31: } c@31: c@31: RequestOrResponse c@31: readRequestCapnp() c@31: { c@31: RequestOrResponse rr; c@31: rr.direction = RequestOrResponse::Request; c@31: c@31: ::capnp::PackedFdMessageReader message(0); // stdin c@31: VampRequest::Reader reader = message.getRoot(); c@31: c@31: rr.type = VampnProto::getRequestResponseType(reader); c@31: c@31: switch (rr.type) { c@31: c@31: case RRType::List: c@31: VampnProto::readVampRequest_List(reader); // type check only c@31: break; c@31: case RRType::Load: c@31: VampnProto::readVampRequest_Load(rr.loadRequest, reader); c@31: break; c@31: case RRType::Configure: c@31: VampnProto::readVampRequest_Configure(rr.configurationRequest, reader, c@31: rr.mapper); c@31: break; c@31: case RRType::Process: c@31: VampnProto::readVampRequest_Process(rr.processRequest, reader, c@31: rr.mapper); c@31: break; c@31: case RRType::Finish: c@31: VampnProto::readVampRequest_Finish(rr.finishPlugin, reader, c@31: rr.mapper); c@31: break; c@31: case RRType::NotValid: c@31: break; c@31: } c@31: c@31: return rr; c@31: } c@31: c@31: void c@31: writeResponseCapnp(RequestOrResponse &rr) c@31: { c@31: ::capnp::MallocMessageBuilder message; c@31: VampResponse::Builder builder = message.initRoot(); c@31: c@31: switch (rr.type) { c@31: c@31: case RRType::List: c@31: VampnProto::buildVampResponse_List(builder, "", rr.listResponse); c@31: break; c@31: case RRType::Load: c@31: VampnProto::buildVampResponse_Load(builder, rr.loadResponse, rr.mapper); c@31: break; c@31: case RRType::Configure: c@31: VampnProto::buildVampResponse_Configure(builder, rr.configurationResponse); c@31: break; c@31: case RRType::Process: c@31: VampnProto::buildVampResponse_Process(builder, rr.processResponse); c@31: break; c@31: case RRType::Finish: c@31: VampnProto::buildVampResponse_Finish(builder, rr.finishResponse); c@31: break; c@31: case RRType::NotValid: c@31: break; c@31: } c@31: c@31: writePackedMessageToFd(1, message); c@31: } c@31: c@31: RequestOrResponse c@31: processRequest(const RequestOrResponse &request) c@31: { c@31: RequestOrResponse response; c@31: response.direction = RequestOrResponse::Response; c@31: //!!! DO THE WORK! c@31: return response; c@31: } c@31: c@31: int main(int argc, char **argv) c@31: { c@31: if (argc != 1) { c@31: usage(); c@31: } c@31: c@31: while (true) { c@31: c@31: try { c@31: c@31: RequestOrResponse request = readRequestCapnp(); c@31: c@31: // NotValid without an exception indicates EOF: c@31: c@31: //!!! not yet it doesn't -- have to figure out how to c@31: //!!! handle this with capnp c@31: if (request.type == RRType::NotValid) break; c@31: c@31: RequestOrResponse response = processRequest(request); c@31: c@31: writeResponseCapnp(response); c@31: c@31: } catch (std::exception &e) { c@31: cerr << "Error: " << e.what() << endl; c@31: exit(1); c@31: } c@31: } c@31: c@31: exit(0); c@31: }