mono/packages/media/cpp/src/ipc/ipc_serve.cpp
2026-04-12 22:57:40 +02:00

106 lines
3.9 KiB
C++

#include "ipc_serve.hpp"
#include <cstdio>
#include <asio.hpp>
#include <asio/read_until.hpp>
#include <asio/write.hpp>
#include <iostream>
#include <nlohmann/json.hpp>
#include "core/resize.hpp"
namespace media::ipc {
static int handle_session(asio::ip::tcp::socket sock) {
try {
asio::streambuf buf;
asio::read_until(sock, buf, '\n');
std::istream is(&buf);
std::string line;
std::getline(is, line);
nlohmann::json j = nlohmann::json::parse(line, nullptr, false);
if (!j.is_object()) {
std::string err = R"({"ok":false,"error":"invalid json"})";
asio::write(sock, asio::buffer(err + "\n"));
return 0;
}
if (!j.contains("input") || !j.contains("output")) {
std::string err = R"({"ok":false,"error":"need input and output"})";
asio::write(sock, asio::buffer(err + "\n"));
return 0;
}
media::ResizeOptions opt;
if (j.contains("max_width"))
opt.max_width = j["max_width"].get<int>();
if (j.contains("max_height"))
opt.max_height = j["max_height"].get<int>();
if (j.contains("format") && j["format"].is_string())
opt.format = j["format"].get<std::string>();
std::string err;
bool ok = media::resize_file(j["input"].get<std::string>(), j["output"].get<std::string>(), opt, err);
nlohmann::json out = ok ? nlohmann::json{{"ok", true}} : nlohmann::json{{"ok", false}, {"error", err}};
std::string payload = out.dump() + "\n";
asio::write(sock, asio::buffer(payload));
} catch (const std::exception& e) {
try {
std::string err = std::string(R"({"ok":false,"error":")") + e.what() + "\"}\n";
asio::write(sock, asio::buffer(err));
} catch (...) {
}
}
return 0;
}
int run_tcp_server(const std::string& host, int port) {
asio::io_context io;
asio::ip::tcp::acceptor acc(io, asio::ip::tcp::endpoint(asio::ip::make_address(host), static_cast<unsigned short>(port)));
std::cerr << "media-img IPC (TCP) " << host << ":" << port << "\n";
for (;;) {
asio::ip::tcp::socket sock(io);
acc.accept(sock);
handle_session(std::move(sock));
}
}
#if !defined(_WIN32)
#include <asio/local/stream_protocol.hpp>
#include <unistd.h>
int run_unix_server(const std::string& path) {
::unlink(path.c_str());
asio::io_context io;
asio::local::stream_protocol::acceptor acc(io, asio::local::stream_protocol::endpoint(path));
std::cerr << "media-img IPC (unix) " << path << "\n";
for (;;) {
asio::local::stream_protocol::socket sock(io);
acc.accept(sock);
// reuse same JSON line protocol over stream socket
asio::streambuf buf;
asio::read_until(sock, buf, '\n');
std::istream is(&buf);
std::string line;
std::getline(is, line);
nlohmann::json j = nlohmann::json::parse(line, nullptr, false);
if (!j.is_object()) {
asio::write(sock, asio::buffer(std::string(R"({"ok":false})") + "\n"));
continue;
}
media::ResizeOptions opt;
if (j.contains("max_width"))
opt.max_width = j["max_width"].get<int>();
if (j.contains("max_height"))
opt.max_height = j["max_height"].get<int>();
if (j.contains("format") && j["format"].is_string())
opt.format = j["format"].get<std::string>();
std::string err;
bool ok = media::resize_file(j["input"].get<std::string>(), j["output"].get<std::string>(), opt, err);
nlohmann::json out = ok ? nlohmann::json{{"ok", true}} : nlohmann::json{{"ok", false}, {"error", err}};
asio::write(sock, asio::buffer(out.dump() + "\n"));
}
}
#endif
} // namespace media::ipc