Ver código fonte

2009-06-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Avoid intermediate object during string concatenation.  Replaced
	post-increment unary operator with pre-increment one in for loop.	
	* src/AdaptiveURISelector.cc
	* src/AnnounceList.cc
	* src/AuthConfig.h
	* src/BtBitfieldMessage.cc
	* src/BtExtendedMessage.cc
	* src/BtHandshakeMessage.cc
	* src/BtPieceMessage.cc
	* src/BtPortMessage.cc
	* src/Cookie.cc
	* src/DHTAnnouncePeerMessage.cc
	* src/DHTAutoSaveCommand.cc
	* src/DHTGetPeersReplyMessage.cc
	* src/DHTNode.cc
	* src/DHTQueryMessage.cc
	* src/DHTResponseMessage.cc
	* src/DHTUnknownMessage.cc
	* src/DefaultBtAnnounce.cc
	* src/DefaultBtContext.cc
	* src/DefaultBtInteractive.cc
	* src/DefaultBtProgressInfoFile.cc
	* src/DefaultPeerStorage.cc
	* src/DownloadEngine.cc
	* src/FeatureConfig.cc
	* src/File.cc
	* src/FtpConnection.cc
	* src/FtpNegotiationCommand.cc
	* src/HandshakeExtensionMessage.cc
	* src/HttpConnection.cc
	* src/HttpRequest.cc
	* src/HttpResponseCommand.cc
	* src/HttpServer.cc
	* src/IndexBtMessage.cc
	* src/Metalink2RequestGroup.cc
	* src/OptionHandlerImpl.h
	* src/PStringBuildVisitor.cc
	* src/Peer.cc
	* src/PeerListenCommand.cc
	* src/Piece.cc
	* src/RangeBtMessage.cc
	* src/Request.cc
	* src/Request.h
	* src/RequestGroup.cc
	* src/RequestGroupMan.cc
	* src/ServerStat.cc
	* src/ServerStatMan.cc
	* src/UTPexExtensionMessage.cc
	* src/Util.cc
	* src/a2functional.h
	* src/download_helper.cc
	* src/messageDigest.cc
Tatsuhiro Tsujikawa 16 anos atrás
pai
commit
3bb2e3b07e
51 arquivos alterados com 503 adições e 157 exclusões
  1. 55 0
      ChangeLog
  2. 2 2
      src/AdaptiveURISelector.cc
  3. 3 3
      src/AnnounceList.cc
  4. 5 2
      src/AuthConfig.h
  5. 2 1
      src/BtBitfieldMessage.cc
  6. 6 3
      src/BtExtendedMessage.cc
  7. 8 4
      src/BtHandshakeMessage.cc
  8. 3 3
      src/BtPieceMessage.cc
  9. 2 1
      src/BtPortMessage.cc
  10. 2 1
      src/Cookie.cc
  11. 4 3
      src/DHTAnnouncePeerMessage.cc
  12. 8 4
      src/DHTAutoSaveCommand.cc
  13. 4 2
      src/DHTGetPeersReplyMessage.cc
  14. 8 5
      src/DHTNode.cc
  15. 7 6
      src/DHTQueryMessage.cc
  16. 7 6
      src/DHTResponseMessage.cc
  17. 4 2
      src/DHTUnknownMessage.cc
  18. 23 14
      src/DefaultBtAnnounce.cc
  19. 12 8
      src/DefaultBtContext.cc
  20. 5 5
      src/DefaultBtInteractive.cc
  21. 3 1
      src/DefaultBtProgressInfoFile.cc
  22. 1 1
      src/DefaultPeerStorage.cc
  23. 4 3
      src/DownloadEngine.cc
  24. 5 2
      src/FeatureConfig.cc
  25. 1 1
      src/File.cc
  26. 50 16
      src/FtpConnection.cc
  27. 3 1
      src/FtpNegotiationCommand.cc
  28. 3 3
      src/HandshakeExtensionMessage.cc
  29. 2 1
      src/HttpConnection.cc
  30. 5 1
      src/HttpRequest.cc
  31. 3 1
      src/HttpResponseCommand.cc
  32. 5 3
      src/HttpServer.cc
  33. 2 1
      src/IndexBtMessage.cc
  34. 6 3
      src/Metalink2RequestGroup.cc
  35. 27 10
      src/OptionHandlerImpl.h
  36. 3 1
      src/PStringBuildVisitor.cc
  37. 3 1
      src/Peer.cc
  38. 1 1
      src/PeerListenCommand.cc
  39. 3 1
      src/Piece.cc
  40. 4 2
      src/RangeBtMessage.cc
  41. 3 2
      src/Request.cc
  42. 1 1
      src/Request.h
  43. 2 1
      src/RequestGroup.cc
  44. 4 2
      src/RequestGroupMan.cc
  45. 1 1
      src/ServerStat.cc
  46. 5 3
      src/ServerStatMan.cc
  47. 3 2
      src/UTPexExtensionMessage.cc
  48. 22 12
      src/Util.cc
  49. 152 0
      src/a2functional.h
  50. 4 3
      src/download_helper.cc
  51. 2 1
      src/messageDigest.cc

+ 55 - 0
ChangeLog

@@ -1,3 +1,58 @@
+2009-06-06  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Avoid intermediate object during string concatenation.  Replaced
+	post-increment unary operator with pre-increment one in for loop.	
+	* src/AdaptiveURISelector.cc
+	* src/AnnounceList.cc
+	* src/AuthConfig.h
+	* src/BtBitfieldMessage.cc
+	* src/BtExtendedMessage.cc
+	* src/BtHandshakeMessage.cc
+	* src/BtPieceMessage.cc
+	* src/BtPortMessage.cc
+	* src/Cookie.cc
+	* src/DHTAnnouncePeerMessage.cc
+	* src/DHTAutoSaveCommand.cc
+	* src/DHTGetPeersReplyMessage.cc
+	* src/DHTNode.cc
+	* src/DHTQueryMessage.cc
+	* src/DHTResponseMessage.cc
+	* src/DHTUnknownMessage.cc
+	* src/DefaultBtAnnounce.cc
+	* src/DefaultBtContext.cc
+	* src/DefaultBtInteractive.cc
+	* src/DefaultBtProgressInfoFile.cc
+	* src/DefaultPeerStorage.cc
+	* src/DownloadEngine.cc
+	* src/FeatureConfig.cc
+	* src/File.cc
+	* src/FtpConnection.cc
+	* src/FtpNegotiationCommand.cc
+	* src/HandshakeExtensionMessage.cc
+	* src/HttpConnection.cc
+	* src/HttpRequest.cc
+	* src/HttpResponseCommand.cc
+	* src/HttpServer.cc
+	* src/IndexBtMessage.cc
+	* src/Metalink2RequestGroup.cc
+	* src/OptionHandlerImpl.h
+	* src/PStringBuildVisitor.cc
+	* src/Peer.cc
+	* src/PeerListenCommand.cc
+	* src/Piece.cc
+	* src/RangeBtMessage.cc
+	* src/Request.cc
+	* src/Request.h
+	* src/RequestGroup.cc
+	* src/RequestGroupMan.cc
+	* src/ServerStat.cc
+	* src/ServerStatMan.cc
+	* src/UTPexExtensionMessage.cc
+	* src/Util.cc
+	* src/a2functional.h
+	* src/download_helper.cc
+	* src/messageDigest.cc
+
 2009-06-04  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Unchoke a peer randomly at first and second choke round in seed

+ 2 - 2
src/AdaptiveURISelector.cc

@@ -124,7 +124,7 @@ std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
     bool selectBest = numPieces == 0 || reservedContext;
     
     if(numPieces > 0)
-      _nbConnections++;
+      ++_nbConnections;
 
     /* At least, 3 mirrors must be tested */
     if(getNbTestedServers(uris) < 3) {
@@ -335,7 +335,7 @@ unsigned int AdaptiveURISelector::getNbTestedServers
       i != uris.end(); ++i) {
     SharedHandle<ServerStat> ss = getServerStats(*i);
     if(ss.isNull())
-      counter++;
+      ++counter;
   }
   return uris.size() - counter;
 }

+ 3 - 3
src/AnnounceList.cc

