Skip to content

Commit

Permalink
Optimize codes
Browse files Browse the repository at this point in the history
  • Loading branch information
tindy2013 committed Nov 9, 2023
1 parent bbcb643 commit 833dee1
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 86 deletions.
43 changes: 21 additions & 22 deletions src/generator/config/ruleconvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,25 +457,33 @@ void rulesetToSurge(INIReader &base_rule, std::vector<RulesetContent> &ruleset_c
}
}

static rapidjson::Value transformRuleToSingBox(const std::string& rule, rapidjson::MemoryPoolAllocator<>& allocator)
static rapidjson::Value transformRuleToSingBox(const std::string& rule, const std::string &group, rapidjson::MemoryPoolAllocator<>& allocator)
{
std::string type, value, group, option;
auto args = split(rule, ",");
if (args.size() < 2) return rapidjson::Value(rapidjson::kObjectType);
auto type = toLower(std::string(args[0]));
auto value = args[1];
// std::string_view option;
// if (args.size() >= 3) option = args[2];

regGetMatch(rule, "^(.*?),(.*?)(?:,(.*?))?(,.*)?$", 5, nullptr, &type, &value, &group, &option);
rapidjson::Value rule_obj(rapidjson::kObjectType);
type = replaceAllDistinct(toLower(type), "-", "_");
type = replaceAllDistinct(type, "ip_cidr6", "ip_cidr");
if (type == "match" || type == "final") {
rule_obj.AddMember("outbound", rapidjson::Value(value.c_str(), allocator), allocator);
} else {
rule_obj.AddMember(rapidjson::Value(type.c_str(), allocator), rapidjson::Value(value.c_str(), allocator), allocator);
if (type == "match" || type == "final")
{
rule_obj.AddMember("outbound", rapidjson::Value(value.data(), value.size(), allocator), allocator);
}
else
{
rule_obj.AddMember(rapidjson::Value(type.c_str(), allocator), rapidjson::Value(value.data(), value.size(), allocator), allocator);
rule_obj.AddMember("outbound", rapidjson::Value(group.c_str(), allocator), allocator);
}
return rule_obj;
}

void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent> &ruleset_content_array, bool overwrite_original_rules)
{
using namespace rapidjson_ext;
std::string rule_group, retrieved_rules, strLine, final;
std::stringstream strStrm;
size_t total_rules = 0;
Expand Down Expand Up @@ -507,10 +515,7 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
final = rule_group;
continue;
}
strLine += "," + rule_group;
if(count_least(strLine, ',', 3))
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
rules.PushBack(transformRuleToSingBox(strLine, allocator), allocator);
rules.PushBack(transformRuleToSingBox(strLine, rule_group, allocator), allocator);
total_rules++;
continue;
}
Expand All @@ -535,21 +540,15 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
strLine.erase(strLine.find("//"));
strLine = trimWhitespace(strLine);
}
strLine += "," + rule_group;
if(count_least(strLine, ',', 3))
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
rules.PushBack(transformRuleToSingBox(strLine, allocator), allocator);
rules.PushBack(transformRuleToSingBox(strLine, rule_group, allocator), allocator);
}
}

if (!base_rule.HasMember("route"))
base_rule.AddMember("route", rapidjson::Value(rapidjson::kObjectType), allocator);
if (!base_rule["route"].HasMember("rules"))
base_rule["route"].AddMember("rules", rapidjson::Value(rapidjson::kArrayType), allocator);
base_rule["route"]["rules"].Swap(rules);

if (!base_rule["route"].HasMember("final"))
base_rule["route"].AddMember("final", rapidjson::Value(final.c_str(), allocator), allocator);
else
base_rule["route"]["final"].SetString(final.c_str(), allocator);
auto finalValue = rapidjson::Value(final.c_str(), allocator);
base_rule["route"]
| AddMemberOrReplace("rules", rules, allocator)
| AddMemberOrReplace("final", finalValue, allocator);
}
69 changes: 24 additions & 45 deletions src/generator/config/subexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,35 +998,19 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &

