Avoid allocations in ScriptUtils::Match

This commit is contained in:
Gunnar Beutner 2017-12-18 09:58:55 +01:00
parent 0d40009a3c
commit 80b72cfb1c
1 changed files with 71 additions and 63 deletions

View File

@ -110,10 +110,8 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified."));
Array::Ptr texts = new Array();
String pattern = args[0]; String pattern = args[0];
Value argTexts = args[1]; const Value& argTexts = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -121,21 +119,22 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argTexts.IsObjectType<Array>()) boost::regex expr(pattern.GetData());
Array::Ptr texts;
if (argTexts.IsObject())
texts = argTexts; texts = argTexts;
else {
texts = new Array(); if (texts) {
texts->Add(argTexts); ObjectLock olock(texts);
}
if (texts->GetLength() == 0) if (texts->GetLength() == 0)
return false; return false;
ObjectLock olock(texts);
for (const String& text : texts) { for (const String& text : texts) {
bool res = false; bool res = false;
try { try {
boost::regex expr(pattern.GetData());
boost::smatch what; boost::smatch what;
res = boost::regex_search(text.GetData(), what, expr); res = boost::regex_search(text.GetData(), what, expr);
} catch (boost::exception&) { } catch (boost::exception&) {
@ -148,7 +147,12 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
return false; return false;
} }
return mode == MatchAll; return true;
} else {
String text = argTexts;
boost::smatch what;
return boost::regex_search(text.GetData(), what, expr);
}
} }
bool ScriptUtils::Match(const std::vector<Value>& args) bool ScriptUtils::Match(const std::vector<Value>& args)
@ -156,10 +160,8 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified."));
Array::Ptr texts = new Array();
String pattern = args[0]; String pattern = args[0];
Value argTexts = args[1]; const Value& argTexts = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -167,17 +169,17 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argTexts.IsObjectType<Array>()) Array::Ptr texts;
if (argTexts.IsObject())
texts = argTexts; texts = argTexts;
else {
texts = new Array(); if (texts) {
texts->Add(argTexts); ObjectLock olock(texts);
}
if (texts->GetLength() == 0) if (texts->GetLength() == 0)
return false; return false;
ObjectLock olock(texts);
for (const String& text : texts) { for (const String& text : texts) {
bool res = Utility::Match(pattern, text); bool res = Utility::Match(pattern, text);
@ -187,7 +189,11 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
return false; return false;
} }
return mode == MatchAll; return true;
} else {
String text = argTexts;
return Utility::Match(pattern, argTexts);
}
} }
bool ScriptUtils::CidrMatch(const std::vector<Value>& args) bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
@ -195,10 +201,8 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified."));
Array::Ptr ips = new Array();
String pattern = args[0]; String pattern = args[0];
Value argIps = args[1]; const Value& argIps = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -206,17 +210,17 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argIps.IsObjectType<Array>()) Array::Ptr ips;
if (argIps.IsObject())
ips = argIps; ips = argIps;
else {
ips = new Array(); if (ips) {
ips->Add(argIps); ObjectLock olock(ips);
}
if (ips->GetLength() == 0) if (ips->GetLength() == 0)
return false; return false;
ObjectLock olock(ips);
for (const String& ip : ips) { for (const String& ip : ips) {
bool res = Utility::CidrMatch(pattern, ip); bool res = Utility::CidrMatch(pattern, ip);
@ -226,7 +230,11 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
return false; return false;
} }
return mode == MatchAll; return true;
} else {
String ip = argIps;
return Utility::CidrMatch(pattern, ip);
}
} }
double ScriptUtils::Len(const Value& value) double ScriptUtils::Len(const Value& value)