@@ -122,11 +122,11 @@ void AnnounceList::announceSuccess() {
 
 void AnnounceList::announceFailure() {
   if(currentTrackerInitialized) {
-    currentTracker++;
+    ++currentTracker;
     if(currentTracker == (*currentTier)->urls.end()) {
       // force next event
       (*currentTier)->nextEventIfAfterStarted();
-      currentTier++;
+      ++currentTier;
       if(currentTier == tiers.end()) {
 	currentTrackerInitialized = false;
       } else {
@@ -238,7 +238,7 @@ void AnnounceList::moveToCompletedAllowedTier() {
 
 void AnnounceList::shuffle() {
   for(AnnounceTiers::iterator itr = tiers.begin();
-      itr != tiers.end(); itr++) {
+      itr != tiers.end(); ++itr) {
     std::deque<std::string>& urls = (*itr)->urls;
     std::random_shuffle(urls.begin(), urls.end(),
 			*(SimpleRandomizer::getInstance().get()));

+ 5 - 2
src/AuthConfig.h

@@ -36,10 +36,13 @@
 #define _D_AUTH_CONFIG_H_
 
 #include "common.h"
-#include "SharedHandle.h"
+
 #include <string>
 #include <iosfwd>
 
+#include "SharedHandle.h"
+#include "a2functional.h"
+
 namespace aria2 {
 
 class AuthConfig {
@@ -55,7 +58,7 @@ public:
 
   std::string getAuthText() const
   {
-    return _user+":"+_password;
+    return strconcat(_user, ":", _password);
   }
 
   const std::string& getUser() const

+ 2 - 1
src/BtBitfieldMessage.cc

@@ -43,6 +43,7 @@
 #include "Peer.h"
 #include "StringFormat.h"
 #include "PieceStorage.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -97,7 +98,7 @@ size_t BtBitfieldMessage::getMessageLength() {
 }
 
 std::string BtBitfieldMessage::toString() const {
-  return NAME+" "+Util::toHex(bitfield, bitfieldLength);
+  return strconcat(NAME, " ", Util::toHex(bitfield, bitfieldLength));
 }
 
 } // namespace aria2

+ 6 - 3
src/BtExtendedMessage.cc

@@ -33,6 +33,10 @@
  */
 /* copyright --> */
 #include "BtExtendedMessage.h"
+
+#include <cassert>
+#include <cstring>
+
 #include "ExtensionMessage.h"
 #include "ExtensionMessageFactory.h"
 #include "PeerMessageUtil.h"
@@ -42,8 +46,7 @@
 #include "message.h"
 #include "Util.h"
 #include "StringFormat.h"
-#include <cassert>
-#include <cstring>
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -92,7 +95,7 @@ bool BtExtendedMessage::sendPredicate() const
 }
 
 std::string BtExtendedMessage::toString() const {
-  return NAME+" "+_extensionMessage->toString();
+  return strconcat(NAME, " ", _extensionMessage->toString());
 }
 
 BtExtendedMessageHandle

+ 8 - 4
src/BtHandshakeMessage.cc

@@ -33,10 +33,13 @@
  */
 /* copyright --> */
 #include "BtHandshakeMessage.h"
+
+#include <cstring>
+
 #include "PeerMessageUtil.h"
 #include "Util.h"
 #include "BtConstants.h"
-#include <cstring>
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -102,9 +105,10 @@ size_t BtHandshakeMessage::getMessageLength() {
 }
 
 std::string BtHandshakeMessage::toString() const {
-  return NAME+" peerId="+
-    Util::urlencode(peerId, PEER_ID_LENGTH)+
-    ", reserved="+Util::toHex(reserved, RESERVED_LENGTH);
+  return strconcat(NAME, " peerId=",
+		   Util::urlencode(peerId, PEER_ID_LENGTH),
+		   ", reserved=",
+		   Util::toHex(reserved, RESERVED_LENGTH));
 }
 
 bool BtHandshakeMessage::isFastExtensionSupported() const {

+ 3 - 3
src/BtPieceMessage.cc

@@ -168,8 +168,8 @@ size_t BtPieceMessage::sendPieceData(off_t offset, size_t length) const {
 }
 
 std::string BtPieceMessage::toString() const {
-  return NAME+" index="+Util::itos(index)+", begin="+Util::itos(begin)+
-    ", length="+Util::itos(blockLength);
+  return strconcat(NAME, " index=", Util::itos(index), ", begin=",
+		   Util::itos(begin), ", length=", Util::itos(blockLength));
 }
 
 bool BtPieceMessage::checkPieceHash(const PieceHandle& piece) {
@@ -205,7 +205,7 @@ void BtPieceMessage::erasePieceOnDisk(const PieceHandle& piece) {
   memset(buf, 0, BUFSIZE);
   off_t offset = (off_t)piece->getIndex()*btContext->getPieceLength();
   div_t res = div(piece->getLength(), BUFSIZE);
-  for(int i = 0; i < res.quot; i++) {
+  for(int i = 0; i < res.quot; ++i) {
     pieceStorage->getDiskAdaptor()->writeData(buf, BUFSIZE, offset);
     offset += BUFSIZE;
   }

+ 2 - 1
src/BtPortMessage.cc

@@ -45,6 +45,7 @@
 #include "DHTTaskFactory.h"
 #include "DHTTask.h"
 #include "StringFormat.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -109,7 +110,7 @@ size_t BtPortMessage::getMessageLength() {
 }
 
 std::string BtPortMessage::toString() const {
-  return NAME+" port="+Util::uitos(_port);
+  return strconcat(NAME, " port=", Util::uitos(_port));
 }
 
 void BtPortMessage::setLocalNode(const WeakHandle<DHTNode>& localNode)

+ 2 - 1
src/Cookie.cc

@@ -40,6 +40,7 @@
 #include "Util.h"
 #include "A2STR.h"
 #include "TimeA2.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -98,7 +99,7 @@ Cookie::~Cookie() {}
 
 std::string Cookie::toString() const
 {
-  return _name+"="+_value;
+  return strconcat(_name, "=", _value);
 }
 
 bool Cookie::good() const

+ 4 - 3
src/DHTAnnouncePeerMessage.cc

@@ -48,6 +48,7 @@
 #include "BtConstants.h"
 #include "StringFormat.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -124,9 +125,9 @@ void DHTAnnouncePeerMessage::setTokenTracker(const WeakHandle<DHTTokenTracker>&
 
 std::string DHTAnnouncePeerMessage::toStringOptional() const
 {
-  return "token="+Util::toHex(_token)+
-    ", info_hash="+Util::toHex(_infoHash, INFO_HASH_LENGTH)+
-    ", tcpPort="+Util::uitos(_tcpPort);
+  return strconcat("token=", Util::toHex(_token),
+		   ", info_hash=", Util::toHex(_infoHash, INFO_HASH_LENGTH),
+		   ", tcpPort=", Util::uitos(_tcpPort));
 }
 
 } // namespace aria2

+ 8 - 4
src/DHTAutoSaveCommand.cc

@@ -33,6 +33,11 @@
  */
 /* copyright --> */
 #include "DHTAutoSaveCommand.h"
+
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+
 #include "DHTRoutingTable.h"
 #include "DHTNode.h"
 #include "File.h"
@@ -46,9 +51,7 @@
 #include "Option.h"
 #include "message.h"
 #include "Logger.h"
-#include <cerrno>
-#include <fstream>
-#include <cstring>
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -75,7 +78,8 @@ void DHTAutoSaveCommand::save()
   std::string dhtFile = _e->option->get(PREF_DHT_FILE_PATH);
   logger->info("Saving DHT routing table to %s.", dhtFile.c_str());
 
-  std::string tempFile = dhtFile+"__temp";
+  std::string tempFile = dhtFile;
+  tempFile += "__temp";
   {
     File f(tempFile);
     if(!f.isFile()) {

+ 4 - 2
src/DHTGetPeersReplyMessage.cc

@@ -47,6 +47,7 @@
 #include "DHTUtil.h"
 #include "Util.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -124,8 +125,9 @@ void DHTGetPeersReplyMessage::setValues(const std::deque<SharedHandle<Peer> >& p
 
 std::string DHTGetPeersReplyMessage::toStringOptional() const
 {
-  return "token="+Util::toHex(_token)+", values="+Util::uitos(_values.size())+
-    ", nodes="+Util::uitos(_closestKNodes.size());
+  return strconcat("token=", Util::toHex(_token),
+		   ", values=", Util::uitos(_values.size()),
+		   ", nodes=", Util::uitos(_closestKNodes.size()));
 }
 
 } // namespace aria2

+ 8 - 5
src/DHTNode.cc

@@ -33,9 +33,12 @@
  */
 /* copyright --> */
 #include "DHTNode.h"
+
+#include <cstring>
+
 #include "DHTUtil.h"
 #include "Util.h"
-#include <cstring>
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -110,10 +113,10 @@ void DHTNode::timeout()
 
 std::string DHTNode::toString() const
 {
-  return "DHTNode ID="+Util::toHex(_id, DHT_ID_LENGTH)+
-    ", Host="+_ipaddr+":"+Util::uitos(_port)+
-    ", Condition="+Util::uitos(_condition)+
-    ", RTT="+Util::uitos(_rtt);
+  return strconcat("DHTNode ID=", Util::toHex(_id, DHT_ID_LENGTH),
+		   ", Host=", _ipaddr, ":", Util::uitos(_port),
+		   ", Condition=", Util::uitos(_condition),
+		   ", RTT=", Util::uitos(_rtt));
 }
 
 void DHTNode::setID(const unsigned char* id)

+ 7 - 6
src/DHTQueryMessage.cc

@@ -36,6 +36,7 @@
 #include "DHTNode.h"
 #include "Util.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -68,12 +69,12 @@ bool DHTQueryMessage::isReply() const
 
 std::string DHTQueryMessage::toString() const
 {
-  return "dht query "+getMessageType()+
-    " TransactionID="+Util::toHex(_transactionID)+
-    " Remote:"+
-    _remoteNode->getIPAddress()+":"+Util::uitos(_remoteNode->getPort())+
-    ", id="+Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH)+
-    ", "+toStringOptional();
+  return strconcat("dht query ", getMessageType(),
+		   " TransactionID=", Util::toHex(_transactionID),
+		   " Remote:", _remoteNode->getIPAddress(),
+		   ":", Util::uitos(_remoteNode->getPort()),
+		   ", id=", Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH),
+		   ", ", toStringOptional());
 }
 
 } // namespace aria2

+ 7 - 6
src/DHTResponseMessage.cc

@@ -36,6 +36,7 @@
 #include "DHTNode.h"
 #include "Util.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -65,12 +66,12 @@ bool DHTResponseMessage::isReply() const
 
 std::string DHTResponseMessage::toString() const
 {
-  return "dht response "+getMessageType()+
-    " TransactionID="+Util::toHex(_transactionID)+
-    " Remote:"+
-    _remoteNode->getIPAddress()+":"+Util::uitos(_remoteNode->getPort())+
-    ", id="+Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH)+
-    ", "+toStringOptional();
+  return strconcat("dht response ", getMessageType(),
+		   " TransactionID=", Util::toHex(_transactionID),
+		   " Remote:", _remoteNode->getIPAddress(),
+		   ":", Util::uitos(_remoteNode->getPort()),
+		   ", id=", Util::toHex(_remoteNode->getID(), DHT_ID_LENGTH),
+		   ", ", toStringOptional());
 }
 
 } // namespace aria2

+ 4 - 2
src/DHTUnknownMessage.cc

@@ -39,6 +39,7 @@
 
 #include "DHTNode.h"
 #include "Util.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -91,8 +92,9 @@ std::string DHTUnknownMessage::toString() const
   }
   std::string sample(&_data[0], &_data[sampleLength]);
 
-  return "dht unknown Remote:"+_ipaddr+":"+Util::uitos(_port)+" length="+
-    Util::uitos(_length)+", first 8 bytes(hex)="+Util::toHex(sample);
+  return strconcat("dht unknown Remote:", _ipaddr, ":", Util::uitos(_port),
+		   " length=", Util::uitos(_length),
+		   ", first 8 bytes(hex)=", Util::toHex(sample));
 }
 
 } // namespace aria2

+ 23 - 14
src/DefaultBtAnnounce.cc

@@ -144,23 +144,31 @@ std::string DefaultBtAnnounce::getAnnounceUrl() {
     pieceStorage->getTotalLength()-pieceStorage->getCompletedLength();
   std::string url = announceList.getAnnounce();
   url += uriHasQuery(url) ? "&" : "?";
-  url += 
-    "info_hash="+Util::torrentUrlencode(btContext->getInfoHash(),
-					btContext->getInfoHashLength())+
-    "&peer_id="+Util::torrentUrlencode(btContext->getPeerId(), 20)+
-    "&uploaded="+Util::uitos(stat.getSessionUploadLength())+
-    "&downloaded="+Util::uitos(stat.getSessionDownloadLength())+
-    "&left="+Util::uitos(left)+
-    "&compact=1"+
-    "&key="+key+
-    "&numwant="+Util::uitos(numWant)+
-    "&no_peer_id=1";
+  url += "info_hash=";
+  url += Util::torrentUrlencode(btContext->getInfoHash(),
+				btContext->getInfoHashLength());
+  url += "&peer_id=";
+  url += Util::torrentUrlencode(btContext->getPeerId(), 20);
+  url += "&uploaded=";
+  url += Util::uitos(stat.getSessionUploadLength());
+  url += "&downloaded=";
+  url += Util::uitos(stat.getSessionDownloadLength());
+  url += "&left=";
+  url += Util::uitos(left);
+  url += "&compact=1";
+  url += "&key=";
+  url += key;
+  url += "&numwant=";
+  url += Util::uitos(numWant);
+  url += "&no_peer_id=1";
   if(btRuntime->getListenPort() > 0) {
-    url += "&port="+Util::uitos(btRuntime->getListenPort());
+    url += "&port=";
+    url += Util::uitos(btRuntime->getListenPort());
   }
   std::string event = announceList.getEventString();
   if(!event.empty()) {
-    url += "&event="+event;
+    url += "&event=";
+    url += event;
   }
   if(!trackerId.empty()) {
     url += "&trackerid="+Util::torrentUrlencode(trackerId);
@@ -171,7 +179,8 @@ std::string DefaultBtAnnounce::getAnnounceUrl() {
     url += "&supportcrypto=1";
   }
   if(!option->blank(PREF_BT_EXTERNAL_IP)) {
-    url += "&ip="+option->get(PREF_BT_EXTERNAL_IP);
+    url += "&ip=";
+    url += option->get(PREF_BT_EXTERNAL_IP);
   }
   return url;
 }

+ 12 - 8
src/DefaultBtContext.cc

@@ -54,6 +54,7 @@
 #include "StringFormat.h"
 #include "A2STR.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -135,7 +136,7 @@ void DefaultBtContext::extractPieceHash(const std::string& hashData,
 					size_t hashLength)
 {
   size_t numPieces = hashData.size()/hashLength;
-  for(size_t i = 0; i < numPieces; i++) {
+  for(size_t i = 0; i < numPieces; ++i) {
     pieceHashes.push_back(Util::toHex(hashData.data()+i*hashLength,
 				      hashLength));
   }
@@ -157,7 +158,7 @@ void DefaultBtContext::extractFileEntries(const BDE& infoDict,
     if(nameData.isString()) {
       name = nameData.s();
     } else {
-      name = File(defaultName).getBasename()+".file";
+      name = strconcat(File(defaultName).getBasename(), ".file");
     }
   } else {
     name = overrideName;
@@ -196,8 +197,8 @@ void DefaultBtContext::extractFileEntries(const BDE& infoDict,
       std::vector<std::string> pathelem(pathList.size());
       std::transform(pathList.listBegin(), pathList.listEnd(), pathelem.begin(),
 		     std::mem_fun_ref(&BDE::s));
-      std::string path =
-	name+"/"+Util::joinPath(pathelem.begin(), pathelem.end());
+      std::string path = name;
+      strappend(path, "/", Util::joinPath(pathelem.begin(), pathelem.end()));
       // Split path with '/' again because each pathList element can
       // contain "/" inside.
       std::deque<std::string> elements;
@@ -207,7 +208,8 @@ void DefaultBtContext::extractFileEntries(const BDE& infoDict,
       std::deque<std::string> uris;
       std::transform(urlList.begin(), urlList.end(), std::back_inserter(uris),
 		     std::bind2nd(std::plus<std::string>(), "/"+path));
-      FileEntryHandle fileEntry(new FileEntry(_dir+"/"+path, fileLengthData.i(),
+      FileEntryHandle fileEntry(new FileEntry(strconcat(_dir, "/", path),
+					      fileLengthData.i(),
 					      offset, uris));
       fileEntries.push_back(fileEntry);
       offset += fileEntry->getLength();
@@ -239,7 +241,9 @@ void DefaultBtContext::extractFileEntries(const BDE& infoDict,
     }
 
     SharedHandle<FileEntry> fileEntry
-      (new FileEntry(_dir+"/"+Util::joinPath(pathelems.begin(),pathelems.end()),
+      (new FileEntry(strconcat(_dir, "/",
+			       Util::joinPath(pathelems.begin(),
+					      pathelems.end())),
 		     totalLength, 0, uris));
     fileEntries.push_back(fileEntry);
   }
@@ -463,7 +467,7 @@ std::string DefaultBtContext::getActualBasePath() const
   if(fileEntries.size() == 1) {
     return fileEntries.front()->getPath();
   } else {
-    return _dir+"/"+name;
+    return strconcat(_dir, "/", name);
   }
 }
 
@@ -489,7 +493,7 @@ void DefaultBtContext::computeFastSet
   unsigned char x[20];
   MessageDigestHelper::digest(x, sizeof(x), MessageDigestContext::SHA1, tx, 24);
   while(fastSet.size() < fastSetSize) {
-    for(size_t i = 0; i < 5 && fastSet.size() < fastSetSize; i++) {
+    for(size_t i = 0; i < 5 && fastSet.size() < fastSetSize; ++i) {
       size_t j = i*4;
       uint32_t ny;
       memcpy(&ny, x+j, 4);

+ 5 - 5
src/DefaultBtInteractive.cc

@@ -190,7 +190,7 @@ void DefaultBtInteractive::addAllowedFastMessageToQueue() {
     std::deque<size_t> fastSet;
     _btContext->computeFastSet(fastSet, peer->ipaddr, allowedFastSetSize);
     for(std::deque<size_t>::const_iterator itr = fastSet.begin();
-	itr != fastSet.end(); itr++) {
+	itr != fastSet.end(); ++itr) {
       dispatcher->addMessageToQueue
 	(messageFactory->createAllowedFastMessage(*itr));
     }
@@ -221,7 +221,7 @@ void DefaultBtInteractive::checkHave() {
     }
   } else {
     for(std::deque<size_t>::iterator itr = indexes.begin();
-	itr != indexes.end(); itr++) {
+	itr != indexes.end(); ++itr) {
       dispatcher->addMessageToQueue(messageFactory->createHaveMessage(*itr));
     }
   }
@@ -237,7 +237,7 @@ void DefaultBtInteractive::sendKeepAlive() {
 
 size_t DefaultBtInteractive::receiveMessages() {
   size_t msgcount = 0;
-  for(int i = 0; i < 50; i++) {
+  for(int i = 0; i < 50; ++i) {
     if(_requestGroupMan->doesOverallDownloadSpeedExceed() ||
        _btContext->getOwnerRequestGroup()->doesDownloadSpeedExceed()) {
       break;
@@ -382,7 +382,7 @@ void DefaultBtInteractive::checkActiveInteraction()
   // To allow aria2 to accept mutially interested peer, disconnect unintersted
   // peer.
   {
-    time_t interval = 30;
+    const time_t interval = 30;
     if(!peer->amInterested() && !peer->peerInterested() &&
        inactiveCheckPoint.elapsed(interval)) {
       // TODO change the message
@@ -395,7 +395,7 @@ void DefaultBtInteractive::checkActiveInteraction()
   // mutual download progress are completely waste of resources, those peers
   // are disconnected in a certain time period.
   {
-    time_t interval = 2*60;
+    const time_t interval = 2*60;
     if(inactiveCheckPoint.elapsed(interval)) {
       throw DL_ABORT_EX
 	(StringFormat(EX_DROP_INACTIVE_CONNECTION, interval).str());

+ 3 - 1
src/DefaultBtProgressInfoFile.cc

@@ -66,7 +66,9 @@ const std::string DefaultBtProgressInfoFile::V0001("0001");
 
 static std::string createFilename(const SharedHandle<DownloadContext>& dctx)
 {
-  return dctx->getActualBasePath()+".aria2";
+  std::string t = dctx->getActualBasePath();
+  t += ".aria2";
+  return t;
 }
 
 DefaultBtProgressInfoFile::DefaultBtProgressInfoFile

+ 1 - 1
src/DefaultPeerStorage.cc

@@ -111,7 +111,7 @@ bool DefaultPeerStorage::addPeer(const PeerHandle& peer) {
 
 void DefaultPeerStorage::addPeer(const Peers& peers) {
   for(Peers::const_iterator itr = peers.begin();
-      itr != peers.end(); itr++) {
+      itr != peers.end(); ++itr) {
     const PeerHandle& peer = *itr;
     if(addPeer(peer)) {
       logger->debug(MSG_ADDING_PEER,

+ 4 - 3
src/DownloadEngine.cc

@@ -107,7 +107,7 @@ static void executeCommand(std::deque<Command*>& commands,
 			   Command::STATUS statusFilter)
 {
   size_t max = commands.size();
-  for(size_t i = 0; i < max; i++) {
+  for(size_t i = 0; i < max; ++i) {
     Command* com = commands.front();
     commands.pop_front();
     if(com->statusMatch(statusFilter)) {
@@ -271,7 +271,7 @@ void DownloadEngine::poolSocket(const std::string& ipaddr,
 				uint16_t port,
 				const SocketPoolEntry& entry)
 {
-  std::string addr = ipaddr+":"+Util::uitos(port);
+  std::string addr = strconcat(ipaddr, ":", Util::uitos(port));
   logger->info("Pool socket for %s", addr.c_str());
   std::multimap<std::string, SocketPoolEntry>::value_type p(addr, entry);
   _socketPool.insert(p);
@@ -349,7 +349,8 @@ void DownloadEngine::poolSocket
 std::multimap<std::string, DownloadEngine::SocketPoolEntry>::iterator
 DownloadEngine::findSocketPoolEntry(const std::string& ipaddr, uint16_t port)
 {
-  std::string addr = ipaddr+":"+Util::uitos(port);
+  std::string addr = ipaddr;
+  strappend(addr, ":", Util::uitos(port));
   std::pair<std::multimap<std::string, SocketPoolEntry>::iterator,
     std::multimap<std::string, SocketPoolEntry>::iterator> range =
     _socketPool.equal_range(addr);

+ 5 - 2
src/FeatureConfig.cc

@@ -33,10 +33,12 @@
  */
 /* copyright --> */
 #include "FeatureConfig.h"
+
+#include <numeric>
+
 #include "array_fun.h"
 #include "Util.h"
 #include "Request.h"
-#include <numeric>
 
 namespace aria2 {
 
@@ -144,7 +146,8 @@ std::string FeatureConfig::featureSummary() const
   for(FeatureMap::const_iterator i = _features.begin();
       i != _features.end(); ++i) {
     if((*i).second) {
-      s += (*i).first+", ";
+      s += (*i).first;
+      s += ", ";
     }
   }
   return Util::trim(s, ", ");

+ 1 - 1
src/File.cc

@@ -114,7 +114,7 @@ bool File::mkdirs() {
     accDir = A2STR::SLASH_C;
   }
   for(std::deque<std::string>::const_iterator itr = dirs.begin(); itr != dirs.end();
-      itr++, accDir += A2STR::SLASH_C) {
+      ++itr, accDir += A2STR::SLASH_C) {
     accDir += *itr;
     if(File(accDir).isDir()) {
       continue;

+ 50 - 16
src/FtpConnection.cc

@@ -54,6 +54,7 @@
 #include "A2STR.h"
 #include "StringFormat.h"
 #include "AuthConfig.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -76,7 +77,9 @@ FtpConnection::~FtpConnection() {}
 bool FtpConnection::sendUser()
 {
   if(_socketBuffer.sendBufferIsEmpty()) {
-    std::string request = "USER "+_authConfig->getUser()+"\r\n";
+    std::string request = "USER ";
+    request += _authConfig->getUser();
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, "USER ********");
     _socketBuffer.feedSendBuffer(request);
   }
@@ -87,7 +90,9 @@ bool FtpConnection::sendUser()
 bool FtpConnection::sendPass()
 {
   if(_socketBuffer.sendBufferIsEmpty()) {
-    std::string request = "PASS "+_authConfig->getPassword()+"\r\n";
+    std::string request = "PASS ";
+    request += _authConfig->getPassword();
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
     _socketBuffer.feedSendBuffer(request);
   }
@@ -104,7 +109,9 @@ bool FtpConnection::sendType()
     } else {
       type = FtpConnection::I;
     }
-    std::string request = "TYPE "+type+"\r\n";
+    std::string request = "TYPE ";
+    request += type;
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -128,9 +135,12 @@ bool FtpConnection::sendCwd()
   if(_socketBuffer.sendBufferIsEmpty()) {
     logger->info("CUID#%d - Using base working directory '%s'",
 		 cuid, _baseWorkingDir.c_str());
-    std::string request = "CWD "+
-      (_baseWorkingDir == "/" ? "" : _baseWorkingDir)+
-      Util::urldecode(req->getDir())+"\r\n";
+    std::string request = "CWD ";
+    if(_baseWorkingDir != "/") {
+      request += _baseWorkingDir;
+    }
+    request += Util::urldecode(req->getDir());
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -141,7 +151,9 @@ bool FtpConnection::sendCwd()
 bool FtpConnection::sendMdtm()
 {
   if(_socketBuffer.sendBufferIsEmpty()) {
-    std::string request = "MDTM "+Util::urlencode(req->getFile())+"\r\n";
+    std::string request = "MDTM ";
+    request += Util::urlencode(req->getFile());
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -152,7 +164,9 @@ bool FtpConnection::sendMdtm()
 bool FtpConnection::sendSize()
 {
   if(_socketBuffer.sendBufferIsEmpty()) {
-    std::string request = "SIZE "+Util::urldecode(req->getFile())+"\r\n";
+    std::string request = "SIZE ";
+    request += Util::urldecode(req->getFile());
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -189,11 +203,19 @@ bool FtpConnection::sendPort(const SharedHandle<SocketCore>& serverSocket)
     sscanf(addrinfo.first.c_str(), "%u.%u.%u.%u",
 	   &ipaddr[0], &ipaddr[1], &ipaddr[2], &ipaddr[3]);
     serverSocket->getAddrInfo(addrinfo);
-    std::string request = "PORT "+
-      Util::uitos(ipaddr[0])+","+Util::uitos(ipaddr[1])+","+
-      Util::uitos(ipaddr[2])+","+Util::uitos(ipaddr[3])+","+
-      Util::uitos(addrinfo.second/256)+","+
-      Util::uitos(addrinfo.second%256)+"\r\n";
+    std::string request = "PORT ";
+    request += Util::uitos(ipaddr[0]);
+    request += ",";
+    request += Util::uitos(ipaddr[1]);
+    request += ",";
+    request += Util::uitos(ipaddr[2]);
+    request += ",";
+    request += Util::uitos(ipaddr[3]);
+    request += ",";
+    request += Util::uitos(addrinfo.second/256);
+    request += ",";
+    request += Util::uitos(addrinfo.second%256);
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -222,7 +244,9 @@ bool FtpConnection::sendRest(const SegmentHandle& segment)
 bool FtpConnection::sendRetr()
 {
   if(_socketBuffer.sendBufferIsEmpty()) {
-    std::string request = "RETR "+Util::urldecode(req->getFile())+"\r\n";
+    std::string request = "RETR ";
+    request += Util::urldecode(req->getFile());
+    request += "\r\n";
     logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
     _socketBuffer.feedSendBuffer(request);
   }
@@ -260,7 +284,11 @@ FtpConnection::findEndOfResponse(unsigned int status,
   if(buf.at(3) == '-') {
     // multi line response
     std::string::size_type p;
-    p = buf.find(A2STR::CRLF+Util::uitos(status)+" ");
+
+    std::string endPattern = A2STR::CRLF;
+    endPattern += Util::uitos(status);
+    endPattern += " ";
+    p = buf.find(endPattern);
     if(p == std::string::npos) {
       return std::string::npos;
     }
@@ -407,7 +435,13 @@ unsigned int FtpConnection::receivePasvResponse(std::pair<std::string, uint16_t>
 	       "(%u,%u,%u,%u,%u,%u).",
 	       &h1, &h2, &h3, &h4, &p1, &p2);
 	// ip address
-	dest.first = Util::uitos(h1)+"."+Util::uitos(h2)+"."+Util::uitos(h3)+"."+Util::uitos(h4);
+ 	dest.first = Util::uitos(h1);
+ 	dest.first += ".";
+	dest.first += Util::uitos(h2);
+	dest.first += ".";
+	dest.first += Util::uitos(h3);
+	dest.first += ".";
+	dest.first += Util::uitos(h4);
 	// port number
 	dest.second = 256*p1+p2;
       } else {

+ 3 - 1
src/FtpNegotiationCommand.cc

@@ -64,6 +64,7 @@
 #include "SegmentMan.h"
 #include "AuthConfigFactory.h"
 #include "AuthConfig.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -327,7 +328,8 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
   SingleFileDownloadContextHandle dctx =
     dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext());
   dctx->setTotalLength(totalLength);
-  dctx->setFilename(dctx->getDir()+"/"+Util::urldecode(req->getFile()));
+  dctx->setFilename
+    (strconcat(dctx->getDir(), "/", Util::urldecode(req->getFile())));
   _requestGroup->preDownloadProcessing();
   if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
     throw DOWNLOAD_FAILURE_EXCEPTION

+ 3 - 3
src/HandshakeExtensionMessage.cc

@@ -76,15 +76,15 @@ std::string HandshakeExtensionMessage::toString() const
 {
   std::string s = getExtensionName();
   if(!_clientVersion.empty()) {
-    s += " client="+Util::urlencode(_clientVersion);
+    strappend(s, " client=", Util::urlencode(_clientVersion));
   }
   if(_tcpPort > 0) {
-    s += ", tcpPort="+Util::uitos(_tcpPort);
+    strappend(s, ", tcpPort=", Util::uitos(_tcpPort));
   }
   for(std::map<std::string, uint8_t>::const_iterator itr = _extensions.begin();
       itr != _extensions.end(); ++itr) {
     const std::map<std::string, uint8_t>::value_type& vt = *itr;
-    s += ", "+vt.first+"="+Util::uitos(vt.second);
+    strappend(s, ", ", vt.first, "=", Util::uitos(vt.second));
   }
   return s;
 }

+ 2 - 1
src/HttpConnection.cc

@@ -54,6 +54,7 @@
 #include "CookieStorage.h"
 #include "AuthConfigFactory.h"
 #include "AuthConfig.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -84,7 +85,7 @@ std::string HttpConnection::eraseConfidentialInfo(const std::string& request)
     } else if(Util::startsWith(line, PROXY_AUTH_HEADER)) {
       result += "Proxy-Authorization: Basic ********\n";
     } else {
-      result += line+"\n";
+      strappend(result, line, "\n");
     }
   }
   return result;

+ 5 - 1
src/HttpRequest.cc

@@ -118,7 +118,11 @@ bool HttpRequest::isRangeSatisfied(const RangeHandle& range) const
 
 std::string HttpRequest::getHostText(const std::string& host, uint16_t port) const
 {
-  return  host+(port == 80 || port == 443 ? "" : ":"+Util::uitos(port));
+  std::string hosttext = host;
+  if(!(port == 80 || port == 443)) {
+    strappend(hosttext, ":", Util::uitos(port));
+  }
+  return hosttext;
 }
 
 std::string HttpRequest::createRequest()

+ 3 - 1
src/HttpResponseCommand.cc

@@ -65,6 +65,7 @@
 #include "CookieStorage.h"
 #include "AuthConfigFactory.h"
 #include "AuthConfig.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -135,7 +136,8 @@ bool HttpResponseCommand::executeInternal()
     SingleFileDownloadContextHandle dctx =
       dynamic_pointer_cast<SingleFileDownloadContext>(_requestGroup->getDownloadContext());
     dctx->setTotalLength(totalLength);
-    dctx->setFilename(dctx->getDir()+"/"+httpResponse->determinFilename());
+    dctx->setFilename
+      (strconcat(dctx->getDir(), "/", httpResponse->determinFilename()));
     dctx->setContentType(httpResponse->getContentType());
     _requestGroup->preDownloadProcessing();
     if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {

+ 5 - 3
src/HttpServer.cc

@@ -45,6 +45,7 @@
 #include "LogFactory.h"
 #include "Logger.h"
 #include "Base64.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -144,9 +145,10 @@ void HttpServer::feedResponse(const std::string& status,
 			      const std::string& text,
 			      const std::string& contentType)
 {
-  std::string header = "HTTP/1.1 "+status+"\r\n"
-    "Content-Type: "+contentType+"\r\n"
-    "Content-Length: "+Util::uitos(text.size())+"\r\n";
+  std::string header = "HTTP/1.1 ";
+  strappend(header, status, "\r\n",
+	    "Content-Type: ", contentType, "\r\n",
+	    "Content-Length: ", Util::uitos(text.size()), "\r\n");
 
   if(!supportsPersistentConnection()) {
     header += "Connection: close\r\n";

+ 2 - 1
src/IndexBtMessage.cc

@@ -34,6 +34,7 @@
 /* copyright --> */
 #include "IndexBtMessage.h"
 #include "Util.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -60,7 +61,7 @@ size_t IndexBtMessage::getMessageLength()
 
 std::string IndexBtMessage::toString() const
 {
-  return getName()+" index="+Util::itos(_index);
+  return strconcat(getName(), " index=", Util::itos(_index));
 }
 
 } // namespace aria2

+ 6 - 3
src/Metalink2RequestGroup.cc

@@ -33,6 +33,9 @@
  */
 /* copyright --> */
 #include "Metalink2RequestGroup.h"
+
+#include <algorithm>
+
 #include "RequestGroup.h"
 #include "Option.h"
 #include "LogFactory.h"
@@ -49,6 +52,7 @@
 #include "MetalinkResource.h"
 #include "FileEntry.h"
 #include "A2STR.h"
+#include "a2functional.h"
 #ifdef ENABLE_BITTORRENT
 # include "BtDependency.h"
 #endif // ENABLE_BITTORRENT
@@ -56,7 +60,6 @@
 # include "Checksum.h"
 # include "ChunkChecksum.h"
 #endif // ENABLE_MESSAGE_DIGEST
-#include <algorithm>
 
 namespace aria2 {
 
@@ -136,7 +139,7 @@ Metalink2RequestGroup::createRequestGroup
   }
   int32_t count = 0;
   for(std::deque<SharedHandle<MetalinkEntry> >::iterator itr = entries.begin(); itr != entries.end();
-      itr++, ++count) {
+      ++itr, ++count) {
     SharedHandle<MetalinkEntry>& entry = *itr;
     if(option->defined(PREF_METALINK_LOCATION)) {
       std::deque<std::string> locations;
@@ -210,7 +213,7 @@ Metalink2RequestGroup::createRequestGroup
        (pieceLength,
 	entry->getLength(),
 	A2STR::NIL,
-	option->get(PREF_DIR)+"/"+entry->file->getPath()));
+	strconcat(option->get(PREF_DIR), "/", entry->file->getPath())));
     dctx->setDir(option->get(PREF_DIR));
 #ifdef ENABLE_MESSAGE_DIGEST
     if(entry->chunkChecksum.isNull()) {

+ 27 - 10
src/OptionHandlerImpl.h

@@ -52,6 +52,7 @@
 #include "StringFormat.h"
 #include "A2STR.h"
 #include "Request.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -126,7 +127,8 @@ public:
     } else if(optarg == "false") {
       option.put(_optName, V_FALSE);
     } else {
-      std::string msg = _optName+" "+_("must be either 'true' or 'false'.");
+      std::string msg = _optName;
+      strappend(msg, " ", _("must be either 'true' or 'false'."));
       throw DL_ABORT_EX(msg);
     }
   }
@@ -159,7 +161,8 @@ public:
     while(seq.hasNext()) {
       int32_t v = seq.next();
       if(v < _min || _max < v) {
-	std::string msg = _optName+" "+_("must be between %s and %s.");
+	std::string msg = _optName;
+	strappend(msg, " ", _("must be between %s and %s."));
 	throw DL_ABORT_EX
 	  (StringFormat(msg.c_str(), Util::itos(_min).c_str(),
 			Util::itos(_max).c_str()).str());
@@ -202,7 +205,8 @@ public:
     if((_min == -1 || _min <= number) && (_max ==  -1 || number <= _max)) {
       option.put(_optName, Util::itos(number));
     } else {
-      std::string msg = _optName+" ";
+      std::string msg = _optName;
+      msg += " ";
       if(_min == -1 && _max != -1) {
 	msg += StringFormat(_("must be smaller than or equal to %s."),
 			    Util::itos(_max).c_str()).str();
@@ -221,8 +225,19 @@ public:
 
   virtual std::string createPossibleValuesString() const
   {
-    return (_min == -1 ? "*" : Util::itos(_min))+"-"+
-      (_max == -1 ? "*" : Util::itos(_max));
+    std::string values;
+    if(_min == -1) {
+      values += "*";
+    } else {
+      values += Util::itos(_min);
+    }
+    values += "-";
+    if(_max == -1) {
+      values += "*";
+    } else {
+      values += Util::itos(_max);
+    }
+    return values;
   }
 };
 
@@ -268,7 +283,8 @@ public:
     if((_min < 0 || _min <= number) && (_max < 0 || number <= _max)) {
       option.put(_optName, optarg);
     } else {
-      std::string msg = _optName+" ";
+      std::string msg = _optName;
+      msg += " ";
       if(_min < 0 && _max >= 0) {
 	msg += StringFormat(_("must be smaller than or equal to %.1f."),
 			    _max).str();
@@ -358,7 +374,7 @@ public:
   virtual void parseArg(Option& option, const std::string& optarg)
   {
     std::string value = option.get(_optName);
-    value += optarg+_delim;
+    strappend(value, optarg, _delim);
     option.put(_optName, value);
   }
 
@@ -384,7 +400,7 @@ public:
     // See optarg is in the fomrat of "INDEX=PATH"
     Util::parseIndexPath(optarg);
     std::string value = option.get(_optName);
-    value += optarg+"\n";
+    strappend(value, optarg, "\n");
     option.put(_optName, value);
   }
 
@@ -453,13 +469,14 @@ public:
     std::deque<std::string>::const_iterator itr =
       std::find(_validParamValues.begin(), _validParamValues.end(), optarg);
     if(itr == _validParamValues.end()) {
-      std::string msg = _optName+" "+_("must be one of the following:");
+      std::string msg = _optName;
+      strappend(msg, " ", _("must be one of the following:"));
       if(_validParamValues.size() == 0) {
 	msg += "''";
       } else {
 	for(std::deque<std::string>::const_iterator itr = _validParamValues.begin();
 	    itr != _validParamValues.end(); ++itr) {
-	  msg += "'"+*itr+"' ";
+	  strappend(msg, "'", *itr, "' ");
 	}
       }
       throw DL_ABORT_EX(msg);

+ 3 - 1
src/PStringBuildVisitor.cc

@@ -36,6 +36,7 @@
 #include "PStringSegment.h"
 #include "PStringNumLoop.h"
 #include "PStringSelect.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -45,7 +46,8 @@ void PStringBuildVisitor::visit(PStringSegment& segment)
   if(_buildQueue.empty()) {
     uri += segment.getValue();
   } else {
-    uri = _buildQueue.front()+segment.getValue();
+    uri = _buildQueue.front();
+    uri += segment.getValue();
   }
   _buildQueue.push_front(uri);
   if(!segment.hasNext()) {

+ 3 - 1
src/Peer.cc

@@ -38,6 +38,7 @@
 #include <cassert>
 
 #include "Util.h"
+#include "a2functional.h"
 #include "PeerSessionResource.h"
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "MessageDigestHelper.h"
@@ -58,7 +59,8 @@ Peer::Peer(std::string ipaddr, uint16_t port, bool incoming):
 {
   memset(_peerId, 0, PEER_ID_LENGTH);
   resetStatus();
-  std::string idSeed = ipaddr+":"+Util::uitos(port);
+  std::string idSeed = ipaddr;
+  strappend(idSeed, ":", Util::uitos(port));
 #ifdef ENABLE_MESSAGE_DIGEST
   id = MessageDigestHelper::digestString(MessageDigestContext::SHA1, idSeed);
 #else

+ 1 - 1
src/PeerListenCommand.cc

@@ -99,7 +99,7 @@ bool PeerListenCommand::execute() {
   if(e->isHaltRequested() || e->_requestGroupMan->downloadFinished()) {
     return true;
   }
-  for(int i = 0; i < 3 && socket->isReadable(0); i++) {
+  for(int i = 0; i < 3 && socket->isReadable(0); ++i) {
     SocketHandle peerSocket;
     try {
       peerSocket.reset(socket->acceptConnection());

+ 3 - 1
src/Piece.cc

@@ -38,6 +38,7 @@
 #include "BitfieldMan.h"
 #include "A2STR.h"
 #include "Util.h"
+#include "a2functional.h"
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "messageDigest.h"
 #endif // ENABLE_MESSAGE_DIGEST
@@ -194,7 +195,8 @@ bool Piece::getAllMissingBlockIndexes
 }
 
 std::string Piece::toString() const {
-  return "piece: index="+Util::itos(index)+", length="+Util::itos(length);
+  return strconcat("piece: index=", Util::itos(index),
+		   ", length=", Util::itos(length));
 }
 
 void Piece::reconfigure(size_t length)

+ 4 - 2
src/RangeBtMessage.cc

@@ -34,6 +34,7 @@
 /* copyright --> */
 #include "RangeBtMessage.h"
 #include "Util.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -78,8 +79,9 @@ size_t RangeBtMessage::getMessageLength()
 
 std::string RangeBtMessage::toString() const
 {
-  return getName()+" index="+Util::uitos(_index)+", begin="+Util::uitos(_begin)+
-    ", length="+Util::uitos(_length);
+  return strconcat(getName(), " index=", Util::uitos(_index),
+		   ", begin=", Util::uitos(_begin),
+		   ", length=", Util::uitos(_length));
 }
 
 } // namespace aria2

+ 3 - 2
src/Request.cc

@@ -41,6 +41,7 @@
 #include "RecoverableException.h"
 #include "StringFormat.h"
 #include "A2STR.h"
+#include "a2functional.h"
 
 #define SAFE_CHARS "abcdefghijklmnopqrstuvwxyz"\
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
@@ -139,10 +140,10 @@ bool Request::redirectUrl(const std::string& url) {
     // field, but some servers don't obey this rule.
     if(Util::startsWith(url, "/")) {
       // abosulute path
-      return parseUrl(protocol+"://"+host+url);
+      return parseUrl(strconcat(protocol, "://", host, url));
     } else {
       // relative path
-      return parseUrl(protocol+"://"+host+dir+"/"+url);
+      return parseUrl(strconcat(protocol, "://", host, dir, "/", url));
     }
   } else {
     return parseUrl(url);

+ 1 - 1
src/Request.h

@@ -94,7 +94,7 @@ public:
   bool redirectUrl(const std::string& url);
   bool resetUrl();
   void resetTryCount() { tryCount = 0; }
-  void addTryCount() { tryCount++; }
+  void addTryCount() { ++tryCount; }
   unsigned int getTryCount() const { return tryCount; }
   //bool noMoreTry() const { return tryCount >= PREF_MAX_TRY; }
 

+ 2 - 1
src/RequestGroup.cc

@@ -77,6 +77,7 @@
 #include "URISelector.h"
 #include "InOrderURISelector.h"
 #include "PieceSelector.h"
+#include "a2functional.h"
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "CheckIntegrityCommand.h"
 #endif // ENABLE_MESSAGE_DIGEST
@@ -572,7 +573,7 @@ bool RequestGroup::tryAutoFileRenaming()
   DefaultBtProgressInfoFile tempInfoFile(tempCtx, SharedHandle<PieceStorage>(), 0);
 
   for(unsigned int i = 1; i < 10000; ++i) {
-    File newfile(filepath+"."+Util::uitos(i));
+    File newfile(strconcat(filepath, ".", Util::uitos(i)));
     tempCtx->setUFilename(newfile.getPath());
     tempInfoFile.updateFilename();
     if(!newfile.exists() || (newfile.exists() && tempInfoFile.exists())) {

+ 4 - 2
src/RequestGroupMan.cc

@@ -216,7 +216,8 @@ static void executeHook(const std::string& command, int gid)
 
   memset(&pi, 0, sizeof (pi));
 
-  std::string cmdline = command + " " + Util::itos(gid);
+  std::string cmdline = command;
+  strappend(cmdline, " ", Util::itos(gid));
 
   DWORD rc = CreateProcess(
     NULL,
@@ -816,7 +817,8 @@ bool RequestGroupMan::loadServerStat(const std::string& filename)
 
 bool RequestGroupMan::saveServerStat(const std::string& filename) const
 {
-  std::string tempfile = filename+"__temp";
+  std::string tempfile = filename;
+  tempfile += "__temp";
   std::ofstream out(tempfile.c_str(), std::ios::binary);
   if(!out) {
     _logger->error(MSG_OPENING_WRITABLE_SERVER_STAT_FILE_FAILED,

+ 1 - 1
src/ServerStat.cc

@@ -145,7 +145,7 @@ void ServerStat::updateMultiConnectionAvgSpeed(unsigned int downloadSpeed)
 
 void ServerStat::increaseCounter()
 {
-  _counter++;
+  ++_counter;
 }
 
 void ServerStat::setCounter(unsigned int value)

+ 5 - 3
src/ServerStatMan.cc

@@ -33,14 +33,16 @@
  */
 /* copyright --> */
 #include "ServerStatMan.h"
-#include "ServerStat.h"
-#include "Util.h"
-#include "RecoverableException.h"
+
 #include <algorithm>
 #include <ostream>
 #include <iterator>
 #include <map>
 
+#include "ServerStat.h"
+#include "Util.h"
+#include "RecoverableException.h"
+
 namespace aria2 {
 
 ServerStatMan::ServerStatMan() {}

+ 3 - 2
src/UTPexExtensionMessage.cc

@@ -42,6 +42,7 @@
 #include "message.h"
 #include "StringFormat.h"
 #include "bencode.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -86,8 +87,8 @@ UTPexExtensionMessage::createCompactPeerListAndFlag(const Peers& peers)
 
 std::string UTPexExtensionMessage::toString() const
 {
-  return "ut_pex added="+Util::uitos(_freshPeers.size())+", dropped="+
-    Util::uitos(_droppedPeers.size());
+  return strconcat("ut_pex added=", Util::uitos(_freshPeers.size()),
+		   ", dropped=", Util::uitos(_droppedPeers.size()));
 }
 
 void UTPexExtensionMessage::doReceivedAction()

+ 22 - 12
src/Util.cc

@@ -66,6 +66,7 @@
 #include "StringFormat.h"
 #include "A2STR.h"
 #include "array_fun.h"
+#include "a2functional.h"
 
 // For libc6 which doesn't define ULLONG_MAX properly because of broken limits.h
 #ifndef ULLONG_MAX
@@ -202,7 +203,8 @@ std::string Util::replace(const std::string& target, const std::string& oldstr,
   std::string::size_type p = 0;
   std::string::size_type np = target.find(oldstr);
   while(np != std::string::npos) {
-    result += target.substr(p, np-p)+newstr;
+    result += target.substr(p, np-p);
+    result += newstr;
     p = np+oldstr.size();
     np = target.find(oldstr, p);
   }
@@ -235,7 +237,7 @@ bool Util::inRFC3986UnreservedChars(const char c)
 
 std::string Util::urlencode(const unsigned char* target, size_t len) {
   std::string dest;
-  for(size_t i = 0; i < len; i++) {
+  for(size_t i = 0; i < len; ++i) {
     if(!inRFC3986UnreservedChars(target[i])) {
       dest.append(StringFormat("%%%02X", target[i]).str());
     } else {
@@ -247,7 +249,7 @@ std::string Util::urlencode(const unsigned char* target, size_t len) {
 
 std::string Util::torrentUrlencode(const unsigned char* target, size_t len) {
   std::string dest;
-  for(size_t i = 0; i < len; i++) {
+  for(size_t i = 0; i < len; ++i) {
     if(('0' <= target[i] && target[i] <= '9') ||
        ('A' <= target[i] && target[i] <= 'Z') ||
        ('a' <= target[i] && target[i] <= 'z')) {
@@ -262,7 +264,7 @@ std::string Util::torrentUrlencode(const unsigned char* target, size_t len) {
 std::string Util::urldecode(const std::string& target) {
   std::string result;
   for(std::string::const_iterator itr = target.begin();
-      itr != target.end(); itr++) {
+      itr != target.end(); ++itr) {
     if(*itr == '%') {
       if(itr+1 != target.end() && itr+2 != target.end() &&
 	 isxdigit(*(itr+1)) && isxdigit(*(itr+2))) {
@@ -280,7 +282,7 @@ std::string Util::urldecode(const std::string& target) {
 
 std::string Util::toHex(const unsigned char* src, size_t len) {
   char* temp = new char[len*2+1];
-  for(size_t i = 0; i < len; i++) {
+  for(size_t i = 0; i < len; ++i) {
     sprintf(temp+i*2, "%02x", src[i]);
   }
   temp[len*2] = '\0';
@@ -350,7 +352,8 @@ bool Util::isPowerOf(int num, int base) {
 std::string Util::secfmt(time_t sec) {
   std::string str;
   if(sec >= 3600) {
-    str = itos(sec/3600)+"h";
+    str = itos(sec/3600);
+    str += "h";
     sec %= 3600;
   }
   if(sec >= 60) {
@@ -358,13 +361,15 @@ std::string Util::secfmt(time_t sec) {
     if(min < 10) {
       str += "0";
     }
-    str += itos(min)+"m";
+    str += itos(min);
+    str += "m";
     sec %= 60;
   }
   if(sec < 10) {
     str += "0";
   }
-  str += itos(sec)+"s";
+  str += itos(sec);
+  str += "s";
   return str;
 }
 
@@ -407,7 +412,7 @@ void unfoldSubRange(const std::string& src, std::deque<int>& range) {
       }
       int left = getNum(src.c_str(), 0, p);
       int right = getNum(src.c_str(), rightNumBegin, nextDelim-rightNumBegin);
-      for(int i = left; i <= right; i++) {
+      for(int i = left; i <= right; ++i) {
 	range.push_back(i);
       }
       if(src.size() > nextDelim) {
@@ -577,7 +582,7 @@ std::string Util::getContentDispositionFilename(const std::string& header) {
 std::string Util::randomAlpha(size_t length, const RandomizerHandle& randomizer) {
   static const char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   std::string str;
-  for(size_t i = 0; i < length; i++) {
+  for(size_t i = 0; i < length; ++i) {
     size_t index = randomizer->getRandomNumber(strlen(random_chars));
     str += random_chars[index];
   }
@@ -679,7 +684,12 @@ std::string Util::abbrevSize(int64_t size)
     r = size&0x3ff;
     size >>= 10;
   }
-  return Util::itos(size, true)+"."+Util::itos(r*10/1024)+units[i]+"i";
+  std::string result = Util::itos(size, true);
+  result += ".";
+  result += Util::itos(r*10/1024);
+  result += units[i];
+  result += "i";
+  return result;
 }
 
 time_t Util::httpGMT(const std::string& httpStdTime)
@@ -706,7 +716,7 @@ void Util::toStream(std::ostream& os, const FileEntries& fileEntries)
   os << "===+===========================================================================" << "\n";
   int32_t count = 1;
   for(FileEntries::const_iterator itr = fileEntries.begin();
-      itr != fileEntries.end(); count++, itr++) {
+      itr != fileEntries.end(); ++count, ++itr) {
     os << std::setw(3) << count << "|" << (*itr)->getPath() << "\n";
     os << "   |" << Util::abbrevSize((*itr)->getLength()) << "B" << "\n";
     os << "---+---------------------------------------------------------------------------" << "\n";

+ 152 - 0
src/a2functional.h

@@ -216,6 +216,158 @@ public:
   }
 };
 
+template<typename T1, typename T2>
+inline std::string strconcat(const T1& a1, const T2& a2)
+{
+  return std::string(a1).append(a2);
+}
+
+template<typename T1, typename T2, typename T3>
+inline std::string strconcat(const T1& a1, const T2& a2, const T3& a3)
+{
+  return std::string(a1).append(a2).append(a3);
+}
+
+template<typename T1, typename T2, typename T3, typename T4>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4)
+{
+  return std::string(a1).append(a2).append(a3).append(a4);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7, const T8& a8)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8, typename T9>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7, const T8& a8,
+	  const T9& a9)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8).append(a9);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8, typename T9, typename T10>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7, const T8& a8,
+	  const T9& a9, const T10& a10)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8).append(a9).append(a10);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8, typename T9, typename T10,
+	 typename T11>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7, const T8& a8,
+	  const T9& a9, const T10& a10, const T11& a11)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8).append(a9).append(a10).append(a11);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8, typename T9, typename T10,
+	 typename T11, typename T12>
+inline std::string
+strconcat(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+	  const T5& a5, const T6& a6, const T7& a7, const T8& a8,
+	  const T9& a9, const T10& a10, const T11& a11,
+	  const T12& a12)
+{
+  return std::string(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8).append(a9).append(a10).append(a11).append(a12);
+}
+
+template<typename T1, typename T2>
+inline void strappend(std::string& base, const T1& a1, const T2& a2)
+{
+  base.append(a1).append(a2);
+}
+
+template<typename T1, typename T2, typename T3>
+inline void strappend(std::string& base,
+		       const T1& a1, const T2& a2, const T3& a3)
+{
+  base.append(a1).append(a2).append(a3);
+}
+
+template<typename T1, typename T2, typename T3, typename T4>
+inline void strappend(std::string& base,
+		       const T1& a1, const T2& a2, const T3& a3, const T4& a4)
+{
+  base.append(a1).append(a2).append(a3).append(a4);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5>
+inline void strappend(std::string& base,
+		       const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+		       const T5& a5)
+{
+  base.append(a1).append(a2).append(a3).append(a4).append(a5);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6>
+inline void strappend(std::string& base,
+		       const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+		      const T5& a5, const T6& a6)
+{
+  base.append(a1).append(a2).append(a3).append(a4).append(a5).append(a6);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7>
+inline void strappend(std::string& base,
+		       const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+		      const T5& a5, const T6& a6, const T7& a7)
+{
+  base.append(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5,
+	 typename T6, typename T7, typename T8>
+inline void strappend(std::string& base,
+		      const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+		      const T5& a5, const T6& a6, const T7& a7, const T8& a8)
+{
+  base.append(a1).append(a2).append(a3).append(a4).append(a5).append(a6).append(a7).append(a8);
+}
+
 } // namespace aria2
 
 #endif // _D_A2_FUNCTIONAL_H_

+ 4 - 3
src/download_helper.cc

@@ -61,6 +61,7 @@
 #include "array_fun.h"
 #include "OptionHandler.h"
 #include "ByteArrayDiskWriter.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -183,7 +184,7 @@ static SharedHandle<RequestGroup> createRequestGroup
       0,
       A2STR::NIL,
       useOutOption&&!option->blank(PREF_OUT)?
-      option->get(PREF_DIR)+"/"+option->get(PREF_OUT):A2STR::NIL));
+      strconcat(option->get(PREF_DIR), "/", option->get(PREF_OUT)):A2STR::NIL));
 
   dctx->setDir(option->get(PREF_DIR));
   rg->setDownloadContext(dctx);
@@ -217,8 +218,8 @@ createBtRequestGroup(const std::string& torrentFilePath,
     Util::createIndexPathMap(indexOutIn);
   for(std::map<size_t, std::string>::const_iterator i = indexPathMap.begin();
       i != indexPathMap.end(); ++i) {
-    btContext->setFilePathWithIndex((*i).first,
-				    btContext->getDir()+"/"+(*i).second);
+    btContext->setFilePathWithIndex
+      ((*i).first, strconcat(btContext->getDir(), "/", (*i).second));
   }
   rg->setDownloadContext(btContext);
   btContext->setOwnerRequestGroup(rg.get());

+ 2 - 1
src/messageDigest.cc

@@ -76,7 +76,8 @@ std::string MessageDigestContext::getSupportedAlgoString()
   std::string algos;
   for(DigestAlgoMap::const_iterator itr = digestAlgos.begin();
       itr != digestAlgos.end(); ++itr) {
-    algos += (*itr).first+", ";
+    algos += (*itr).first;
+    algos += ", ";
   }
   return Util::trim(algos, ", ");
 }