mirror of
https://github.com/MountCloud/FireDog.git
synced 2026-10-16 20:20:49 +08:00
1:特征库改为yaml,2:支持多种逻辑运算,3:GUI展示部分调整
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)matcher.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)rule\rule.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)stringutil.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)yaml\yaml.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)converter.cpp" />
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<Filter Include="rule">
|
||||
<UniqueIdentifier>{e756ca74-1d30-4cf7-a5df-4a73f2ab6d0d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="yaml">
|
||||
<UniqueIdentifier>{c8dfd22c-da71-4c8c-801d-42eb85ecaa96}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)errorcode.h" />
|
||||
@@ -37,6 +40,9 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)rule\rule.h">
|
||||
<Filter>rule</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)yaml\yaml.hpp">
|
||||
<Filter>yaml</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)featurelibrary.cpp" />
|
||||
|
||||
+2
-2
@@ -3,9 +3,9 @@
|
||||
|
||||
|
||||
//main version
|
||||
#define FIREDOG_VERSION "1.3.0"
|
||||
#define FIREDOG_VERSION "1.3.1"
|
||||
|
||||
//feature library version
|
||||
#define FIREDOG_FEATURE_LIBRARY_VERSION "1.2.0"
|
||||
#define FIREDOG_FEATURE_LIBRARY_VERSION "1.2.1"
|
||||
|
||||
#endif
|
||||
+266
-47
@@ -1,10 +1,5 @@
|
||||
#include "featurelibrary.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "json/json-schema/json-schema.hpp"
|
||||
|
||||
#include "rule/rule.h"
|
||||
|
||||
using namespace nlohmann;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
@@ -12,6 +7,10 @@ using namespace mountcloud;
|
||||
using namespace firedog;
|
||||
using namespace std;
|
||||
|
||||
#define RYML_SINGLE_HDR_DEFINE_NOW
|
||||
#include "yaml/yaml.hpp"
|
||||
|
||||
#include "stringutil.h"
|
||||
|
||||
FeatureLibrary::FeatureLibrary() {
|
||||
items = new std::vector<FeatureLibraryItem*>();
|
||||
@@ -89,7 +88,7 @@ FeatureLibrary* FeatureLibrary::createByJson(string json, int* errorcode) {
|
||||
//ÏÈ¿´¹æÔò
|
||||
nlohmann::json rulejson = item["rule"];
|
||||
|
||||
vector<Rule*> rules = parseRules(rulejson);
|
||||
vector<Rule*> rules = parseRulesByJson(rulejson);
|
||||
if (rules.size()==0) {
|
||||
continue;
|
||||
}
|
||||
@@ -141,18 +140,112 @@ FeatureLibrary* FeatureLibrary::createByJson(string json, int* errorcode) {
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
vector<Rule*> rules;
|
||||
FeatureLibrary* FeatureLibrary::createByYaml(std::string yaml, int* errorcode) {
|
||||
|
||||
auto eachlogicchild = [](nlohmann::json childjson, LogicRule* logicRule) {
|
||||
for (int i = 0; i < childjson.size(); i++) {
|
||||
nlohmann::json cj = childjson[i];
|
||||
vector<Rule*> rules = parseRules(cj);
|
||||
if (rules.size() > 0) {
|
||||
logicRule->addRules(rules);
|
||||
FeatureLibrary* result = NULL;
|
||||
|
||||
ryml::Tree tree;
|
||||
|
||||
bool parseStatus = false;
|
||||
try {
|
||||
tree = ryml::parse_in_place(ryml::to_substr(yaml));
|
||||
parseStatus = true;
|
||||
}
|
||||
catch (std::runtime_error const&) {
|
||||
parseStatus = false;
|
||||
|
||||
}
|
||||
auto rootref = tree.rootref();
|
||||
if (!parseStatus || !rootref.has_child("version") || !rootref.has_child("items")) {
|
||||
*errorcode = FL_CONTENT_FORMATE_ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
//get version
|
||||
string version;
|
||||
tree["version"] >> version;
|
||||
|
||||
//check version
|
||||
if (version != FIREDOG_FEATURE_LIBRARY_VERSION) {
|
||||
*errorcode = FL_CONTENT_VERSION_ERROR;
|
||||
}
|
||||
|
||||
result = new FeatureLibrary();
|
||||
|
||||
result->version = version;
|
||||
|
||||
auto items = tree["items"];
|
||||
|
||||
if (items.is_seq()) {
|
||||
int itemscount = items.num_children();
|
||||
for (int i = 0; i < itemscount; i++) {
|
||||
auto item = items[i];
|
||||
if (item.is_map()
|
||||
&& item.has_child("author")
|
||||
&& item.has_child("name")
|
||||
&& item.has_child("describe")
|
||||
&& item.has_child("features") && item["features"].is_seq()
|
||||
&& item.has_child("rules") && item["rules"].is_seq()) {
|
||||
|
||||
//ÏÈ¿´¹æÔò
|
||||
c4::yml::NodeRef rulesYml = item["rules"];
|
||||
|
||||
vector<Rule*> rules = parseRulesByYaml(rulesYml);
|
||||
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();
|
||||
item["author"] >> fitem->author;
|
||||
item["name"] >> fitem->name;
|
||||
item["describe"] >> fitem->describe;
|
||||
fitem->rule = rule;
|
||||
|
||||
auto features = item["features"];
|
||||
int featurescount = features.num_children();
|
||||
for (int y = 0; y < featurescount; y++) {
|
||||
auto feature = features[y];
|
||||
if (feature.has_child("key")
|
||||
&& (feature.has_child("hex")
|
||||
|| feature.has_child("text"))) {
|
||||
string fkey;
|
||||
feature["key"] >> fkey;
|
||||
string fhex = "";
|
||||
string ftext = "";
|
||||
if (feature.has_child("hex")) {
|
||||
feature["hex"] >> fhex;
|
||||
}
|
||||
|
||||
if (feature.has_child("text")) {
|
||||
feature["text"] >> ftext;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
vector<Rule*> FeatureLibrary::parseRulesByJson(nlohmann::json rulejson) {
|
||||
vector<Rule*> rules;
|
||||
|
||||
if (rulejson.is_string()) {
|
||||
string id = rulejson;
|
||||
CountRule* countRule = new CountRule(id);
|
||||
@@ -161,20 +254,22 @@ vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
for (auto ruleiter = rulejson.begin(); ruleiter != rulejson.end(); ruleiter++) {
|
||||
std::string key = ruleiter.key();
|
||||
nlohmann::json childrulejson = rulejson[key];
|
||||
if (key == "$and") {
|
||||
AndRule* andRule = new AndRule();
|
||||
eachlogicchild(childrulejson, andRule);
|
||||
rules.push_back(andRule);
|
||||
}
|
||||
else if(key == "$or") {
|
||||
OrRule* orRule = new OrRule();
|
||||
eachlogicchild(childrulejson, orRule);
|
||||
rules.push_back(orRule);
|
||||
}
|
||||
else if (key == "$not") {
|
||||
NotRule* notRule = new NotRule();
|
||||
eachlogicchild(childrulejson, notRule);
|
||||
rules.push_back(notRule);
|
||||
if (key == "$and" || key == "$or" || key == "$not") {
|
||||
LogicRule* logicRule = NULL;
|
||||
vector<Rule*> 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()) {
|
||||
@@ -184,9 +279,13 @@ vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
}
|
||||
}
|
||||
else if (key == "$count") {
|
||||
if (childrulejson.is_array()) {
|
||||
vector<string> ids;
|
||||
long num = 1L;
|
||||
vector<string> 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];
|
||||
@@ -201,22 +300,25 @@ vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.size() > 0) {
|
||||
CountRule* countRule = new CountRule(ids);
|
||||
countRule->setCritical(num);
|
||||
rules.push_back(countRule);
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
if (!childrulejson.is_array()&&childrulejson.size()==2) {
|
||||
Rule* compareRule = NULL;
|
||||
nlohmann::json num1json = childrulejson[0];
|
||||
nlohmann::json num2json = childrulejson[1];
|
||||
Rule* num1Rule = parseRule(num1json);
|
||||
Rule* num2Rule = parseRule(num2json);
|
||||
if (num1Rule!=NULL&&num1Rule->getBaseType() == RULE_BASE_TYPE_NUMBER
|
||||
&&num2Rule!=NULL&&num2Rule->getBaseType() == RULE_BASE_TYPE_NUMBER) {
|
||||
Rule* compareRule = NULL;
|
||||
|
||||
vector<Rule*> 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);
|
||||
}
|
||||
@@ -233,6 +335,7 @@ vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
if (compareRule != NULL) {
|
||||
rules.push_back(compareRule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,10 +343,10 @@ vector<Rule*> FeatureLibrary::parseRules(nlohmann::json rulejson) {
|
||||
return rules;
|
||||
}
|
||||
|
||||
Rule* FeatureLibrary::parseRule(nlohmann::json rulejson) {
|
||||
Rule* FeatureLibrary::parseRuleByJson(nlohmann::json rulejson) {
|
||||
Rule* rule = NULL;
|
||||
|
||||
vector<Rule*> rules = parseRules(rulejson);
|
||||
vector<Rule*> rules = parseRulesByJson(rulejson);
|
||||
if (rules.size()>0) {
|
||||
rule = rules.at(0);
|
||||
}
|
||||
@@ -362,6 +465,122 @@ nlohmann::json FeatureLibrary::ruleToJson(mountcloud::Rule* rule,bool* state) {
|
||||
return jsonRule;
|
||||
}
|
||||
|
||||
std::vector<mountcloud::Rule*> FeatureLibrary::parseRulesByYaml(c4::yml::NodeRef node) {
|
||||
std::vector<mountcloud::Rule*> rules;
|
||||
if (node.is_seq()) {
|
||||
int count = node.num_children();
|
||||
for (int i = 0; i < count; i++) {
|
||||
std::vector<mountcloud::Rule*> crules = parseRulesByYaml(node[i]);
|
||||
if (crules.size() > 0) {
|
||||
rules.insert(rules.end(), crules.begin(), crules.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(node.is_map()){
|
||||
c4::yml::Tree* tree = node.tree();
|
||||
int nodeid = node.id();
|
||||
for (size_t child_id = tree->first_child(nodeid); child_id != ryml::NONE; child_id = tree->next_sibling(child_id)) {
|
||||
auto key = tree->key(child_id);
|
||||
auto childrule = node[key];
|
||||
if (key == "$and" || key == "$or" || key == "$not") {
|
||||
LogicRule* logicRule = NULL;
|
||||
vector<Rule*> childRules = parseRulesByYaml(childrule);
|
||||
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 (childrule.is_keyval()) {
|
||||
long num = 0L;
|
||||
string numstr;
|
||||
childrule >> numstr;
|
||||
if (StringUtil::isNumber(numstr)) {
|
||||
num = atoi(numstr.c_str());
|
||||
IntRule* intRule = new IntRule(num);
|
||||
rules.push_back(intRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (key == "$count") {
|
||||
vector<string> ids;
|
||||
long num = 1L;
|
||||
|
||||
if (childrule.is_keyval()) {
|
||||
string id;
|
||||
childrule >> id;
|
||||
ids.push_back(id);
|
||||
}
|
||||
else if (childrule.is_seq()) {
|
||||
int idslen = childrule.num_children();
|
||||
for (int i = 0; i < idslen; i++) {
|
||||
auto crj = childrule[i];
|
||||
string id;
|
||||
crj >> id;
|
||||
ids.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
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<Rule*> childRules = parseRulesByYaml(childrule);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
mountcloud::Rule* FeatureLibrary::parseRuleByYaml(c4::yml::NodeRef node) {
|
||||
vector<Rule*> rules = parseRulesByYaml(node);
|
||||
if (rules.size() > 0) {
|
||||
return rules[0];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FeatureLibraryItem::~FeatureLibraryItem() {
|
||||
if (features != NULL) {
|
||||
for (int i = 0; i < features->size(); i++) {
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "config.h"
|
||||
#include "json/json-schema/json-schema.hpp"
|
||||
#include "rule/rule.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
#include "errorcode.h"
|
||||
|
||||
@@ -13,7 +17,6 @@
|
||||
#define FEATURE_TYPE_HEX_STR "hex"
|
||||
#define FEATURE_TYPE_TEXT_STR "text"
|
||||
|
||||
|
||||
static const char* FIREDOG_FEATURE_LIBRARAY_JSON_SCHEMA = R"(
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
@@ -89,16 +92,17 @@ static const char* FIREDOG_FEATURE_LIBRARAY_JSON_SCHEMA = R"(
|
||||
}
|
||||
)";
|
||||
|
||||
namespace mountcloud {
|
||||
class Rule;
|
||||
}
|
||||
namespace c4 {
|
||||
namespace yml {
|
||||
class NodeRef;
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Feature Library h
|
||||
/// </summary>
|
||||
namespace firedog {
|
||||
|
||||
|
||||
class Feature {
|
||||
public:
|
||||
std::string key;
|
||||
@@ -143,6 +147,7 @@ namespace firedog {
|
||||
/// create by json
|
||||
/// </summary>
|
||||
static FeatureLibrary* createByJson(std::string json, int* errorcode);
|
||||
static FeatureLibrary* createByYaml(std::string yaml, int* errorcode);
|
||||
|
||||
/// <summary>
|
||||
/// library version
|
||||
@@ -165,8 +170,11 @@ namespace firedog {
|
||||
~FeatureLibrary();
|
||||
|
||||
private:
|
||||
static std::vector<mountcloud::Rule*> parseRules(nlohmann::json rulejson);
|
||||
static mountcloud::Rule* parseRule(nlohmann::json rulejson);
|
||||
static std::vector<mountcloud::Rule*> parseRulesByJson(nlohmann::json rulejson);
|
||||
static mountcloud::Rule* parseRuleByJson(nlohmann::json rulejson);
|
||||
|
||||
static std::vector<mountcloud::Rule*> parseRulesByYaml(c4::yml::NodeRef node);
|
||||
static mountcloud::Rule* parseRuleByYaml(c4::yml::NodeRef node);
|
||||
/// <summary>
|
||||
/// rule to json object
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "firedog.h"
|
||||
#include "featurelibrary.h"
|
||||
#include "matcher.h"
|
||||
|
||||
using namespace firedog;
|
||||
|
||||
|
||||
+2
-6
@@ -4,6 +4,8 @@
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include "errorcode.h"
|
||||
#include "featurelibrary.h"
|
||||
#include "matcher.h"
|
||||
|
||||
/// <summary>
|
||||
/// fire dog main header
|
||||
@@ -11,12 +13,6 @@
|
||||
|
||||
namespace firedog {
|
||||
|
||||
class FeatureLibrary;
|
||||
|
||||
class MatcherDataSource;
|
||||
|
||||
class Matcher;
|
||||
|
||||
class FireDog {
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
+4
-7
@@ -1,10 +1,5 @@
|
||||
#include "matcher.h"
|
||||
|
||||
#include "featurelibrary.h"
|
||||
#include "stringutil.h"
|
||||
#include "rule/rule.h"
|
||||
#include "converter.h"
|
||||
|
||||
using namespace mountcloud;
|
||||
using namespace firedog;
|
||||
using namespace std;
|
||||
@@ -418,7 +413,6 @@ std::vector<MatcherResult*>* Matcher::checkMatcherFeatureMap(AvlMap<char, Matche
|
||||
MatcherData* iterMbd = mbditer->mapped_value;
|
||||
//这里我在想是不是以后可以用多种模式控制,如果是fast模式直接return匹配到的特征?
|
||||
if (iterMbd->features != NULL) {
|
||||
result = new std::vector<MatcherResult*>();
|
||||
for (int i = 0; i < iterMbd->features->size(); i++) {
|
||||
MatcherFeature* mf = iterMbd->features->at(i);
|
||||
int featureId = mf->featureId;
|
||||
@@ -435,13 +429,16 @@ std::vector<MatcherResult*>* Matcher::checkMatcherFeatureMap(AvlMap<char, Matche
|
||||
ruleData = featureRuleData->at(featureId);
|
||||
}
|
||||
|
||||
//ruleData->set(featureKey, true);
|
||||
ruleData->hit(featureKey);
|
||||
|
||||
featureRuleData->operator[](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*>();
|
||||
}
|
||||
MatcherResult* mr = new MatcherResult();
|
||||
mr->featureId = featureId;
|
||||
mr->author = fitem->author;
|
||||
|
||||
+4
-8
@@ -7,21 +7,17 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "map/avlmap.h"
|
||||
#include "featurelibrary.h"
|
||||
#include "stringutil.h"
|
||||
#include "rule/rule.h"
|
||||
#include "converter.h"
|
||||
|
||||
/// <summary>
|
||||
/// fire dog matcher
|
||||
/// </summary>
|
||||
|
||||
namespace mountcloud {
|
||||
class RuleData;
|
||||
}
|
||||
|
||||
namespace firedog {
|
||||
|
||||
class FeatureLibrary;
|
||||
class FeatureLibraryItem;
|
||||
|
||||
class Hex;
|
||||
|
||||
class MatcherFeature {
|
||||
public:
|
||||
|
||||
@@ -70,6 +70,10 @@ bool AllRule::check(RuleData* data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> AllRule::getIds() {
|
||||
return this->ids;
|
||||
}
|
||||
|
||||
LogicRule::LogicRule() {
|
||||
rules = new std::vector<Rule*>();
|
||||
baseType = RULE_BASE_TYPE_LOGIC;
|
||||
@@ -99,6 +103,10 @@ void LogicRule::addRules(std::vector<Rule*> rules) {
|
||||
this->rules->insert(this->rules->end(), rules.begin(), rules.end());
|
||||
}
|
||||
|
||||
std::vector<Rule*>* LogicRule::getRules() {
|
||||
return this->rules;
|
||||
}
|
||||
|
||||
bool AndRule::check(RuleData* data) {
|
||||
//andµÄÇé¿ö
|
||||
if (rules != NULL && rules->size() > 0) {
|
||||
@@ -157,6 +165,10 @@ IntRule::IntRule(long num) {
|
||||
type = RULE_TYPE_NUMBER_INT;
|
||||
}
|
||||
|
||||
long IntRule::getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
bool IntRule::check(RuleData* data) {
|
||||
return true;
|
||||
}
|
||||
@@ -214,6 +226,9 @@ bool CountRule::check(RuleData* data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> CountRule::getIds() {
|
||||
return this->ids;
|
||||
}
|
||||
|
||||
CompareRule::CompareRule(NumberRule* num1, NumberRule* num2) {
|
||||
this->num1 = num1;
|
||||
@@ -225,6 +240,14 @@ LtRule::LtRule(NumberRule* num1, NumberRule* num2) : CompareRule(num1, num2) {
|
||||
type = RULE_TYPE_COMPARE_LT;
|
||||
}
|
||||
|
||||
NumberRule* CompareRule::getNum1() {
|
||||
return this->num1;
|
||||
}
|
||||
|
||||
NumberRule* CompareRule::getNum2() {
|
||||
return this->num2;
|
||||
}
|
||||
|
||||
bool LtRule::check(RuleData* data) {
|
||||
long n1 = num1->getNumber(data);
|
||||
long n2 = num2->getNumber(data);
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace mountcloud {
|
||||
AllRule(std::vector<std::string> ids);
|
||||
void addId(std::string id);
|
||||
bool check(RuleData* data) override;
|
||||
std::vector<std::string> getIds();
|
||||
private:
|
||||
std::vector<std::string> ids;
|
||||
};
|
||||
@@ -74,6 +75,7 @@ namespace mountcloud {
|
||||
~LogicRule();
|
||||
void addRule(Rule* rule);
|
||||
void addRules(std::vector<Rule*> rules);
|
||||
std::vector<Rule*>* getRules();
|
||||
protected:
|
||||
std::vector<Rule*>* rules = NULL;
|
||||
};
|
||||
@@ -109,6 +111,7 @@ namespace mountcloud {
|
||||
IntRule(long num);
|
||||
bool check(RuleData* data) override;
|
||||
long getNumber(RuleData* data) override;
|
||||
long getNum();
|
||||
private:
|
||||
long num = 0;
|
||||
};
|
||||
@@ -127,6 +130,8 @@ namespace mountcloud {
|
||||
bool check(RuleData* data) override;
|
||||
|
||||
void setCritical(long critical);
|
||||
|
||||
std::vector<std::string> getIds();
|
||||
private:
|
||||
long critical = 1;
|
||||
std::vector<std::string> ids;
|
||||
@@ -136,6 +141,8 @@ namespace mountcloud {
|
||||
class CompareRule :public Rule {
|
||||
public:
|
||||
CompareRule(NumberRule* num1, NumberRule* num2);
|
||||
NumberRule* getNum1();
|
||||
NumberRule* getNum2();
|
||||
protected:
|
||||
NumberRule* num1 = NULL;
|
||||
NumberRule* num2 = NULL;
|
||||
|
||||
+18
-4
@@ -13,14 +13,12 @@
|
||||
class StringUtil {
|
||||
public:
|
||||
static std::string ltrim(std::string str) {
|
||||
std::string::iterator p = find_if(str.begin(), str.end(), not1(std::ptr_fun<int, int>(isspace)));
|
||||
str.erase(str.begin(), p);
|
||||
str.erase(0, str.find_first_not_of(" "));
|
||||
return str;
|
||||
};
|
||||
|
||||
static std::string rtrim(std::string str) {
|
||||
std::string::reverse_iterator p = find_if(str.rbegin(), str.rend(), not1(std::ptr_fun<int, int>(isspace)));
|
||||
str.erase(p.base(), str.end());
|
||||
str.erase(str.find_last_not_of(" ")+1);
|
||||
return str;
|
||||
};
|
||||
|
||||
@@ -99,6 +97,22 @@ public:
|
||||
results->push_back(chr);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isNumber(std::string str) {
|
||||
for (int i = 0; i < str.size(); i++)
|
||||
{
|
||||
int tmp = (int)str[i];
|
||||
if (tmp >= 48 && tmp <= 57)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
+32009
File diff suppressed because it is too large
Load Diff
@@ -740,6 +740,81 @@ void FireDogEditor::slots_selectFeatureTableEvent(const QModelIndex& current, co
|
||||
|
||||
QStandardItem* FireDogEditor::ruleToItem(mountcloud::Rule* rule) {
|
||||
QStandardItem* ruleitem = new QStandardItem();
|
||||
|
||||
if (rule->getBaseType() == RULE_BASE_TYPE_ALL) {
|
||||
ruleitem->setText(QStringLiteral("$all"));
|
||||
mountcloud::AllRule* allRule = (mountcloud::AllRule*) rule;
|
||||
std::vector<std::string> ids = allRule->getIds();
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
QStandardItem* idsItem = new QStandardItem();
|
||||
idsItem->setText(QString(ids[i].c_str()));
|
||||
ruleitem->appendRow(idsItem);
|
||||
}
|
||||
}
|
||||
else if(rule->getBaseType() == RULE_BASE_TYPE_LOGIC) {
|
||||
mountcloud::LogicRule* logicRule = (mountcloud::LogicRule*)rule;
|
||||
|
||||
if (logicRule->getType() == RULE_TYPE_LOGIC_AND) {
|
||||
ruleitem->setText(QStringLiteral("$and"));
|
||||
}
|
||||
else if (logicRule->getType() == RULE_TYPE_LOGIC_OR) {
|
||||
ruleitem->setText(QStringLiteral("$or"));
|
||||
}
|
||||
else if (logicRule->getType() == RULE_TYPE_LOGIC_NOT) {
|
||||
ruleitem->setText(QStringLiteral("$not"));
|
||||
}
|
||||
|
||||
for (int i = 0; i < logicRule->getRules()->size(); i++) {
|
||||
mountcloud::Rule* crule = logicRule->getRules()->at(i);
|
||||
QStandardItem* citem = ruleToItem(crule);
|
||||
ruleitem->appendRow(citem);
|
||||
}
|
||||
|
||||
}
|
||||
else if (rule->getType() == RULE_TYPE_NUMBER_INT) {
|
||||
mountcloud::IntRule* intRule = (mountcloud::IntRule*)rule;
|
||||
|
||||
ruleitem->setText(QStringLiteral("$int"));
|
||||
QStandardItem* citem = new QStandardItem();
|
||||
citem->setText(QString::number(intRule->getNum()));
|
||||
ruleitem->appendRow(citem);
|
||||
}
|
||||
else if (rule->getType() == RULE_TYPE_NUMBER_COUNT) {
|
||||
mountcloud::CountRule* countRule = (mountcloud::CountRule*)rule;
|
||||
|
||||
ruleitem->setText(QStringLiteral("$count"));
|
||||
for (int i = 0; i < countRule->getIds().size(); i++) {
|
||||
QStandardItem* idsItem = new QStandardItem();
|
||||
idsItem->setText(QString(countRule->getIds()[i].c_str()));
|
||||
ruleitem->appendRow(idsItem);
|
||||
}
|
||||
}
|
||||
else if (rule->getBaseType() == RULE_BASE_TYPE_COMPARE) {
|
||||
|
||||
if (rule->getType() == RULE_TYPE_COMPARE_LT) {
|
||||
ruleitem->setText(QStringLiteral("$lt"));
|
||||
}
|
||||
else if (rule->getType() == RULE_TYPE_COMPARE_LE) {
|
||||
ruleitem->setText(QStringLiteral("$le"));
|
||||
}
|
||||
else if (rule->getType() == RULE_TYPE_COMPARE_GT) {
|
||||
ruleitem->setText(QStringLiteral("$gt"));
|
||||
}
|
||||
else if (rule->getType() == RULE_TYPE_COMPARE_GE) {
|
||||
ruleitem->setText(QStringLiteral("$ge"));
|
||||
}
|
||||
|
||||
mountcloud::CompareRule* compareRule = (mountcloud::CompareRule*)rule;
|
||||
mountcloud::NumberRule* num1rule = compareRule->getNum1();
|
||||
mountcloud::NumberRule* num2rule = compareRule->getNum2();
|
||||
|
||||
QStandardItem* c1item = ruleToItem(num1rule);
|
||||
QStandardItem* c2item = ruleToItem(num2rule);
|
||||
|
||||
ruleitem->appendRow(c1item);
|
||||
ruleitem->appendRow(c2item);
|
||||
}
|
||||
|
||||
//if (!rule->id.empty()) {
|
||||
// ruleitem->setText(QString(rule->id.c_str()));
|
||||
//}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "Qss/Qss.h"
|
||||
|
||||
#define FIREDOG_EDITOR_VERSION "v1.0"
|
||||
#define FIREDOG_EDITOR_VERSION "v2.1 DEV"
|
||||
#define EXIT_CODE_REBOOT -123456789
|
||||
|
||||
//匹配管家
|
||||
|
||||
@@ -26,7 +26,7 @@ void ParseThread::run() {
|
||||
QString featureLibraryJson = file.readAll();
|
||||
|
||||
int errorCode = 0;
|
||||
FeatureLibrary* library = FeatureLibrary::createByJson(featureLibraryJson.toStdString(),&errorCode);
|
||||
FeatureLibrary* library = FeatureLibrary::createByYaml(featureLibraryJson.toStdString(),&errorCode);
|
||||
|
||||
int resultCode = PARSE_SUCCESS;
|
||||
//有异常的话
|
||||
|
||||
+171
-98
@@ -1,5 +1,6 @@
|
||||
// TestWindows.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
//
|
||||
#pragma warning(disable: 4996)
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -13,113 +14,62 @@
|
||||
|
||||
#include "rule/rule.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace firedog;
|
||||
|
||||
void testMatcher() {
|
||||
|
||||
//test featureLibrary
|
||||
const char* featureLibraryJson = R"(
|
||||
const char* featureLibraryJson = R"(
|
||||
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"version":"1.1.0",
|
||||
"items":[
|
||||
"author": "mountcloud",
|
||||
"describe": "t",
|
||||
"features": [
|
||||
{
|
||||
"name":"test simple",
|
||||
"describe":"match hello world,hello hex:68 65 6C 6C 6F,world hex:77 6F 72 6C 64",
|
||||
"author":"MountCloud",
|
||||
"features":[
|
||||
{
|
||||
"key":"str1",
|
||||
"text":"hello"
|
||||
},
|
||||
{
|
||||
"key":"str2",
|
||||
"text":"world"
|
||||
}
|
||||
],
|
||||
"rule":{
|
||||
"$and":[
|
||||
"str1",
|
||||
"str2"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name":"test complex hex match",
|
||||
"describe":"match mountcloud firedog,mountcloud hex:6D 6F 75 6E 74 63 6C 6F 75 64,firedog hex:66 69 72 65 64 6F 67",
|
||||
"author":"MountCloud",
|
||||
"features":[
|
||||
{
|
||||
"key":"hex1",
|
||||
"hex":"6D ?? ?5 6? [73-75] [41-5A,61-7A] 6C 6F 75 64"
|
||||
},
|
||||
{
|
||||
"key":"hex2",
|
||||
"hex":"66 6? 72 ?? 64 [60-70] 67"
|
||||
}
|
||||
],
|
||||
"rule":{
|
||||
"$and":[
|
||||
"hex1",
|
||||
"hex2"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name":"test complex rule match",
|
||||
"describe":"match we can do it.",
|
||||
"author":"MountCloud",
|
||||
"features":[
|
||||
{
|
||||
"key":"str1",
|
||||
"text":"we"
|
||||
},
|
||||
{
|
||||
"key":"str2",
|
||||
"text":"can"
|
||||
},
|
||||
{
|
||||
"key":"str3",
|
||||
"text":"do"
|
||||
},
|
||||
{
|
||||
"key":"str4",
|
||||
"text":"it"
|
||||
}
|
||||
],
|
||||
"rule":{
|
||||
"$and":[
|
||||
{
|
||||
"$or":[
|
||||
{
|
||||
"$and":[
|
||||
"str1","str2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"$and":[
|
||||
"str3","str4"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"$and":[
|
||||
"str1",
|
||||
"str4"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
"key": "t",
|
||||
"text": "t"
|
||||
},{
|
||||
"key": "a",
|
||||
"text": "a"
|
||||
}
|
||||
]
|
||||
],
|
||||
"name": "t",
|
||||
"rule": {
|
||||
"$and": {
|
||||
"$gt":{
|
||||
"$count":"t",
|
||||
"$int" : 5
|
||||
},
|
||||
"$not":{
|
||||
"$gt":{
|
||||
"$count":"t",
|
||||
"$int" : 10
|
||||
}
|
||||
},
|
||||
"$gt":{
|
||||
"$count":"a",
|
||||
"$int" : 3
|
||||
},
|
||||
"$lt":{
|
||||
"$count":"a",
|
||||
"$int" : 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": "1.2.0"
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
//bytes
|
||||
//const string bytes = "fire dog hello world.";
|
||||
const string bytes = "123213123213 mountcloud 12312312313 firedog";
|
||||
const string bytes = "ttttttaaa";
|
||||
|
||||
int ecode = NO_ERROR;
|
||||
|
||||
@@ -148,29 +98,152 @@ void testMatcher() {
|
||||
|
||||
//step4: matcher bytes
|
||||
int length = bytes.length();
|
||||
MatcherResult* mr = NULL;
|
||||
|
||||
vector<MatcherResult*>* mrs = NULL;
|
||||
//test match bytes
|
||||
//mr = matcher->matchBytes(bytes.c_str(), length);
|
||||
//or
|
||||
for (int i = 0; i < bytes.size(); i++) {
|
||||
char byte = bytes[i];
|
||||
mr = matcher->matchByte(byte);
|
||||
if (mr != NULL) {
|
||||
mrs = matcher->matchByte(byte);
|
||||
if (mrs != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mr != NULL) {
|
||||
cout << "found it:" << mr->name << endl;
|
||||
if (mrs != NULL) {
|
||||
cout << "found it:" << mrs->size() << endl;
|
||||
}
|
||||
else {
|
||||
cout << "not found." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
struct YamlErrorHandler
|
||||
{
|
||||
bool iserror = false;
|
||||
// this will be called on error
|
||||
void on_error(const char* msg, size_t len, ryml::Location loc)
|
||||
{
|
||||
iserror = true;
|
||||
}
|
||||
|
||||
// bridge
|
||||
ryml::Callbacks callbacks()
|
||||
{
|
||||
return ryml::Callbacks(this, nullptr, nullptr, YamlErrorHandler::s_error);
|
||||
}
|
||||
static void s_error(const char* msg, size_t len, ryml::Location loc, void* this_)
|
||||
{
|
||||
return ((YamlErrorHandler*)this_)->on_error(msg, len, loc);
|
||||
}
|
||||
|
||||
// save the default callbacks for checking
|
||||
YamlErrorHandler() : defaults(ryml::get_callbacks()) {}
|
||||
ryml::Callbacks defaults;
|
||||
} YamlErrorHandler;
|
||||
|
||||
//void testyaml() {
|
||||
// const char* featureLibraryJson = R"(
|
||||
//
|
||||
//items:
|
||||
// - author: mountcloud
|
||||
// describe: t
|
||||
// features:
|
||||
// - key: t
|
||||
// text: t
|
||||
// - key: a
|
||||
// text: a
|
||||
// name: t
|
||||
// rules:
|
||||
// - $and:
|
||||
// - $gt:
|
||||
// $count: a
|
||||
// $int: 3
|
||||
// - $not:
|
||||
// - $gt:
|
||||
// $count: t
|
||||
// $int: 10
|
||||
// - $lt:
|
||||
// $count: a
|
||||
// $int: 5
|
||||
//version: 1.2.0
|
||||
//
|
||||
// )";
|
||||
//
|
||||
// // set a global error handler. Note the error callback must never
|
||||
// // return: it must either abort or throw an exception. Otherwise,
|
||||
// // the parser will enter into an infinite loop, or the program may
|
||||
// // crash.
|
||||
// ryml::set_callbacks(ryml::Callbacks(NULL, NULL, NULL, [](const char* msg, size_t len, ryml::Location loc, void* this_) {
|
||||
//
|
||||
// }));
|
||||
//
|
||||
// std::string contents = featureLibraryJson;
|
||||
//
|
||||
// bool iserror = false;
|
||||
//
|
||||
// char yml_buf[] = "{foo: 1, bar: [2, 3], john: doe}";
|
||||
// ryml::Tree tree;
|
||||
//
|
||||
// try {
|
||||
// tree = ryml::parse_in_place(ryml::to_substr(contents));
|
||||
// }
|
||||
// catch (std::runtime_error const&) {
|
||||
// iserror = true;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// size_t root_id = tree.root_id();
|
||||
// string version;
|
||||
// auto versionnode = tree.rootref().has_child("version");
|
||||
// auto status = tree.rootref().has_child("items");
|
||||
// status = tree["items"].is_seq();
|
||||
// status = tree["version"].is_seq();
|
||||
//
|
||||
// size_t count = 0;
|
||||
// for (size_t child_id = tree.first_child(root_id); child_id != ryml::NONE; child_id = tree.next_sibling(child_id)) {
|
||||
// auto key = tree.key(child_id);
|
||||
// if (key == "version") {
|
||||
// tree[key] >> version;
|
||||
// cout << version << endl;
|
||||
// }
|
||||
// }
|
||||
// auto rules = tree["items"][0]["rules"];
|
||||
//
|
||||
// for (int i = 0; i < rules.num_children(); i++) {
|
||||
// auto rule = rules[i];
|
||||
// for (size_t child_id = tree.first_child(rule.id()); child_id != ryml::NONE; child_id = tree.next_sibling(child_id)) {
|
||||
// auto key = tree.key(child_id);
|
||||
//
|
||||
// string keyst;
|
||||
// if (key == "$and") {
|
||||
// cout << "is and " << endl;
|
||||
// }
|
||||
// if (key == "or") {
|
||||
// cout << "is and " << endl;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// int num = tree["items"].num_children();
|
||||
// for (int i = 0; i < num; i++) {
|
||||
// auto item = tree["items"][i];
|
||||
//
|
||||
// }
|
||||
//
|
||||
// int ii = 0;
|
||||
//}
|
||||
|
||||
int main()
|
||||
{
|
||||
testMatcher();
|
||||
//testMatcher();
|
||||
|
||||
//testyaml();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -89,6 +89,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -103,6 +104,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -117,6 +119,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -131,6 +134,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
Reference in New Issue
Block a user