Rewritten util::split and added its iterator version.

Iterator based functions util::startsWith, util::endsWith,
util::streq, util::strieq were added.
pull/2/head
Tatsuhiro Tsujikawa 2011-11-04 22:27:58 +09:00
parent 6267676e8b
commit f84d2253b2
29 changed files with 841 additions and 194 deletions

View File

@ -589,16 +589,19 @@ namespace {
bool inNoProxy(const SharedHandle<Request>& req,
const std::string& noProxy)
{
std::vector<std::string> entries;
util::split(noProxy, std::back_inserter(entries), ",", true);
std::vector<Scip> entries;
util::splitIter(noProxy.begin(), noProxy.end(), std::back_inserter(entries),
',', true);
if(entries.empty()) {
return false;
}
for(std::vector<std::string>::const_iterator i = entries.begin(),
for(std::vector<Scip>::const_iterator i = entries.begin(),
eoi = entries.end(); i != eoi; ++i) {
std::string::size_type slashpos = (*i).find('/');
if(slashpos == std::string::npos) {
if(util::noProxyDomainMatch(req->getHost(), *i)) {
std::string::const_iterator slashpos =
std::find((*i).first, (*i).second, '/');
if(slashpos == (*i).second) {
if(util::noProxyDomainMatch
(req->getHost(), std::string((*i).first, (*i).second))) {
return true;
}
} else {
@ -606,9 +609,9 @@ bool inNoProxy(const SharedHandle<Request>& req,
// implementation is that we should first resolve
// hostname(which may result in several IP addresses) and
// evaluates against all of them
std::string ip = (*i).substr(0, slashpos);
std::string ip((*i).first, slashpos);
uint32_t bits;
if(!util::parseUIntNoThrow(bits, (*i).begin()+slashpos+1, (*i).end())) {
if(!util::parseUIntNoThrow(bits, slashpos+1, (*i).second)) {
continue;
}
if(util::inSameCidrBlock(ip, req->getHost(), bits)) {

View File

@ -97,6 +97,12 @@ public:
void setName(const std::string& name);
template<typename InputIterator>
void setName(InputIterator first, InputIterator last)
{
name_.assign(first, last);
}
const std::string& getValue() const
{
return value_;
@ -104,6 +110,12 @@ public:
void setValue(const std::string& value);
template<typename InputIterator>
void setValue(InputIterator first, InputIterator last)
{
value_.assign(first, last);
}
time_t getExpiryTime() const
{
return expiryTime_;
@ -131,6 +143,12 @@ public:
void setDomain(const std::string& domain);
template<typename InputIterator>
void setDomain(InputIterator first, InputIterator last)
{
domain_.assign(first, last);
}
bool getHostOnly() const
{
return hostOnly_;
@ -148,6 +166,12 @@ public:
void setPath(const std::string& path);
template<typename InputIterator>
void setPath(InputIterator first, InputIterator last)
{
path_.assign(first, last);
}
bool getSecure() const
{
return secure_;

View File

@ -210,11 +210,19 @@ bool CookieStorage::parseAndStore
struct CookiePathDivider {
Cookie cookie_;
int pathDepth_;
CookiePathDivider(const Cookie& cookie):cookie_(cookie)
CookiePathDivider(const Cookie& cookie):cookie_(cookie), pathDepth_(0)
{
std::vector<std::string> paths;
util::split(cookie_.getPath(), std::back_inserter(paths), A2STR::SLASH_C);
pathDepth_ = paths.size();
const std::string& path = cookie_.getPath();
if(!path.empty()) {
for(size_t i = 1, len = path.size(); i < len; ++i) {
if(path[i] == '/' && path[i-1] != '/') {
++pathDepth_;
}
}
if(path[path.size()-1] != '/') {
++pathDepth_;
}
}
}
};
@ -302,14 +310,14 @@ std::vector<Cookie> CookieStorage::criteriaFind
(requestHost, domains_.begin(), domains_.end(), std::back_inserter(res),
requestHost, requestPath, now, secure);
} else {
std::vector<std::string> levels;
util::split(requestHost, std::back_inserter(levels),A2STR::DOT_C);
std::reverse(levels.begin(), levels.end());
std::vector<Scip> levels;
util::splitIter(requestHost.begin(), requestHost.end(),
std::back_inserter(levels), '.');
std::string domain;
for(std::vector<std::string>::const_iterator i =
levels.begin(), eoi = levels.end();
for(std::vector<Scip>::const_reverse_iterator i =
levels.rbegin(), eoi = levels.rend();
i != eoi; ++i, domain.insert(domain.begin(), '.')) {
domain.insert(domain.begin(), (*i).begin(), (*i).end());
domain.insert(domain.begin(), (*i).first, (*i).second);
searchCookieByDomainSuffix
(domain, domains_.begin(), domains_.end(),
std::back_inserter(res), requestHost, requestPath, now, secure);

View File

@ -487,12 +487,13 @@ unsigned int FtpConnection::receiveEpsvResponse(uint16_t& port)
leftParen > rightParen) {
return response.first;
}
std::vector<std::string> rd;
util::split(response.second.substr(leftParen+1, rightParen-(leftParen+1)),
std::back_inserter(rd), "|", true, true);
std::vector<Scip> rd;
util::splitIter(response.second.begin()+leftParen+1,
response.second.begin()+rightParen,
std::back_inserter(rd), '|', true, true);
uint32_t portTemp = 0;
if(rd.size() == 5 &&
util::parseUIntNoThrow(portTemp, rd[3].begin(), rd[3].end())) {
util::parseUIntNoThrow(portTemp, rd[3].first, rd[3].second)) {
if(0 < portTemp && portTemp <= UINT16_MAX) {
port = portTemp;
}

View File

@ -270,9 +270,9 @@ bool FtpNegotiationCommand::sendCwdPrep()
{
// Calling setReadCheckSocket() is needed when the socket is reused,
setReadCheckSocket(getSocket());
util::split(getRequest()->getDir(), std::back_inserter(cwdDirs_),
A2STR::SLASH_C);
cwdDirs_.push_front(ftp_->getBaseWorkingDir());
util::split(getRequest()->getDir().begin(), getRequest()->getDir().end(),
std::back_inserter(cwdDirs_), '/');
sequence_ = SEQ_SEND_CWD;
return true;
}

View File

@ -95,6 +95,12 @@ public:
void setVersion(const std::string& version);
template<typename InputIterator>
void setVersion(InputIterator first, InputIterator last)
{
version_.assign(first, last);
}
const std::string& getMethod() const
{
return method_;
@ -102,6 +108,12 @@ public:
void setMethod(const std::string& method);
template<typename InputIterator>
void setMethod(InputIterator first, InputIterator last)
{
method_.assign(first, last);
}
const std::string& getRequestPath() const
{
return requestPath_;
@ -109,6 +121,12 @@ public:
void setRequestPath(const std::string& requestPath);
template<typename InputIterator>
void setRequestPath(InputIterator first, InputIterator last)
{
requestPath_.assign(first, last);
}
void fill
(std::string::const_iterator first,
std::string::const_iterator last);

View File

@ -139,16 +139,17 @@ SharedHandle<HttpHeader> HttpHeaderProcessor::getHttpRequestHeader()
delimpos < 14) {
throw DL_RETRY_EX(EX_NO_STATUS_HEADER);
}
std::vector<std::string> firstLine;
util::split(buf_.substr(0, delimpos), std::back_inserter(firstLine)," ",true);
std::vector<Scip> firstLine;
util::splitIter(buf_.begin(), buf_.begin()+delimpos,
std::back_inserter(firstLine), ' ', true);
if(firstLine.size() != 3) {
throw DL_ABORT_EX2("Malformed HTTP request header.",
error_code::HTTP_PROTOCOL_ERROR);
}
SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpHeader->setMethod(firstLine[0]);
httpHeader->setRequestPath(firstLine[1]);
httpHeader->setVersion(firstLine[2]);
httpHeader->setMethod(firstLine[0].first, firstLine[0].second);
httpHeader->setRequestPath(firstLine[1].first, firstLine[1].second);
httpHeader->setVersion(firstLine[2].first, firstLine[2].second);
if((delimpos = buf_.find("\r\n\r\n")) == std::string::npos &&
(delimpos = buf_.find("\n\n")) == std::string::npos) {
delimpos = buf_.size();

View File

@ -317,9 +317,8 @@ void HttpRequest::disableContentEncoding()
void HttpRequest::addHeader(const std::string& headersString)
{
std::vector<std::string> headers;
util::split(headersString, std::back_inserter(headers), "\n", true);
headers_.insert(headers_.end(), headers.begin(), headers.end());
util::split(headersString.begin(), headersString.end(),
std::back_inserter(headers_), '\n', true);
}
void HttpRequest::clearHeader()

View File

@ -378,8 +378,12 @@ void HttpResponse::getMetalinKHttpEntries
if(!result.empty()) {
std::vector<std::string> locs;
if(option->defined(PREF_METALINK_LOCATION)) {
util::split(util::toLower(option->get(PREF_METALINK_LOCATION)),
std::back_inserter(locs), ",", true);
const std::string& loc = option->get(PREF_METALINK_LOCATION);
util::split(loc.begin(), loc.end(), std::back_inserter(locs), ',', true);
for(std::vector<std::string>::iterator i = locs.begin(), eoi = locs.end();
i != eoi; ++i) {
util::lowercase(*i);
}
}
for(std::vector<MetalinkHttpEntry>::iterator i = result.begin(),
eoi = result.end(); i != eoi; ++i) {

View File

@ -49,6 +49,7 @@
#include "fmt.h"
#include "SocketRecvBuffer.h"
#include "TimeA2.h"
#include "array_fun.h"
namespace aria2 {
@ -99,12 +100,20 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
(lastRequestHeader_->getVersion() == HttpHeader::HTTP_1_1 ||
connection.find("keep-alive") != std::string::npos);
std::vector<std::string> acceptEncodings;
util::split(lastRequestHeader_->getFirst(HttpHeader::ACCEPT_ENCODING),
std::back_inserter(acceptEncodings), A2STR::COMMA_C, true);
acceptsGZip_ =
std::find(acceptEncodings.begin(), acceptEncodings.end(), "gzip")
!= acceptEncodings.end();
std::vector<Scip> acceptEncodings;
const std::string& acceptEnc =
lastRequestHeader_->getFirst(HttpHeader::ACCEPT_ENCODING);
util::splitIter(acceptEnc.begin(), acceptEnc.end(),
std::back_inserter(acceptEncodings), ',', true);
const char A2_GZIP[] = "gzip";
acceptsGZip_ = false;
for(std::vector<Scip>::const_iterator i = acceptEncodings.begin(),
eoi = acceptEncodings.end(); i != eoi; ++i) {
if(util::streq((*i).first, (*i).second, A2_GZIP, vend(A2_GZIP)-1)) {
acceptsGZip_ = true;
break;
}
}
return header;
} else {
socketRecvBuffer_->clearBuffer();
@ -209,20 +218,18 @@ bool HttpServer::authenticate()
}
std::pair<Scip, Scip> p;
util::divide(p, authHeader.begin(), authHeader.end(), ' ');
const char authMethod[] = "Basic";
if(!std::distance(p.first.first, p.first.second) == sizeof(authMethod) ||
!std::equal(p.first.first, p.first.second, &authMethod[0])) {
const char A2_AUTHMETHOD[] = "Basic";
if(!util::streq(p.first.first, p.first.second,
A2_AUTHMETHOD, vend(A2_AUTHMETHOD)-1)) {
return false;
}
std::string userpass = Base64::decode(std::string(p.second.first,
p.second.second));
util::divide(p, userpass.begin(), userpass.end(), ':');
return username_.size() ==
static_cast<size_t>(std::distance(p.first.first, p.first.second)) &&
std::equal(username_.begin(), username_.end(), p.first.first) &&
password_.size() ==
static_cast<size_t>(std::distance(p.second.first, p.second.second)) &&
std::equal(password_.begin(), password_.end(), p.second.first);
return util::streq(p.first.first, p.first.second,
username_.begin(), username_.end()) &&
util::streq(p.second.first, p.second.second,
password_.begin(), password_.end());
}
void HttpServer::setUsernamePassword

View File

@ -156,8 +156,13 @@ Metalink2RequestGroup::createRequestGroup
}
std::vector<std::string> locations;
if(optionTemplate->defined(PREF_METALINK_LOCATION)) {
util::split(util::toLower(optionTemplate->get(PREF_METALINK_LOCATION)),
std::back_inserter(locations), ",", true);
const std::string& loc = optionTemplate->get(PREF_METALINK_LOCATION);
util::split(loc.begin(), loc.end(),
std::back_inserter(locations), ',', true);
for(std::vector<std::string>::iterator i = locations.begin(),
eoi = locations.end(); i != eoi; ++i) {
util::lowercase(*i);
}
}
std::string preferredProtocol;
if(optionTemplate->get(PREF_METALINK_PREFERRED_PROTOCOL) != V_NONE) {

View File

@ -99,9 +99,9 @@ namespace {
ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
{
std::vector<std::string> servers;
util::split(serversOpt,
util::split(serversOpt.begin(), serversOpt.end(),
std::back_inserter(servers),
A2STR::COMMA_C,
',',
true /* doStrip */);
ares_addr_node root;
root.next = 0;

View File

@ -43,6 +43,7 @@
#include "A2STR.h"
#include "util.h"
#include "BufferedFile.h"
#include "array_fun.h"
namespace aria2 {
@ -152,44 +153,58 @@ void Netrc::parse(const std::string& path)
if(util::startsWith(line, "#")) {
continue;
}
std::vector<std::string> tokens;
util::split(line, std::back_inserter(tokens), " \t", true);
for(std::vector<std::string>::const_iterator iter = tokens.begin(),
std::vector<Scip> tokens;
const char A2_DELIMS[] = " \t";
util::splitIterM(line.begin(), line.end(), std::back_inserter(tokens),
A2_DELIMS, vend(A2_DELIMS)-1, true);
const char A2_MACHINE[] = "machine";
const char A2_DEFAULT[] = "default";
const char A2_LOGIN[] = "login";
const char A2_PASSWORD[] = "password";
const char A2_ACCOUNT[] = "account";
const char A2_MACDEF[] = "macdef";
for(std::vector<Scip>::const_iterator iter = tokens.begin(),
eoi = tokens.end(); iter != eoi; ++iter) {
const std::string& token = *iter;
if(state == GET_TOKEN) {
if(token == "machine") {
if(util::streq((*iter).first, (*iter).second,
A2_MACHINE, vend(A2_MACHINE)-1)) {
storeAuthenticator(authenticator);
authenticator.reset(new Authenticator());
state = SET_MACHINE;
} else if(token == "default") {
} else if(util::streq((*iter).first, (*iter).second,
A2_DEFAULT, vend(A2_DEFAULT)-1)) {
storeAuthenticator(authenticator);
authenticator.reset(new DefaultAuthenticator());
} else {
if(!authenticator) {
throw DL_ABORT_EX
(fmt("Netrc:parse error. %s encounterd where 'machine'"
" or 'default' expected.", token.c_str()));
" or 'default' expected.",
std::string((*iter).first, (*iter).second).c_str()));
}
if(token == "login") {
if(util::streq((*iter).first, (*iter).second,
A2_LOGIN, vend(A2_LOGIN)-1)) {
state = SET_LOGIN;
} else if(token == "password") {
} else if(util::streq((*iter).first, (*iter).second,
A2_PASSWORD, vend(A2_PASSWORD)-1)) {
state = SET_PASSWORD;
} else if(token == "account") {
} else if(util::streq((*iter).first, (*iter).second,
A2_ACCOUNT, vend(A2_ACCOUNT)-1)) {
state = SET_ACCOUNT;
} else if(token == "macdef") {
} else if(util::streq((*iter).first, (*iter).second,
A2_MACDEF, vend(A2_MACDEF)-1)) {
state = SET_MACDEF;
}
}
} else {
if(state == SET_MACHINE) {
authenticator->setMachine(token);
authenticator->setMachine((*iter).first, (*iter).second);
} else if(state == SET_LOGIN) {
authenticator->setLogin(token);
authenticator->setLogin((*iter).first, (*iter).second);
} else if(state == SET_PASSWORD) {
authenticator->setPassword(token);
authenticator->setPassword((*iter).first, (*iter).second);
} else if(state == SET_ACCOUNT) {
authenticator->setAccount(token);
authenticator->setAccount((*iter).first, (*iter).second);
} else if(state == SET_MACDEF) {
skipMacdef(fp);
}

View File

@ -76,6 +76,12 @@ public:
void setMachine(const std::string& machine);
template<typename InputIterator>
void setMachine(InputIterator first, InputIterator last)
{
machine_.assign(first, last);
}
const std::string& getLogin() const
{
return login_;
@ -83,6 +89,12 @@ public:
void setLogin(const std::string& login);
template<typename InputIterator>
void setLogin(InputIterator first, InputIterator last)
{
login_.assign(first, last);
}
const std::string& getPassword() const
{
return password_;
@ -90,12 +102,24 @@ public:
void setPassword(const std::string& password);
template<typename InputIterator>
void setPassword(InputIterator first, InputIterator last)
{
password_.assign(first, last);
}
const std::string& getAccount() const
{
return account_;
}
void setAccount(const std::string& account);
template<typename InputIterator>
void setAccount(InputIterator first, InputIterator last)
{
account_.assign(first, last);
}
};
class DefaultAuthenticator : public Authenticator {

View File

@ -45,6 +45,7 @@
#include "Cookie.h"
#include "cookie_helper.h"
#include "BufferedFile.h"
#include "array_fun.h"
namespace aria2 {
@ -52,26 +53,23 @@ NsCookieParser::NsCookieParser() {}
NsCookieParser::~NsCookieParser() {}
namespace {
const std::string C_TRUE("TRUE");
} // namespace
namespace {
bool parseNsCookie
(Cookie& cookie, const std::string& nsCookieStr, time_t creationTime)
{
std::vector<std::string> vs;
util::split(nsCookieStr, std::back_inserter(vs), "\t", true);
std::vector<Scip> vs;
util::splitIter(nsCookieStr.begin(), nsCookieStr.end(),
std::back_inserter(vs), '\t', true);
if(vs.size() < 6) {
return false;
}
std::string cookieDomain = cookie::removePrecedingDots(vs[0]);
if(vs[5].empty() || cookieDomain.empty() ||
!cookie::goodPath(vs[2].begin(), vs[2].end())) {
vs[0].first = util::lstripIter(vs[0].first, vs[0].second, '.');
if(vs[5].first == vs[5].second || vs[0].first == vs[0].second ||
!cookie::goodPath(vs[2].first, vs[2].second)) {
return false;
}
int64_t expiryTime;
if(!util::parseLLIntNoThrow(expiryTime, vs[4].begin(), vs[4].end())) {
if(!util::parseLLIntNoThrow(expiryTime, vs[4].first, vs[4].second)) {
return false;
}
if(std::numeric_limits<time_t>::max() < expiryTime) {
@ -79,16 +77,24 @@ bool parseNsCookie
} else if(std::numeric_limits<time_t>::min() > expiryTime) {
expiryTime = std::numeric_limits<time_t>::min();
}
cookie.setName(vs[5]);
cookie.setValue(vs.size() >= 7? vs[6]:A2STR::NIL);
cookie.setName(vs[5].first, vs[5].second);
if(vs.size() >= 7) {
cookie.setValue(vs[6].first, vs[6].second);
} else {
cookie.setValue(A2STR::NIL.begin(), A2STR::NIL.end());
}
cookie.setExpiryTime(expiryTime == 0?
std::numeric_limits<time_t>::max():expiryTime);
// aria2 treats expiryTime == 0 means session cookie.
cookie.setPersistent(expiryTime != 0);
cookie.setDomain(cookieDomain);
cookie.setHostOnly(util::isNumericHost(cookieDomain) || vs[1] != C_TRUE);
cookie.setPath(vs[2]);
cookie.setSecure(vs[3] == C_TRUE);
cookie.setDomain(vs[0].first, vs[0].second);
const char C_TRUE[] = "TRUE";
cookie.setHostOnly(util::isNumericHost(cookie.getDomain()) ||
!util::streq(vs[1].first, vs[1].second,
C_TRUE, vend(C_TRUE)-1));
cookie.setPath(vs[2].first, vs[2].second);
cookie.setSecure(util::streq(vs[3].first, vs[3].second,
C_TRUE, vend(C_TRUE)-1));
cookie.setCreationTime(creationTime);
return true;
}

View File

@ -92,8 +92,8 @@ ParameterizedStringParser::createSelect(const std::string& src, int& offset)
throw DL_ABORT_EX("Missing '}' in the parameterized string.");
}
std::vector<std::string> values;
util::split(src.substr(offset, rightParenIndex-offset),
std::back_inserter(values), ",", true);
util::split(src.begin()+offset, src.begin()+rightParenIndex,
std::back_inserter(values), ',', true);
if(values.empty()) {
throw DL_ABORT_EX("Empty {} is not allowed.");
}

View File

@ -155,13 +155,13 @@ bool ServerStatMan::load(const std::string& filename)
continue;
}
std::string line(p.first, p.second);
std::vector<std::string> items;
util::split(line, std::back_inserter(items), ",");
std::vector<Scip> items;
util::splitIter(line.begin(), line.end(), std::back_inserter(items), ',');
std::map<std::string, std::string> m;
for(std::vector<std::string>::const_iterator i = items.begin(),
for(std::vector<Scip>::const_iterator i = items.begin(),
eoi = items.end(); i != eoi; ++i) {
std::pair<Scip, Scip> p;
util::divide(p, (*i).begin(), (*i).end(), '=');
util::divide(p, (*i).first, (*i).second, '=');
m[std::string(p.first.first, p.first.second)] =
std::string(p.second.first, p.second.second);
}

View File

@ -85,8 +85,9 @@ bool writeOption(BufferedFile& fp, const SharedHandle<Option>& op)
const SharedHandle<OptionHandler>& h = oparser->find(pref);
if(h && h->getInitialOption() && op->defined(pref)) {
if(h->getCumulative()) {
const std::string& val = op->get(pref);
std::vector<std::string> v;
util::split(op->get(pref), std::back_inserter(v), "\n",
util::split(val.begin(), val.end(), std::back_inserter(v), '\n',
false, false);
for(std::vector<std::string>::const_iterator j = v.begin(),
eoj = v.end(); j != eoj; ++j) {

View File

@ -100,14 +100,17 @@ bool parseTime(int64_t& time, InputIterator first, InputIterator last)
namespace {
int cookieRowMapper(void* data, int columns, char** values, char** names)
{
if(columns != 7) {
if(columns != 7 || !values[0] || !values[1] || !values[4]) {
return 0;
}
std::vector<Cookie>& cookies =
*reinterpret_cast<std::vector<Cookie>*>(data);
std::string cookieDomain = cookie::removePrecedingDots(toString(values[0]));
std::string cookieName = toString(values[4]);
std::string cookiePath = toString(values[1]);
size_t val0len = strlen(values[0]);
std::string cookieDomain
(util::lstripIter(&values[0][0], &values[0][val0len], '.'),
&values[0][val0len]);
std::string cookieName(&values[4][0], &values[4][strlen(values[4])]);
std::string cookiePath(&values[1][0], &values[1][strlen(values[1])]);
if(cookieName.empty() || cookieDomain.empty() ||
!cookie::goodPath(cookiePath.begin(), cookiePath.end())) {
return 0;

View File

@ -66,7 +66,8 @@ void UriListParser::parseNext(std::vector<std::string>& uris, Option& op)
const SharedHandle<OptionParser>& optparser = OptionParser::getInstance();
while(1) {
if(!util::startsWith(line_, A2STR::SHARP_C) && !util::strip(line_).empty()){
util::split(line_, std::back_inserter(uris), "\t", true);
util::split(line_.begin(), line_.end(), std::back_inserter(uris),
'\t', true);
// Read options
std::stringstream ss;
while(1) {

View File

@ -1036,10 +1036,12 @@ void adjustAnnounceUri
{
std::vector<std::string> excludeUris;
std::vector<std::string> addUris;
util::split(option->get(PREF_BT_EXCLUDE_TRACKER),
std::back_inserter(excludeUris), A2STR::COMMA_C, true);
util::split(option->get(PREF_BT_TRACKER),
std::back_inserter(addUris), A2STR::COMMA_C, true);
const std::string& exTracker = option->get(PREF_BT_EXCLUDE_TRACKER);
util::split(exTracker.begin(), exTracker.end(),
std::back_inserter(excludeUris), ',', true);
const std::string& btTracker = option->get(PREF_BT_TRACKER);
util::split(btTracker.begin(), btTracker.end(),
std::back_inserter(addUris), ',', true);
removeAnnounceUri(attrs, excludeUris);
addAnnounceUri(attrs, addUris);
}

View File

@ -352,14 +352,6 @@ bool parse
return true;
}
std::string removePrecedingDots(const std::string& host)
{
std::string::const_iterator noDot = host.begin();
std::string::const_iterator end = host.end();
for(; noDot != end && *noDot == '.'; ++noDot);
return std::string(noDot, end);
}
bool goodPath
(std::string::const_iterator first,
std::string::const_iterator last)

View File

@ -59,8 +59,6 @@ bool parse
const std::string& defaultPath,
time_t creationTime);
std::string removePrecedingDots(const std::string& host);
bool goodPath
(std::string::const_iterator first,
std::string::const_iterator last);

View File

@ -620,21 +620,30 @@ decodeGetParams(const std::string& query)
Scip method;
Scip id;
Scip params;
std::vector<std::string> getParams;
util::split(query.substr(1), std::back_inserter(getParams), "&");
for(std::vector<std::string>::const_iterator i =
std::vector<Scip> getParams;
util::splitIter(query.begin()+1, query.end(), std::back_inserter(getParams),
'&');
const char A2_METHOD[] = "method=";
const char A2_ID[] = "id=";
const char A2_PARAMS[] = "params=";
const char A2_JSONCB[] = "jsoncallback=";
for(std::vector<Scip>::const_iterator i =
getParams.begin(), eoi = getParams.end(); i != eoi; ++i) {
if(util::startsWith(*i, "method=")) {
method.first = (*i).begin()+7;
method.second = (*i).end();
} else if(util::startsWith(*i, "id=")) {
id.first = (*i).begin()+3;
id.second = (*i).end();
} else if(util::startsWith(*i, "params=")) {
params.first = (*i).begin()+7;
params.second = (*i).end();
} else if(util::startsWith(*i, "jsoncallback=")) {
callback.assign((*i).begin()+13, (*i).end());
if(util::startsWith((*i).first, (*i).second,
A2_METHOD, vend(A2_METHOD)-1)) {
method.first = (*i).first+7;
method.second = (*i).second;
} else if(util::startsWith((*i).first, (*i).second,
A2_ID, vend(A2_ID)-1)) {
id.first = (*i).first+3;
id.second = (*i).second;
} else if(util::startsWith((*i).first, (*i).second,
A2_PARAMS, vend(A2_PARAMS)-1)) {
params.first = (*i).first+7;
params.second = (*i).second;
} else if(util::startsWith((*i).first, (*i).second,
A2_JSONCB, vend(A2_JSONCB)-1)) {
callback.assign((*i).first+13, (*i).second);
}
}
std::string jsonParam =

View File

@ -46,15 +46,15 @@ SharedHandle<Dict> parse(const std::string& magnet)
return dict;
}
dict.reset(new Dict());
std::vector<std::string> queries;
util::split(std::string(magnet.begin()+8, magnet.end()),
std::back_inserter(queries), "&");
for(std::vector<std::string>::const_iterator i = queries.begin(),
std::vector<Scip> queries;
util::splitIter(magnet.begin()+8, magnet.end(), std::back_inserter(queries),
'&');
for(std::vector<Scip>::const_iterator i = queries.begin(),
eoi = queries.end(); i != eoi; ++i) {
std::string::const_iterator eq = std::find((*i).begin(), (*i).end(), '=');
std::string name((*i).begin(), eq);
std::string value =
eq == (*i).end() ? "" : util::percentDecode(eq+1, (*i).end());
std::pair<Scip, Scip> p;
util::divide(p, (*i).first, (*i).second, '=');
std::string name(p.first.first, p.first.second);
std::string value(util::percentDecode(p.second.first, p.second.second));
List* l = downcast<List>(dict->get(name));
if(l) {
l->append(String::g(value));

View File

@ -307,7 +307,8 @@ std::string joinUri(const std::string& baseUri, const std::string& uri)
}
std::vector<std::string> parts;
if(!util::startsWith(uri, "/")) {
util::split(bus.dir, std::back_inserter(parts), "/");
util::split(bus.dir.begin(), bus.dir.end(), std::back_inserter(parts),
'/');
}
std::string::const_iterator qend;
for(qend = uri.begin(); qend != uri.end(); ++qend) {
@ -321,15 +322,13 @@ std::string joinUri(const std::string& baseUri, const std::string& uri)
break;
}
}
std::string path(uri.begin(), end);
util::split(path, std::back_inserter(parts), "/");
util::split(uri.begin(), end, std::back_inserter(parts), '/');
bus.dir.clear();
bus.file.clear();
bus.query.clear();
std::string res = construct(bus);
res += util::joinPath(parts.begin(), parts.end());
if((path.empty() || util::endsWith(path, "/")) &&
!util::endsWith(res, "/")) {
if((uri.begin() == end || *(end-1) == '/') && *(res.end()-1) != '/') {
res += "/";
}
res.append(end, qend);

View File

@ -687,26 +687,31 @@ void parsePrioritizePieceRange
uint64_t defaultSize)
{
std::vector<size_t> indexes;
std::vector<std::string> parts;
split(src, std::back_inserter(parts), ",", true);
for(std::vector<std::string>::const_iterator i = parts.begin(),
std::vector<Scip> parts;
const char A2_HEAD[] = "head";
const char A2_HEADEQ[] = "head=";
const char A2_TAIL[] = "tail";
const char A2_TAILEQ[] = "tail=";
splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true);
for(std::vector<Scip>::const_iterator i = parts.begin(),
eoi = parts.end(); i != eoi; ++i) {
if((*i) == "head") {
if(util::streq((*i).first, (*i).second, A2_HEAD, vend(A2_HEAD)-1)) {
computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
} else if(util::startsWith(*i, "head=")) {
std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
(*i).end());
} else if(util::startsWith((*i).first, (*i).second,
A2_HEADEQ, vend(A2_HEADEQ)-1)) {
std::string sizestr((*i).first+5, (*i).second);
computeHeadPieces(indexes, fileEntries, pieceLength,
std::max((int64_t)0, getRealSize(sizestr)));
} else if((*i) == "tail") {
} else if(util::streq((*i).first, (*i).second, A2_TAIL, vend(A2_TAIL)-1)) {
computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
} else if(util::startsWith(*i, "tail=")) {
std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
(*i).end());
} else if(util::startsWith((*i).first, (*i).second,
A2_TAILEQ, vend(A2_TAILEQ)-1)) {
std::string sizestr((*i).first+5, (*i).second);
computeTailPieces(indexes, fileEntries, pieceLength,
std::max((int64_t)0, getRealSize(sizestr)));
} else {
throw DL_ABORT_EX(fmt("Unrecognized token %s", (*i).c_str()));
throw DL_ABORT_EX(fmt("Unrecognized token %s",
std::string((*i).first, (*i).second).c_str()));
}
}
std::sort(indexes.begin(), indexes.end());
@ -802,16 +807,15 @@ std::string getContentDispositionFilename(const std::string& header)
if(markeritr == param.end() || *markeritr != '=') {
continue;
}
std::string value(markeritr+1, param.end());
std::vector<std::string> extValues;
split(value, std::back_inserter(extValues), "'", true, true);
std::vector<Scip> extValues;
splitIter(markeritr+1, param.end(), std::back_inserter(extValues),
'\'', true, true);
if(extValues.size() != 3) {
continue;
}
bool bad = false;
const std::string& charset = extValues[0];
for(std::string::const_iterator j = charset.begin(), eoi = charset.end();
j != eoi; ++j) {
for(std::string::const_iterator j = extValues[0].first,
eoj = extValues[0].second; j != eoj; ++j) {
// Since we first split parameter by ', we can safely assume
// that ' is not included in charset.
if(!inRFC2978MIMECharset(*j)) {
@ -823,12 +827,11 @@ std::string getContentDispositionFilename(const std::string& header)
continue;
}
bad = false;
value = extValues[2];
for(std::string::const_iterator j = value.begin(), eoi = value.end();
j != eoi; ++j){
for(std::string::const_iterator j = extValues[2].first,
eoj = extValues[2].second; j != eoj; ++j){
if(*j == '%') {
if(j+1 != value.end() && isHexDigit(*(j+1)) &&
j+2 != value.end() && isHexDigit(*(j+2))) {
if(j+1 != eoj && isHexDigit(*(j+1)) &&
j+2 != eoj && isHexDigit(*(j+2))) {
j += 2;
} else {
bad = true;
@ -844,8 +847,11 @@ std::string getContentDispositionFilename(const std::string& header)
if(bad) {
continue;
}
value = percentDecode(value.begin(), value.end());
if(toLower(extValues[0]) == "iso-8859-1") {
std::string value =
percentDecode(extValues[2].first, extValues[2].second);
const char A2_ISO88591[] = "iso-8859-1";
if(util::strieq(extValues[0].first, extValues[0].second,
A2_ISO88591, vend(A2_ISO88591)-1)) {
value = iso8859ToUtf8(value);
}
if(!detectDirTraversal(value) &&

View File

@ -177,6 +177,31 @@ std::pair<InputIterator, InputIterator> stripIter
return std::make_pair(first, left+1);
}
template<typename InputIterator>
InputIterator lstripIter
(InputIterator first, InputIterator last, char ch)
{
for(; first != last && *first == ch; ++first);
return first;
}
template<typename InputIterator, typename InputIterator2>
InputIterator lstripIter
(InputIterator first, InputIterator last,
InputIterator2 cfirst, InputIterator2 clast)
{
for(; first != last && std::find(cfirst, clast, *first) != clast; ++first);
return first;
}
template<typename InputIterator>
InputIterator lstripIter
(InputIterator first, InputIterator last)
{
return lstripIter(first, last,
DEFAULT_STRIP_CHARSET.begin(), DEFAULT_STRIP_CHARSET.end());
}
std::string strip
(const std::string& str, const std::string& chars = DEFAULT_STRIP_CHARSET);
@ -526,22 +551,86 @@ parseIndexPath(const std::string& line);
std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i);
/**
* Take a string src which is a delimited list and add its elements
* into result. result is stored in out.
* Take a string [first, last) which is a delimited list and add its
* elements into result as iterator pair. result is stored in out.
*/
template<typename OutputIterator>
OutputIterator split(const std::string& src, OutputIterator out,
const std::string& delims, bool doStrip = false,
bool allowEmpty = false)
template<typename InputIterator, typename OutputIterator>
OutputIterator splitIter
(InputIterator first,
InputIterator last,
OutputIterator out,
char delim,
bool doStrip = false,
bool allowEmpty = false)
{
std::string::const_iterator first = src.begin();
std::string::const_iterator last = src.end();
for(std::string::const_iterator i = first; i != last;) {
std::string::const_iterator j = i;
for(; j != last &&
std::find(delims.begin(), delims.end(), *j) == delims.end(); ++j);
std::pair<std::string::const_iterator,
std::string::const_iterator> p(i, j);
for(InputIterator i = first; i != last;) {
InputIterator j = std::find(i, last, delim);
std::pair<InputIterator, InputIterator> p(i, j);
if(doStrip) {
p = stripIter(i, j);
}
if(allowEmpty || p.first != p.second) {
*out++ = p;
}
i = j;
if(j != last) {
++i;
}
}
if(allowEmpty &&
(first == last || *(last-1) == delim)) {
*out++ = std::make_pair(last, last);
}
return out;
}
template<typename InputIterator,
typename InputIterator2,
typename OutputIterator>
OutputIterator splitIterM
(InputIterator first,
InputIterator last,
OutputIterator out,
InputIterator2 dfirst,
InputIterator2 dlast,
bool doStrip = false,
bool allowEmpty = false)
{
for(InputIterator i = first; i != last;) {
InputIterator j = i;
for(; j != last && std::find(dfirst, dlast, *j) == dlast; ++j);
std::pair<InputIterator, InputIterator> p(i, j);
if(doStrip) {
p = stripIter(i, j);
}
if(allowEmpty || p.first != p.second) {
*out++ = p;
}
i = j;
if(j != last) {
++i;
}
}
if(allowEmpty &&
(first == last ||
std::find(dfirst, dlast, *(last-1)) != dlast)) {
*out++ = std::make_pair(last, last);
}
return out;
}
template<typename InputIterator, typename OutputIterator>
OutputIterator split
(InputIterator first,
InputIterator last,
OutputIterator out,
char delim,
bool doStrip = false,
bool allowEmpty = false)
{
for(InputIterator i = first; i != last;) {
InputIterator j = std::find(i, last, delim);
std::pair<InputIterator, InputIterator> p(i, j);
if(doStrip) {
p = stripIter(i, j);
}
@ -554,14 +643,77 @@ OutputIterator split(const std::string& src, OutputIterator out,
}
}
if(allowEmpty &&
(src.empty() ||
std::find(delims.begin(), delims.end(),
src[src.size()-1]) != delims.end())) {
*out++ = A2STR::NIL;
(first == last || *(last-1) == delim)) {
*out++ = std::string(last, last);
}
return out;
}
template<typename InputIterator1, typename InputIterator2>
bool streq
(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2)
{
if(last1-first1 != last2-first2) {
return false;
}
return std::equal(first1, last1, first2);
}
template<typename InputIterator1, typename InputIterator2>
bool strieq
(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2)
{
if(last1-first1 != last2-first2) {
return false;
}
for(; first1 != last1; ++first1, ++first2) {
char c1 = *first1;
char c2 = *first2;
if('A' <= c1 && c1 <= 'Z') {
c1 = c1-'A'+'a';
}
if('A' <= c2 && c2 <= 'Z') {
c2 = c2-'A'+'a';
}
if(c1 != c2) {
return false;
}
}
return true;
}
template<typename InputIterator1, typename InputIterator2>
bool startsWith
(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2)
{
if(last1-first1 < last2-first2) {
return false;
}
return std::equal(first2, last2, first1);
}
template<typename InputIterator1, typename InputIterator2>
bool endsWith
(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2)
{
if(last1-first1 < last2-first2) {
return false;
}
return std::equal(first2, last2, last1-(last2-first2));
}
void generateRandomData(unsigned char* data, size_t length);
// Saves data to file whose name is filename. If overwrite is true,

View File

@ -24,8 +24,14 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(UtilTest);
CPPUNIT_TEST(testStrip);
CPPUNIT_TEST(testStripIter);
CPPUNIT_TEST(testLstripIter);
CPPUNIT_TEST(testLstripIter_char);
CPPUNIT_TEST(testDivide);
CPPUNIT_TEST(testSplit);
CPPUNIT_TEST(testSplitIter);
CPPUNIT_TEST(testSplitIterM);
CPPUNIT_TEST(testStreq);
CPPUNIT_TEST(testStrieq);
CPPUNIT_TEST(testEndsWith);
CPPUNIT_TEST(testReplace);
CPPUNIT_TEST(testStartsWith);
@ -85,8 +91,14 @@ public:
void testStrip();
void testStripIter();
void testLstripIter();
void testLstripIter_char();
void testDivide();
void testSplit();
void testSplitIter();
void testSplitIterM();
void testStreq();
void testStrieq();
void testEndsWith();
void testReplace();
void testStartsWith();
@ -211,6 +223,46 @@ void UtilTest::testStripIter()
CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
}
void UtilTest::testLstripIter()
{
std::string::iterator r;
std::string s = "foo";
r = util::lstripIter(s.begin(), s.end());
CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string(r, s.end()));
s = " foo bar ";
r = util::lstripIter(s.begin(), s.end());
CPPUNIT_ASSERT_EQUAL(std::string("foo bar "), std::string(r, s.end()));
s = "f";
r = util::lstripIter(s.begin(), s.end());
CPPUNIT_ASSERT_EQUAL(std::string("f"), std::string(r, s.end()));
s = "foo ";
r = util::lstripIter(s.begin(), s.end());
CPPUNIT_ASSERT_EQUAL(std::string("foo "), std::string(r, s.end()));
}
void UtilTest::testLstripIter_char()
{
std::string::iterator r;
std::string s = "foo";
r = util::lstripIter(s.begin(), s.end(), '$');
CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string(r, s.end()));
s = "$$foo$bar$$";
r = util::lstripIter(s.begin(), s.end(), '$');
CPPUNIT_ASSERT_EQUAL(std::string("foo$bar$$"), std::string(r, s.end()));
s = "f";
r = util::lstripIter(s.begin(), s.end(), '$');
CPPUNIT_ASSERT_EQUAL(std::string("f"), std::string(r, s.end()));
s = "foo$$";
r = util::lstripIter(s.begin(), s.end(), '$');
CPPUNIT_ASSERT_EQUAL(std::string("foo$$"), std::string(r, s.end()));
}
void UtilTest::testDivide() {
std::pair<Scip, Scip> p1;
std::string s = "name=value";
@ -247,7 +299,8 @@ void UtilTest::testDivide() {
void UtilTest::testSplit() {
std::vector<std::string> v;
util::split("k1; k2;; k3", std::back_inserter(v), ";", true);
std::string s = "k1; k2;; k3";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', true);
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
std::vector<std::string>::iterator itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
@ -256,8 +309,8 @@ void UtilTest::testSplit() {
v.clear();
util::split("k1; k2; k3",
std::back_inserter(v), ";");
s = "k1; k2; k3";
util::split(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
@ -266,14 +319,16 @@ void UtilTest::testSplit() {
v.clear();
util::split("k=v", std::back_inserter(v), ";", false, true);
s = "k=v";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string("k=v"), *itr++);
v.clear();
util::split(";;k1;;k2;", std::back_inserter(v), ";", false, true);
s = ";;k1;;k2;";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
@ -285,7 +340,8 @@ void UtilTest::testSplit() {
v.clear();
util::split(";;k1;;k2;", std::back_inserter(v), ";");
s = ";;k1;;k2;";
util::split(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
@ -293,7 +349,8 @@ void UtilTest::testSplit() {
v.clear();
util::split("k; ", std::back_inserter(v), ";");
s = "k; ";
util::split(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string("k"), *itr++);
@ -301,29 +358,34 @@ void UtilTest::testSplit() {
v.clear();
util::split(" ", std::back_inserter(v), ";", true, true);
s = " ";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', true, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), v[0]);
v.clear();
util::split(" ", std::back_inserter(v), ";", true);
s = " ";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', true);
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
util::split(" ", std::back_inserter(v), ";");
s = " ";
util::split(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(" "), v[0]);
v.clear();
util::split(";", std::back_inserter(v), ";");
s = ";";
util::split(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
util::split(";", std::back_inserter(v), ";", false, true);
s = ";";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
itr = v.begin();
CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
@ -331,43 +393,337 @@ void UtilTest::testSplit() {
v.clear();
util::split("", std::back_inserter(v), ";", false, true);
s = "";
util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), v[0]);
}
void UtilTest::testSplitIter() {
std::vector<Scip> v;
std::string s = "k1; k2;; k3";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true);
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
v.clear();
s = "k1; k2; k3";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(" k2"),
std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string(" k3"),
std::string(v[2].first, v[2].second));
v.clear();
s = "k=v";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k=v"),
std::string(v[0].first, v[0].second));
v.clear();
s = ";;k1;;k2;";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[2].first, v[2].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[4].first, v[4].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
v.clear();
s = ";;k1;;k2;";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
v.clear();
s = "k; ";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[1].first, v[1].second));
v.clear();
s = " ";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
v.clear();
s = " ";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true);
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
s = " ";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[0].first, v[0].second));
v.clear();
s = ";";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
s = ";";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
v.clear();
s = "";
util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
}
void UtilTest::testSplitIterM() {
std::string d = ";";
std::string md = "; ";
std::vector<Scip> v;
std::string s = "k1; k2;; k3";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), true);
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
v.clear();
s = "k1; k2; k3";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end());
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(" k2"),
std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string(" k3"),
std::string(v[2].first, v[2].second));
v.clear();
s = "k1; k2; k3";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
md.begin(), md.end());
CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
v.clear();
s = "k1; k2; k3;";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
md.begin(), md.end(), false, true);
CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[2].first, v[2].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[4].first, v[4].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
v.clear();
s = "k=v";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k=v"),
std::string(v[0].first, v[0].second));
v.clear();
s = ";;k1;;k2;";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), false, true);
CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[2].first, v[2].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[4].first, v[4].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
v.clear();
s = ";;k1;;k2;";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end());
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
v.clear();
s = "k; ";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end());
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string("k"), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[1].first, v[1].second));
v.clear();
s = " ";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), true, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
v.clear();
s = " ";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), true);
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
s = " ";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end());
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[0].first, v[0].second));
v.clear();
s = ";";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end());
CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
v.clear();
s = ";";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), false, true);
CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
v.clear();
s = "";
util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
d.begin(), d.end(), false, true);
CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
}
void UtilTest::testEndsWith() {
std::string target = "abcdefg";
std::string part = "fg";
CPPUNIT_ASSERT(util::endsWith(target, part));
CPPUNIT_ASSERT(util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "abdefg";
part = "g";
CPPUNIT_ASSERT(util::endsWith(target, part));
CPPUNIT_ASSERT(util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "abdefg";
part = "eg";
CPPUNIT_ASSERT(!util::endsWith(target, part));
CPPUNIT_ASSERT(!util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "g";
part = "eg";
CPPUNIT_ASSERT(!util::endsWith(target, part));
CPPUNIT_ASSERT(!util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "g";
part = "g";
CPPUNIT_ASSERT(util::endsWith(target, part));
CPPUNIT_ASSERT(util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "g";
part = "";
CPPUNIT_ASSERT(util::endsWith(target, part));
CPPUNIT_ASSERT(util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "";
part = "";
CPPUNIT_ASSERT(util::endsWith(target, part));
CPPUNIT_ASSERT(util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "";
part = "g";
CPPUNIT_ASSERT(!util::endsWith(target, part));
CPPUNIT_ASSERT(!util::endsWith(target.begin(), target.end(),
part.begin(), part.end()));
}
void UtilTest::testStreq()
{
std::string s1, s2;
s1 = "foo";
s2 = "foo";
CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "fooo";
CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "fo";
CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "";
CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s1 = "";
CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
}
void UtilTest::testStrieq()
{
std::string s1, s2;
s1 = "foo";
s2 = "foo";
CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s1 = "FoO";
s2 = "fOo";
CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "fooo";
CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "fo";
CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s2 = "";
CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
s1 = "";
CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
}
void UtilTest::testReplace() {
@ -385,31 +741,44 @@ void UtilTest::testStartsWith() {
target = "abcdefg";
part = "abc";
CPPUNIT_ASSERT(util::startsWith(target, part));
CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "abcdefg";
part = "abx";
CPPUNIT_ASSERT(!util::startsWith(target, part));
CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "abcdefg";
part = "bcd";
CPPUNIT_ASSERT(!util::startsWith(target, part));
CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "";
part = "a";
CPPUNIT_ASSERT(!util::startsWith(target, part));
CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "";
part = "";
CPPUNIT_ASSERT(util::startsWith(target, part));
CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "a";
part = "";
CPPUNIT_ASSERT(util::startsWith(target, part));
CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
target = "a";
part = "a";
CPPUNIT_ASSERT(util::startsWith(target, part));
CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(),
part.begin(), part.end()));
}
void UtilTest::testGetContentDispositionFilename() {