ソースを参照

Removed static const char[] as much as possible.

Provided convenient functions for streq, strieq, startsWith,
istartsWith, endsWith, iendsWith to support this move.
Tatsuhiro Tsujikawa 13 年 前
コミット
9331f6a43d

+ 2 - 7
src/HttpConnection.cc

@@ -83,18 +83,13 @@ HttpConnection::~HttpConnection() {}
 
 std::string HttpConnection::eraseConfidentialInfo(const std::string& request)
 {
-  static const char A2_AUTH_HEADER[] = "Authorization: Basic";
-  static const char A2_PROXY_AUTH_HEADER[] = "Proxy-Authorization: Basic";
   std::istringstream istr(request);
   std::string result;
   std::string line;
   while(getline(istr, line)) {
-    if(util::startsWith(line.begin(), line.end(),
-                        A2_AUTH_HEADER, vend(A2_AUTH_HEADER)-1)) {
+    if(util::startsWith(line, "Authorization: Basic")) {
       result += "Authorization: Basic ********\n";
-    } else if(util::startsWith(line.begin(), line.end(),
-                               A2_PROXY_AUTH_HEADER,
-                               vend(A2_PROXY_AUTH_HEADER)-1)) {
+    } else if(util::startsWith(line, "Proxy-Authorization: Basic")) {
       result += "Proxy-Authorization: Basic ********\n";
     } else {
       result += line;

+ 2 - 6
src/HttpRequest.cc

@@ -444,14 +444,10 @@ bool HttpRequest::conditionalRequest() const
   if(!ifModSinceHeader_.empty()) {
     return true;
   }
-  static const char A2_IF_MOD_SINCE[] = "if-modified-since";
-  static const char A2_IF_NONE_MATCH[] = "if-none-match";
   for(std::vector<std::string>::const_iterator i = headers_.begin(),
         eoi = headers_.end(); i != eoi; ++i) {
-    if(util::istartsWith((*i).begin(), (*i).end(),
-                        A2_IF_MOD_SINCE, vend(A2_IF_MOD_SINCE)-1) ||
-       util::istartsWith((*i).begin(), (*i).end(),
-                        A2_IF_NONE_MATCH, vend(A2_IF_NONE_MATCH)-1)) {
+    if(util::istartsWith(*i, "if-modified-since") ||
+       util::istartsWith(*i, "if-none-match")) {
       return true;
     }
   }

+ 1 - 3
src/HttpServer.cc

@@ -235,9 +235,7 @@ bool HttpServer::authenticate()
   }
   std::pair<Scip, Scip> p;
   util::divide(p, authHeader.begin(), authHeader.end(), ' ');
-  static const char A2_AUTHMETHOD[] = "Basic";
-  if(!util::streq(p.first.first, p.first.second,
-                  A2_AUTHMETHOD, vend(A2_AUTHMETHOD)-1)) {
+  if(!util::streq(p.first.first, p.first.second, "Basic")) {
     return false;
   }
   std::string userpass = base64::decode(p.second.first, p.second.second);

+ 8 - 21
src/Netrc.cc

@@ -154,25 +154,16 @@ void Netrc::parse(const std::string& path)
       continue;
     }
     std::vector<Scip> tokens;
-    static const char A2_DELIMS[] = " \t";
-    util::splitIterM(&buf[0], &buf[len], std::back_inserter(tokens),
-                     A2_DELIMS, vend(A2_DELIMS)-1, true);
-    static const char A2_MACHINE[] = "machine";
-    static const char A2_DEFAULT[] = "default";
-    static const char A2_LOGIN[] = "login";
-    static const char A2_PASSWORD[] = "password";
-    static const char A2_ACCOUNT[] = "account";
-    static const char A2_MACDEF[] = "macdef";
+    util::splitIterM(&buf[0], &buf[len], std::back_inserter(tokens), " \t",
+                     true);
     for(std::vector<Scip>::const_iterator iter = tokens.begin(),
           eoi = tokens.end(); iter != eoi; ++iter) {
       if(state == GET_TOKEN) {
-        if(util::streq((*iter).first, (*iter).second,
-                       A2_MACHINE, vend(A2_MACHINE)-1)) {
+        if(util::streq((*iter).first, (*iter).second, "machine")) {
           storeAuthenticator(authenticator);
           authenticator.reset(new Authenticator());
           state = SET_MACHINE;
-        } else if(util::streq((*iter).first, (*iter).second,
-                              A2_DEFAULT, vend(A2_DEFAULT)-1)) {
+        } else if(util::streq((*iter).first, (*iter).second, "default")) {
           storeAuthenticator(authenticator);
           authenticator.reset(new DefaultAuthenticator());
         } else {
@@ -182,17 +173,13 @@ void Netrc::parse(const std::string& path)
                    " or 'default' expected.",
                    std::string((*iter).first, (*iter).second).c_str()));
           }
-          if(util::streq((*iter).first, (*iter).second,
-                         A2_LOGIN, vend(A2_LOGIN)-1)) {
+          if(util::streq((*iter).first, (*iter).second, "login")) {
             state = SET_LOGIN;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_PASSWORD, vend(A2_PASSWORD)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "password")) {
             state = SET_PASSWORD;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_ACCOUNT, vend(A2_ACCOUNT)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "account")) {
             state = SET_ACCOUNT;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_MACDEF, vend(A2_MACDEF)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "macdef")) {
             state = SET_MACDEF;
           }
         }

+ 2 - 5
src/NsCookieParser.cc

@@ -88,13 +88,10 @@ bool parseNsCookie
   // aria2 treats expiryTime == 0 means session cookie.
   cookie.setPersistent(expiryTime != 0);
   cookie.setDomain(vs[0].first, vs[0].second);
-  static 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));
+                     !util::streq(vs[1].first, vs[1].second, "TRUE"));
   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.setSecure(util::streq(vs[3].first, vs[3].second, "TRUE"));
   cookie.setCreationTime(creationTime);
   return true;
 }

