summaryrefslogtreecommitdiffhomepage
path: root/midiplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'midiplay.cpp')
-rw-r--r--midiplay.cpp138
1 files changed, 104 insertions, 34 deletions
diff --git a/midiplay.cpp b/midiplay.cpp
index d5c0ef0..34879ee 100644
--- a/midiplay.cpp
+++ b/midiplay.cpp
@@ -1,63 +1,133 @@
#include "MIDIPlayer.h"
+#include <stdexcept>
#include <string>
#include <fcgiapp.h>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
#include <fmt/format.h>
-std::string getPostData(FCGX_Request& request)
+namespace pt = boost::property_tree;
+
+using namespace std::string_literals;
+
+namespace {
+
+class PostData
{
- std::string result;
- std::string contentLengthString(FCGX_GetParam("CONTENT_LENGTH", request.envp));
- int contentLength = std::stoul(contentLengthString);
+public:
+ PostData(FCGX_Request& request) {
+ std::string result;
+ std::string contentLengthString(FCGX_GetParam("CONTENT_LENGTH", request.envp));
+ int contentLength = std::stoul(contentLengthString);
- if (contentLength < 1) {
- return "Bad content length";
- } else {
result.resize(contentLength);
unsigned int status = FCGX_GetStr(result.data(), result.size(), request.in);
if (status != result.size()) {
- return fmt::format("Read error: {}/{}", status, result.size());
+ throw std::runtime_error(fmt::format("Read error: {}/{}", status, result.size()));
}
- return result;
+ m_data = result;
+ }
+
+ std::string getData()
+ {
+ return m_data;
+ }
+
+ // path: xml path, e.g. data.value
+ std::string getXMLElement(const std::string& path)
+ {
+ pt::ptree tree{};
+ std::istringstream iss{m_data};
+ pt::read_xml(iss, tree, pt::xml_parser::trim_whitespace);
+
+ return tree.get<std::string>(path);
+ }
+
+private:
+ std::string m_data;
+};
+
+std::string getCommand(FCGX_Request& request)
+{
+ std::string query = FCGX_GetParam("QUERY_STRING", request.envp);
+ size_t pos = query.find("command=");
+ if (pos != query.npos) {
+ return query.substr(pos + 8);
+ } else {
+ return {};
}
}
-int main(int argc, char* argv[]) {
+std::string to_xml(const std::vector<std::string>& filelist, const std::string& selected)
+{
+ std::string result{"<data><status>ok</status><list>"};
+
+ for (const auto& i: filelist) {
+ result += "<filename>" + i + "</filename>";
+ }
+
+ result += "</list>";
+ result += "<selected>" + selected + "</selected>";
+ return result + "</data>";
+}
- int result = FCGX_Init();
- if (result != 0) {
- return 1; // error on init
- }
+} // namespace
- FCGX_Request request;
+int main(int argc, char* argv[]) {
+ MIDIPlayer player;
- if (FCGX_InitRequest(&request, 0, 0) != 0) {
- return 1; // error on init
- }
+ std::string ok_data{"<data><status>ok</status><message>OK</message></data>"};
+ std::string error_data{"<data><status>error</status><message>General Error</message></data>"};
- while (FCGX_Accept_r(&request) == 0) {
- std::string query = FCGX_GetParam("QUERY_STRING", request.envp);
-
- std::string method = FCGX_GetParam("REQUEST_METHOD", request.envp);
+ int result = FCGX_Init();
+ if (result != 0) {
+ return 1; // error on init
+ }
- if (method == "POST") {
- FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out);
+ FCGX_Request request;
- std::string data = getPostData(request);
- if (data == "<data><command>3</command></data>") {
- FCGX_PutS("<data><value1>4</value1></data>", request.out);
- }
- } else {
- FCGX_PutS("Content-Type: text/text\r\n\r\n", request.out);
- FCGX_PutS("Bad request method: POST expected", request.out);
- }
+ if (FCGX_InitRequest(&request, 0, 0) != 0) {
+ return 1; // error on init
+ }
- }
+ while (FCGX_Accept_r(&request) == 0) {
+ std::string method = FCGX_GetParam("REQUEST_METHOD", request.envp);
+
+ try {
+ if (method == "POST") {
+ FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out);
+
+ PostData data{request};
+ std::string command {getCommand(request)};
+ if (command == "start") {
+ player.start();
+ FCGX_PutS(ok_data.c_str(), request.out);
+ } else if (command == "stop") {
+ player.stop();
+ FCGX_PutS(ok_data.c_str(), request.out);
+ } else if (command == "getlist") {
+ FCGX_PutS(to_xml(player.get_filelist(), player.get_file()).c_str(), request.out);
+ } else if (command == "setfile") {
+ std::string filename = data.getXMLElement("data.value");
+ player.set_file(filename);
+ FCGX_PutS(ok_data.c_str(), request.out);
+ } else {
+ FCGX_PutS(error_data.c_str(), request.out);
+ }
+ } else {
+ throw std::runtime_error(fmt::format("Bad request method: POST expected, got {}", method).c_str());
+ }
+ } catch (const std::exception& ex) {
+ FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out);
+ FCGX_PutS(("<data><status>error</status><message>"s + ex.what() + "</message></data>").c_str(), request.out);
+ }
+ }
- return 0;
+ return 0;
}