CreoOtkPluging/ShellExportHandler.cpp

256 lines
9.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ShellExportHandler.h"
#include <algorithm>
#include <regex>
#include <stdexcept>
HttpResponse ShellExportHandler::HandleShrinkwrapShellRequest(const HttpRequest& request) {
std::string validation_error;
if (!ValidateHttpRequest(request, validation_error)) {
return FormatErrorResponse(400, validation_error);
}
try {
ShrinkwrapShellRequest shrinkwrap_request = ParseShrinkwrapRequest(request.body);
ShrinkwrapShellResult result = ShrinkwrapManager::Instance().ExecuteShrinkwrapShell(shrinkwrap_request);
if (result.success) {
return FormatSuccessResponse(result);
} else {
return FormatErrorResponse(500, result.error_message);
}
} catch (const std::exception& e) {
return FormatErrorResponse(500, "Request processing error: " + std::string(e.what()));
} catch (...) {
return FormatErrorResponse(500, "Unknown error during shrinkwrap shell export");
}
}
std::string ShellExportHandler::ExtractJsonValue(const std::string& json, const std::string& key) {
try {
std::string search_pattern = "\\\"" + key + "\\\"\\s*:\\s*\\\"([^\\\"]*?)\\\"";
std::regex pattern(search_pattern);
std::smatch match;
if (std::regex_search(json, match, pattern)) {
return match[1].str();
}
std::string search_pattern2 = "\\\"" + key + "\\\"\\s*:\\s*([^,}\\s]+)";
std::regex pattern2(search_pattern2);
if (std::regex_search(json, match, pattern2)) {
std::string value = match[1].str();
if (value.front() == '\"' && value.back() == '\"') {
value = value.substr(1, value.length() - 2);
}
return value;
}
} catch (...) {
// Error handling
}
return "";
}
bool ShellExportHandler::ExtractJsonBoolValue(const std::string& json, const std::string& key, bool default_value) {
std::string value = ExtractJsonValue(json, key);
if (value.empty()) {
return default_value;
}
std::string lower_value = value;
std::transform(lower_value.begin(), lower_value.end(), lower_value.begin(), ::tolower);
return (lower_value == "true" || lower_value == "1");
}
int ShellExportHandler::ExtractJsonIntValue(const std::string& json, const std::string& key, int default_value) {
std::string value = ExtractJsonValue(json, key);
if (value.empty()) {
return default_value;
}
try {
return std::stoi(value);
} catch (...) {
return default_value;
}
}
double ShellExportHandler::ExtractJsonDoubleValue(const std::string& json, const std::string& key, double default_value) {
std::string value = ExtractJsonValue(json, key);
if (value.empty()) {
return default_value;
}
try {
return std::stod(value);
} catch (...) {
return default_value;
}
}
std::string ShellExportHandler::EscapeJsonString(const std::string& input) {
std::string output;
output.reserve(input.length() * 2);
for (char c : input) {
switch (c) {
case '\"': output += "\\\""; break;
case '\\': output += "\\\\"; break;
case '\b': output += "\\b"; break;
case '\f': output += "\\f"; break;
case '\n': output += "\\n"; break;
case '\r': output += "\\r"; break;
case '\t': output += "\\t"; break;
default:
if (c < 0x20) {
char buffer[7];
snprintf(buffer, sizeof(buffer), "\\u%04x", static_cast<unsigned char>(c));
output += buffer;
} else {
output += c;
}
break;
}
}
return output;
}
bool ShellExportHandler::ValidateHttpRequest(const HttpRequest& request, std::string& error_message) {
if (request.method != "POST") {
error_message = "Method not allowed. Only POST requests are supported.";
return false;
}
if (request.body.empty()) {
error_message = "Request body is empty";
return false;
}
std::string trimmed_body = Trim(request.body);
if (!StartsWith(trimmed_body, "{") || !EndsWith(trimmed_body, "}")) {
error_message = "Invalid JSON format";
return false;
}
return true;
}
ShrinkwrapShellRequest ShellExportHandler::ParseShrinkwrapRequest(const std::string& json_body) {
ShrinkwrapShellRequest request;
request.software_type = ExtractJsonValue(json_body, "software_type");
if (request.software_type.empty()) {
request.software_type = "creo";
}
std::string project_name = ExtractJsonValue(json_body, "project_name");
if (!project_name.empty()) {
request.project_name = project_name;
}
std::string method = ExtractJsonValue(json_body, "method");
if (!method.empty()) {
request.method = method;
}
// 解析 component_path 参数(可选,用于指定子装配体)
request.component_path = ExtractJsonValue(json_body, "component_path");
request.quality = ExtractJsonIntValue(json_body, "quality", 8);
request.chord_height = ExtractJsonDoubleValue(json_body, "chord_height", 0.1);
request.fill_holes = ExtractJsonBoolValue(json_body, "fill_holes", true);
request.ignore_small_surfaces = ExtractJsonBoolValue(json_body, "ignore_small_surfaces", true);
request.small_surface_percentage = ExtractJsonDoubleValue(json_body, "small_surface_percentage", 0.5);
request.ignore_quilts = ExtractJsonBoolValue(json_body, "ignore_quilts", true);
request.ignore_skeleton = ExtractJsonBoolValue(json_body, "ignore_skeleton", true);
request.assign_mass_properties = ExtractJsonBoolValue(json_body, "assign_mass_properties", false);
request.output_file_path = ExtractJsonValue(json_body, "output_file_path");
request.output_type = ExtractJsonValue(json_body, "output_type");
if (request.output_type.empty()) {
request.output_type = "solid_surface";
}
request.preset = ExtractJsonValue(json_body, "preset");
// 解析超时参数默认30秒最大300秒
request.timeout_seconds = ExtractJsonIntValue(json_body, "timeout_seconds", 30);
if (request.timeout_seconds < 10) {
request.timeout_seconds = 10; // 最小10秒
}
if (request.timeout_seconds > 300) {
request.timeout_seconds = 300; // 最大300秒
}
return request;
}
HttpResponse ShellExportHandler::FormatSuccessResponse(const ShrinkwrapShellResult& result) {
HttpResponse response;
response.status_code = 200;
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"message\": \"" << EscapeJsonString(result.message) << "\","
<< "\"data\": {"
<< "\"output_file\": \"" << EscapeJsonString(result.parameters.output_file_path) << "\","
<< "\"file_size\": \"" << EscapeJsonString(result.parameters.output_file_size) << "\","
<< "\"export_time\": \"" << EscapeJsonString(result.parameters.shrinkwrap_time) << "\","
<< "\"parameters_used\": {"
<< "\"method\": \"" << EscapeJsonString(result.parameters.method) << "\","
<< "\"quality\": " << result.parameters.quality << ","
<< "\"fill_holes\": " << (result.parameters.fill_holes ? "true" : "false") << ","
<< "\"ignore_small_surfaces\": " << (result.parameters.ignore_small_surfaces ? "true" : "false") << ","
<< "\"small_surface_percentage\": " << result.parameters.small_surface_percentage << ","
<< "\"ignore_quilts\": " << (result.parameters.ignore_quilts ? "true" : "false") << ","
<< "\"ignore_skeleton\": " << (result.parameters.ignore_skeleton ? "true" : "false") << ","
<< "\"assign_mass_properties\": " << (result.parameters.assign_mass_properties ? "true" : "false")
<< "}"
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
return response;
}
HttpResponse ShellExportHandler::FormatErrorResponse(int status_code, const std::string& error_message) {
HttpResponse response;
response.status_code = status_code;
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"message\": null,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(error_message) << "\""
<< "}";
response.body = json.str();
return response;
}
std::string ShellExportHandler::Trim(const std::string& str) {
size_t start = str.find_first_not_of(" \t\n\r");
if (start == std::string::npos) {
return "";
}
size_t end = str.find_last_not_of(" \t\n\r");
return str.substr(start, end - start + 1);
}
bool ShellExportHandler::StartsWith(const std::string& str, const std::string& prefix) {
return str.length() >= prefix.length() &&
str.compare(0, prefix.length(), prefix) == 0;
}
bool ShellExportHandler::EndsWith(const std::string& str, const std::string& suffix) {
return str.length() >= suffix.length() &&
str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
}