move string utils in namespace utils::string

This commit is contained in:
badaix 2017-06-05 12:48:59 +02:00
parent b8f69ce58f
commit fa3f78b08d
12 changed files with 178 additions and 133 deletions

View file

@ -171,7 +171,7 @@ int main (int argc, char **argv)
if (userValue.getValue().empty()) if (userValue.getValue().empty())
std::invalid_argument("user must not be empty"); std::invalid_argument("user must not be empty");
vector<string> user_group = split(userValue.getValue(), ':'); vector<string> user_group = utils::string::split(userValue.getValue(), ':');
user = user_group[0]; user = user_group[0];
if (user_group.size() > 1) if (user_group.size() > 1)
group = user_group[1]; group = user_group[1];

View file

@ -22,6 +22,7 @@
#include "sampleFormat.h" #include "sampleFormat.h"
#include "common/strCompat.h" #include "common/strCompat.h"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
#include "common/log.h" #include "common/log.h"
@ -57,7 +58,7 @@ string SampleFormat::getFormat() const
void SampleFormat::setFormat(const std::string& format) void SampleFormat::setFormat(const std::string& format)
{ {
std::vector<std::string> strs; std::vector<std::string> strs;
strs = split(format, ':'); strs = utils::string::split(format, ':');
if (strs.size() == 3) if (strs.size() == 3)
setFormat( setFormat(
cpt::stoul(strs[0]), cpt::stoul(strs[0]),

View file

@ -20,8 +20,8 @@
#define UTILS_H #define UTILS_H
#include "common/strCompat.h" #include "common/strCompat.h"
#include "common/utils/string_utils.h"
#include <algorithm>
#include <functional> #include <functional>
#include <cctype> #include <cctype>
#include <locale> #include <locale>
@ -51,94 +51,11 @@
#endif #endif
// trim from start namespace strutils = utils::string;
static inline std::string &ltrim(std::string &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
static inline std::string &rtrim(std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
static inline std::string &trim(std::string &s)
{
return ltrim(rtrim(s));
}
// trim from start
static inline std::string ltrim_copy(const std::string &s)
{
std::string str(s);
return ltrim(str);
}
// trim from end
static inline std::string rtrim_copy(const std::string &s)
{
std::string str(s);
return rtrim(str);
}
// trim from both ends
static inline std::string trim_copy(const std::string &s)
{
std::string str(s);
return trim(str);
}
// decode %xx to char
static std::string uriDecode(const std::string& src) {
std::string ret;
char ch;
for (size_t i=0; i<src.length(); i++)
{
if (int(src[i]) == 37)
{
unsigned int ii;
sscanf(src.substr(i+1, 2).c_str(), "%x", &ii);
ch = static_cast<char>(ii);
ret += ch;
i += 2;
}
else
{
ret += src[i];
}
}
return (ret);
}
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
static std::vector<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
static int mkdirRecursive(const char *path, mode_t mode) static int mkdirRecursive(const char *path, mode_t mode)
{ {
std::vector<std::string> pathes = split(path, '/'); std::vector<std::string> pathes = strutils::split(path, '/');
std::stringstream ss; std::stringstream ss;
int res = 0; int res = 0;
for (const auto& p: pathes) for (const auto& p: pathes)
@ -166,7 +83,7 @@ static std::string execGetOutput(const std::string& cmd)
if (fgets(buffer, 1024, pipe.get()) != NULL) if (fgets(buffer, 1024, pipe.get()) != NULL)
result += buffer; result += buffer;
} }
return trim(result); return strutils::trim(result);
} }
@ -182,18 +99,18 @@ static std::string getOS()
{ {
std::string os; std::string os;
#ifdef ANDROID #ifdef ANDROID
os = trim_copy("Android " + getProp("ro.build.version.release")); os = strutils::trim_copy("Android " + getProp("ro.build.version.release"));
#else #else
os = execGetOutput("lsb_release -d"); os = execGetOutput("lsb_release -d");
if ((os.find(":") != std::string::npos) && (os.find("lsb_release") == std::string::npos)) if ((os.find(":") != std::string::npos) && (os.find("lsb_release") == std::string::npos))
os = trim_copy(os.substr(os.find(":") + 1)); os = strutils::trim_copy(os.substr(os.find(":") + 1));
#endif #endif
if (os.empty()) if (os.empty())
{ {
os = trim_copy(execGetOutput("grep /etc/os-release /etc/openwrt_release -e PRETTY_NAME -e DISTRIB_DESCRIPTION")); os = strutils::trim_copy(execGetOutput("grep /etc/os-release /etc/openwrt_release -e PRETTY_NAME -e DISTRIB_DESCRIPTION"));
if (os.find("=") != std::string::npos) if (os.find("=") != std::string::npos)
{ {
os = trim_copy(os.substr(os.find("=") + 1)); os = strutils::trim_copy(os.substr(os.find("=") + 1));
os.erase(std::remove(os.begin(), os.end(), '"'), os.end()); os.erase(std::remove(os.begin(), os.end(), '"'), os.end());
os.erase(std::remove(os.begin(), os.end(), '\''), os.end()); os.erase(std::remove(os.begin(), os.end(), '\''), os.end());
} }
@ -204,7 +121,7 @@ static std::string getOS()
uname(&u); uname(&u);
os = u.sysname; os = u.sysname;
} }
return trim_copy(os); return strutils::trim_copy(os);
} }
@ -235,7 +152,7 @@ static std::string getArch()
arch = execGetOutput("uname -i"); arch = execGetOutput("uname -i");
if (arch.empty() || (arch == "unknown")) if (arch.empty() || (arch == "unknown"))
arch = execGetOutput("uname -m"); arch = execGetOutput("uname -m");
return trim_copy(arch); return strutils::trim_copy(arch);
} }
@ -249,7 +166,7 @@ static long uptime()
std::string uptime = execGetOutput("sysctl kern.boottime"); std::string uptime = execGetOutput("sysctl kern.boottime");
if ((uptime.find(" sec = ") != std::string::npos) && (uptime.find(",") != std::string::npos)) if ((uptime.find(" sec = ") != std::string::npos) && (uptime.find(",") != std::string::npos))
{ {
uptime = trim_copy(uptime.substr(uptime.find(" sec = ") + 7)); uptime = strutils::trim_copy(uptime.substr(uptime.find(" sec = ") + 7));
uptime.resize(uptime.find(",")); uptime.resize(uptime.find(","));
timeval now; timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
@ -361,7 +278,7 @@ static std::string getMacAddress(int sock)
std::string line; std::string line;
if (infile.good() && std::getline(infile, line)) if (infile.good() && std::getline(infile, line))
{ {
trim(line); strutils::trim(line);
if ((line.size() == 17) && (line[2] == ':')) if ((line.size() == 17) && (line[2] == ':'))
return line; return line;
} }
@ -391,6 +308,22 @@ static std::string getMacAddress(int sock)
} }
static std::string getClientId(const std::string defaultId = "")
{
std::string result = defaultId;
if (!result.empty())
return result;
#ifdef ANDROID
result = getProp("ro.serialno");
if (!result.empty())
return result;
#endif
return getHostName();
}
#endif #endif

103
common/utils/string_utils.h Normal file
View file

@ -0,0 +1,103 @@
#ifndef STRING_UTILS_H
#define STRING_UTILS_H
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
namespace utils
{
namespace string
{
// trim from start
static inline std::string &ltrim(std::string &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
static inline std::string &rtrim(std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
static inline std::string &trim(std::string &s)
{
return ltrim(rtrim(s));
}
// trim from start
static inline std::string ltrim_copy(const std::string &s)
{
std::string str(s);
return ltrim(str);
}
// trim from end
static inline std::string rtrim_copy(const std::string &s)
{
std::string str(s);
return rtrim(str);
}
// trim from both ends
static inline std::string trim_copy(const std::string &s)
{
std::string str(s);
return trim(str);
}
// decode %xx to char
static std::string uriDecode(const std::string& src) {
std::string ret;
char ch;
for (size_t i=0; i<src.length(); i++)
{
if (int(src[i]) == 37)
{
unsigned int ii;
sscanf(src.substr(i+1, 2).c_str(), "%x", &ii);
ch = static_cast<char>(ii);
ret += ch;
i += 2;
}
else
{
ret += src[i];
}
}
return (ret);
}
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
static std::vector<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
} // namespace string
} // namespace utils
#endif

View file

@ -24,9 +24,11 @@
#include <vector> #include <vector>
#include <sys/time.h> #include <sys/time.h>
#include "externals/json.hpp" #include "externals/json.hpp"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
namespace strutils = utils::string;
using json = nlohmann::json; using json = nlohmann::json;
struct ClientInfo; struct ClientInfo;
@ -93,11 +95,11 @@ struct Host
void fromJson(const json& j) void fromJson(const json& j)
{ {
name = trim_copy(jGet<std::string>(j, "name", "")); name = strutils::trim_copy(jGet<std::string>(j, "name", ""));
mac = trim_copy(jGet<std::string>(j, "mac", "")); mac = strutils::trim_copy(jGet<std::string>(j, "mac", ""));
os = trim_copy(jGet<std::string>(j, "os", "")); os = strutils::trim_copy(jGet<std::string>(j, "os", ""));
arch = trim_copy(jGet<std::string>(j, "arch", "")); arch = strutils::trim_copy(jGet<std::string>(j, "arch", ""));
ip = trim_copy(jGet<std::string>(j, "ip", "")); ip = strutils::trim_copy(jGet<std::string>(j, "ip", ""));
} }
json toJson() json toJson()
@ -127,7 +129,7 @@ struct ClientConfig
void fromJson(const json& j) void fromJson(const json& j)
{ {
name = trim_copy(jGet<std::string>(j, "name", "")); name = strutils::trim_copy(jGet<std::string>(j, "name", ""));
volume.fromJson(j["volume"]); volume.fromJson(j["volume"]);
latency = jGet<int32_t>(j, "latency", 0); latency = jGet<int32_t>(j, "latency", 0);
instance = jGet<size_t>(j, "instance", 1); instance = jGet<size_t>(j, "instance", 1);
@ -136,7 +138,7 @@ struct ClientConfig
json toJson() json toJson()
{ {
json j; json j;
j["name"] = trim_copy(name); j["name"] = strutils::trim_copy(name);
j["volume"] = volume.toJson(); j["volume"] = volume.toJson();
j["latency"] = latency; j["latency"] = latency;
j["instance"] = instance; j["instance"] = instance;
@ -163,16 +165,16 @@ struct Snapcast
virtual void fromJson(const json& j) virtual void fromJson(const json& j)
{ {
name = trim_copy(jGet<std::string>(j, "name", "")); name = strutils::trim_copy(jGet<std::string>(j, "name", ""));
version = trim_copy(jGet<std::string>(j, "version", "")); version = strutils::trim_copy(jGet<std::string>(j, "version", ""));
protocolVersion = jGet<int>(j, "protocolVersion", 1); protocolVersion = jGet<int>(j, "protocolVersion", 1);
} }
virtual json toJson() virtual json toJson()
{ {
json j; json j;
j["name"] = trim_copy(name); j["name"] = strutils::trim_copy(name);
j["version"] = trim_copy(version); j["version"] = strutils::trim_copy(version);
j["protocolVersion"] = protocolVersion; j["protocolVersion"] = protocolVersion;
return j; return j;
} }
@ -266,9 +268,9 @@ struct Group
void fromJson(const json& j) void fromJson(const json& j)
{ {
name = trim_copy(jGet<std::string>(j, "name", "")); name = strutils::trim_copy(jGet<std::string>(j, "name", ""));
id = trim_copy(jGet<std::string>(j, "id", "")); id = strutils::trim_copy(jGet<std::string>(j, "id", ""));
streamId = trim_copy(jGet<std::string>(j, "stream_id", "")); streamId = strutils::trim_copy(jGet<std::string>(j, "stream_id", ""));
muted = jGet<bool>(j, "muted", false); muted = jGet<bool>(j, "muted", false);
clients.clear(); clients.clear();
if (j.count("clients")) if (j.count("clients"))
@ -286,9 +288,9 @@ struct Group
json toJson() json toJson()
{ {
json j; json j;
j["name"] = trim_copy(name); j["name"] = strutils::trim_copy(name);
j["id"] = trim_copy(id); j["id"] = strutils::trim_copy(id);
j["stream_id"] = trim_copy(streamId); j["stream_id"] = strutils::trim_copy(streamId);
j["muted"] = muted; j["muted"] = muted;
json jClients = json::array(); json jClients = json::array();

View file

@ -20,7 +20,7 @@
#include "pcmEncoder.h" #include "pcmEncoder.h"
#include "oggEncoder.h" #include "oggEncoder.h"
#include "flacEncoder.h" #include "flacEncoder.h"
#include "common/utils.h" #include "common/utils/string_utils.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/log.h" #include "common/log.h"
@ -35,8 +35,8 @@ Encoder* EncoderFactory::createEncoder(const std::string& codecSettings) const
std::string codecOptions; std::string codecOptions;
if (codec.find(":") != std::string::npos) if (codec.find(":") != std::string::npos)
{ {
codecOptions = trim_copy(codec.substr(codec.find(":") + 1)); codecOptions = utils::string::trim_copy(codec.substr(codec.find(":") + 1));
codec = trim_copy(codec.substr(0, codec.find(":"))); codec = utils::string::trim_copy(codec.substr(0, codec.find(":")));
} }
if (codec == "ogg") if (codec == "ogg")
encoder = new OggEncoder(codecOptions); encoder = new OggEncoder(codecOptions);

View file

@ -22,6 +22,7 @@
#include "oggEncoder.h" #include "oggEncoder.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/strCompat.h" #include "common/strCompat.h"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
#include "common/log.h" #include "common/log.h"
@ -144,11 +145,11 @@ void OggEncoder::initEncoder()
{ {
if (codecOptions_.find(":") == string::npos) if (codecOptions_.find(":") == string::npos)
throw SnapException("Invalid codec options: \"" + codecOptions_ + "\""); throw SnapException("Invalid codec options: \"" + codecOptions_ + "\"");
string mode = trim_copy(codecOptions_.substr(0, codecOptions_.find(":"))); string mode = utils::string::trim_copy(codecOptions_.substr(0, codecOptions_.find(":")));
if (mode != "VBR") if (mode != "VBR")
throw SnapException("Unsupported codec mode: \"" + mode + "\". Available: \"VBR\""); throw SnapException("Unsupported codec mode: \"" + mode + "\". Available: \"VBR\"");
string qual = trim_copy(codecOptions_.substr(codecOptions_.find(":") + 1)); string qual = utils::string::trim_copy(codecOptions_.substr(codecOptions_.find(":") + 1));
double quality = 1.0; double quality = 1.0;
try try
{ {

View file

@ -25,6 +25,7 @@
#include "common/daemon.h" #include "common/daemon.h"
#endif #endif
#include "common/timeDefs.h" #include "common/timeDefs.h"
#include "common/utils/string_utils.h"
#include "common/signalHandler.h" #include "common/signalHandler.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/sampleFormat.h" #include "common/sampleFormat.h"
@ -157,7 +158,7 @@ int main(int argc, char* argv[])
if (userValue.getValue().empty()) if (userValue.getValue().empty())
std::invalid_argument("user must not be empty"); std::invalid_argument("user must not be empty");
vector<string> user_group = split(userValue.getValue(), ':'); vector<string> user_group = utils::string::split(userValue.getValue(), ':');
user = user_group[0]; user = user_group[0];
if (user_group.size() > 1) if (user_group.size() > 1)
group = user_group[1]; group = user_group[1];

View file

@ -18,6 +18,7 @@
#include "airplayStream.h" #include "airplayStream.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
#include "common/log.h" #include "common/log.h"
@ -68,7 +69,7 @@ void AirplayStream::initExeAndPath(const std::string& filename)
void AirplayStream::onStderrMsg(const char* buffer, size_t n) void AirplayStream::onStderrMsg(const char* buffer, size_t n)
{ {
string logmsg = trim_copy(string(buffer, n)); string logmsg = utils::string::trim_copy(string(buffer, n));
if (logmsg.empty()) if (logmsg.empty())
return; return;
logO << "(" << getName() << ") " << logmsg << "\n"; logO << "(" << getName() << ") " << logmsg << "\n";

View file

@ -22,6 +22,7 @@
#include <fcntl.h> #include <fcntl.h>
#include "processStream.h" #include "processStream.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
#include "common/log.h" #include "common/log.h"
@ -120,7 +121,7 @@ void ProcessStream::onStderrMsg(const char* buffer, size_t n)
{ {
if (logStderr_) if (logStderr_)
{ {
string line = trim_copy(string(buffer, n)); string line = utils::string::trim_copy(string(buffer, n));
if ((line.find('\0') == string::npos) && !line.empty()) if ((line.find('\0') == string::npos) && !line.empty())
logO << "(" << getName() << ") " << line << "\n"; logO << "(" << getName() << ") " << line << "\n";
} }

View file

@ -18,6 +18,7 @@
#include "spotifyStream.h" #include "spotifyStream.h"
#include "common/snapException.h" #include "common/snapException.h"
#include "common/utils/string_utils.h"
#include "common/utils.h" #include "common/utils.h"
#include "common/log.h" #include "common/log.h"
@ -101,7 +102,7 @@ void SpotifyStream::onStderrMsg(const char* buffer, size_t n)
// 2016-11-03 09-00-18 [out] INFO:librespot::session: Connecting to AP lon3-accesspoint-a34.ap.spotify.com:443 // 2016-11-03 09-00-18 [out] INFO:librespot::session: Connecting to AP lon3-accesspoint-a34.ap.spotify.com:443
// 2016-11-03 09-00-18 [out] INFO:librespot::session: Authenticated ! // 2016-11-03 09-00-18 [out] INFO:librespot::session: Authenticated !
watchdog_->trigger(); watchdog_->trigger();
string logmsg = trim_copy(string(buffer, n)); string logmsg = utils::string::trim_copy(string(buffer, n));
if ((logmsg.find("allocated stream") == string::npos) && if ((logmsg.find("allocated stream") == string::npos) &&
(logmsg.find("Got channel") == string::npos) && (logmsg.find("Got channel") == string::npos) &&
(logmsg.find('\0') == string::npos) && (logmsg.find('\0') == string::npos) &&

View file

@ -17,12 +17,13 @@
***/ ***/
#include "streamUri.h" #include "streamUri.h"
#include "common/utils.h" #include "common/utils/string_utils.h"
#include "common/strCompat.h" #include "common/strCompat.h"
#include "common/log.h" #include "common/log.h"
using namespace std; using namespace std;
namespace strutils = utils::string;
StreamUri::StreamUri(const std::string& streamUri) StreamUri::StreamUri(const std::string& streamUri)
@ -32,13 +33,13 @@ StreamUri::StreamUri(const std::string& streamUri)
// would be more elegant with regex. Not yet supported on my dev machine's gcc 4.8 :( // would be more elegant with regex. Not yet supported on my dev machine's gcc 4.8 :(
logD << "StreamUri: " << streamUri << "\n"; logD << "StreamUri: " << streamUri << "\n";
size_t pos; size_t pos;
uri = trim_copy(streamUri); uri = strutils::trim_copy(streamUri);
while (!uri.empty() && ((uri[0] == '\'') || (uri[0] == '"'))) while (!uri.empty() && ((uri[0] == '\'') || (uri[0] == '"')))
uri = uri.substr(1); uri = uri.substr(1);
while (!uri.empty() && ((uri[uri.length()-1] == '\'') || (uri[uri.length()-1] == '"'))) while (!uri.empty() && ((uri[uri.length()-1] == '\'') || (uri[uri.length()-1] == '"')))
uri = uri.substr(0, this->uri.length()-1); uri = uri.substr(0, this->uri.length()-1);
string decodedUri = uriDecode(uri); string decodedUri = strutils::uriDecode(uri);
logD << "StreamUri: " << decodedUri << "\n"; logD << "StreamUri: " << decodedUri << "\n";
string tmp(decodedUri); string tmp(decodedUri);
@ -46,7 +47,7 @@ StreamUri::StreamUri(const std::string& streamUri)
pos = tmp.find(':'); pos = tmp.find(':');
if (pos == string::npos) if (pos == string::npos)
throw invalid_argument("missing ':'"); throw invalid_argument("missing ':'");
scheme = trim_copy(tmp.substr(0, pos)); scheme = strutils::trim_copy(tmp.substr(0, pos));
tmp = tmp.substr(pos + 1); tmp = tmp.substr(pos + 1);
logD << "scheme: '" << scheme << "' tmp: '" << tmp << "'\n"; logD << "scheme: '" << scheme << "' tmp: '" << tmp << "'\n";
@ -57,7 +58,7 @@ StreamUri::StreamUri(const std::string& streamUri)
pos = tmp.find('/'); pos = tmp.find('/');
if (pos == string::npos) if (pos == string::npos)
throw invalid_argument("missing path separator: '/'"); throw invalid_argument("missing path separator: '/'");
host = trim_copy(tmp.substr(0, pos)); host = strutils::trim_copy(tmp.substr(0, pos));
tmp = tmp.substr(pos); tmp = tmp.substr(pos);
path = tmp; path = tmp;
logD << "host: '" << host << "' tmp: '" << tmp << "' path: '" << path << "'\n"; logD << "host: '" << host << "' tmp: '" << tmp << "' path: '" << path << "'\n";
@ -66,7 +67,7 @@ StreamUri::StreamUri(const std::string& streamUri)
if (pos == string::npos) if (pos == string::npos)
return; return;
path = trim_copy(tmp.substr(0, pos)); path = strutils::trim_copy(tmp.substr(0, pos));
tmp = tmp.substr(pos + 1); tmp = tmp.substr(pos + 1);
string queryStr = tmp; string queryStr = tmp;
logD << "path: '" << path << "' tmp: '" << tmp << "' query: '" << queryStr << "'\n"; logD << "path: '" << path << "' tmp: '" << tmp << "' query: '" << queryStr << "'\n";
@ -76,18 +77,18 @@ StreamUri::StreamUri(const std::string& streamUri)
{ {
queryStr = tmp.substr(0, pos); queryStr = tmp.substr(0, pos);
tmp = tmp.substr(pos + 1); tmp = tmp.substr(pos + 1);
fragment = trim_copy(tmp); fragment = strutils::trim_copy(tmp);
logD << "query: '" << queryStr << "' fragment: '" << fragment << "' tmp: '" << tmp << "'\n"; logD << "query: '" << queryStr << "' fragment: '" << fragment << "' tmp: '" << tmp << "'\n";
} }
vector<string> keyValueList = split(queryStr, '&'); vector<string> keyValueList = strutils::split(queryStr, '&');
for (auto& kv: keyValueList) for (auto& kv: keyValueList)
{ {
pos = kv.find('='); pos = kv.find('=');
if (pos != string::npos) if (pos != string::npos)
{ {
string key = trim_copy(kv.substr(0, pos)); string key = strutils::trim_copy(kv.substr(0, pos));
string value = trim_copy(kv.substr(pos+1)); string value = strutils::trim_copy(kv.substr(pos+1));
query[key] = value; query[key] = value;
} }
} }