Explorar o código

Changed parse*Int functions so that it accepts iterators.

Tatsuhiro Tsujikawa %!s(int64=14) %!d(string=hai) anos
pai
achega
9bb914b76e

+ 1 - 1
src/AbstractCommand.cc

@@ -608,7 +608,7 @@ bool inNoProxy(const SharedHandle<Request>& req,
       // evaluates against all of them
       std::string ip = (*i).substr(0, slashpos);
       uint32_t bits;
-      if(!util::parseUIntNoThrow(bits, (*i).substr(slashpos+1))) {
+      if(!util::parseUIntNoThrow(bits, (*i).begin()+slashpos+1, (*i).end())) {
         continue;
       }
       if(util::inSameCidrBlock(ip, req->getHost(), bits)) {

+ 1 - 1
src/ChunkedDecodingStreamFilter.cc

@@ -96,7 +96,7 @@ bool ChunkedDecodingStreamFilter::readChunkSize
   if(extPos == std::string::npos || crlfPos < extPos) {
     extPos = crlfPos;
   }
-  chunkSize_ = util::parseULLInt(buf_.substr(0, extPos), 16);
+  chunkSize_ = util::parseULLInt(buf_.begin(), buf_.begin()+extPos, 16);
   assert(crlfPos+2 > pbufSize);
   inbufOffset += crlfPos+2-pbufSize;
   buf_.clear();

+ 9 - 13
src/FtpConnection.cc

@@ -434,7 +434,7 @@ unsigned int FtpConnection::receiveSizeResponse(uint64_t& size)
     if(response.first == 213) {
       std::pair<std::string, std::string> rp;
       util::divide(rp, response.second, ' ');
-      size = util::parseULLInt(rp.second);
+      size = util::parseULLInt(rp.second.begin(), rp.second.end());
     }
     return response.first;
   } else {
@@ -455,17 +455,12 @@ unsigned int FtpConnection::receiveMdtmResponse(Time& time)
         // and included strptime doesn't parse data for this format.
         struct tm tm;
         memset(&tm, 0, sizeof(tm));
-        tm.tm_sec = util::parseInt(&buf[12]);
-        buf[12] = '\0';
-        tm.tm_min = util::parseInt(&buf[10]);
-        buf[10] = '\0';
-        tm.tm_hour = util::parseInt(&buf[8]);
-        buf[8] = '\0';
-        tm.tm_mday = util::parseInt(&buf[6]);
-        buf[6] = '\0';
-        tm.tm_mon = util::parseInt(&buf[4])-1;
-        buf[4] = '\0';
-        tm.tm_year = util::parseInt(&buf[0])-1900;
+        tm.tm_sec = util::parseInt(&buf[12], &buf[14]);
+        tm.tm_min = util::parseInt(&buf[10], &buf[12]);
+        tm.tm_hour = util::parseInt(&buf[8], &buf[10]);
+        tm.tm_mday = util::parseInt(&buf[6], &buf[8]);
+        tm.tm_mon = util::parseInt(&buf[4], &buf[6])-1;
+        tm.tm_year = util::parseInt(&buf[0], &buf[4])-1900;
         time = Time(timegm(&tm));
       } else {
         time = Time::null();
@@ -493,7 +488,8 @@ unsigned int FtpConnection::receiveEpsvResponse(uint16_t& port)
       util::split(response.second.substr(leftParen+1, rightParen-(leftParen+1)),
                   std::back_inserter(rd), "|", true, true);
       uint32_t portTemp = 0;
-      if(rd.size() == 5 && util::parseUIntNoThrow(portTemp, rd[3])) {
+      if(rd.size() == 5 &&
+         util::parseUIntNoThrow(portTemp, rd[3].begin(), rd[3].end())) {
         if(0 < portTemp  && portTemp <= UINT16_MAX) {
           port = portTemp;
         }

+ 8 - 7
src/HttpHeader.cc

@@ -128,7 +128,7 @@ uint64_t HttpHeader::getFirstAsULLInt(const std::string& name) const {
   if(value.empty()) {
     return 0;
   } else {
-    return util::parseULLInt(value);
+    return util::parseULLInt(value.begin(), value.end());
   }
 }
 
@@ -136,11 +136,12 @@ RangeHandle HttpHeader::getRange() const
 {
   const std::string& rangeStr = getFirst(CONTENT_RANGE);
   if(rangeStr.empty()) {
-    const std::string& contentLengthStr = getFirst(CONTENT_LENGTH);
-    if(contentLengthStr.empty()) {
+    const std::string& clenStr = getFirst(CONTENT_LENGTH);
+    if(clenStr.empty()) {
       return SharedHandle<Range>(new Range());
     } else {
-      uint64_t contentLength = util::parseULLInt(contentLengthStr);
+      uint64_t contentLength =
+        util::parseULLInt(clenStr.begin(), clenStr.end());
       if(contentLength == 0) {
         return SharedHandle<Range>(new Range());
       } else {
@@ -177,9 +178,9 @@ RangeHandle HttpHeader::getRange() const
   if(minus == slash) {
     return SharedHandle<Range>(new Range());
   }
-  off_t startByte = util::parseLLInt(std::string(byteRangeSpec, minus));
-  off_t endByte = util::parseLLInt(std::string(minus+1, slash));
-  uint64_t entityLength = util::parseULLInt(std::string(slash+1, rangeStr.end()));
+  off_t startByte = util::parseLLInt(byteRangeSpec, minus);
+  off_t endByte = util::parseLLInt(minus+1, slash);
+  uint64_t entityLength = util::parseULLInt(slash+1, rangeStr.end());
   return SharedHandle<Range>(new Range(startByte, endByte, entityLength));
 }
 

+ 1 - 1
src/HttpHeaderProcessor.cc

@@ -112,7 +112,7 @@ SharedHandle<HttpHeader> HttpHeaderProcessor::getHttpResponseHeader()
     throw DL_RETRY_EX(EX_NO_STATUS_HEADER);
   }
   int32_t statusCode;
-  if(!util::parseIntNoThrow(statusCode, buf_.substr(9, 3))) {
+  if(!util::parseIntNoThrow(statusCode, buf_.begin()+9, buf_.begin()+12)) {
     throw DL_RETRY_EX("Status code could not be parsed as integer.");
   }
   HttpHeaderHandle httpHeader(new HttpHeader());

+ 1 - 1
src/HttpResponse.cc

@@ -342,7 +342,7 @@ bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s)
         }
       } else if(name == "pri") {
         int32_t priValue;
-        if(util::parseIntNoThrow(priValue, value)) {
+        if(util::parseIntNoThrow(priValue, value.begin(), value.end())) {
           if(1 <= priValue && priValue <= 999999) {
             result.pri = priValue;
           }

+ 2 - 1
src/Makefile.am

@@ -230,7 +230,8 @@ SRCS =  Socket.h\
 	console.cc console.h\
 	BufferedFile.cc BufferedFile.h\
 	SegList.h\
-	NullHandle.h
+	NullHandle.h\
+	a2iterator.h
 
 if MINGW_BUILD
 SRCS += WinConsoleFile.cc WinConsoleFile.h

+ 11 - 6
src/MetalinkParserStateV3Impl.cc

@@ -155,7 +155,8 @@ void FileMetalinkParserState::beginElement
         maxConnections = -1;
       } else {
         try {
-          maxConnections = util::parseInt((*itr).value);
+          maxConnections =
+            util::parseInt((*itr).value.begin(), (*itr).value.end());
         } catch(RecoverableException& e) {
           maxConnections = -1;
         }
@@ -185,7 +186,8 @@ void SizeMetalinkParserState::endElement
  const std::string& characters)
 {
   try {
-    stm->setFileLengthOfEntry(util::parseULLInt(characters));
+    stm->setFileLengthOfEntry
+      (util::parseULLInt(characters.begin(), characters.end()));
   } catch(RecoverableException& e) {
     // current metalink specification doesn't require size element.
   }
@@ -251,7 +253,7 @@ void VerificationMetalinkParserState::beginElement
         if(itr == attrs.end()) {
           return;
         } else {
-          length = util::parseInt((*itr).value);
+          length = util::parseInt((*itr).value.begin(), (*itr).value.end());
         }
       }
       std::string type;
@@ -317,7 +319,8 @@ void PiecesMetalinkParserState::beginElement
       stm->cancelChunkChecksumTransaction();
     } else {
       try {
-        stm->createNewHashOfChunkChecksum(util::parseInt((*itr).value));
+        stm->createNewHashOfChunkChecksum
+          (util::parseInt((*itr).value.begin(), (*itr).value.end()));
       } catch(RecoverableException& e) {
         stm->cancelChunkChecksumTransaction();
       }
@@ -396,7 +399,8 @@ void ResourcesMetalinkParserState::beginElement
           // In Metalink3Spec, highest prefernce value is 100.  We
           // uses Metalink4Spec priority unit system in which 1 is
           // higest.
-          preference = 101-util::parseInt((*itr).value);
+          preference =
+            101-util::parseInt((*itr).value.begin(), (*itr).value.end());
         } catch(RecoverableException& e) {
           preference = MetalinkResource::getLowestPriority();
         }
@@ -409,7 +413,8 @@ void ResourcesMetalinkParserState::beginElement
         maxConnections = -1;
       } else {
         try {
-          maxConnections = util::parseInt((*itr).value);
+          maxConnections =
+            util::parseInt((*itr).value.begin(), (*itr).value.end());
         } catch(RecoverableException& e) {
           maxConnections = -1;
         }

+ 5 - 4
src/MetalinkParserStateV4Impl.cc

@@ -151,7 +151,7 @@ void FileMetalinkParserStateV4::beginElement
         priority = MetalinkResource::getLowestPriority();
       } else {
         try {
-          priority = util::parseInt((*itr).value);
+          priority = util::parseInt((*itr).value.begin(), (*itr).value.end());
           if(priority < 1 || MetalinkResource::getLowestPriority() < priority) {
             stm->logError("metaurl@priority is out of range");
             return;
@@ -192,7 +192,7 @@ void FileMetalinkParserStateV4::beginElement
         priority = MetalinkResource::getLowestPriority();
       } else {
         try {
-          priority = util::parseInt((*itr).value);
+          priority = util::parseInt((*itr).value.begin(), (*itr).value.end());
           if(priority < 1 || MetalinkResource::getLowestPriority() < priority) {
             stm->logError("url@priority is out of range");
             return;
@@ -229,7 +229,7 @@ void FileMetalinkParserStateV4::beginElement
         return;
       } else {
         try {
-          length = util::parseInt((*itr).value);
+          length = util::parseInt((*itr).value.begin(), (*itr).value.end());
         } catch(RecoverableException& e) {
           stm->logError("Bad pieces@length");
           return;
@@ -283,7 +283,8 @@ void SizeMetalinkParserStateV4::endElement
  const std::string& characters)
 {
   try {
-    stm->setFileLengthOfEntry(util::parseULLInt(characters));
+    stm->setFileLengthOfEntry
+      (util::parseULLInt(characters.begin(), characters.end()));
   } catch(RecoverableException& e) {
     stm->cancelEntryTransaction();
     stm->logError("Bad size");

+ 1 - 1
src/NsCookieParser.cc

@@ -71,7 +71,7 @@ bool parseNsCookie
     return false;
   }
   int64_t expiryTime;
-  if(!util::parseLLIntNoThrow(expiryTime, vs[4])) {
+  if(!util::parseLLIntNoThrow(expiryTime, vs[4].begin(), vs[4].end())) {
     return false;
   }
   if(std::numeric_limits<time_t>::max() < expiryTime) {

+ 1 - 1
src/OptionHandlerImpl.cc

@@ -152,7 +152,7 @@ NumberOptionHandler::~NumberOptionHandler() {}
 
 void NumberOptionHandler::parseArg(Option& option, const std::string& optarg)
 {
-  int64_t num = util::parseLLInt(optarg);
+  int64_t num = util::parseLLInt(optarg.begin(), optarg.end());
   parseArg(option, num);
 }
 

+ 3 - 3
src/ParameterizedStringParser.cc

@@ -118,7 +118,7 @@ ParameterizedStringParser::createLoop(const std::string& src, int& offset)
   if(colonIndex != std::string::npos) {
     std::string stepStr = loopStr.substr(colonIndex+1);
     if(util::isNumber(stepStr)) {
-      step = util::parseUInt(stepStr);
+      step = util::parseUInt(loopStr.begin()+colonIndex+1, loopStr.end());
     } else {
       throw DL_ABORT_EX("A step count must be a positive number.");
     }
@@ -134,8 +134,8 @@ ParameterizedStringParser::createLoop(const std::string& src, int& offset)
   unsigned int end;
   if(util::isNumber(range.first) && util::isNumber(range.second)) {
     nd.reset(new FixedWidthNumberDecorator(range.first.size()));
-    start = util::parseUInt(range.first);
-    end = util::parseUInt(range.second);
+    start = util::parseUInt(range.first.begin(), range.first.end());
+    end = util::parseUInt(range.second.begin(), range.second.end());
   } else if(util::isLowercase(range.first) && util::isLowercase(range.second)) {
     nd.reset(new AlphaNumberDecorator(range.first.size()));
     start = util::alphaToNum(range.first);

+ 1 - 1
src/RpcMethodImpl.cc

@@ -197,7 +197,7 @@ namespace {
 a2_gid_t str2Gid(const String* str)
 {
   assert(str);
-  return util::parseLLInt(str->s());
+  return util::parseLLInt(str->s().begin(), str->s().end());
 }
 } // namespace
 

+ 11 - 5
src/ServerStatMan.cc

@@ -171,20 +171,26 @@ bool ServerStatMan::load(const std::string& filename)
     }
     SharedHandle<ServerStat> sstat(new ServerStat(m[S_HOST], m[S_PROTOCOL]));
     try {
-      sstat->setDownloadSpeed(util::parseUInt(m[S_DL_SPEED]));
+      const std::string& dlSpeed = m[S_DL_SPEED];
+      sstat->setDownloadSpeed(util::parseUInt(dlSpeed.begin(), dlSpeed.end()));
       // Old serverstat file doesn't contains SC_AVG_SPEED
       if(m.find(S_SC_AVG_SPEED) != m.end()) {
-        sstat->setSingleConnectionAvgSpeed(util::parseUInt(m[S_SC_AVG_SPEED]));
+        const std::string& s = m[S_SC_AVG_SPEED];
+        sstat->setSingleConnectionAvgSpeed(util::parseUInt(s.begin(), s.end()));
       }
       // Old serverstat file doesn't contains MC_AVG_SPEED
       if(m.find(S_MC_AVG_SPEED) != m.end()) {
-        sstat->setMultiConnectionAvgSpeed(util::parseUInt(m[S_MC_AVG_SPEED]));
+        const std::string& s = m[S_MC_AVG_SPEED];
+        sstat->setMultiConnectionAvgSpeed(util::parseUInt(s.begin(), s.end()));
       }
       // Old serverstat file doesn't contains COUNTER_SPEED
       if(m.find(S_COUNTER) != m.end()) {
-        sstat->setCounter(util::parseUInt(m[S_COUNTER]));
+        const std::string& s = m[S_COUNTER];
+        sstat->setCounter(util::parseUInt(s.begin(), s.end()));
       }
-      sstat->setLastUpdated(Time(util::parseInt(m[S_LAST_UPDATED])));
+      const std::string& lastUpdated = m[S_LAST_UPDATED];
+      sstat->setLastUpdated
+        (Time(util::parseInt(lastUpdated.begin(), lastUpdated.end())));
       sstat->setStatus(m[S_STATUS]);
       add(sstat);
     } catch(RecoverableException& e) {

+ 11 - 8
src/Sqlite3CookieParser.cc

@@ -82,9 +82,10 @@ std::string toString(const char* str)
 } // namespace
 
 namespace {
-bool parseTime(int64_t& time, const std::string& s)
+template<typename InputIterator>
+bool parseTime(int64_t& time, InputIterator first, InputIterator last)
 {
-  if(!util::parseLLIntNoThrow(time, s)) {
+  if(!util::parseLLIntNoThrow(time, first, last)) {
     return false;
   }
   if(std::numeric_limits<time_t>::max() < time) {
@@ -112,11 +113,13 @@ int cookieRowMapper(void* data, int columns, char** values, char** names)
     return 0;
   }
   int64_t expiryTime;
-  if(!parseTime(expiryTime, toString(values[3]))) {
+  if(!values[3] ||
+     !parseTime(expiryTime, &values[3][0], &values[3][strlen(values[3])])) {
     return 0;
   }
   int64_t lastAccessTime;
-  if(!parseTime(lastAccessTime, toString(values[6]))) {
+  if(!values[6] ||
+     !parseTime(lastAccessTime, &values[6][0], &values[6][strlen(values[6])])) {
     return 0;
   }
   Cookie c(cookieName,
@@ -124,9 +127,10 @@ int cookieRowMapper(void* data, int columns, char** values, char** names)
            expiryTime,
            true, // persistent
            cookieDomain,
-           util::isNumericHost(cookieDomain) || values[0][0] != '.', // hostOnly
+           util::isNumericHost(cookieDomain) ||
+           (values[0] && values[0][0] != '.'), // hostOnly
            cookiePath,
-           strcmp(toString(values[2]).c_str(), "1") == 0, //secure
+           values[2] && strcmp(values[2], "1") == 0, //secure
            false,
            lastAccessTime // creation time. Set this later.
            );
@@ -151,8 +155,7 @@ void Sqlite3CookieParser::parse(std::vector<Cookie>& cookies)
   }
   if(SQLITE_OK != ret) {
     throw DL_ABORT_EX
-      (fmt("Failed to read SQLite3 database: %s",
-           errMsg.c_str()));
+      (fmt("Failed to read SQLite3 database: %s", errMsg.c_str()));
   }
   cookies.swap(tcookies);
 }

+ 1 - 1
src/XmlRpcRequestParserStateImpl.cc

@@ -198,7 +198,7 @@ void IntXmlRpcRequestParserState::endElement
  const std::string& characters)
 {
   try {
-    int64_t value = util::parseLLInt(characters);
+    int64_t value = util::parseLLInt(characters.begin(), characters.end());
     stm->setCurrentFrameValue(Integer::g(value));
   } catch(RecoverableException& e) {
     // nothing to do here: We just leave current frame value to null.

+ 52 - 0
src/a2iterator.h

@@ -0,0 +1,52 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef D_A2_ITERATOR_H
+#define D_A2_ITERATOR_H
+
+#include "common.h"
+
+#include <string>
+
+namespace aria2 {
+
+typedef std::pair<std::string::const_iterator,
+                  std::string::const_iterator> Scip;
+
+typedef std::pair<std::string::iterator,
+                  std::string::iterator> Sip;
+
+} // namespace aria2
+
+#endif // D_A2_ITERATOR_H

+ 6 - 7
src/cookie_helper.cc

@@ -117,9 +117,9 @@ bool parseDate
         goto NOT_TIME;
       }
       foundTime = true;
-      hour = util::parseInt(std::string((*i).begin(), hEnd));
-      minute = util::parseInt(std::string(hEnd+1, mEnd));
-      second = util::parseInt(std::string(mEnd+1, sEnd));
+      hour = util::parseInt((*i).begin(), hEnd);
+      minute = util::parseInt(hEnd+1, mEnd);
+      second = util::parseInt(mEnd+1, sEnd);
       continue;
     NOT_TIME:
       ;
@@ -129,7 +129,7 @@ bool parseDate
       size_t len = std::distance((*i).begin(), j);
       if(1 <= len && len <= 2) {
         foundDayOfMonth = true;
-        dayOfMonth = util::parseInt(std::string((*i).begin(), j));
+        dayOfMonth = util::parseInt((*i).begin(), j);
         continue;
       }
     }
@@ -154,7 +154,7 @@ bool parseDate
       size_t len = std::distance((*i).begin(), j);
       if(1 <= len && len <= 4) {
         foundYear = true;
-        year = util::parseInt(std::string((*i).begin(), j));
+        year = util::parseInt((*i).begin(), j);
         continue;
       }
     }
@@ -273,8 +273,7 @@ bool parse
         }
       }
       int64_t delta;
-      if(util::parseLLIntNoThrow(delta,
-                                 std::string(attrp.first, attrp.second))) {
+      if(util::parseLLIntNoThrow(delta, attrp.first, attrp.second)) {
         foundMaxAge = true;
         if(delta <= 0) {
           maxAge = 0;

+ 8 - 10
src/json.cc

@@ -161,13 +161,12 @@ decodeString
       checkEof(first, last);
       if(*first == 'u') {
         ++first;
-        std::string uchars;
+        std::string::const_iterator uchars = first;
         for(int i = 0; i < 4; ++i, ++first) {
           checkEof(first, last);
-          uchars += *first;
         }
         checkEof(first, last);
-        uint16_t codepoint = util::parseUInt(uchars, 16);
+        uint16_t codepoint = util::parseUInt(uchars, first, 16);
         if(codepoint <= 0x007fu) {
           s += static_cast<char>(codepoint);
         } else if(codepoint <= 0x07ffu) {
@@ -183,13 +182,12 @@ decodeString
                                error_code::JSON_PARSE_ERROR);
           }
           first += 2;
-          std::string uchars;
+          std::string::const_iterator uchars = first;
           for(int i = 0; i < 4; ++i, ++first) {
             checkEof(first, last);
-            uchars += *first;
           }
           checkEof(first, last);
-          uint16_t codepoint2 = util::parseUInt(uchars, 16);
+          uint16_t codepoint2 = util::parseUInt(uchars, first, 16);
           if(!in(codepoint2, 0xDC00u, 0xDFFFu)) {
             throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
                                error_code::JSON_PARSE_ERROR);
@@ -290,7 +288,7 @@ decodeNumber
   checkEof(first, last);
   checkEmptyDigit(offset, first);
   checkLeadingZero(offset, first);
-  s += std::string(offset, first);
+  s.append(offset, first);
   bool fp = false;
   if(*first == '.') {
     fp = true;
@@ -302,7 +300,7 @@ decodeNumber
     }
     checkEof(first, last);
     checkEmptyDigit(offset, first);
-    s += std::string(offset, first);
+    s.append(offset, first);
   }
   if(*first == 'e') {
     fp = true;
@@ -319,14 +317,14 @@ decodeNumber
     }
     checkEof(first, last);
     checkEmptyDigit(offset, first);
-    s += std::string(offset, first);
+    s.append(offset, first);
   }
   if(fp) {
     // Since we don't have floating point coutner part in ValueBase,
     // we just treat it as string.
     return std::make_pair(String::g(s), first);
   } else {
-    Integer::ValueType val = util::parseLLInt(s);
+    Integer::ValueType val = util::parseLLInt(s.begin(), s.end());
     return std::make_pair(Integer::g(val), first);
   }
 }

+ 1 - 1
src/uri.cc

@@ -211,7 +211,7 @@ bool parse(UriStruct& result, const std::string& uri)
     result.port = defPort;
   } else {
     uint32_t tempPort;
-    if(util::parseUIntNoThrow(tempPort, std::string(portFirst, authorityLast))){
+    if(util::parseUIntNoThrow(tempPort, portFirst, authorityLast)) {
       if(65535 < tempPort) {
         return false;
       }

+ 6 - 138
src/util.cc

@@ -35,8 +35,6 @@
 #include "util.h"
 
 #include <signal.h>
-#include <limits.h>
-#include <stdint.h>
 
 #include <cerrno>
 #include <cassert>
@@ -51,15 +49,12 @@
 
 #include "SimpleRandomizer.h"
 #include "File.h"
-#include "message.h"
 #include "Randomizer.h"
 #include "a2netcompat.h"
-#include "DlAbortEx.h"
 #include "BitfieldMan.h"
 #include "DefaultDiskWriter.h"
 #include "FatalException.h"
 #include "FileEntry.h"
-#include "fmt.h"
 #include "A2STR.h"
 #include "array_fun.h"
 #include "bitfield.h"
@@ -496,7 +491,7 @@ std::string percentDecode(const std::string& target) {
     if(*itr == '%') {
       if(itr+1 != target.end() && itr+2 != target.end() &&
          isHexDigit(*(itr+1)) && isHexDigit(*(itr+2))) {
-        result += parseInt(std::string(itr+1, itr+3), 16);
+        result += parseInt(itr+1, itr+3, 16);
         itr += 2;
       } else {
         result += *itr;
@@ -625,133 +620,6 @@ int getNum(const char* buf, int offset, size_t length) {
   return x;
 }
 
-int32_t parseInt(const std::string& s, int32_t base)
-{
-  int64_t v = parseLLInt(s, base);
-  if(v < INT32_MIN || INT32_MAX < v) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          s.c_str()));
-  }
-  return v;
-}
-
-bool parseIntNoThrow(int32_t& result, const std::string& s, int base)
-{
-  // Without trim, strtol("  -1  ",..) emits error.
-  std::string trimed = strip(s);
-  if(trimed.empty()) {
-    return false;
-  }
-  char* stop;
-  errno = 0;
-  long int v = strtol(trimed.c_str(), &stop, base);
-  if(*stop != '\0') {
-    return false;
-  } else if(((v == LONG_MAX || v == LONG_MIN) && (errno == ERANGE)) ||
-            v < INT32_MIN || INT32_MAX < v) {
-    return false;
-  }
-  result = v;
-  return true;
-}
-
-uint32_t parseUInt(const std::string& s, int base)
-{
-  uint64_t v = parseULLInt(s, base);
-  if(UINT32_MAX < v) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          s.c_str()));
-  }
-  return v;
-}
-
-bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base)
-{
-  // Without trim, strtol("  -1  ",..) emits error.
-  std::string trimed = strip(s);
-  if(trimed.empty()) {
-    return false;
-  }
-  // We don't allow negative number.
-  if(trimed[0] == '-') {
-    return false;
-  }
-  char* stop;
-  errno = 0;
-  unsigned long int v = strtoul(trimed.c_str(), &stop, base);
-  if(*stop != '\0') {
-    return false;
-  } else if(((v == ULONG_MAX) && (errno == ERANGE)) || (v > UINT32_MAX)) {
-    return false;
-  }
-  result = v;
-  return true;
-}
-
-int64_t parseLLInt(const std::string& s, int32_t base)
-{
-  std::string trimed = strip(s);
-  if(trimed.empty()) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          "empty string"));
-  }
-  char* stop;
-  errno = 0;
-  int64_t v = strtoll(trimed.c_str(), &stop, base);
-  if(*stop != '\0') {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          trimed.c_str()));
-  } else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          trimed.c_str()));
-  }
-  return v;
-}
-
-bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base)
-{
-  // Without trim, strtol("  -1  ",..) emits error.
-  std::string trimed = strip(s);
-  if(trimed.empty()) {
-    return false;
-  }
-  char* stop;
-  errno = 0;
-  int64_t v = strtoll(trimed.c_str(), &stop, base);
-  if(*stop != '\0') {
-    return false;
-  } else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
-    return false;
-  }
-  result = v;
-  return true;
-}
-
-uint64_t parseULLInt(const std::string& s, int base)
-{
-  std::string trimed = strip(s);
-  if(trimed.empty()) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          "empty string"));
-  }
-  // We don't allow negative number.
-  if(trimed[0] == '-') {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          trimed.c_str()));
-  }
-  char* stop;
-  errno = 0;
-  uint64_t v = strtoull(trimed.c_str(), &stop, base);
-  if(*stop != '\0') {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          trimed.c_str()));
-  } else if((v == ULLONG_MAX) && (errno == ERANGE)) {
-    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
-                          trimed.c_str()));
-  }
-  return v;
-}
-
 void parseIntSegments(SegList<int>& sgl, const std::string& src)
 {
   for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) {
@@ -762,13 +630,13 @@ void parseIntSegments(SegList<int>& sgl, const std::string& src)
     }
     std::string::const_iterator p = std::find(i, j, '-');
     if(p == j) {
-      int a = parseInt(std::string(i, j));
+      int a = parseInt(i, j);
       sgl.add(a, a+1);
     } else if(p == i || p+1 == j) {
       throw DL_ABORT_EX(fmt(MSG_INCOMPLETE_RANGE, std::string(i, j).c_str()));
     } else {
-      int a = parseInt(std::string(i, p));
-      int b = parseInt(std::string(p+1, j));
+      int a = parseInt(i, p);
+      int b = parseInt(p+1, j);
       sgl.add(a, b+1);
     }
     if(j == eoi) {
@@ -1139,7 +1007,7 @@ int64_t getRealSize(const std::string& sizeWithUnit)
     }
     size = sizeWithUnit.substr(0, p);
   }
