#include "stdafx.h" #include "GlassJson.h" #include #include #include #include #include #include "CGlass.h" #include "CParam.h" #include "CJobDataS.h" #include "CPath.h" using namespace SERVO; // ==================== С¹¤¾ß£¨¼æÈÝÀÏ JsonCpp£© ==================== // ½« optional תºÁÃ루int64£©£¬ÔÙÒÔ×Ö·û´®Ð´Èë JSON static std::string tp_to_ms_str(std::optional tp) { if (!tp) return std::string(); // ¿Õ´®±íʾÎÞ using namespace std::chrono; long long ms = duration_cast(tp->time_since_epoch()).count(); return std::to_string(ms); } // ´Ó JSON µÄ×Ö·û´®/Êý×ÖÈÝÈÌʽ¶ÁÈ¡ 64 룬ÓÅÏÈ string static bool get_ll_from_json(const Json::Value& v, const char* key, long long& out) { if (!v.isMember(key)) return false; const Json::Value& x = v[key]; if (x.isString()) { const std::string s = x.asString(); if (s.empty()) return false; char* endp = nullptr; errno = 0; #if defined(_MSC_VER) long long val = _strtoi64(s.c_str(), &endp, 10); #else long long val = std::strtoll(s.c_str(), &endp, 10); #endif if (endp && *endp == '\0' && errno == 0) { out = val; return true; } // ÈÝ´í£ºÈç¹ûÆäʵÊÇÊý×Ö×Ö·û´®£¨´ø¿Õ¸ñ£©£¬ÔÙÊÔÒ»´Î try { out = std::stoll(s); return true; } catch (...) {} return false; } if (x.isInt()) { out = static_cast(x.asInt()); return true; } if (x.isUInt()) { out = static_cast(x.asUInt()); return true; } if (x.isDouble()) { out = static_cast(x.asDouble()); return true; } return false; } // д 64 λΪ×Ö·û´®£¨¿ç°æ±¾/¿çÓïÑÔ¸üÎÈ£© static void put_ull_as_str(Json::Value& obj, const char* key, unsigned long long v) { obj[key] = Json::Value(std::to_string(v)); } static void put_ll_as_str(Json::Value& obj, const char* key, long long v) { obj[key] = Json::Value(std::to_string(v)); } // ¼ò»¯¶ÁÈ¡£¨´øÄ¬ÈÏ£© static int JInt(const Json::Value& v, const char* k, int d = 0) { return v.isMember(k) ? v[k].asInt() : d; } static unsigned JUInt(const Json::Value& v, const char* k, unsigned d = 0) { return v.isMember(k) ? v[k].asUInt() : d; } static bool JBool(const Json::Value& v, const char* k, bool d = false) { return v.isMember(k) ? v[k].asBool() : d; } static std::string JStr(const Json::Value& v, const char* k, const std::string& d = "") { return v.isMember(k) ? v[k].asString() : d; } static double JDouble(const Json::Value& v, const char* k, double d = 0.0) { return v.isMember(k) ? v[k].asDouble() : d; } // ==================== CGlass -> JSON ==================== Json::Value GlassJson::ToJson(const CGlass& gConst) { CGlass& g = const_cast(gConst); // Ðí¶à getter ²»ÊÇ const Json::Value root(Json::objectValue); // »ù±¾ root["id"] = g.getID(); root["materials"] = static_cast(g.getType()); // 0/1/2/3 root["buddy_id"] = g.getBuddyId(); root["has_buddy"] = (g.getBuddy() != nullptr); int port = 0, slot = 0; g.getOrginPort(port, slot); root["origin_port"] = port; root["origin_slot"] = slot; root["scheduled"] = g.isScheduledForProcessing() ? true : false; root["state"] = static_cast(g.state()); // GlsState -> int root["fail_reason"] = g.m_failReason; // ʱ¼ä´Á£ºÒÔ×Ö·û´®Ð´ root["t_queued_ms"] = tp_to_ms_str(g.tQueued()); root["t_start_ms"] = tp_to_ms_str(g.tStart()); root["t_end_ms"] = tp_to_ms_str(g.tEnd()); // params: vector { Json::Value arr(Json::arrayValue); for (auto& p : g.getParams()) { Json::Value jp(Json::objectValue); jp["id"] = p.getId(); jp["name"] = p.getName(); jp["unit"] = p.getUnit(); int vt = p.getValueType(); // PVT_INT=0, PVT_DOUBLE=1 jp["vtype"] = vt; if (vt == PVT_INT) jp["iv"] = p.getIntValue(); else jp["fv"] = p.getDoubleValue(); arr.append(std::move(jp)); } root["params"] = std::move(arr); } // JobDataS { CJobDataS& s = *g.getJobDataS(); Json::Value js(Json::objectValue); js["cassette_seq_no"] = s.getCassetteSequenceNo(); js["job_seq_no"] = s.getJobSequenceNo(); js["lot_id"] = s.getLotId(); js["product_id"] = s.getProductId(); js["operation_id"] = s.getOperationId(); js["glass1_id"] = s.getGlass1Id(); js["glass2_id"] = s.getGlass2Id(); js["job_type"] = s.getJobType(); js["materials_type"] = s.getMaterialsType(); js["product_type"] = s.getProductType(); js["dummy_type"] = s.getDummyType(); js["skip_flag"] = s.getSkipFlag(); js["process_flag"] = s.getProcessFlag(); js["process_reason"] = s.getProcessResonCode(); js["last_glass_flag"] = s.getLastGlassFlag(); js["first_glass_flag"] = s.getFirstGlassFlag(); Json::Value q(Json::arrayValue); for (int i = 0; i < 3; i++) q.append(s.getQTime(i)); js["qtime"] = std::move(q); js["qtime_over_flag"] = s.getQTimeOverFlag(); js["master_recipe"] = s.getMasterRecipe(); Json::Value rids(Json::arrayValue); for (int i = 0; i < DEVICE_COUNT; i++) rids.append(s.getDeviceRecipeId(i)); js["device_recipe_ids"] = std::move(rids); js["panel_measure"] = s.getPanelMeasure(); js["mode"] = s.getMode(); js["slot_unit_select_flag"] = s.getSlotUnitSelectFlag(); js["source_port_no"] = s.getSourcePortNo(); js["source_slot_no"] = s.getSourceSlotNo(); js["target_port_no"] = s.getTargetPortNo(); js["target_slot_no"] = s.getTargetSlotNo(); js["product_judge"] = s.getProductJudge(); root["job_data_s"] = std::move(js); } // path£¨Á´±í ¡ú Êý×飻ʱ¼ä×Ö¶ÎÒÔ×Ö·û´®´æ£© { Json::Value arr(Json::arrayValue); if (auto head = g.getPath()) { CPath* p = head->getHeadPath(); while (p) { Json::Value n(Json::objectValue); n["eq_id"] = p->getEqID(); n["unit"] = p->getUnit(); put_ull_as_str(n, "time_in", static_cast(p->getInTime())); put_ull_as_str(n, "time_out", static_cast(p->getOutTime())); n["processed"] = p->isProcessEnd() ? true : false; n["insp_result"] = static_cast(p->getInspResult()); // 0:not,1:pass,2:fail arr.append(std::move(n)); p = p->getNext(); } } root["path"] = std::move(arr); } root["payload_version"] = 1; return root; } // ==================== JSON -> CGlass ==================== void GlassJson::FromJson(const Json::Value& root, CGlass& g) { // »ù±¾ g.setID(JStr(root, "id").c_str()); g.setType(static_cast(JInt(root, "materials", 0))); g.getBuddyId() = JStr(root, "buddy_id"); g.setScheduledForProcessing(JBool(root, "scheduled") ? TRUE : FALSE); g.m_failReason = JStr(root, "fail_reason"); g.setOriginPort(JInt(root, "origin_port", 0), JInt(root, "origin_slot", 0)); // ״̬Óëʱ¼ä£¨Ê±¼ä´Ó×Ö·û´®/Êý×ÖÈÝ´í½âÎö£© g.m_state = static_cast(JInt(root, "state", 0)); long long ms = 0; if (get_ll_from_json(root, "t_queued_ms", ms)) g.m_tQueued = std::chrono::system_clock::time_point(std::chrono::milliseconds(ms)); else g.m_tQueued = std::nullopt; if (get_ll_from_json(root, "t_start_ms", ms)) g.m_tStart = std::chrono::system_clock::time_point(std::chrono::milliseconds(ms)); else g.m_tStart = std::nullopt; if (get_ll_from_json(root, "t_end_ms", ms)) g.m_tEnd = std::chrono::system_clock::time_point(std::chrono::milliseconds(ms)); else g.m_tEnd = std::nullopt; // params g.getParams().clear(); if (root.isMember("params") && root["params"].isArray()) { for (const auto& jp : root["params"]) { const int vt = JInt(jp, "vtype", 0); // 0=int,1=double const std::string name = JStr(jp, "name"); const std::string id = JStr(jp, "id"); const std::string unit = JStr(jp, "unit"); if (vt == PVT_INT) { CParam p(name.c_str(), id.c_str(), unit.c_str(), JInt(jp, "iv", 0)); g.getParams().push_back(std::move(p)); } else { CParam p(name.c_str(), id.c_str(), unit.c_str(), JDouble(jp, "fv", 0.0)); g.getParams().push_back(std::move(p)); } } } // JobDataS if (root.isMember("job_data_s") && root["job_data_s"].isObject()) { const auto& js = root["job_data_s"]; CJobDataS* s = g.getJobDataS(); s->setCassetteSequenceNo(JInt(js, "cassette_seq_no", 0)); s->setJobSequenceNo(JInt(js, "job_seq_no", 0)); s->setLotId(JStr(js, "lot_id").c_str()); s->setProductId(JStr(js, "product_id").c_str()); s->setOperationId(JStr(js, "operation_id").c_str()); s->setGlass1Id(JStr(js, "glass1_id").c_str()); s->setGlass2Id(JStr(js, "glass2_id").c_str()); s->setJobType(JInt(js, "job_type", 0)); s->setMaterialsType(JInt(js, "materials_type", 0)); s->setProductType(JInt(js, "product_type", 0)); s->setDummyType(JInt(js, "dummy_type", 0)); s->setSkipFlag(JInt(js, "skip_flag", 0)); s->setProcessFlag(JInt(js, "process_flag", 0)); s->setProcessResonCode(JInt(js, "process_reason", 0)); s->setLastGlassFlag(JInt(js, "last_glass_flag", 0)); s->setFirstGlassFlag(JInt(js, "first_glass_flag", 0)); if (js.isMember("qtime") && js["qtime"].isArray()) { for (int i = 0; i < 3; i++) { int v = (i < (int)js["qtime"].size()) ? js["qtime"][i].asInt() : 0; s->setQTime(i, v); } } else { for (int i = 0; i < 3; i++) s->setQTime(i, 0); } s->setQTimeOverFlag(JInt(js, "qtime_over_flag", 0)); s->setMasterRecipe(JInt(js, "master_recipe", 0)); if (js.isMember("device_recipe_ids") && js["device_recipe_ids"].isArray()) { for (int i = 0; i < DEVICE_COUNT; i++) { int v = (i < (int)js["device_recipe_ids"].size()) ? js["device_recipe_ids"][i].asInt() : 0; s->setDeviceRecipeId(i, static_cast(v)); } } else { for (int i = 0; i < DEVICE_COUNT; i++) s->setDeviceRecipeId(i, 0); } s->setPanelMeasure(JStr(js, "panel_measure").c_str()); s->setMode(JInt(js, "mode", 0)); s->setSlotUnitSelectFlag(JInt(js, "slot_unit_select_flag", 0)); s->setSourcePortNo(JInt(js, "source_port_no", 0)); s->setSourceSlotNo(JInt(js, "source_slot_no", 0)); s->setTargetPortNo(JInt(js, "target_port_no", 0)); s->setTargetSlotNo(JInt(js, "target_slot_no", 0)); s->setProductJudge(static_cast(JInt(js, "product_judge", 0))); } // path£ºË³ÐòÖØ½¨Á´£¨Ê±¼ä×Ö¶ÎÒÔ×Ö·û´®¶Á»Ø£© if (root.isMember("path") && root["path"].isArray()) { for (const auto& n : root["path"]) { unsigned eq = JUInt(n, "eq_id", 0); unsigned unit = JUInt(n, "unit", 0); g.addPath(eq, unit); CPath* tail = nullptr; if (auto head = g.getPath()) tail = head->getTailPath(); if (!tail) continue; long long tin = 0, tout = 0; if (get_ll_from_json(n, "time_in", tin)) tail->setInTime(static_cast(tin)); if (get_ll_from_json(n, "time_out", tout)) tail->setOutTime(static_cast(tout)); tail->setInspResult(static_cast(JInt(n, "insp_result", 0))); if (JBool(n, "processed", false)) tail->processEnd(); } } } // ==================== ±ã½Ý·â×° ==================== std::string GlassJson::ToString(const CGlass& g) { Json::FastWriter w; // ¾É°æ£º½ô´Õ£¬ÎÞ¸ñʽ // w.omitEndingLineFeed(); // È¥µôĩβ»»ÐУ¨Èç¹ûÄãµÄ JsonCpp °æ±¾Ö§³Ö£© return w.write(ToJson(g)); } std::string GlassJson::ToPrettyString(const CGlass& g) { Json::StyledWriter w; // ¾É°æ£ºÃÀ»¯Êä³ö return w.write(ToJson(g)); } bool GlassJson::FromString(const std::string& text, CGlass& g, std::string* err) { Json::Reader reader; // ¾É°æ½âÎöÆ÷ Json::Value j; bool ok = reader.parse(text, j, /*collectComments*/ false); if (!ok) { if (err) *err = reader.getFormatedErrorMessages(); return false; } FromJson(j, g); return true; }