diff --git a/FireDog/featurelibrary.cpp b/FireDog/featurelibrary.cpp index cc65b3b..a7b0c38 100644 --- a/FireDog/featurelibrary.cpp +++ b/FireDog/featurelibrary.cpp @@ -26,120 +26,6 @@ FeatureLibrary::~FeatureLibrary() { } } -FeatureLibrary* FeatureLibrary::createByJson(string json, int* errorcode) { - FeatureLibrary* result = NULL; - nlohmann::json root; - bool parseStatus = false; - try { - root = json::parse(json); - parseStatus = true; - } - catch (nlohmann::detail::parse_error er) { - parseStatus = false; - - } - if (!parseStatus || !root.is_object()|| !root.contains("version") || !root.contains("items")) { - *errorcode = FL_CONTENT_FORMATE_ERROR; - return result; - } - - bool validstate = false; - auto schema = json::parse(FIREDOG_FEATURE_LIBRARAY_JSON_SCHEMA); - - json_validator validator; // create validator - validator.set_root_schema(schema); - try { - validator.validate(root); - validstate = true; - } - catch (const std::exception& e) { - validstate = false; - } - - if (!validstate) { - *errorcode = FL_CONTENT_FORMATE_ERROR; - return result; - } - - //get version - string version = root["version"]; - - //check version - if (version != FIREDOG_FEATURE_LIBRARY_VERSION) { - *errorcode = FL_CONTENT_VERSION_ERROR; - } - - result = new FeatureLibrary(); - - result->version = version; - - nlohmann::json items = root["items"]; - - if (items.is_array()) { - for (int i = 0; i < items.size(); i++) { - nlohmann::json item = items[i]; - if (item.is_object() - && item.contains("author") && item["author"].is_string() - && item.contains("name") && item["name"].is_string() - && item.contains("describe") && item["describe"].is_string() - && item.contains("features") && item["features"].is_array() && item["features"].size() > 0 - && item.contains("rule") && item["rule"].is_object()) { - - //Ïȿ´¹æÔò - nlohmann::json rulejson = item["rule"]; - - vector rules = parseRulesByJson(rulejson); - if (rules.size()==0) { - continue; - } - - Rule* rule = NULL; - if (rules.size()==1) { - rule = rules.at(0); - } - else { - AndRule* andRule = new AndRule(); - andRule->addRules(rules); - } - - FeatureLibraryItem* fitem = new FeatureLibraryItem(); - fitem->author = item["author"]; - fitem->name = item["name"]; - fitem->describe = item["describe"]; - fitem->rule = rule; - - nlohmann::json features = item["features"]; - for (int y = 0; y < features.size(); y++) { - nlohmann::json feature = features[y]; - if (feature.contains("key") && feature["key"].is_string() - && (feature.contains("hex") && feature["hex"].is_string() - || feature.contains("text") && feature["text"].is_string())) { - string fkey = feature["key"]; - string fhex = ""; - string ftext = ""; - if (feature.contains("hex")) { - fhex = feature["hex"]; - } - - if (feature.contains("text")) { - ftext = feature["text"]; - } - - Feature* feature = new Feature(); - feature->key = fkey; - feature->hex = fhex; - feature->text = ftext; - fitem->features->push_back(feature); - } - } - result->items->push_back(fitem); - } - } - } - - return result; -} - FeatureLibrary* FeatureLibrary::createByYaml(std::string yaml, int* errorcode) { FeatureLibrary* result = NULL; @@ -243,226 +129,139 @@ FeatureLibrary* FeatureLibrary::createByYaml(std::string yaml, int* errorcode) { return result; } -vector FeatureLibrary::parseRulesByJson(nlohmann::json rulejson) { - vector rules; - - if (rulejson.is_string()) { - string id = rulejson; - CountRule* countRule = new CountRule(id); - rules.push_back(countRule); - }else if (rulejson.is_object()&&!rulejson.is_array()) { - for (auto ruleiter = rulejson.begin(); ruleiter != rulejson.end(); ruleiter++) { - std::string key = ruleiter.key(); - nlohmann::json childrulejson = rulejson[key]; - if (key == "$and" || key == "$or" || key == "$not") { - LogicRule* logicRule = NULL; - vector childRules = parseRulesByJson(childrulejson); - if (childRules.size()>0) { - if (key == "$and") { - logicRule = new AndRule(); - } - if (key == "$or") { - logicRule = new OrRule(); - } - if (key == "$not") { - logicRule = new NotRule(); - } - logicRule->addRules(childRules); - rules.push_back(logicRule); - } - } - else if (key == "$int") { - if (childrulejson.is_number()) { - long num = childrulejson; - IntRule* intRule = new IntRule(childrulejson); - rules.push_back(intRule); - } - } - else if (key == "$count") { - vector ids; - long num = 1L; - - if (childrulejson.is_string()) { - string id = childrulejson; - ids.push_back(id); - }else if (childrulejson.is_array()) { - int idslen = childrulejson.size(); - for (int i = 0; i < idslen; i++) { - nlohmann::json crj = childrulejson[i]; - if (crj.is_string()) { - string id = crj; - ids.push_back(id); - } - else if (i == idslen - 1 && crj.is_number()) { - long tempnum = crj; - if (tempnum > 1) { - num = tempnum; - } - } - } - } - - if (ids.size() > 0) { - CountRule* countRule = new CountRule(ids); - countRule->setCritical(num); - rules.push_back(countRule); - } - } - else if(key == "$lt"|| key == "$le" || key == "$gt" || key == "$ge") { - Rule* compareRule = NULL; - - vector childRules = parseRulesByJson(childrulejson); - - if (childRules.size()==2) { - - Rule* num1Rule = childRules[0]; - Rule* num2Rule = childRules[1]; - if (num1Rule != NULL && num1Rule->getBaseType() == RULE_BASE_TYPE_NUMBER - && num2Rule != NULL && num2Rule->getBaseType() == RULE_BASE_TYPE_NUMBER) { - if (key == "$lt") { - compareRule = new LtRule((NumberRule*)num1Rule, (NumberRule*)num2Rule); - } - if (key == "$le") { - compareRule = new LeRule((NumberRule*)num1Rule, (NumberRule*)num2Rule); - } - if (key == "$gt") { - compareRule = new GtRule((NumberRule*)num1Rule, (NumberRule*)num2Rule); - } - if (key == "$ge") { - compareRule = new GeRule((NumberRule*)num1Rule, (NumberRule*)num2Rule); - } - } - if (compareRule != NULL) { - rules.push_back(compareRule); - } - - } - } - } - } - return rules; -} - -Rule* FeatureLibrary::parseRuleByJson(nlohmann::json rulejson) { - Rule* rule = NULL; - - vector rules = parseRulesByJson(rulejson); - if (rules.size()>0) { - rule = rules.at(0); - } - - return rule; -} - FeatureLibraryItem::FeatureLibraryItem() { features = new vector(); } -std::string FeatureLibrary::toJson(int* state){ - json jsonFeatureLibrary; - jsonFeatureLibrary["version"] = FIREDOG_FEATURE_LIBRARY_VERSION; +std::string FeatureLibrary::toYaml(int* state) { + string ymlstr; + ryml::Tree tree; + try { + c4::yml::NodeRef root = tree.rootref(); + root |= ryml::MAP; + root["version"] << string(FIREDOG_FEATURE_LIBRARY_VERSION); + if (items != NULL) { + root["items"] |= ryml::SEQ; + for (int i = 0; i < items->size(); i++) { + FeatureLibraryItem* item = items->at(i); + root["items"][i] |= ryml::MAP; + root["items"][i]["name"] << item->name; + root["items"][i]["author"] << item->author; + root["items"][i]["describe"] << item->describe; - if (items!=NULL) { - std::vector jsonItems; - for (int i = 0; i < items->size(); i++) { - json jsonItem; - - FeatureLibraryItem* item = items->at(i); - - jsonItem["name"] = item->name; - jsonItem["describe"] = item->describe; - jsonItem["author"] = item->author; - - std::vector jsonFeatures; - if (item->features != NULL && item->features->size() > 0) { - for (int y = 0; y < item->features->size(); y++) { - Feature* feature = item->features->at(y); - json jsonFeature; - jsonFeature["key"] = feature->key; - if (!feature->hex.empty()) { - jsonFeature["hex"] = feature->hex; + if (item->features != NULL && item->features->size() > 0) { + root["items"][i]["features"] |= ryml::SEQ;; + for (int y = 0; y < item->features->size(); y++) { + Feature* feature = item->features->at(y); + root["items"][i]["features"][y] |= ryml::MAP; + root["items"][i]["features"][y]["key"] << feature->key; + if (!feature->hex.empty()) { + root["items"][i]["features"][y]["hex"] << feature->hex; + } + else { + root["items"][i]["features"][y]["text"] << feature->text; + } } - else { - jsonFeature["text"] = feature->text; - } - jsonFeatures.push_back(jsonFeature); } + root["items"][i]["rules"] |= ryml::SEQ; + root["items"][i]["rules"][0] |= ryml::MAP; + c4::yml::NodeRef ymlrules = root["items"][i]["rules"][0]; + ruleToYaml(ymlrules, item->rule); } - else { - *state = FL_CONTENT_EXIST_EMPTY_FEATURES_FAIL; - return ""; - } - jsonItem["features"] = jsonFeatures; - - bool ruleState = false; - json ruleJson = ruleToJson(item->rule,&ruleState); - - if (!ruleState) { - *state = FL_CONTENT_EXIST_RULE_FORMATE_FAIL; - return ""; - } - - jsonItem["rule"] = ruleJson; - jsonItems.push_back(jsonItem); } - jsonFeatureLibrary["items"] = jsonItems; + *state = 0; } - else { - *state = FL_CONTENT_ITEMS_IS_EMPTY; - return ""; + catch (...) { + *state = -1; } - std::string json = jsonFeatureLibrary.dump(4); - *state = NO_ERROR; - return json; + + if (*state == 0) { + ymlstr = ryml::emitrs(tree); + } + + return ymlstr; } -nlohmann::json FeatureLibrary::ruleToJson(mountcloud::Rule* rule,bool* state) { - json jsonRule; - //if (rule != NULL) { - // if (!rule->id.empty()) { - // jsonRule = rule->id; - // *state = true; - // } - // else if(rule->ands!=NULL&&rule->ands->size()>0){ - // vector andsjson; - // for (int i = 0; i < rule->ands->size(); i++) { - // mountcloud::Rule* andRule = rule->ands->at(i); - // bool andRuleState = false; +void FeatureLibrary::ruleToYaml(c4::yml::NodeRef& parentNode, mountcloud::Rule* rule) { + if (rule->getType() == RULE_BASE_TYPE_ALL) { + AllRule* allRule = (AllRule*)rule; + if (allRule->getIds().size() > 0) { + parentNode["$all"] |= ryml::SEQ; + for (int i = 0; i < allRule->getIds().size(); i++) { + parentNode["$all"][i] << allRule->getIds().at(i); + } + } + } + //------------------------------------------------ + else if (rule->getBaseType() == RULE_BASE_TYPE_LOGIC) { + c4::yml::NodeRef logicNode; + if (rule->getType() == RULE_TYPE_LOGIC_AND) { + parentNode["$and"] |= ryml::SEQ; + logicNode = parentNode["$and"]; + } + else if (rule->getType() == RULE_TYPE_LOGIC_OR) { + parentNode["$or"] |= ryml::SEQ; + logicNode = parentNode["$or"]; + } + else if (rule->getType() == RULE_TYPE_LOGIC_NOT) { + parentNode["$not"] |= ryml::SEQ; + logicNode = parentNode["$not"]; + } - // json andJson = ruleToJson(andRule, &andRuleState); - // if (!andRuleState) { - // *state = false; - // return jsonRule; - // } - // andsjson.push_back(andJson); - // } - // *state = true; - // jsonRule["$and"] = andsjson; - // } - // else if(rule->ors!=NULL&&rule->ors->size()>0){ - // vector orsjson; - // for (int i = 0; i < rule->ors->size(); i++) { - // mountcloud::Rule* orRule = rule->ors->at(i); - // bool orRuleState = false; + LogicRule* logicRule = (LogicRule*)rule; - // json orJson = ruleToJson(orRule, &orRuleState); - // if (!orRuleState) { - // *state = false; - // return jsonRule; - // } - // orsjson.push_back(orJson); - // } - // *state = true; - // jsonRule["$or"] = orsjson; - // } - // else { - // *state = false; - // } - //} - //else { - // *state = false; - //} - return jsonRule; + for (int i = 0; i < logicRule->getRules()->size(); i++) { + Rule* tlr = logicRule->getRules()->at(i); + logicNode[i] |= ryml::MAP; + c4::yml::NodeRef logicChildNode = logicNode[i]; + ruleToYaml(logicChildNode, tlr); + } + } + //------------------------------------------------ + else if (rule->getType() == RULE_TYPE_NUMBER_INT) { + IntRule* intRule = (IntRule*)rule; + parentNode["$int"] << intRule->getNum(); + } + else if (rule->getType() == RULE_TYPE_NUMBER_COUNT) { + CountRule* countRule = (CountRule*)rule; + parentNode["$count"] |= ryml::SEQ; + for (int i = 0; i < countRule->getIds().size(); i++) { + parentNode["$count"][i] << countRule->getIds().at(i); + } + } + //------------------------------------------------ + else if (rule->getBaseType() == RULE_BASE_TYPE_COMPARE) { + c4::yml::NodeRef compaerNode; + if (rule->getType() == RULE_TYPE_COMPARE_LT) { + parentNode["$lt"] |= ryml::SEQ; + compaerNode = parentNode["$lt"]; + } + else if (rule->getType() == RULE_TYPE_COMPARE_LE) { + parentNode["$lt"] |= ryml::SEQ; + compaerNode = parentNode["$lt"]; + } + else if (rule->getType() == RULE_TYPE_COMPARE_GT) { + parentNode["$gt"] |= ryml::SEQ; + compaerNode = parentNode["$gt"]; + } + else if (rule->getType() == RULE_TYPE_COMPARE_GE) { + parentNode["$ge"] |= ryml::SEQ; + compaerNode = parentNode["$ge"]; + } + CompareRule* compareRule = (CompareRule*)rule; + + + compaerNode[0] |= ryml::MAP; + compaerNode[1] |= ryml::MAP; + + c4::yml::NodeRef num1Node = compaerNode[0]; + c4::yml::NodeRef num2Node = compaerNode[1]; + + ruleToYaml(num1Node, compareRule->getNum1()); + ruleToYaml(num2Node, compareRule->getNum2()); + + } + } std::vector FeatureLibrary::parseRulesByYaml(c4::yml::NodeRef node) { diff --git a/FireDog/featurelibrary.h b/FireDog/featurelibrary.h index cbfaf38..ff9d044 100644 --- a/FireDog/featurelibrary.h +++ b/FireDog/featurelibrary.h @@ -144,10 +144,9 @@ namespace firedog { class FeatureLibrary { public: /// - /// create by json + /// create by yml /// - static FeatureLibrary* createByJson(std::string json, int* errorcode); - static FeatureLibrary* createByYaml(std::string yaml, int* errorcode); + static FeatureLibrary* createByYaml(std::string yaml, int* errorcode); /// /// library version @@ -161,26 +160,20 @@ namespace firedog { std::vector* items = NULL; /// - /// to json + /// to yml /// /// - std::string toJson(int* state); + std::string toYaml(int* state); FeatureLibrary(); ~FeatureLibrary(); private: - static std::vector parseRulesByJson(nlohmann::json rulejson); - static mountcloud::Rule* parseRuleByJson(nlohmann::json rulejson); - static std::vector parseRulesByYaml(c4::yml::NodeRef node); static mountcloud::Rule* parseRuleByYaml(c4::yml::NodeRef node); - /// - /// rule to json object - /// - /// - /// - nlohmann::json ruleToJson(mountcloud::Rule* rule,bool* state); + + void ruleToYaml(c4::yml::NodeRef& parentNode, mountcloud::Rule* rule); + }; diff --git a/FireDog/matcher.cpp b/FireDog/matcher.cpp index 633d252..dbf405a 100644 --- a/FireDog/matcher.cpp +++ b/FireDog/matcher.cpp @@ -271,28 +271,14 @@ Matcher::~Matcher() { } -std::vector * Matcher::matchBytes(const char* bytes, int length) { - - std::vector * result = NULL; - +void Matcher::matchBytes(const char* bytes, int length) { for (int i = 0; i < length; i++) { char byte = bytes[i]; - std::vector * tempResult = this->matchByte(byte); - if (tempResult != NULL) { - //ƥÅ䵽ÁË - if (result == NULL) { - result = new std::vector(); - } - result->insert(result->end(), tempResult->begin(), tempResult->end()); - //ɾµôvectorµÄָÕë - delete tempResult; - } + this->matchByte(byte); } - return result; } -std::vector * Matcher::matchByte(const char byte) { - std::vector * result = NULL; +void Matcher::matchByte(const char byte) { if (matchCache == NULL) { matchCache = new std::vector(); } @@ -304,16 +290,8 @@ std::vector * Matcher::matchByte(const char byte) { MatcherData* mbd = matchCache->at(i); //УÑéÍêÕû×ֽÚ - std::vector * tempResult = checkMatcherFeature(mbd, byte, tempMatchBytesCache); - if (tempResult !=NULL) { - //ƥÅ䵽ÁË - if (result==NULL) { - result = new std::vector(); - } - result->insert(result->end(), tempResult->begin(), tempResult->end()); - //ɾµôvectorµÄָÕë - delete tempResult; - } + matcherFeature(mbd, byte, tempMatchBytesCache); + } this->matchCache->clear(); delete this->matchCache; @@ -322,90 +300,52 @@ std::vector * Matcher::matchByte(const char byte) { //step2:find by feature library Ȼºó´ÓÌØÕ÷¿âÖÐÀ­ȡ //УÑéÍêÕû×ֽÚ - std::vector * tempResult = checkMatcherFeature(this->dataSource->getData(), byte, this->matchCache); - if (tempResult != NULL) { - //ƥÅ䵽ÁË - if (result == NULL) { - result = new std::vector(); + matcherFeature(this->dataSource->getData(), byte, this->matchCache); +} + +std::vector * Matcher::check() { + std::vector * result = NULL; + + for (std::unordered_map::iterator iter = featureRuleData->begin(); iter != featureRuleData->end(); iter++) { + int featureId = iter->first; + mountcloud::RuleData* ruleData = iter->second; + FeatureLibraryItem* fitem = dataSource->getFeatureLibraryItem(featureId); + Rule* rule = fitem->rule; + if (rule != NULL && rule->check(ruleData)) { + if (result == NULL) { + result = new std::vector(); + } + MatcherResult* mr = new MatcherResult(); + mr->featureId = featureId; + mr->author = fitem->author; + mr->name = fitem->name; + mr->describe = fitem->describe; + result->push_back(mr); } - result->insert(result->end(), tempResult->begin(), tempResult->end()); - //ɾµôvectorµÄָÕë - delete tempResult; } return result; } -std::vector * Matcher::checkMatcherFeature(MatcherData* mbd, char byte, std::vector* tempMatchBytesCache) { - std::vector * result = NULL; +void Matcher::matcherFeature(MatcherData* mbd, char byte, std::vector* tempMatchBytesCache) { //¸ßλ const char highPos = StringUtil::byteHigh(byte); //µÍλ const char lowPos = StringUtil::byteLow(byte); //УÑéÍêÕû×ֽÚ - result = checkMatcherFeatureMap(mbd->fullData, byte, tempMatchBytesCache); - if (result != NULL) { - return result; - } + matcherFeatureMap(mbd->fullData, byte, tempMatchBytesCache); + //УÑé¸ßλ - result = checkMatcherFeatureMap(mbd->highPosData, highPos, tempMatchBytesCache); - if (result != NULL) { - return result; - } + matcherFeatureMap(mbd->highPosData, highPos, tempMatchBytesCache); + //УÑéµÍλ - result = checkMatcherFeatureMap(mbd->lowPosData, lowPos, tempMatchBytesCache); - if (result != NULL) { - return result; - } + matcherFeatureMap(mbd->lowPosData, lowPos, tempMatchBytesCache); - //УÑéany - //if (mbd->anyData != NULL) { - // //any ƥÅ䵽ÁË - // if (mbd->anyData->features != NULL) { - // result = new std::vector(); - // for (int i = 0; i < mbd->anyData->features->size(); i++) { - // MatcherFeature* mf = mbd->anyData->features->at(i); - // int featureId = mf->featureId; - // string featureKey = mf->featureKey; - - // RuleData* ruleData = NULL; - // if (featureRuleData == NULL) { - // featureRuleData = new unordered_map(); - // } - // if (featureRuleData->find(featureId) == featureRuleData->end()) { - // ruleData = new RuleData(); - // } - // else { - // ruleData = featureRuleData->at(featureId); - // } - - // ruleData->set(featureKey, true); - - // FeatureLibraryItem* fitem = dataSource->getFeatureLibraryItem(featureId); - // Rule* rule = fitem->rule; - // if (rule != NULL && rule->check(ruleData)) { - // MatcherResult* mr = new MatcherResult(); - // mr->featureId = featureId; - // mr->author = fitem->author; - // mr->name = fitem->name; - // mr->describe = fitem->describe; - // result->push_back(mr); - // } - // } - // } - // else { - // //anyûÓÐƥÅ䵽 - // tempMatchBytesCache->push_back(mbd->anyData); - // } - //} - - return result; } -std::vector* Matcher::checkMatcherFeatureMap(AvlMap* map, char byte, std::vector* tempMatchBytesCache) { - std::vector* result = NULL; +void Matcher::matcherFeatureMap(AvlMap* map, char byte, std::vector* tempMatchBytesCache) { if (map==NULL) { - return result; + return; } AvlMap::Iterator mbditer = map->find(byte); @@ -433,24 +373,10 @@ std::vector* Matcher::checkMatcherFeatureMap(AvlMapoperator[](featureId) = ruleData; - FeatureLibraryItem* fitem = dataSource->getFeatureLibraryItem(featureId); - Rule* rule = fitem->rule; - if (rule != NULL && rule->check(ruleData)) { - if (result==NULL) { - result = new std::vector(); - } - MatcherResult* mr = new MatcherResult(); - mr->featureId = featureId; - mr->author = fitem->author; - mr->name = fitem->name; - mr->describe = fitem->describe; - result->push_back(mr); - } } } tempMatchBytesCache->push_back(iterMbd); } - return result; } MatcherData* MatcherDataSource::getData() { diff --git a/FireDog/matcher.h b/FireDog/matcher.h index 139ca7b..82576af 100644 --- a/FireDog/matcher.h +++ b/FireDog/matcher.h @@ -90,8 +90,10 @@ namespace firedog { Matcher(MatcherDataSource* dataSource); ~Matcher(); - std::vector * matchBytes(const char* bytes, int length); - std::vector * matchByte(const char byte); + void matchBytes(const char* bytes, int length); + void matchByte(const char byte); + + std::vector * check(); private: /// /// data source, @@ -109,8 +111,8 @@ namespace firedog { std::unordered_map* featureRuleData = NULL; - std::vector* checkMatcherFeature(MatcherData* mbd, char byte, std::vector* tempMatchBytesCache); - std::vector* checkMatcherFeatureMap(AvlMap* map,char byte, std::vector* tempMatchBytesCache); + void matcherFeature(MatcherData* mbd, char byte, std::vector* tempMatchBytesCache); + void matcherFeatureMap(AvlMap* map,char byte, std::vector* tempMatchBytesCache); }; } diff --git a/FireDog/rule/rule.cpp b/FireDog/rule/rule.cpp index 4599646..6837129 100644 --- a/FireDog/rule/rule.cpp +++ b/FireDog/rule/rule.cpp @@ -118,6 +118,9 @@ bool AndRule::check(RuleData* data) { } return true; } + else { + return true; + } return true; } @@ -135,7 +138,10 @@ bool OrRule::check(RuleData* data) { } } } - return true; + else { + return true; + } + return false; } NotRule::NotRule() { @@ -153,7 +159,10 @@ bool NotRule::check(RuleData* data) { } return true; } - return true; + else { + return true; + } + return false; } NumberRule::NumberRule() { diff --git a/FireDogEditor/FireDogEditor.cpp b/FireDogEditor/FireDogEditor.cpp index 96c6fbf..7373836 100644 --- a/FireDogEditor/FireDogEditor.cpp +++ b/FireDogEditor/FireDogEditor.cpp @@ -15,6 +15,8 @@ #include "gui18n.h" #include "gui18nutil.h" +#include "stringutil.h" + using namespace firedog; //¹¹Ô캯Êý @@ -44,6 +46,9 @@ FireDogEditor::FireDogEditor(QWidget *parent) //³õʼ»¯ void FireDogEditor::init() { + QIcon iconFile(":/FireDogEditor/resources/icon.ico"); + this->setWindowIcon(iconFile); + QFile qss(":/qss/css/qss.css"); if (qss.open(QIODevice::ReadOnly)) { QByteArray qssBytes = qss.readAll(); @@ -409,14 +414,14 @@ void FireDogEditor::slots_saveFile() { QFile file(this->openFilePath); int state = -1; - std::string json = this->featureLibrary->toJson(&state); + std::string ymlstr = this->featureLibrary->toYaml(&state); if (state != NO_ERROR) { QssMessageBox::warn("Save fail,Feature library convert to json fail!.", this, "Warn"); return; } - QString jsonstr = QString::fromUtf8(QByteArray::fromRawData(json.c_str(), json.size())); + QString jsonstr = QString::fromUtf8(QByteArray::fromRawData(ymlstr.c_str(), ymlstr.size())); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -457,7 +462,7 @@ void FireDogEditor::slots_saveToFile() { } int state = -1; - std::string json = this->featureLibrary->toJson(&state); + std::string ymlstr = this->featureLibrary->toYaml(&state); if (state != NO_ERROR) { QString titleStr = Gui18n::GetInstance()->GetConfig("text-message-box-title-warning", "Warning"); @@ -466,7 +471,7 @@ void FireDogEditor::slots_saveToFile() { return; } - QString jsonstr = QString::fromUtf8(QByteArray::fromRawData(json.c_str(), json.size())); + QString jsonstr = QString::fromUtf8(QByteArray::fromRawData(ymlstr.c_str(), ymlstr.size())); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -1005,6 +1010,14 @@ void FireDogEditor::slots_featureLibraryInfoRuleMenuAddEvent() { bool isOk = this->fireDogFeatureRuleInfoView->updateRule(&rule, &childs, parent); if (isOk) { QStandardItem* ruleitem = new QStandardItem(rule); + if (rule=="$lt"||rule=="$le"||rule=="$gt"||rule=="$ge") { + for (int i=0;iappendRow(childitem); + } + } //Èç¹ûÊǿյÄ if (ruleIsEmpty) { featureLibraryInfoRuleTreeModel->appendRow(ruleitem); @@ -1018,6 +1031,7 @@ void FireDogEditor::slots_featureLibraryInfoRuleMenuAddEvent() { QModelIndex index = this->featureLibraryInfoRuleTreeModel->indexFromItem(ruleitem); ui.treeViewLibraryInfoRules->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + ui.treeViewLibraryInfoRules->expand(index); } } @@ -1044,7 +1058,24 @@ void FireDogEditor::slots_featureLibraryInfoRuleMenuEditEvent() { bool isOk = this->fireDogFeatureRuleInfoView->updateRule(&rule, &childs, parent); if (isOk) { + + bool resultIsCmp = false; + if (rule == "$lt" || rule == "$le" || rule == "$gt" || rule == "$ge") { + resultIsCmp = true; + } + selectItem->setText(rule); + + if (resultIsCmp) { + selectItem->removeRows(0, selectItem->rowCount()); + for (int i = 0; i < childs.size(); i++) + { + QString childStr = childs.at(i); + QStandardItem* childitem = new QStandardItem(childStr); + selectItem->appendRow(childitem); + } + ui.treeViewLibraryInfoRules->expand(selectItem->index()); + } } } @@ -1192,7 +1223,7 @@ mountcloud::Rule* FireDogEditor::itemToRule(QStandardItem* item) { goto fail; } - bool isOperation = text == "$and" || text == "$or"; + bool isOperation = text == "$and" || text == "$or" || text == "$not"; //¸ù¹æÔòֻÄÜÊÇÂ߼­±í´ïʽ if (item->parent()==NULL) { @@ -1210,34 +1241,96 @@ mountcloud::Rule* FireDogEditor::itemToRule(QStandardItem* item) { } } - mountcloud::Rule* result = new mountcloud::Rule(); + mountcloud::Rule* result = NULL; - // if (isOperation) { - // int childCount = item->rowCount(); - // for (int i = 0; i < childCount; i++) { - // QStandardItem* childItem = item->child(i); - // mountcloud::Rule* childRule = itemToRule(childItem); - // if (childRule==NULL) { - // delete result; - // return NULL; - // } - // if(text=="$and"){ - // if (result->ands == NULL) { - // result->ands = new std::vector(); - // } - // result->ands->push_back(childRule); - // } - // else { - // if (result->ors == NULL) { - // result->ors = new std::vector(); - // } - // result->ors->push_back(childRule); - // } - // } - //} - // else { - // result->id = text.toStdString(); - // } + + if (text == "$and" || text == "$or" || text == "$not") { + mountcloud::LogicRule* logicRule = NULL; + if (text == "$and") { + logicRule = new mountcloud::AndRule(); + } + else if (text == "$or") { + logicRule = new mountcloud::OrRule(); + } + else { + logicRule = new mountcloud::NotRule(); + } + int childCount = item->rowCount(); + for (int i = 0; i < childCount; i++) { + QStandardItem* childItem = item->child(i); + mountcloud::Rule* cr = itemToRule(childItem); + if (cr != NULL) { + logicRule->addRule(cr); + } + } + result = logicRule; + } + else if (text.startsWith("$all")) { + QString infostr = text.mid(text.indexOf(":") + 1); + QStringList idsQList = infostr.split(","); + if (idsQList.size() > 0) { + std::vector ids; + for (int i = 0; i < idsQList.size(); i++) { + QString id = idsQList.at(i); + ids.push_back(id.toStdString()); + } + mountcloud::AllRule* allRule = new mountcloud::AllRule(ids); + result = allRule; + } + } + else if (text.startsWith("$count")) { + QString infostr = text.mid(text.indexOf(":") + 1); + QStringList idsQList = infostr.split(","); + if (idsQList.size() > 0) { + std::vector ids; + for (int i = 0; i < idsQList.size(); i++) { + QString id = idsQList.at(i); + ids.push_back(id.toStdString()); + } + mountcloud::CountRule* countRule = new mountcloud::CountRule(ids); + result = countRule; + } + } + else if (text.startsWith("$int")) { + QString infostr = text.mid(text.indexOf(":") + 1); + std::string numstr = infostr.toStdString(); + if (StringUtil::isNumber(numstr)) { + int num = atoi(numstr.c_str()); + mountcloud::IntRule* intRule = new mountcloud::IntRule(num); + result = intRule; + } + } + else if (text == "$lt" || text == "$le" || text == "$gt" || text == "$ge") { + + int childCount = item->rowCount(); + if (childCount == 2) { + mountcloud::Rule* num1 = itemToRule(item->child(0)); + mountcloud::Rule* num2 = itemToRule(item->child(1)); + + if (num1 != NULL && num1->getBaseType() == RULE_BASE_TYPE_NUMBER + && num2 != NULL && num2->getBaseType() == RULE_BASE_TYPE_NUMBER) { + + mountcloud::NumberRule* numRule1 = (mountcloud::NumberRule*)num1; + mountcloud::NumberRule* numRule2 = (mountcloud::NumberRule*)num2; + + mountcloud::CompareRule* compareRule = NULL; + if (text == "$lt") { + compareRule = new mountcloud::LtRule(numRule1, numRule2); + } + else if (text == "$le") { + compareRule = new mountcloud::LeRule(numRule1, numRule2); + } + else if (text == "$gt") { + compareRule = new mountcloud::GtRule(numRule1, numRule2); + } + else if (text == "$ge") { + compareRule = new mountcloud::GeRule(numRule1, numRule2); + } + + result = compareRule; + } + } + } return result; diff --git a/FireDogEditor/FireDogEditor.h b/FireDogEditor/FireDogEditor.h index 18cf346..807e328 100644 --- a/FireDogEditor/FireDogEditor.h +++ b/FireDogEditor/FireDogEditor.h @@ -17,7 +17,7 @@ #include "Qss/Qss.h" -#define FIREDOG_EDITOR_VERSION "v2.1 DEV" +#define FIREDOG_EDITOR_VERSION "v2.1" #define EXIT_CODE_REBOOT -123456789 //ƥÅä¹ܼÒ diff --git a/FireDogEditor/FireDogEditor.pri b/FireDogEditor/FireDogEditor.pri index f073840..dc86559 100644 --- a/FireDogEditor/FireDogEditor.pri +++ b/FireDogEditor/FireDogEditor.pri @@ -19,10 +19,13 @@ HEADERS += ../FireDog/config.h \ ../FireDog/matcher.h \ ../FireDog/rule/rule.h \ ../FireDog/stringutil.h \ + ../FireDog/yaml/yaml.hpp \ + ./resource.h \ ./FireDogEditor.h \ ./FireDogFeatureInfo.h \ ./FireDogFeatureRuleInfo.h \ ./FireDogSwitchLanguage.h \ + ./FireDogAbout.h \ ./bigdatatableitem.h \ ./loadingdialog.h \ ./hexeditor.h \ @@ -32,9 +35,7 @@ HEADERS += ../FireDog/config.h \ ./partutil.h \ ./matchthread.h \ ./gui18n.h \ - ./gui18nutil.h \ - ./FireDogAbout.h \ - ./resource.h + ./gui18nutil.h SOURCES += ../FireDog/converter.cpp \ ../FireDog/featurelibrary.cpp \ ../FireDog/firedog.cpp \ @@ -45,6 +46,7 @@ SOURCES += ../FireDog/converter.cpp \ ../FireDog/json/json-schema/string-format-check.cpp \ ../FireDog/matcher.cpp \ ../FireDog/rule/rule.cpp \ + ./FireDogAbout.cpp \ ./FireDogFeatureInfo.cpp \ ./FireDogFeatureRuleInfo.cpp \ ./FireDogSwitchLanguage.cpp \ @@ -59,8 +61,7 @@ SOURCES += ../FireDog/converter.cpp \ ./partutil.cpp \ ./matchthread.cpp \ ./gui18n.cpp \ - ./gui18nutil.cpp \ - ./FireDogAbout.cpp + ./gui18nutil.cpp FORMS += ./FireDogEditor.ui \ ./FireDogFeatureInfo.ui \ ./FireDogFeatureRuleInfo.ui \ diff --git a/FireDogEditor/FireDogEditor.qrc b/FireDogEditor/FireDogEditor.qrc index fa27f39..d1fd7f9 100644 --- a/FireDogEditor/FireDogEditor.qrc +++ b/FireDogEditor/FireDogEditor.qrc @@ -2,5 +2,6 @@ resources/loading.gif resources/loading-new-backgroud.png + resources/icon.ico diff --git a/FireDogEditor/FireDogEditor.ui b/FireDogEditor/FireDogEditor.ui index 0fcccaf..15e39d1 100644 --- a/FireDogEditor/FireDogEditor.ui +++ b/FireDogEditor/FireDogEditor.ui @@ -245,6 +245,9 @@ + + QAbstractItemView::NoEditTriggers + true diff --git a/FireDogEditor/FireDogFeatureInfo.cpp b/FireDogEditor/FireDogFeatureInfo.cpp index 0ce310f..a45628f 100644 --- a/FireDogEditor/FireDogFeatureInfo.cpp +++ b/FireDogEditor/FireDogFeatureInfo.cpp @@ -18,8 +18,6 @@ FireDogFeatureInfo::FireDogFeatureInfo(QWidget *parent) : void FireDogFeatureInfo::init() { - - QRegExp hexregx(FEATURE_FORMATE_REG_HEX); this->hexValidator = new QRegExpValidator(hexregx, ui->lineEditContent); diff --git a/FireDogEditor/FireDogFeatureRuleInfo.cpp b/FireDogEditor/FireDogFeatureRuleInfo.cpp index 44e43c9..c85e20d 100644 --- a/FireDogEditor/FireDogFeatureRuleInfo.cpp +++ b/FireDogEditor/FireDogFeatureRuleInfo.cpp @@ -25,6 +25,13 @@ void FireDogFeatureRuleInfo::init() { this->keyValidator = new QRegExpValidator(keyregx, ui->lineEditKey); ui->lineEditKey->setValidator(keyValidator); + this->num1KeyValidator = new QRegExpValidator(keyregx, ui->lineEditNum1Count); + ui->lineEditNum1Count->setValidator(num1KeyValidator); + + this->num2KeyValidator = new QRegExpValidator(keyregx, ui->lineEditNum2Count); + ui->lineEditNum2Count->setValidator(num2KeyValidator); + + ui->comboBoxNum1Type->addItem("$count"); ui->comboBoxNum1Type->addItem("$int"); ui->spinBoxNum1Int->setVisible(false); @@ -54,7 +61,14 @@ void FireDogFeatureRuleInfo::init() { connect(ui->comboBoxNum2Type, SIGNAL(currentIndexChanged(QString)), this, SLOT(currentIndexChanged(QString))); //i18n - //Gui18nUtil::SetText(ui->labelType, "feature-rule-info-type"); + Gui18nUtil::SetText(ui->groupBoxType, "feature-rule-info-type"); + Gui18nUtil::SetText(ui->groupBoxRuleInfo, "feature-rule-info-ruleinfo"); + + Gui18nUtil::SetText(ui->labelKeyTips, "feature-rule-info-keytips"); + Gui18nUtil::SetText(ui->labelCompageTips, "feature-rule-info-keytips"); + + Gui18nUtil::SetText(ui->labelNumTips, "feature-rule-info-numtips"); + Gui18nUtil::SetText(ui->labelKey, "feature-rule-info-key"); Gui18nUtil::SetText(ui->pushButtonSave, "feature-rule-info-save"); Gui18nUtil::SetText(ui->pushButtonCancel, "feature-rule-info-cancel"); @@ -107,14 +121,26 @@ void FireDogFeatureRuleInfo::slots_radioClick() { void FireDogFeatureRuleInfo::slots_saveClick() { this->isOk = true; - //if (ui->radioButtonKey->isChecked()){ - // if (ui->lineEditKey->text().isEmpty()) { - // QString titleStr = Gui18n::GetInstance()->GetConfig("text-message-box-title-warning", "Warning"); - // QString messageStr = Gui18n::GetInstance()->GetConfig("feature-rule-please-enter-key", "Please enter [Key]."); - // QssMessageBox::warn(messageStr, this, titleStr); - // return; - // } - //} + //Õâ¸öº¯ÊýÖ÷ҪÊÇУÑé + if (ui->radioButtonAll->isChecked() || ui->radioButtonCount->isChecked()) { + if (ui->lineEditKey->text().isEmpty()) { + QString titleStr = Gui18n::GetInstance()->GetConfig("text-message-box-title-warning", "Warning"); + QString messageStr = Gui18n::GetInstance()->GetConfig("feature-rule-please-enter-key", "Please enter [Key]."); + QssMessageBox::warn(messageStr, this, titleStr); + return; + } + } + + if (ui->radioButtonLt->isChecked() || ui->radioButtonLe->isChecked() || + ui->radioButtonGt->isChecked() || ui->radioButtonGe->isChecked()) { + if ((ui->comboBoxNum1Type->currentText() == "$count" && ui->lineEditNum1Count->text().isEmpty()) + || (ui->comboBoxNum2Type->currentText() == "$count" && ui->lineEditNum2Count->text().isEmpty())) { + QString titleStr = Gui18n::GetInstance()->GetConfig("text-message-box-title-warning", "Warning"); + QString messageStr = Gui18n::GetInstance()->GetConfig("feature-rule-please-enter-key", "Please enter [Key]."); + QssMessageBox::warn(messageStr, this, titleStr); + return; + } + } this->hide(); } @@ -128,12 +154,6 @@ bool FireDogFeatureRuleInfo::updateRule(QString* rule, QVector* childs, this->isOk = false; setDefaultValue(); - // if (isRoot) { - // //ui->radioButtonKey->setEnabled(false); - // } - //else { - // //ui->radioButtonKey->setEnabled(true); - // } auto getRuleInfoByStr = [](QString& rulestr) { int index = rulestr.lastIndexOf(":"); @@ -141,6 +161,30 @@ bool FireDogFeatureRuleInfo::updateRule(QString* rule, QVector* childs, return infostr; }; + //¸ù¾ݸ¸½ڵãÆôÓýûÓÃ״̬ + if (parent.isEmpty()) { + ui->radioButtonAll->setEnabled(false); + ui->radioButtonCount->setEnabled(false); + ui->radioButtonInt->setEnabled(false); + + ui->radioButtonLt->setEnabled(false); + ui->radioButtonLe->setEnabled(false); + ui->radioButtonGt->setEnabled(false); + ui->radioButtonGe->setEnabled(false); + } + else if (parent == "$lt" || parent == "$le" || parent == "$gt" || parent == "$ge") { + ui->radioButtonAnd->setEnabled(false); + ui->radioButtonOr->setEnabled(false); + ui->radioButtonNot->setEnabled(false); + + ui->radioButtonAll->setEnabled(false); + + ui->radioButtonLt->setEnabled(false); + ui->radioButtonLe->setEnabled(false); + ui->radioButtonGt->setEnabled(false); + ui->radioButtonGe->setEnabled(false); + } + if (!rule->isEmpty()) { if (*rule == "$and") { ui->radioButtonAnd->setChecked(true); @@ -174,7 +218,7 @@ bool FireDogFeatureRuleInfo::updateRule(QString* rule, QVector* childs, else if (*rule == "$ge") { ui->radioButtonGe->setChecked(true); } - + //ÉèÖÃĬÈÏֵ if (rule->startsWith("$all") || rule->startsWith("$count")) { QString infostr = getRuleInfoByStr(*rule); @@ -186,6 +230,14 @@ bool FireDogFeatureRuleInfo::updateRule(QString* rule, QVector* childs, ui->spinBoxInt->setValue(intval); } else if (*rule == "$lt" || *rule == "$le" || *rule == "$gt" || *rule == "$ge") { + ui->radioButtonAnd->setEnabled(false); + ui->radioButtonOr->setEnabled(false); + ui->radioButtonNot->setEnabled(false); + + ui->radioButtonAll->setEnabled(false); + ui->radioButtonCount->setEnabled(false); + ui->radioButtonInt->setEnabled(false); + QString num1 = childs->at(0); QString num2 = childs->at(1); @@ -221,18 +273,87 @@ bool FireDogFeatureRuleInfo::updateRule(QString* rule, QVector* childs, this->exec(); if (this->isOk) { + if (ui->radioButtonAnd->isChecked()) { - rule->clear(); - rule->append("$and"); - } + rule->clear(); + rule->append("$and"); + } else if (ui->radioButtonOr->isChecked()) { rule->clear(); rule->append("$or"); - } + } + else if (ui->radioButtonNot->isChecked()) { + rule->clear(); + rule->append("$not"); + } + ///////////////////////////////////////////// + else if (ui->radioButtonAll->isChecked()) { + rule->clear(); + rule->append("$all:"); + rule->append(ui->lineEditKey->text()); + } + else if (ui->radioButtonCount->isChecked()) { + rule->clear(); + rule->append("$count:"); + rule->append(ui->lineEditKey->text()); + } + else if (ui->radioButtonInt->isChecked()) { + rule->clear(); + rule->append("$int:"); + rule->append(QString::number(ui->spinBoxInt->value())); + } + ///////////////////////////////////////////// + else if(ui->radioButtonLt->isChecked() || ui->radioButtonLe->isChecked() || ui->radioButtonGt->isChecked() || ui->radioButtonGe->isChecked()){ + rule->clear(); + if (ui->radioButtonLt->isChecked()) { + rule->append("$lt"); + } + else if (ui->radioButtonLe->isChecked()) { + rule->append("$le"); + } + else if (ui->radioButtonGt->isChecked()) { + rule->append("$gt"); + } + else if (ui->radioButtonGe->isChecked()) { + rule->append("$ge"); + } + childs->clear(); + QString num1Str = ""; + if (ui->comboBoxNum1Type->currentText()=="$count") { + num1Str.append("$count:"); + num1Str.append(ui->lineEditNum1Count->text()); + } + else { + num1Str.append("$int1:"); + num1Str.append(QString::number(ui->spinBoxNum1Int->value())); + } + + QString num2Str = ""; + if (ui->comboBoxNum2Type->currentText() == "$count") { + num2Str.append("$count:"); + num2Str.append(ui->lineEditNum2Count->text()); + } + else { + num2Str.append("$int1:"); + num2Str.append(QString::number(ui->spinBoxNum2Int->value())); + } + + childs->push_back(num1Str); + childs->push_back(num2Str); + } + + /*if (ui->radioButtonAnd->isChecked()) { + rule->clear(); + rule->append("$and"); + } + else if (ui->radioButtonOr->isChecked()) { + rule->clear(); + rule->append("$or"); + } else { rule->clear(); rule->append(ui->lineEditKey->text()); - } + }*/ } return this->isOk; @@ -279,5 +400,18 @@ void FireDogFeatureRuleInfo::setDefaultValue() { ui->stackedWidgetRuleInfo->setCurrentIndex(0); + ui->radioButtonAnd->setEnabled(true); + ui->radioButtonOr->setEnabled(true); + ui->radioButtonNot->setEnabled(true); + + ui->radioButtonAll->setEnabled(true); + ui->radioButtonCount->setEnabled(true); + ui->radioButtonInt->setEnabled(true); + + ui->radioButtonLt->setEnabled(true); + ui->radioButtonLe->setEnabled(true); + ui->radioButtonGt->setEnabled(true); + ui->radioButtonGe->setEnabled(true); + slots_radioClick(); } diff --git a/FireDogEditor/FireDogFeatureRuleInfo.h b/FireDogEditor/FireDogFeatureRuleInfo.h index 1c0195e..773d6fe 100644 --- a/FireDogEditor/FireDogFeatureRuleInfo.h +++ b/FireDogEditor/FireDogFeatureRuleInfo.h @@ -7,7 +7,7 @@ #include "Qss/Qss.h" -#define FEATURE_RULE_FORMATE_REG_KEY "[0-9a-zA-Z]{0,}" +#define FEATURE_RULE_FORMATE_REG_KEY "[0-9a-zA-Z,]{0,}" namespace Ui { class FireDogFeatureRuleInfo; @@ -33,6 +33,8 @@ private: Ui::FireDogFeatureRuleInfo *ui; QValidator* keyValidator = NULL; + QValidator* num1KeyValidator = NULL; + QValidator* num2KeyValidator = NULL; bool isOk = false; diff --git a/FireDogEditor/FireDogFeatureRuleInfo.ui b/FireDogEditor/FireDogFeatureRuleInfo.ui index 5a8cffe..b5507e1 100644 --- a/FireDogEditor/FireDogFeatureRuleInfo.ui +++ b/FireDogEditor/FireDogFeatureRuleInfo.ui @@ -435,7 +435,7 @@ Separate multiple ids with commas (,). - + 150 @@ -476,7 +476,7 @@ - + 150 diff --git a/FireDogEditor/matchthread.cpp b/FireDogEditor/matchthread.cpp index d04ad67..b9b6cb3 100644 --- a/FireDogEditor/matchthread.cpp +++ b/FireDogEditor/matchthread.cpp @@ -68,9 +68,9 @@ void MatchWorkThread::run() { while (true) { QByteArray bytes = file.read(WORK_READ_FILE_LENGTH); - bool matchState = match(bytes); + match(bytes); //ƥÅ䵽Á˻òÕßÎļþ¶ÁÍêÁË - if (bytes.size() < WORK_READ_FILE_LENGTH || matchState) { + if (bytes.size() < WORK_READ_FILE_LENGTH) { break; } } @@ -99,13 +99,42 @@ void MatchWorkThread::run() { QByteArray bytes = file.read(WORK_READ_FILE_LENGTH); readlength = readlength + len; - bool matchState = match(bytes); + match(bytes); //ƥÅ䵽Á˻òÕßÎļþ¶ÁÍêÁË - if (bytes.size() < WORK_READ_FILE_LENGTH || matchState) { + if (bytes.size() < WORK_READ_FILE_LENGTH) { break; } } } + vector* result = this->nowWork->matcher->check(); + if (result != NULL) { + + int sourceId = this->nowWork->sourceId; + int workType = this->nowWork->workType; + QString workContent = this->nowWork->content; + + for (int i = 0; i < result->size(); i++) { + + MatcherResult* mr = result->at(i); + + HitFeature hf; + hf.sourceId = sourceId; + hf.featureId = mr->featureId; + hf.workType = workType; + hf.content = workContent; + hf.name = QString::fromStdString(mr->name); + hf.author = QString::fromStdString(mr->author); + hf.describe = QString::fromStdString(mr->describe); + + emit hit(hf); + + delete mr; + mr = NULL; + } + + delete result; + result = NULL; + } } this->state = STATE_NO_ERROR; @@ -116,43 +145,13 @@ void MatchWorkThread::run() { emit workSuccess(this->id); } -bool MatchWorkThread::match(QByteArray byteArray) { +void MatchWorkThread::match(QByteArray byteArray) { Matcher* matcher = this->nowWork->matcher; bool matchstate = false; for (int i = 0; i < byteArray.size(); i++) { char byte = byteArray.at(i); - vector* result = matcher->matchByte(byte); - if (result != NULL) { - - int sourceId = this->nowWork->sourceId; - int workType = this->nowWork->workType; - QString workContent = this->nowWork->content; - - for (int i = 0; i < result->size(); i++) { - - MatcherResult* mr = result->at(i); - - HitFeature hf; - hf.sourceId = sourceId; - hf.featureId = mr->featureId; - hf.workType = workType; - hf.content = workContent; - hf.name = QString::fromStdString(mr->name); - hf.author = QString::fromStdString(mr->author); - hf.describe = QString::fromStdString(mr->describe); - - emit hit(hf); - - delete mr; - mr = NULL; - } - - delete result; - result = NULL; - matchstate = true; - } + matcher->matchByte(byte); } - return matchstate; } int MatchWorkThread::getState() { diff --git a/FireDogEditor/matchthread.h b/FireDogEditor/matchthread.h index 7ef6327..f08ce4d 100644 --- a/FireDogEditor/matchthread.h +++ b/FireDogEditor/matchthread.h @@ -68,7 +68,7 @@ private: int state; MatchWork* nowWork = NULL; - bool match(QByteArray byteArray); + void match(QByteArray byteArray); signals: void nextWork(MatchWorkThread* misson, int* state); diff --git a/FireDogEditor/resources/fdlanguages/en-us.json b/FireDogEditor/resources/fdlanguages/en-us.json index c6e6be6..e73f6d8 100644 --- a/FireDogEditor/resources/fdlanguages/en-us.json +++ b/FireDogEditor/resources/fdlanguages/en-us.json @@ -127,6 +127,9 @@ "feature-rule-window-title":"Feature Rule Editor", "feature-rule-info-type":"Type", + "feature-rule-info-ruleinfo":"RuleInfo", + "feature-rule-info-keytips":"Separate multiple ids with commas (,).", + "feature-rule-info-numtips":"Only numbers are allowed.", "feature-rule-info-key":"Key", "feature-rule-info-save":"Save", "feature-rule-info-cancel":"Cancel", diff --git a/FireDogEditor/resources/fdlanguages/zh-cn.json b/FireDogEditor/resources/fdlanguages/zh-cn.json index 966451d..1008991 100644 --- a/FireDogEditor/resources/fdlanguages/zh-cn.json +++ b/FireDogEditor/resources/fdlanguages/zh-cn.json @@ -127,6 +127,9 @@ "feature-rule-window-title":"特征规则编辑器", "feature-rule-info-type":"类型", + "feature-rule-info-ruleinfo":"规则详情", + "feature-rule-info-keytips":"多个id之间用英文“,”逗号分隔。", + "feature-rule-info-numtips":"只能使用数字。", "feature-rule-info-key":"Key", "feature-rule-info-save":"保存", "feature-rule-info-cancel":"取消", diff --git a/README.md b/README.md index 68b048d..fa0fc17 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # FireDog 开源跨平台轻量级病毒特征检测引擎。Open source cross-platform lightweight virus signature detection engine. +在Releases下载最新版本,跟路径有个demo文件夹,可以参考,并且READEME.txt中也有说明。 + # 语言 Language C++ 11 @@ -32,6 +34,28 @@ https://github.com/MountCloud/FireDog/releases # 更新日志 Update log +# v1.3.1 + +``` +FireDog Version: v1.3.1 +FireDog Editor Version: v2.1 +Feature Libraray Version: v1.2.1 + +1:重构规则引擎,支持多种逻辑运算,支持多种统计运算,支持多种比较运算。 +2:重构特征库格式,从json改用yaml(json确实看起来不好看)。 +3:更改特征匹配逻辑,将字节匹配与校验匹配结果拆分。 +4:编辑器适配新的规则引擎和特征库格式。 + +1: Refactor the rule engine to support multiple logical operations, multiple statistical operations, and multiple comparison operations. +2: Refactor the feature library format and use yaml instead of json (json does not look good). +3: Change the feature matching logic to split the byte matching and check matching results. +4: The editor adapts to the new rule engine and signature library format. +``` + +## v1.3.1 界面GUI +### 规则配置GUI Rule Configuration GUI +![](images/v1.3.1-rule-gui.png) + # v1.2.1 @@ -77,6 +101,50 @@ Feature Libraray Version: v1.1.0 Support hex, md5, text type detection. ``` +# 说明 + +## 特征说明 Feature Description + +``` +key:代表这个特征的标识。 +hex:hex是以二进制形式进行匹配的二进制数据,允许模糊匹配如:0F ?0 A? ??。 +text:以文本形式匹配的关键字。 + +key: The identifier representing this feature. +hex: hex is binary data that is matched in binary form, allowing fuzzy matching such as: 0F ?0 A? ??. +text: The keyword to match in text form. +``` +## 规则说明 Rules Description + +``` +$and:[规则数组] 并运算,只有子规则结果全部为true(通过)时,结果为true(通过),如果有一条子规则结果为false(不通过),则结果为false(不通过)。 +$or:[规则数组] 或运算,有一条子规则结果全部为true(通过)时,结果为true(通过),如果全部子规则结果为false(不通过),则结果为false(不通过)。 +$not:[规则数组] 非运算,只有子规则结果全部为false(不通过)时,结果为true(通过),如果有一条子规则结果为true(通过),则结果为false(不通过)。意思就是如果$not的子规则是$lt($count(key1),$int(5))=$not(key1出现次数小于5)=不能(key1出现的次数小于5)=key1出现的次数需要大于5 + +$all:[字符串数组] 表示一组key必须至少全部出现1次。$all(key1,key2)表示key1和key2必须至少都出现一次。 +$count:*数字规则*[字符串数组] 表示统计key出现的次数。$count(key1,key2)就是统计key1和key2出现的次数。 +$int:*数字规则*[数字类型] 表示一个数字。$int(1)代表数字1 + +$lt:*比较规则*,小于比较,使用两个*数字规则*进行比较,数字规则1 < 数字规则2,则为true(通过)。 +$le:*比较规则*,小于等于比较,使用两个*数字规则*进行比较,数字规则1 <= 数字规则2,则为true(通过)。 +$gt:*比较规则*,大于比较,使用两个*数字规则*进行比较,数字规则1 > 数字规则2,则为true(通过)。 +$ge:*比较规则*,大于等于比较,使用两个*数字规则*进行比较,数字规则1 >= 数字规则2,则为true(通过)。 + + +$and: [rule array] Parallel operation, only when the sub-rule results are all true (pass), the result is true (pass), if there is a sub-rule result is false (fail), the result is false (fail) . +$or: [rule array] OR operation, when one sub-rule result is all true (pass), the result is true (pass), if all sub-rule results are false (fail), the result is false (fail) . +$not: [rule array] Non-operation, only when the sub-rule results are all false (fail), the result is true (pass), if there is a sub-rule result is true (pass), the result is false (fail) . It means that if the sub-rule of $not is $lt($count(key1), $int(5)) = $not (the number of occurrences of key1 is less than 5) = cannot (the number of occurrences of key1 is less than 5) = the number of occurrences of key1 needs to be greater than 5 + +$all: [string array] Indicates that a set of keys must all appear at least once. $all(key1,key2) means that both key1 and key2 must appear at least once. +$count: *Number rule*[String array] Indicates the number of times the key appears. $count(key1,key2) is to count the number of occurrences of key1 and key2. +$int: *Number Rule* [Number Type] Represents a number. $int(1) represents the number 1 + +$lt: *comparison rule*, less than comparison, use two *number rule* for comparison, number rule 1 < number rule 2, true (pass). +$le: *comparison rule*, less than or equal comparison, use two *number rule* for comparison, number rule 1 <= number rule 2, it is true (pass). +$gt: *comparison rule*, greater than comparison, use two *number rule* for comparison, number rule 1 > number rule 2, it is true (pass). +$ge: *comparison rule*, greater than or equal to comparison, use two *number rule* for comparison, number rule 1 >= number rule 2, it is true (pass). +``` + # 使用 Use ## Step 1: download diff --git a/images/v1.3.1-rule-gui.png b/images/v1.3.1-rule-gui.png new file mode 100644 index 0000000..37e2ab1 Binary files /dev/null and b/images/v1.3.1-rule-gui.png differ diff --git a/temp/README.txt b/temp/README.txt new file mode 100644 index 0000000..24b19c5 --- /dev/null +++ b/temp/README.txt @@ -0,0 +1,63 @@ +本项目为开源项目,MIT开源协议。 +https://github.com/MountCloud/FireDog + +1:请使用gui打开/demo/demo.fdog来参考 +!!!修改完规则记得点击 添加或修改。修改完规则库记得点击顶部菜单->操作->保存或者另存为!!! + +2:特征讲解 +key:代表这个特征的标识。 +hex:hex是以二进制形式进行匹配的二进制数据,允许模糊匹配如:0F ?0 A? ??。 +text:以文本形式匹配的关键字。 + +3:规则 +$and:[规则数组] 并运算,只有子规则结果全部为true(通过)时,结果为true(通过),如果有一条子规则结果为false(不通过),则结果为false(不通过)。 +$or:[规则数组] 或运算,有一条子规则结果全部为true(通过)时,结果为true(通过),如果全部子规则结果为false(不通过),则结果为false(不通过)。 +$not:[规则数组] 非运算,只有子规则结果全部为false(不通过)时,结果为true(通过),如果有一条子规则结果为true(通过),则结果为false(不通过)。意思就是如果$not的子规则是$lt($count(key1),$int(5))=$not(key1出现次数小于5)=不能(key1出现的次数小于5)=key1出现的次数需要大于5 + +$all:[字符串数组] 表示一组key必须至少全部出现1次。$all(key1,key2)表示key1和key2必须至少都出现一次。 +$count:*数字规则*[字符串数组] 表示统计key出现的次数。$count(key1,key2)就是统计key1和key2出现的次数。 +$int:*数字规则*[数字类型] 表示一个数字。$int(1)代表数字1 + +$lt:*比较规则*,小于比较,使用两个*数字规则*进行比较,数字规则1 < 数字规则2,则为true(通过)。 +$le:*比较规则*,小于等于比较,使用两个*数字规则*进行比较,数字规则1 <= 数字规则2,则为true(通过)。 +$gt:*比较规则*,大于比较,使用两个*数字规则*进行比较,数字规则1 > 数字规则2,则为true(通过)。 +$ge:*比较规则*,大于等于比较,使用两个*数字规则*进行比较,数字规则1 >= 数字规则2,则为true(通过)。 + +4:demo中的规则描述(请勿复制描述的规则,因为引擎不识别注释): +规则库格式是yaml,yaml语法可以自学一下。 +规则建议还是别手写,用gui配置减少错误率,而且gui用起来多爽。 + +特征库讲解: +这个规则结果是:ab至少出现一次,并且c至少出现一次,并且d至少出现一次,并且a至少出现3次($ge是大于等于), +所以aaabcd能被该规则匹配到: + +version: 1.2.1 //当前规则引擎版本号 +items: //规则集合 + - name: test //单条规则名称 + author: mountcloud //作者 + describe: test new rule engine. //规则描述 + features: //特征集合 + - key: key1 //特征的key + text: a //text代表文本类型,hex代表二进制类型 + - key: key2 + text: b + - key: key3 + text: c + - key: key4 + text: d + - key: key5 + hex: 0F ?0 A? ?? //二进制类型允许使用模糊匹配 + rules: //规则 + - $and: //(规则是第1层)规则是And类型 + - $all: //($and的子规则)All是以下key至少全部都出现一次 + - key1 + - key2 + - $and: //(第一层$and的子规则) + - $all: //(第二层$and的子规则) + - key3 + - $all: + - key4 + - $ge: //(第一层$and的子规则)$ge是大于比较,比较第一个规则要大于第二个规则 + - $count: ($ge的子规则)$count是统计key出现的总数 + - key1 + - $int: 3 ($ge的子规则)$int代表一个固定数字,这里就是 key1出现的次数要大于3 diff --git a/temp/demo/demo.fdog b/temp/demo/demo.fdog new file mode 100644 index 0000000..1c918dd --- /dev/null +++ b/temp/demo/demo.fdog @@ -0,0 +1,28 @@ +version: 1.2.1 +items: + - name: test + author: mountcloud + describe: test new rule engine. + features: + - key: key1 + text: a + - key: key2 + text: b + - key: key3 + text: c + - key: key4 + text: d + rules: + - $and: + - $all: + - key1 + - key2 + - $and: + - $all: + - key3 + - $all: + - key4 + - $ge: + - $count: + - key1 + - $int: 3 diff --git a/temp/demo/using-gui-open-demo.txt b/temp/demo/using-gui-open-demo.txt new file mode 100644 index 0000000..664e910 --- /dev/null +++ b/temp/demo/using-gui-open-demo.txt @@ -0,0 +1,57 @@ +1:请使用gui打开/demo/demo.fdog来参考 +!!!修改完规则记得点击 添加或修改。修改完规则库记得点击顶部菜单->操作->保存或者另存为!!! + +2:特征讲解 +key:代表这个特征的标识。 +hex:hex是以二进制形式进行匹配的二进制数据,允许模糊匹配如:0F ?0 A? ??。 +text:以文本形式匹配的关键字。 + +3:规则 +$and:[规则数组] 并运算,只有子规则结果全部为true(通过)时,结果为true(通过),如果有一条子规则结果为false(不通过),则结果为false(不通过)。 +$or:[规则数组] 或运算,有一条子规则结果全部为true(通过)时,结果为true(通过),如果全部子规则结果为false(不通过),则结果为false(不通过)。 +$not:[规则数组] 非运算,只有子规则结果全部为false(不通过)时,结果为true(通过),如果有一条子规则结果为true(通过),则结果为false(不通过)。意思就是如果$not的子规则是$lt($count(key1),$int(5))=$not(key1出现次数小于5)=不能(key1出现的次数小于5)=key1出现的次数需要大于5 + +$all:[字符串数组] 表示一组key必须至少全部出现1次。$all(key1,key2)表示key1和key2必须至少都出现一次。 +$count:*数字规则*[字符串数组] 表示统计key出现的次数。$count(key1,key2)就是统计key1和key2出现的次数。 +$int:*数字规则*[数字类型] 表示一个数字。$int(1)代表数字1 + +$lt:*比较规则*,小于比较,使用两个*数字规则*进行比较,数字规则1 < 数字规则2,则为true(通过)。 +$le:*比较规则*,小于等于比较,使用两个*数字规则*进行比较,数字规则1 <= 数字规则2,则为true(通过)。 +$gt:*比较规则*,大于比较,使用两个*数字规则*进行比较,数字规则1 > 数字规则2,则为true(通过)。 +$ge:*比较规则*,大于等于比较,使用两个*数字规则*进行比较,数字规则1 >= 数字规则2,则为true(通过)。 + +4:demo中的规则描述(请勿复制描述的规则,因为引擎不识别注释): +规则库格式是yaml,yaml语法可以自学一下。 +规则建议还是别手写,用gui配置减少错误率,而且gui用起来多爽。 + +特征库讲解: +version: 1.2.1 //当前规则引擎版本号 +items: //规则集合 + - name: test //单条规则名称 + author: mountcloud //作者 + describe: test new rule engine. //规则描述 + features: //特征集合 + - key: key1 //特征的key + text: a //text代表文本类型,hex代表二进制类型 + - key: key2 + text: b + - key: key3 + text: c + - key: key4 + text: d + - key: key5 + hex: 0F ?0 A? ?? //二进制类型允许使用模糊匹配 + rules: //规则 + - $and: //(规则是第1层)规则是And类型 + - $all: //($and的子规则)All是以下key至少全部都出现一次 + - key1 + - key2 + - $and: //(第一层$and的子规则) + - $all: //(第二层$and的子规则) + - key3 + - $all: + - key4 + - $ge: //(第一层$and的子规则)$ge是大于比较,比较第一个规则要大于第二个规则 + - $count: ($ge的子规则)$count是统计key出现的总数 + - key1 + - $int: 3 ($ge的子规则)$int代表一个固定数字,这里就是 key1出现的次数要大于3