+ 3 - 9
src/OptionHandlerImpl.cc

@@ -528,15 +528,9 @@ void HttpProxyOptionHandler::parseArg(Option& option, const std::string& optarg)
     option.put(pref_, optarg);
   } else {
     std::string uri;
-    static const char A2_HTTP[] = "http://";
-    static const char A2_HTTPS[] = "https://";
-    static const char A2_FTP[] = "ftp://";
-    if(util::startsWith(optarg.begin(), optarg.end(),
-                        A2_HTTP, vend(A2_HTTP)-1) ||
-       util::startsWith(optarg.begin(), optarg.end(),
-                        A2_HTTPS, vend(A2_HTTPS)-1) ||
-       util::startsWith(optarg.begin(), optarg.end(),
-                        A2_FTP, vend(A2_FTP)-1)) {
+    if(util::startsWith(optarg.begin(), optarg.end(), "http://") ||
+       util::startsWith(optarg.begin(), optarg.end(), "https://") ||
+       util::startsWith(optarg.begin(), optarg.end(), "ftp://")) {
       uri = optarg;
     } else {
       uri = "http://";

+ 1 - 3
src/bittorrent_helper.cc

@@ -875,12 +875,10 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
   }
   SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
   std::string infoHash;
-  static const char A2_URN_BTIH[] = "urn:btih:";
   for(List::ValueType::const_iterator xtiter = xts->begin(),
         eoi = xts->end(); xtiter != eoi && infoHash.empty(); ++xtiter) {
     const String* xt = downcast<String>(*xtiter);
-    if(util::startsWith(xt->s().begin(), xt->s().end(),
-                        A2_URN_BTIH, vend(A2_URN_BTIH)-1)) {
+    if(util::startsWith(xt->s(), "urn:btih:")) {
       size_t size = xt->s().end()-xt->s().begin()-9;
       if(size == 32) {
         std::string rawhash = base32::decode(xt->s().begin()+9, xt->s().end());

+ 6 - 12
src/cookie_helper.cc

@@ -243,12 +243,6 @@ bool parse
   if(nvEnd != end) {
     ++nvEnd;
   }
-  static const char A2_EXPIRES[] = "expires";
-  static const char A2_MAX_AGE[] = "max-age";
-  static const char A2_DOMAIN[] = "domain";
-  static const char A2_PATH[] = "path";
-  static const char A2_SECURE[] = "secure";
-  static const char A2_HTTPONLY[] = "httponly";
   for(std::string::const_iterator i = nvEnd; i != end;) {
     std::string::const_iterator j = std::find(i, end, ';');
     std::string::const_iterator eq = std::find(i, j, '=');
@@ -264,13 +258,13 @@ bool parse
     if(j != end) {
       ++i;
     }
-    if(util::strieq(p.first, p.second, A2_EXPIRES, vend(A2_EXPIRES)-1)) {
+    if(util::strieq(p.first, p.second, "expires")) {
       if(parseDate(expiryTime, attrp.first, attrp.second)) {
         foundExpires = true;
       } else {
         return false;
       }
-    } else if(util::strieq(p.first, p.second, A2_MAX_AGE, vend(A2_MAX_AGE)-1)) {
+    } else if(util::strieq(p.first, p.second, "max-age")) {
       if(attrp.first == attrp.second ||
          (!in(static_cast<unsigned char>(*attrp.first), 0x30u, 0x39u) &&
           *attrp.first != '-')) {
@@ -300,7 +294,7 @@ bool parse
       } else {
         return false;
       }
-    } else if(util::strieq(p.first, p.second, A2_DOMAIN, vend(A2_DOMAIN)-1)) {
+    } else if(util::strieq(p.first, p.second, "domain")) {
       if(attrp.first == attrp.second) {
         return false;
       }
@@ -311,15 +305,15 @@ bool parse
         return false;
       }
       cookieDomain.assign(noDot, end);
-    } else if(util::strieq(p.first, p.second, A2_PATH, vend(A2_PATH)-1)) {
+    } else if(util::strieq(p.first, p.second, "path")) {
       if(goodPath(attrp.first, attrp.second)) {
         cookiePath.assign(attrp.first, attrp.second);
       } else {
         cookiePath = defaultPath;
       }
-    } else if(util::strieq(p.first, p.second, A2_SECURE, vend(A2_SECURE)-1)) {
+    } else if(util::strieq(p.first, p.second, "secure")) {
       secure = true;
-    } else if(util::strieq(p.first, p.second, A2_HTTPONLY, vend(A2_HTTPONLY)-1)) {
+    } else if(util::strieq(p.first, p.second, "httponly")) {
       httpOnly = true;
     }
   }

+ 4 - 12
src/json.cc

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

+ 1 - 3
src/magnet.cc

@@ -43,9 +43,7 @@ namespace magnet {
 SharedHandle<Dict> parse(const std::string& magnet)
 {
   SharedHandle<Dict> dict;
-  static const char A2_MSGNET[] = "magnet:?";
-  if(!util::startsWith(magnet.begin(), magnet.end(),
-                       A2_MSGNET, vend(A2_MSGNET)-1)) {
+  if(!util::startsWith(magnet, "magnet:?")) {
     return dict;
   }
   dict.reset(new Dict());

+ 1 - 3
src/option_processing.cc

@@ -201,9 +201,7 @@ void option_processing(Option& op, std::vector<std::string>& uris,
           keyword = TAG_BASIC;
         } else {
           keyword = op.get(PREF_HELP);
-          static const char A2_HH[] = "--";
-          if(util::startsWith(keyword.begin(), keyword.end(),
-                              A2_HH, vend(A2_HH)-1)) {
+          if(util::startsWith(keyword, "--")) {
             keyword.erase(keyword.begin(), keyword.begin()+2);
           }
           std::string::size_type eqpos = keyword.find("=");

+ 52 - 56
src/util.cc

@@ -730,24 +730,18 @@ void parsePrioritizePieceRange
 {
   std::vector<size_t> indexes;
   std::vector<Scip> parts;
-  static const char A2_HEAD[] = "head";
-  static const char A2_HEADEQ[] = "head=";
-  static const char A2_TAIL[] = "tail";
-  static 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(util::streq((*i).first, (*i).second, A2_HEAD, vend(A2_HEAD)-1)) {
+    if(util::streq((*i).first, (*i).second, "head")) {
       computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
-    } else if(util::startsWith((*i).first, (*i).second,
-                               A2_HEADEQ, vend(A2_HEADEQ)-1)) {
+    } else if(util::startsWith((*i).first, (*i).second, "head=")) {
       std::string sizestr((*i).first+5, (*i).second);
       computeHeadPieces(indexes, fileEntries, pieceLength,
                         std::max((int64_t)0, getRealSize(sizestr)));
-    } else if(util::streq((*i).first, (*i).second, A2_TAIL, vend(A2_TAIL)-1)) {
+    } else if(util::streq((*i).first, (*i).second, "tail")) {
       computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
-    } else if(util::startsWith((*i).first, (*i).second,
-                               A2_TAILEQ, vend(A2_TAILEQ)-1)) {
+    } else if(util::startsWith((*i).first, (*i).second, "tail=")) {
       std::string sizestr((*i).first+5, (*i).second);
       computeTailPieces(indexes, fileEntries, pieceLength,
                         std::max((int64_t)0, getRealSize(sizestr)));
@@ -835,8 +829,7 @@ std::string getContentDispositionFilename(const std::string& header)
   for(std::vector<std::string>::const_iterator i = params.begin(),
         eoi = params.end(); i != eoi; ++i) {
     const std::string& param = *i;
-    if(!istartsWith(param.begin(), param.end(),
-                   A2_KEYNAME, vend(A2_KEYNAME)-1) ||
+    if(!istartsWith(param, A2_KEYNAME) ||
        param.size() == sizeof(A2_KEYNAME)-1) {
       continue;
     }
@@ -893,13 +886,10 @@ std::string getContentDispositionFilename(const std::string& header)
       }
       std::string value =
         percentDecode(extValues[2].first, extValues[2].second);
-      static const char A2_ISO88591[] = "iso-8859-1";
-      if(util::strieq(extValues[0].first, extValues[0].second,
-                      A2_ISO88591, vend(A2_ISO88591)-1)) {
+      if(util::strieq(extValues[0].first, extValues[0].second, "iso-8859-1")) {
         value = iso8859ToUtf8(value);
       }
-      if(!detectDirTraversal(value) &&
-         value.find(A2STR::SLASH_C) == std::string::npos) {
+      if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
         filename = value;
       }
       if(!filename.empty()) {
@@ -929,8 +919,7 @@ std::string getContentDispositionFilename(const std::string& header)
       value = percentDecode(value.begin(), filenameLast);
       value = strip(value, TRIMMED);
       value.erase(std::remove(value.begin(), value.end(), '\\'), value.end());
-      if(!detectDirTraversal(value) &&
-         value.find(A2STR::SLASH_C) == std::string::npos) {
+      if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
         filename = value;
       }
       // continue because there is a chance we can find filename*=...
@@ -940,11 +929,12 @@ std::string getContentDispositionFilename(const std::string& header)
 }
 
 std::string randomAlpha(size_t length, const RandomizerHandle& randomizer) {
-  static const char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+  static const char randomChars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   std::string str;
   for(size_t i = 0; i < length; ++i) {
-    size_t index = randomizer->getRandomNumber(strlen(random_chars));
-    str += random_chars[index];
+    size_t index = randomizer->getRandomNumber(sizeof(randomChars)-1);
+    str += randomChars[index];
   }
   return str;
 }
@@ -1368,17 +1358,11 @@ void generateRandomKey(unsigned char* key)
 // 192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
 bool inPrivateAddress(const std::string& ipv4addr)
 {
-  static const char A2_IP10[] = "10.";
-  static const char A2_IP192[] = "192.168.";
-  static const char A2_IP172[] = "172.";
-  if(util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP10, vend(A2_IP10)-1) ||
-     util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP192, vend(A2_IP192)-1)) {
+  if(util::startsWith(ipv4addr, "10.") ||
+     util::startsWith(ipv4addr, "192.168.")) {
     return true;
   }
-  if(util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP172, vend(A2_IP172)-1)) {
+  if(util::startsWith(ipv4addr, "172.")) {
     for(int i = 16; i <= 31; ++i) {
       std::string t(fmt("%d.", i));
       if(util::startsWith(ipv4addr.begin()+4, ipv4addr.end(),
@@ -1401,25 +1385,12 @@ bool detectDirTraversal(const std::string& s)
       return true;
     }
   }
-
-  static const char A2_DS[] = "./";
-  static const char A2_DDS[] = "../";
-  static const char A2_SD[] = "/.";
-  static const char A2_SDD[] = "/..";
-  static const char A2_SDDS[] = "/../";
-  static const char A2_SDS[] = "/./";
-  static const char A2_DD[] = "..";
-
-  return s == A2STR::DOT_C ||
-    s == A2_DD ||
-    s[0] == '/' ||
-    util::startsWith(s.begin(), s.end(), A2_DS, vend(A2_DS)-1) ||
-    util::startsWith(s.begin(), s.end(), A2_DDS, vend(A2_DDS)-1) ||
-    s.find(A2_SDDS) != std::string::npos ||
-    s.find(A2_SDS) != std::string::npos ||
+  return s == "." || s == ".." || s[0] == '/' ||
+    util::startsWith(s, "./") || util::startsWith(s, "../") ||
+    s.find("/../") != std::string::npos ||
+    s.find("/./") != std::string::npos ||
     s[s.size()-1] == '/' ||
-    util::endsWith(s.begin(), s.end(), A2_SD, vend(A2_SD)-1) ||
-    util::endsWith(s.begin(), s.end(), A2_SDD, vend(A2_SDD)-1);
+    util::endsWith(s, "/.") || util::endsWith(s, "/..");
 }
 
 std::string escapePath(const std::string& s)
@@ -1523,12 +1494,8 @@ void executeHook
 
   memset(&si, 0, sizeof (si));
   si.cb = sizeof(STARTUPINFO);
-
   memset(&pi, 0, sizeof (pi));
-
-  static const char A2_BAT[] = ".bat";
-  bool batch = util::iendsWith(command.begin(), command.end(),
-                               A2_BAT, vend(A2_BAT)-1);
+  bool batch = util::iendsWith(command, ".bat");
   std::string cmdline;
   std::string cmdexe;
   if(batch) {
@@ -1638,13 +1605,42 @@ bool noProxyDomainMatch
  const std::string& domain)
 {
   if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) {
-    return util::endsWith(hostname.begin(), hostname.end(),
-                          domain.begin(), domain.end());
+    return util::endsWith(hostname, domain);
   } else {
     return hostname == domain;
   }
 }
 
+bool startsWith(const std::string& a, const char* b)
+{
+  return startsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool istartsWith(const std::string& a, const char* b)
+{
+  return istartsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool endsWith(const std::string& a, const char* b)
+{
+  return endsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool endsWith(const std::string& a, const std::string& b)
+{
+  return endsWith(a.begin(), a.end(), b.begin(), b.end());
+}
+
+bool iendsWith(const std::string& a, const char* b)
+{
+  return iendsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool iendsWith(const std::string& a, const std::string& b)
+{
+  return iendsWith(a.begin(), a.end(), b.begin(), b.end());
+}
+
 } // namespace util
 
 } // namespace aria2

+ 41 - 7
src/util.h

@@ -42,6 +42,7 @@
 #include <stdint.h>
 
 #include <cstdio>
+#include <cstring>
 #include <string>
 #include <utility>
 #include <iosfwd>
@@ -478,21 +479,20 @@ OutputIterator splitIter
   return out;
 }
 
-template<typename InputIterator,
-         typename InputIterator2,
-         typename OutputIterator>
+template<typename InputIterator, typename OutputIterator>
 OutputIterator splitIterM
 (InputIterator first,
  InputIterator last,
  OutputIterator out,
- InputIterator2 dfirst,
- InputIterator2 dlast,
+ const char* delims,
  bool doStrip = false,
  bool allowEmpty = false)
 {
+  size_t numDelims = strlen(delims);
+  const char* dlast = delims+numDelims;
   for(InputIterator i = first; i != last;) {
     InputIterator j = i;
-    for(; j != last && std::find(dfirst, dlast, *j) == dlast; ++j);
+    for(; j != last && std::find(delims, dlast, *j) == dlast; ++j);
     std::pair<InputIterator, InputIterator> p(i, j);
     if(doStrip) {
       p = stripIter(i, j);
@@ -507,7 +507,7 @@ OutputIterator splitIterM
   }
   if(allowEmpty &&
      (first == last ||
-      std::find(dfirst, dlast, *(last-1)) != dlast)) {
+      std::find(delims, dlast, *(last-1)) != dlast)) {
     *out++ = std::make_pair(last, last);
   }
   return out;
@@ -556,6 +556,12 @@ bool streq
   return std::equal(first1, last1, first2);
 }
 
+template<typename InputIterator>
+bool streq(InputIterator first, InputIterator last, const char* b)
+{
+  return streq(first, last, b, b+strlen(b));
+}
+
 struct CaseCmp {
   bool operator()(char lhs, char rhs) const
   {
@@ -592,6 +598,12 @@ bool strieq
   return std::equal(first1, last1, first2, CaseCmp());
 }
 
+template<typename InputIterator>
+bool strieq(InputIterator first, InputIterator last, const char* b)
+{
+  return strieq(first, last, b, b+strlen(b));
+}
+
 template<typename InputIterator1, typename InputIterator2>
 bool startsWith
 (InputIterator1 first1,
@@ -605,6 +617,14 @@ bool startsWith
   return std::equal(first2, last2, first1);
 }
 
+template<typename InputIterator>
+bool startsWith(InputIterator first, InputIterator last, const char* b)
+{
+  return startsWith(first, last, b, b+strlen(b));
+}
+
+bool startsWith(const std::string& a, const char* b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool istartsWith
 (InputIterator1 first1,
@@ -618,6 +638,14 @@ bool istartsWith
   return std::equal(first2, last2, first1, CaseCmp());
 }
 
+template<typename InputIterator>
+bool istartsWith(InputIterator first, InputIterator last, const char* b)
+{
+  return istartsWith(first, last, b, b+strlen(b));
+}
+
+bool istartsWith(const std::string& a, const char* b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool endsWith
 (InputIterator1 first1,
@@ -631,6 +659,9 @@ bool endsWith
   return std::equal(first2, last2, last1-(last2-first2));
 }
 
+bool endsWith(const std::string& a, const char* b);
+bool endsWith(const std::string& a, const std::string& b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool iendsWith
 (InputIterator1 first1,
@@ -644,6 +675,9 @@ bool iendsWith
   return std::equal(first2, last2, last1-(last2-first2), CaseCmp());
 }
 
+bool iendsWith(const std::string& a, const char* b);
+bool iendsWith(const std::string& a, const std::string& b);
+
 void generateRandomData(unsigned char* data, size_t length);
 
 // Saves data to file whose name is filename. If overwrite is true,

+ 16 - 30
test/UtilTest.cc

@@ -506,12 +506,11 @@ void UtilTest::testSplitIter() {
 }
 
 void UtilTest::testSplitIterM() {
-  std::string d = ";";
-  std::string md = "; ";
+  const char d[] = ";";
+  const char 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);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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));
@@ -520,8 +519,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   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"),
@@ -532,8 +530,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   md.begin(), md.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md);
   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));
@@ -542,8 +539,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   md.begin(), md.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md, 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));
@@ -555,8 +551,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k=v";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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));
@@ -564,8 +559,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = ";;k1;;k2;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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));
@@ -577,8 +571,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = ";;k1;;k2;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   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));
@@ -586,8 +579,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k; ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   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));
@@ -595,38 +587,33 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = " ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), true, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   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());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   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);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, 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));
@@ -634,8 +621,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
 }