std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra_settings &ext)
{
rapidjson::Document json, base;
std::string output_content;

auto &alloc = json.GetAllocator();
json.SetObject();
json.AddMember("remarks", "", alloc);
json.AddMember("server", "", alloc);
json.AddMember("server_port", 0, alloc);
json.AddMember("method", "", alloc);
json.AddMember("password", "", alloc);
json.AddMember("plugin", "", alloc);
json.AddMember("plugin_opts", "", alloc);
using namespace rapidjson_ext;
rapidjson::Document base;

auto &alloc = base.GetAllocator();

base_conf = trimWhitespace(base_conf);
if(base_conf.empty())
base_conf = "{}";
rapidjson::ParseResult result = base.Parse(base_conf.data());
if(result)
{
for(auto iter = base.MemberBegin(); iter != base.MemberEnd(); iter++)
json.AddMember(iter->name, iter->value, alloc);
}
else
if (!result)
writeLog(0, std::string("SIP008 base loader failed with error: ") + rapidjson::GetParseError_En(result.Code()) + " (" + std::to_string(result.Offset()) + ")", LOG_LEVEL_ERROR);

rapidjson::Value jsondata;
jsondata = json.Move();

output_content = "[";
rapidjson::Value proxies(rapidjson::kArrayType);
for(Proxy &x : nodes)
{
std::string &remark = x.Remark;
Expand All @@ -1051,19 +1035,18 @@ std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra
default:
continue;
}
jsondata["remarks"].SetString(rapidjson::StringRef(remark.c_str(), remark.size()));
jsondata["server"].SetString(rapidjson::StringRef(hostname.c_str(), hostname.size()));
jsondata["server_port"] = x.Port;
jsondata["password"].SetString(rapidjson::StringRef(password.c_str(), password.size()));
jsondata["method"].SetString(rapidjson::StringRef(method.c_str(), method.size()));
jsondata["plugin"].SetString(rapidjson::StringRef(plugin.c_str(), plugin.size()));
jsondata["plugin_opts"].SetString(rapidjson::StringRef(pluginopts.c_str(), pluginopts.size()));
output_content += SerializeObject(jsondata) + ",";
rapidjson::Value proxy(rapidjson::kObjectType);
proxy.CopyFrom(base, alloc)
| AddMemberOrReplace("remarks", rapidjson::Value(remark.c_str(), remark.size()), alloc)
| AddMemberOrReplace("server", rapidjson::Value(hostname.c_str(), hostname.size()), alloc)
| AddMemberOrReplace("server_port", rapidjson::Value(x.Port), alloc)
| AddMemberOrReplace("method", rapidjson::Value(method.c_str(), method.size()), alloc)
| AddMemberOrReplace("password", rapidjson::Value(password.c_str(), password.size()), alloc)
| AddMemberOrReplace("plugin", rapidjson::Value(plugin.c_str(), plugin.size()), alloc)
| AddMemberOrReplace("plugin_opts", rapidjson::Value(pluginopts.c_str(), pluginopts.size()), alloc);
proxies.PushBack(proxy, alloc);
}
if(output_content.size() > 1)
output_content.erase(output_content.size() - 1);
output_content += "]";
return output_content;
return proxies | SerializeObject();
}

std::string proxyToQuan(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext)
Expand Down Expand Up @@ -2101,6 +2084,7 @@ static rapidjson::Value buildV2RayTransport(const Proxy& proxy, rapidjson::Memor
}

void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
using namespace rapidjson_ext;
rapidjson::Document::AllocatorType &allocator = json.GetAllocator();
rapidjson::Value outbounds(rapidjson::kArrayType), route(rapidjson::kArrayType);
std::vector<Proxy> nodelist;
Expand Down Expand Up @@ -2231,11 +2215,8 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
proxy.AddMember("tag", rapidjson::StringRef(x.Remark.c_str()), allocator);
proxy.AddMember("server", rapidjson::StringRef(x.Hostname.c_str()), allocator);
proxy.AddMember("server_port", x.Port, allocator);
if (x.TLSSecure)
{
proxy.AddMember("username", rapidjson::StringRef(x.Username.c_str()), allocator);
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
}
proxy.AddMember("username", rapidjson::StringRef(x.Username.c_str()), allocator);
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
break;
}
case ProxyType::SOCKS5:
Expand Down Expand Up @@ -2272,7 +2253,7 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
nodelist.push_back(x);
outbounds.PushBack(proxy, allocator);
}
for (const ProxyGroupConfig& x: extra_proxy_group)
for (const ProxyGroupConfig &x: extra_proxy_group)
{
string_array filtered_nodelist;
std::string type;
Expand Down Expand Up @@ -2318,16 +2299,14 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
if (x.Tolerance > 0)
group.AddMember("tolerance", x.Tolerance, allocator);
}

outbounds.PushBack(group, allocator);
}
if (json.HasMember("outbounds"))
json.RemoveMember("outbounds");
json.AddMember("outbounds", outbounds, allocator);
json | AddMemberOrReplace("outbounds", outbounds, allocator);
}

