import os R = r"C:\Projects\CMSCore" def w(rel, txt): p = os.path.join(R, rel) os.makedirs(os.path.dirname(p), exist_ok=True) with open(p, "w", encoding="utf-8", newline="\r\n") as f: f.write(txt.lstrip("\n")) print(f" OK: {rel}") # ============================================================================ # 5. json_serializer.cpp (simple manual JSON - no nlohmann dependency yet) # ============================================================================ w("anscloud-common/src/json_serializer.cpp", r'''#include #include #include #include #include #include // ========================================================================== // Minimal JSON builder/parser (no external dependency). // Replace with nlohmann/json when you add it via NuGet/vcpkg. // ========================================================================== namespace anscloud { namespace json { // ---- Utilities ---- std::string now_iso8601() { auto now = std::chrono::system_clock::now(); auto t = std::chrono::system_clock::to_time_t(now); struct tm buf; #ifdef _WIN32 gmtime_s(&buf, &t); #else gmtime_r(&t, &buf); #endif std::ostringstream ss; ss << std::put_time(&buf, "%Y-%m-%dT%H:%M:%SZ"); return ss.str(); } std::string generate_uuid() { static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution dist(0, 0xFFFFFFFF); auto hex = [](uint32_t v, int digits) { std::ostringstream s; s << std::hex << std::setfill('0') << std::setw(digits) << v; return s.str(); }; uint32_t a = dist(gen), b = dist(gen), c = dist(gen), d = dist(gen); return hex(a, 8) + "-" + hex(b >> 16, 4) + "-4" + hex((b & 0xFFF), 3) + "-" + hex(0x8000 | (c & 0x3FFF), 4) + "-" + hex(d, 8) + hex(c >> 16, 4); } // Simple JSON escape static std::string esc(const std::string& s) { std::string r; r.reserve(s.size() + 8); for (char c : s) { switch (c) { case '"': r += "\\\""; break; case '\\': r += "\\\\"; break; case '\n': r += "\\n"; break; case '\r': r += "\\r"; break; case '\t': r += "\\t"; break; default: r += c; } } return r; } // Helper macros for building JSON #define JS_STR(k, v) "\"" k "\":\"" + esc(v) + "\"" #define JS_NUM(k, v) "\"" k "\":" + std::to_string(v) #define JS_BOOL(k, v) "\"" k "\":" + std::string((v) ? "true" : "false") // ---- Serialize implementations ---- std::string serialize(const SystemMetrics& m) { return "{" + JS_NUM("cpu_usage_percent", m.cpu_usage_percent) + "," + JS_NUM("ram_usage_percent", m.ram_usage_percent) + "," + JS_NUM("ram_total_mb", m.ram_total_mb) + "," + JS_NUM("ram_used_mb", m.ram_used_mb) + "," + JS_NUM("gpu_usage_percent", m.gpu_usage_percent) + "," + JS_NUM("gpu_memory_percent", m.gpu_memory_percent) + "," + JS_NUM("gpu_temperature_c", m.gpu_temperature_c) + "," + JS_NUM("disk_usage_percent", m.disk_usage_percent) + "," + JS_NUM("disk_total_gb", m.disk_total_gb) + "," + JS_NUM("disk_used_gb", m.disk_used_gb) + "," + JS_NUM("cpu_temperature_c", m.cpu_temperature_c) + "," + JS_NUM("process_count", m.process_count) + "," + JS_NUM("network_rx_mbps", m.network_rx_mbps) + "," + JS_NUM("network_tx_mbps", m.network_tx_mbps) + "}"; } std::string serialize(const CameraInfo& cam) { return "{" + JS_STR("camera_id", cam.camera_id) + "," + JS_STR("name", cam.name) + "," + JS_STR("rtsp_url", cam.rtsp_url) + "," + JS_STR("status", cam.status) + "," + JS_NUM("width", cam.width) + "," + JS_NUM("height", cam.height) + "," + JS_NUM("fps", cam.fps) + "," + JS_STR("codec", cam.codec) + "," + JS_STR("ai_models", cam.ai_models) + "," + JS_BOOL("recording", cam.recording) + "}"; } std::string serialize(const std::vector& cams) { std::string r = "["; for (size_t i = 0; i < cams.size(); ++i) { if (i > 0) r += ","; r += serialize(cams[i]); } return r + "]"; } std::string serialize(const InferenceMetrics& inf) { return "{" + JS_NUM("active_models", inf.active_models) + "," + JS_NUM("avg_latency_ms", inf.avg_latency_ms) + "," + JS_NUM("total_fps", inf.total_fps) + "," + JS_NUM("total_detections", inf.total_detections) + "}"; } std::string serialize(const Heartbeat& hb) { return "{" + JS_STR("device_id", hb.device_id) + "," + JS_STR("timestamp", hb.timestamp) + "," + JS_STR("status", to_string(hb.status)) + "," + JS_NUM("uptime_seconds", hb.uptime_seconds) + "," + JS_STR("firmware_version", hb.firmware_version) + "," + JS_STR("ansvis_version", hb.ansvis_version) + "}"; } std::string serialize(const DeviceTelemetry& tel) { return "{" + JS_STR("device_id", tel.device_id) + "," + JS_STR("timestamp", tel.timestamp) + "," + "\"metrics\":" + serialize(tel.metrics) + "," + "\"cameras\":" + serialize(tel.cameras) + "," + "\"inference\":" + serialize(tel.inference) + "}"; } std::string serialize(const Command& cmd) { return "{" + JS_STR("command_id", cmd.command_id) + "," + JS_STR("device_id", cmd.device_id) + "," + JS_STR("type", to_string(cmd.type)) + "," + JS_STR("type_name", cmd.type_name) + "," + "\"params\":" + (cmd.params_json.empty() ? "{}" : cmd.params_json) + "," + JS_STR("correlation_id", cmd.correlation_id) + "," + JS_STR("reply_to", cmd.reply_to) + "," + JS_NUM("timeout_seconds", cmd.timeout_seconds) + "," + JS_STR("timestamp", cmd.timestamp) + "}"; } std::string serialize(const CommandResponse& r) { return "{" + JS_STR("command_id", r.command_id) + "," + JS_STR("device_id", r.device_id) + "," + JS_STR("status", to_string(r.status)) + "," + "\"result\":" + (r.result_json.empty() ? "{}" : r.result_json) + "," + JS_STR("error_message", r.error_message) + "," + JS_STR("correlation_id", r.correlation_id) + "," + JS_NUM("execution_time_ms", r.execution_time_ms) + "," + JS_STR("timestamp", r.timestamp) + "}"; } std::string serialize(const DeviceEvent& e) { return "{" + JS_STR("event_id", e.event_id) + "," + JS_STR("device_id", e.device_id) + "," + JS_STR("type", to_string(e.type)) + "," + JS_STR("type_name", e.type_name) + "," + JS_STR("camera_id", e.camera_id) + "," + "\"data\":" + (e.data_json.empty() ? "{}" : e.data_json) + "," + JS_STR("timestamp", e.timestamp) + "," + JS_NUM("severity", e.severity) + "}"; } std::string serialize(const DeviceStatusMessage& s) { return "{" + JS_STR("device_id", s.device_id) + "," + JS_STR("status", to_string(s.status)) + "," + JS_STR("timestamp", s.timestamp) + "," + JS_STR("firmware_version", s.firmware_version) + "," + JS_STR("ansvis_version", s.ansvis_version) + "," + JS_STR("ip_address", s.ip_address) + "," + JS_STR("message", s.message) + "}"; } // ---- Deserialize stubs (TODO: implement with proper JSON parser) ---- // For now these return default-constructed objects. // Replace with nlohmann/json parsing when ready. Heartbeat deserialize_heartbeat(const std::string&) { return {}; } DeviceTelemetry deserialize_telemetry(const std::string&) { return {}; } SystemMetrics deserialize_metrics(const std::string&) { return {}; } Command deserialize_command(const std::string&) { return {}; } CommandResponse deserialize_response(const std::string&) { return {}; } DeviceEvent deserialize_event(const std::string&) { return {}; } DeviceStatusMessage deserialize_status_message(const std::string&) { return {}; } CameraInfo deserialize_camera(const std::string&) { return {}; } std::vector deserialize_camera_list(const std::string&){ return {}; } } // namespace json } // namespace anscloud ''') print(" [5] json_serializer.cpp done")