-  int64_t v = parseLLInt(size);
+  int64_t v = parseLLInt(size.begin(), size.end());
 
   if(v < 0) {
     throw DL_ABORT_EX(fmt("Negative value detected: %s", sizeWithUnit.c_str()));
@@ -1381,7 +1249,7 @@ parseIndexPath(const std::string& line)
 {
   std::pair<std::string, std::string> p;
   divide(p, line, '=');
-  size_t index = parseUInt(p.first);
+  size_t index = parseUInt(p.first.begin(), p.first.end());
   if(p.second.empty()) {
     throw DL_ABORT_EX(fmt("Path with index=%u is empty.",
                           static_cast<unsigned int>(index)));

+ 169 - 8
src/util.h

@@ -38,6 +38,8 @@
 #include "common.h"
 
 #include <sys/time.h>
+#include <limits.h>
+#include <stdint.h>
 
 #include <cstdio>
 #include <string>
@@ -55,6 +57,10 @@
 #include "a2netcompat.h"
 #include "a2functional.h"
 #include "SegList.h"
+#include "a2iterator.h"
+#include "message.h"
+#include "DlAbortEx.h"
+#include "fmt.h"
 
 namespace aria2 {
 
@@ -201,19 +207,174 @@ bool isPowerOf(int num, int base);
 
 std::string secfmt(time_t sec);
 
-int32_t parseInt(const std::string& s, int32_t base = 10);
+template<typename InputIterator>
+bool parseIntNoThrow
+(int32_t& result, InputIterator first, InputIterator last, int base = 10)
+{
+  // Without strip, strtol("  -1  ",..) emits error.
+  Scip p = util::stripIter(first, last);
+  if(p.first == p.second) {
+    return false;
+  }
+  char buf[32];
+  size_t len = std::distance(p.first, p.second);
+  if(len+1 > sizeof(buf)) {
+    return false;
+  }
+  std::copy(p.first, p.second, &buf[0]);
+  buf[len] = '\0';
+  char* stop;
+  errno = 0;
+  long int v = strtol(buf, &stop, base);
+  if(*stop != '\0') {
+    return false;
+  } else if(((v == LONG_MAX || v == LONG_MIN) && (errno == ERANGE)) ||
+            v < INT32_MIN || INT32_MAX < v) {
+    return false;
+  }
+  result = v;
+  return true;
+}
 
-bool parseIntNoThrow(int32_t& result, const std::string& s, int base = 10);
+template<typename InputIterator>
+bool parseUIntNoThrow
+(uint32_t& result, InputIterator first, InputIterator last, int base = 10)
+{
+  // Without strip, strtol("  -1  ",..) emits error.
+  Scip p = util::stripIter(first, last);
+  if(p.first == p.second) {
+    return false;
+  }
+  char buf[32];
+  size_t len = std::distance(p.first, p.second);
+  if(len+1 > sizeof(buf)) {
+    return false;
+  }
+  std::copy(p.first, p.second, &buf[0]);
+  buf[len] = '\0';
+  // We don't allow negative number.
+  if(buf[0] == '-') {
+    return false;
+  }
+  char* stop;
+  errno = 0;
+  unsigned long int v = strtoul(buf, &stop, base);
+  if(*stop != '\0') {
+    return false;
+  } else if(((v == ULONG_MAX) && (errno == ERANGE)) || (v > UINT32_MAX)) {
+    return false;
+  }
+  result = v;
+  return true;
+}
 
-uint32_t parseUInt(const std::string& s, int base = 10);
-  
-bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base = 10);
+template<typename InputIterator>
+bool parseLLIntNoThrow
+(int64_t& result, InputIterator first, InputIterator last, int base = 10)
+{
+  // Without strip, strtol("  -1  ",..) emits error.
+  Scip p = util::stripIter(first, last);
+  if(p.first == p.second) {
+    return false;
+  }
+  char buf[32];
+  size_t len = std::distance(p.first, p.second);
+  if(len+1 > sizeof(buf)) {
+    return false;
+  }
+  std::copy(p.first, p.second, &buf[0]);
+  buf[len] = '\0';
+  char* stop;
+  errno = 0;
+  int64_t v = strtoll(buf, &stop, base);
+  if(*stop != '\0') {
+    return false;
+  } else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
+    return false;
+  }
+  result = v;
+  return true;
+}
+
+template<typename InputIterator>
+int64_t parseLLInt(InputIterator first, InputIterator last, int base = 10)
+{
+  Scip p = util::stripIter(first, last);
+  if(p.first == p.second) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          "empty string"));
+  }
+  char buf[32];
+  size_t len = std::distance(p.first, p.second);
+  if(len+1 > sizeof(buf)) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          "too large"));
+  }
+  std::copy(p.first, p.second, &buf[0]);
+  buf[len] = '\0';
+  char* stop;
+  errno = 0;
+  int64_t v = strtoll(buf, &stop, base);
+  if(*stop != '\0') {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, buf));
+  } else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, buf));
+  }
+  return v;
+}
 
