diff --git a/src/generator/config/ruleconvert.cpp b/src/generator/config/ruleconvert.cpp index 70f6c85ba..37935c4ea 100644 --- a/src/generator/config/ruleconvert.cpp +++ b/src/generator/config/ruleconvert.cpp @@ -486,17 +486,21 @@ static rapidjson::Value transformRuleToSingBox(const std::string& rule, const st static void appendSingBoxRule(rapidjson::Value &rules, const std::string& rule, rapidjson::MemoryPoolAllocator<>& allocator) { using namespace rapidjson_ext; - auto args = split(rule, ","); + auto args = split(rule, ','); if (args.size() < 2) return; - auto type = toLower(std::string(args[0])); - auto value = toLower(args[1]); + auto type = args[0]; // std::string_view option; // if (args.size() >= 3) option = args[2]; - type = replaceAllDistinct(type, "-", "_"); - type = replaceAllDistinct(type, "ip_cidr6", "ip_cidr"); + if (none_of(SingBoxRuleTypes, [&](const std::string& t){ return type == t; })) + return; + + auto realType = toLower(std::string(type)); + auto value = toLower(std::string(args[1])); + realType = replaceAllDistinct(realType, "-", "_"); + realType = replaceAllDistinct(realType, "ip_cidr6", "ip_cidr"); - rules | AppendToArray(type.c_str(), rapidjson::Value(value.c_str(), allocator), allocator); + rules | AppendToArray(realType.c_str(), rapidjson::Value(value.c_str(), value.size(), allocator), allocator); } void rulesetToSingBox(rapidjson::Document &base_rule, std::vector &ruleset_content_array, bool overwrite_original_rules) @@ -565,8 +569,6 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored continue; - if(std::none_of(SingBoxRuleTypes.begin(), SingBoxRuleTypes.end(), [strLine](const std::string& type){return startsWith(strLine, type);})) - continue; if(strFind(strLine, "//")) { strLine.erase(strLine.find("//")); diff --git a/src/utils/rapidjson_extra.h b/src/utils/rapidjson_extra.h index 1b9d6be29..c5fd5c2fe 100644 --- a/src/utils/rapidjson_extra.h +++ b/src/utils/rapidjson_extra.h @@ -117,14 +117,23 @@ namespace rapidjson_ext { struct AppendToArray : public ExtensionFunction { rapidjson::Value &value; - const rapidjson::Value::Ch *name; + rapidjson::GenericValue> name; rapidjson::MemoryPoolAllocator<> &allocator; AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &value, - rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {} + rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, allocator)), allocator(allocator) {} AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &&value, - rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {} + rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, allocator)), allocator(allocator) {} + + AppendToArray(const rapidjson::Value::Ch *name, std::size_t length, rapidjson::Value &value, + rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, length, allocator)), allocator(allocator) {} + + AppendToArray(const rapidjson::Value::Ch *name, std::size_t length, rapidjson::Value &&value, + rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, length, allocator)), allocator(allocator) {} + + AppendToArray(rapidjson::Value &&name, rapidjson::Value &value, + rapidjson::MemoryPoolAllocator<> &allocator): value(value), allocator(allocator) { this->name.Swap(name); } inline rapidjson::Value &operator()(rapidjson::Value &root) const override { diff --git a/src/utils/stl_extra.h b/src/utils/stl_extra.h index 46c3723a3..6e14390cd 100644 --- a/src/utils/stl_extra.h +++ b/src/utils/stl_extra.h @@ -14,4 +14,25 @@ template inline void eraseElements(T &target) T().swap(target); } +template +concept ConstIterable = requires(Container a, Element b) { + { a.cbegin() } -> std::same_as; + { a.cend() } -> std::same_as; + typename Container::const_reference; +}; + +template +concept Iterable = requires(Container a, Element b) { + { a.begin() } -> std::same_as; + { a.end() } -> std::same_as; + typename Container::reference; +}; + +template +requires ConstIterable +inline bool none_of(ConstIterableContainer &container, std::function func) +{ + return std::none_of(container.cbegin(), container.cend(), func); +} + #endif // STL_EXTRA_H_INCLUDED diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 667279c90..86b1ca881 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -9,7 +9,7 @@ #include "string.h" #include "map_extra.h" -std::vector split(const std::string &s, const std::string &seperator) +std::vector split(const std::string &s, const std::string &separator) { std::vector result; string_size i = 0; @@ -20,7 +20,7 @@ std::vector split(const std::string &s, const std::string &seperato while(i != s.size() && flag == 0) { flag = 1; - for(char x : seperator) + for(char x : separator) if(s[i] == x) { ++i; @@ -33,7 +33,7 @@ std::vector split(const std::string &s, const std::string &seperato string_size j = i; while(j != s.size() && flag == 0) { - for(char x : seperator) + for(char x : separator) if(s[j] == x) { flag = 1; @@ -51,6 +51,45 @@ std::vector split(const std::string &s, const std::string &seperato return result; } +std::vector split(std::string_view s, char separator) +{ + std::vector result; + string_size i = 0; + + while (i != s.size()) + { + int flag = 0; + while(i != s.size() && flag == 0) + { + flag = 1; + if(s[i] == separator) + { + ++i; + flag = 0; + break; + } + } + + flag = 0; + string_size j = i; + while(j != s.size() && flag == 0) + { + if(s[j] == separator) + { + flag = 1; + break; + } + ++j; + } + if (i != j) + { + result.push_back(s.substr(i, j-i)); + i = j; + } + } + return result; +} + std::string UTF8ToCodePoint(const std::string &data) { std::stringstream ss; diff --git a/src/utils/string.h b/src/utils/string.h index b376dcc12..9d1571fa2 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -14,7 +14,8 @@ using string_map = std::map; using string_multimap = std::multimap; using string_pair_array = std::vector>; -std::vector split(const std::string &s, const std::string &seperator); +std::vector split(const std::string &s, const std::string &separator); +std::vector split(std::string_view s, char separator); std::string join(const string_array &arr, const std::string &delimiter); template