std::string proxyToSingBox(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext)
{
using namespace rapidjson_ext;
rapidjson::Document json;
json.Parse(base_conf.data());
if(json.HasParseError())
Expand All @@ -2339,5 +2318,5 @@ std::string proxyToSingBox(std::vector<Proxy> &nodes, const std::string &base_co
proxyToSingBox(nodes, json, ruleset_content_array, extra_proxy_group, ext);
rulesetToSingBox(json, ruleset_content_array, ext.overwrite_original_rules);

return SerializeObject(json);
return json | SerializeObject();
}
3 changes: 2 additions & 1 deletion src/parser/subparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "subparser.h"

using namespace rapidjson;
using namespace rapidjson_ext;
using namespace YAML;

string_array ss_ciphers = {"rc4-md5", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", "bf-cfb", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "salsa20", "chacha20", "chacha20-ietf"};
Expand Down Expand Up @@ -2140,7 +2141,7 @@ void explodeNetchConf(std::string netch, std::vector<Proxy> &nodes)
for(uint32_t i = 0; i < json["Server"].Size(); i++)
{
Proxy node;
explodeNetch("Netch://" + base64Encode(SerializeObject(json["Server"][i])), node);
explodeNetch("Netch://" + base64Encode(json["Server"][i] | SerializeObject()), node);

node.Id = index;
nodes.emplace_back(std::move(node));
Expand Down
72 changes: 58 additions & 14 deletions src/utils/rapidjson_extra.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ template <typename T> void exception_thrower(T e, const std::string &cond, const
#include <rapidjson/error/en.h>
#include <string>

inline void operator >> (const rapidjson::Value& value, std::string& i)
inline void operator >> (const rapidjson::Value &value, std::string &i)
{
if(value.IsNull())
i = "";
Expand All @@ -35,7 +35,7 @@ inline void operator >> (const rapidjson::Value& value, std::string& i)
i = "";
}

inline void operator >> (const rapidjson::Value& value, int& i)
inline void operator >> (const rapidjson::Value &value, int &i)
{
if(value.IsNull())
i = 0;
Expand All @@ -49,31 +49,23 @@ inline void operator >> (const rapidjson::Value& value, int& i)
i = 0;
}

inline std::string GetMember(const rapidjson::Value& value, const std::string &member)
inline std::string GetMember(const rapidjson::Value &value, const std::string &member)
{
std::string retStr;
if(value.IsObject() && value.HasMember(member.data()))
value[member.data()] >> retStr;
return retStr;
}

inline void GetMember(const rapidjson::Value& value, const std::string &member, std::string& target)
inline void GetMember(const rapidjson::Value &value, const std::string &member, std::string &target)
{
std::string retStr = GetMember(value, member);
if(retStr.size())
if(!retStr.empty())
target.assign(retStr);
}

inline std::string SerializeObject(const rapidjson::Value& value)
{
rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer_json(sb);
value.Accept(writer_json);
return sb.GetString();
}

template <typename ...Args>
inline rapidjson::Value buildObject(rapidjson::MemoryPoolAllocator<> & allocator, Args... kvs)
inline rapidjson::Value buildObject(rapidjson::MemoryPoolAllocator<> &allocator, Args... kvs)
{
static_assert(sizeof...(kvs) % 2 == 0, "buildObject requires an even number of arguments");
static_assert((std::is_same<Args, const char*>::value && ...), "buildObject requires all arguments to be const char*");
Expand All @@ -93,5 +85,57 @@ inline rapidjson::Value buildBooleanValue(bool value)
return value ? rapidjson::Value(rapidjson::kTrueType) : rapidjson::Value(rapidjson::kFalseType);
}

namespace rapidjson_ext {
template <typename ReturnType>
struct ExtensionFunction {
virtual ReturnType operator() (rapidjson::Value &root) const = 0;
virtual ReturnType operator() (rapidjson::Value &&root) const
{
return (*this)(root);
};
};

struct AddMemberOrReplace : public ExtensionFunction<rapidjson::Value &> {
rapidjson::Value &member;
const rapidjson::Value::Ch *name;
rapidjson::MemoryPoolAllocator<> &allocator;
AddMemberOrReplace(const rapidjson::Value::Ch *name, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator) : member(value), name(name), allocator(allocator) {}
AddMemberOrReplace(const rapidjson::Value::Ch *name, rapidjson::Value &&value,
rapidjson::MemoryPoolAllocator<> &allocator) : member(value), name(name), allocator(allocator) {}

inline rapidjson::Value & operator() (rapidjson::Value &root) const override
{
if (root.HasMember(name))
root[name] = member;
else
root.AddMember(rapidjson::StringRef(name), member, allocator);
return root;
}
};

struct SerializeObject : public ExtensionFunction<std::string> {
inline std::string operator() (rapidjson::Value &root) const override
{
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
root.Accept(writer);
return buffer.GetString();
}
};

template <typename ReturnType>
inline ReturnType operator| (rapidjson::Value &root, const ExtensionFunction<ReturnType> &func)
{
return func(root);
}

template <typename ReturnType>
inline ReturnType operator| (rapidjson::Value &&root, const ExtensionFunction<ReturnType> &func)
{
return func(root);
}
}


#endif // RAPIDJSON_EXTRA_H_INCLUDED
8 changes: 4 additions & 4 deletions src/utils/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ std::vector<std::string> split(const std::string &s, const std::string &seperato
while(i != s.size() && flag == 0)
{
flag = 1;
for(string_size x = 0; x < seperator.size(); ++x)
if(s[i] == seperator[x])
for(char x : seperator)
if(s[i] == x)
{
++i;
flag = 0;
Expand All @@ -32,8 +32,8 @@ std::vector<std::string> split(const std::string &s, const std::string &seperato
string_size j = i;
while(j != s.size() && flag == 0)
{
for(string_size x = 0; x < seperator.size(); ++x)
if(s[j] == seperator[x])
for(char x : seperator)
if(s[j] == x)
{
flag = 1;
break;
Expand Down

0 comments on commit 833dee1

Please sign in to comment.