-int64_t parseLLInt(const std::string& s, int32_t base = 10);
+template<typename InputIterator>
+int32_t parseInt(InputIterator first, InputIterator last, int base = 10)
+{
+  int64_t v = util::parseLLInt(first, last, base);
+  if(v < INT32_MIN || INT32_MAX < v) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          std::string(first, last).c_str()));
+  }
+  return v;
+}
 
-bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base = 10);
+template<typename InputIterator>
+uint64_t parseULLInt(InputIterator first, InputIterator last, int base = 10)
+{
+  Scip p = util::stripIter(first, last);
+  if(p.first == p.second) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          "empty string"));
+  }
+  char buf[32];
+  size_t len = std::distance(p.first, p.second);
+  if(len+1 > sizeof(buf)) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          "too large"));
+  }
+  std::copy(p.first, p.second, &buf[0]);
+  buf[len] = '\0';
+  // We don't allow negative number.
+  if(buf[0] == '-') {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, buf));
+  }
+  char* stop;
+  errno = 0;
+  uint64_t v = strtoull(buf, &stop, base);
+  if(*stop != '\0') {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, buf));
+  } else if((v == ULLONG_MAX) && (errno == ERANGE)) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, buf));
+  }
+  return v;
+}
 
-uint64_t parseULLInt(const std::string& s, int base = 10);
+template<typename InputIterator>
+uint32_t parseUInt(InputIterator first, InputIterator last, int base = 10)
+{
+  uint64_t v = util::parseULLInt(first, last, base);
+  if(UINT32_MAX < v) {
+    throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
+                          std::string(first, last).c_str()));
+  }
+  return v;
+}
 
 void parseIntSegments(SegList<int>& sgl, const std::string& src);
 

+ 1 - 1
test/GZipEncoderTest.cc

@@ -30,7 +30,7 @@ void GZipEncoderTest::testEncode()
   inputs.push_back("Fox");
   
   encoder << inputs[0];
-  encoder << util::parseLLInt(inputs[1]);
+  encoder << util::parseLLInt(inputs[1].begin(), inputs[1].end());
   encoder << inputs[2].c_str();
 
   std::string gzippedData = encoder.str();

+ 124 - 40
test/UtilTest.cc

@@ -23,6 +23,7 @@ class UtilTest:public CppUnit::TestFixture {
 
   CPPUNIT_TEST_SUITE(UtilTest);
   CPPUNIT_TEST(testStrip);
+  CPPUNIT_TEST(testStripIter);
   CPPUNIT_TEST(testDivide);
   CPPUNIT_TEST(testSplit);
   CPPUNIT_TEST(testEndsWith);
@@ -83,6 +84,7 @@ public:
   }
 
   void testStrip();
+  void testStripIter();
   void testDivide();
   void testSplit();
   void testEndsWith();
@@ -161,6 +163,54 @@ void UtilTest::testStrip()
   CPPUNIT_ASSERT_EQUAL(str4, util::strip("  A  "));
 }
 
+void UtilTest::testStripIter()
+{
+  Scip p;
+  std::string str1 = "aria2";
+  std::string s = "aria2";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
+  s = " aria2";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
+  s = "aria2 ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
+  s = " aria2 ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
+  s = "  aria2  ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
+  std::string str2 = "aria2 debut";
+  s = "aria2 debut";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str2, std::string(p.first, p.second));
+  s = " aria2 debut ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str2, std::string(p.first, p.second));
+  std::string str3 = "";
+  s = "";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
+  s = " ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
+  s = "  ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
+  std::string str4 = "A";
+  s = "A";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
+  s = " A ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
+  s = "  A  ";
+  p = util::stripIter(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
+}
+
 void UtilTest::testDivide() {
   std::pair<std::string, std::string> p1;
   util::divide(p1, "name=value", '=');
@@ -757,76 +807,92 @@ void UtilTest::testParseIntSegments_invalidRange()
 
 void UtilTest::testParseInt()
 {
-  CPPUNIT_ASSERT_EQUAL(-1, util::parseInt(" -1 "));
-  CPPUNIT_ASSERT_EQUAL(2147483647, util::parseInt("2147483647"));
+  std::string s;
+  s = " -1 ";
+  CPPUNIT_ASSERT_EQUAL(-1, util::parseInt(s.begin(), s.end()));
+  s = "2147483647";
+  CPPUNIT_ASSERT_EQUAL(2147483647, util::parseInt(s.begin(), s.end()));
   try {
-    util::parseInt("2147483648");
+    s = "2147483648";
+    util::parseInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
   try {
-    util::parseInt("-2147483649");
+    s = "-2147483649";
+    util::parseInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
   try {
-    util::parseInt("12x");
+    s = "12x";
+    util::parseInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
   try {
-    util::parseInt("");
+    s = "";
+    util::parseInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
 }
 
 void UtilTest::testParseUInt()
 {
-  CPPUNIT_ASSERT_EQUAL(4294967295U, util::parseUInt(" 4294967295 "));
+  std::string s;
+  s = " 4294967295 ";
+  CPPUNIT_ASSERT_EQUAL(4294967295U, util::parseUInt(s.begin(), s.end()));
   try {
-    util::parseUInt("-1");
+    s = "-1";
+    util::parseUInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
   try {
-    util::parseUInt("4294967296");
+    s = "4294967296";
+    util::parseUInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
 }
 
 void UtilTest::testParseLLInt()
 {
-  CPPUNIT_ASSERT_EQUAL((int64_t)-1LL, util::parseLLInt(" -1 "));
-  CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
-                       util::parseLLInt("9223372036854775807"));
+  std::string s;
+  {
+    s = " -1 ";
+    CPPUNIT_ASSERT_EQUAL((int64_t)-1LL, util::parseLLInt(s.begin(), s.end()));
+  }
+  {
+    s = "9223372036854775807";
+    CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
+                         util::parseLLInt(s.begin(), s.end()));
+  }
   try {
-    util::parseLLInt("9223372036854775808");
+    s = "9223372036854775808";
+    util::parseLLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace();
   }
   try {
-    util::parseLLInt("-9223372036854775809");
+    s = "-9223372036854775809";
+    util::parseLLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace();
   }
   try {
-    util::parseLLInt("12x");
+    s = "12x";
+    util::parseLLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace();
   }
   try {
-    util::parseLLInt("");
+    s = "";
+    util::parseLLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace();
@@ -835,56 +901,74 @@ void UtilTest::testParseLLInt()
 
 void UtilTest::testParseULLInt()
 {
+  std::string s;
+  s = "18446744073709551615";
   CPPUNIT_ASSERT_EQUAL((uint64_t)18446744073709551615ULL,
-                       util::parseULLInt("18446744073709551615"));
+                       util::parseULLInt(s.begin(), s.end()));
   try {
-    util::parseUInt("-1");
+    s = "-1";
+    util::parseULLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
   try {
-    util::parseLLInt("18446744073709551616");
+    s = "18446744073709551616";
+    util::parseULLInt(s.begin(), s.end());
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
-    std::cerr << e.stackTrace();
   }
 }
 
 void UtilTest::testParseIntNoThrow()
 {
+  std::string s;
   int32_t n;
-  CPPUNIT_ASSERT(util::parseIntNoThrow(n, " -1 "));
+  s = " -1 ";
+  CPPUNIT_ASSERT(util::parseIntNoThrow(n, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((int32_t)-1, n);
 
-  CPPUNIT_ASSERT(util::parseIntNoThrow(n, "2147483647"));
+  s = "2147483647";
+  CPPUNIT_ASSERT(util::parseIntNoThrow(n, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((int32_t)2147483647, n);
 
-  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "2147483648"));
-  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "-2147483649"));
+  s = "2147483648";
+  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, s.begin(), s.end()));
+  s = "-2147483649";
+  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, s.begin(), s.end()));
 
-  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "12x"));
-  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, ""));
+  s = "12x";
+  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, s.begin(), s.end()));
+  s = "";
+  CPPUNIT_ASSERT(!util::parseIntNoThrow(n, s.begin(), s.end()));
 }
 
 void UtilTest::testParseUIntNoThrow()
 {
+  std::string s;
   uint32_t n;
-  CPPUNIT_ASSERT(util::parseUIntNoThrow(n, " 4294967295 "));
+  s = " 4294967295 ";
+  CPPUNIT_ASSERT(util::parseUIntNoThrow(n, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((uint32_t)UINT32_MAX, n);
-  CPPUNIT_ASSERT(!util::parseUIntNoThrow(n, "4294967296"));
-  CPPUNIT_ASSERT(!util::parseUIntNoThrow(n, "-1"));
+  s = "4294967296";
+  CPPUNIT_ASSERT(!util::parseUIntNoThrow(n, s.begin(), s.end()));
+  s = "-1";
+  CPPUNIT_ASSERT(!util::parseUIntNoThrow(n, s.begin(), s.end()));
 }
 
 void UtilTest::testParseLLIntNoThrow()
 {
+  std::string s;
   int64_t n;
-  CPPUNIT_ASSERT(util::parseLLIntNoThrow(n, " 9223372036854775807 "));
+  s = " 9223372036854775807 ";
+  CPPUNIT_ASSERT(util::parseLLIntNoThrow(n, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((int64_t)INT64_MAX, n);
-  CPPUNIT_ASSERT(!util::parseLLIntNoThrow(n, "9223372036854775808"));
-  CPPUNIT_ASSERT(util::parseLLIntNoThrow(n, "-9223372036854775808"));
+  s = "9223372036854775808";
+  CPPUNIT_ASSERT(!util::parseLLIntNoThrow(n, s.begin(), s.end()));
+  s = "-9223372036854775808";
+  CPPUNIT_ASSERT(util::parseLLIntNoThrow(n, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((int64_t)INT64_MIN, n);
-  CPPUNIT_ASSERT(!util::parseLLIntNoThrow(n, "-9223372036854775809"));
+  s = "-9223372036854775809";
+  CPPUNIT_ASSERT(!util::parseLLIntNoThrow(n, s.begin(), s.end()));
 }
 
 void UtilTest::testToString_binaryStream()