Browse Source

Use std::unique_ptr for Metalink objects

Tatsuhiro Tsujikawa 12 years ago
parent
commit
41121e09f7

+ 2 - 2
src/ChunkChecksum.cc

@@ -80,9 +80,9 @@ void ChunkChecksum::setHashType(const std::string& hashType)
   hashType_ = hashType;
 }
 
-void ChunkChecksum::setPieceHashes(const std::vector<std::string>& pieceHashes)
+void ChunkChecksum::setPieceHashes(std::vector<std::string> pieceHashes)
 {
-  pieceHashes_ = pieceHashes;
+  pieceHashes_ = std::move(pieceHashes);
 }
 
 } // namespace aria2

+ 1 - 1
src/ChunkChecksum.h

@@ -64,7 +64,7 @@ public:
 
   const std::string& getPieceHash(size_t index) const;
 
-  void setPieceHashes(const std::vector<std::string>& pieceHashes);
+  void setPieceHashes(std::vector<std::string> pieceHashes);
   const std::vector<std::string>& getPieceHashes() const
   {
     return pieceHashes_;

+ 4 - 6
src/Context.cc

@@ -99,12 +99,10 @@ namespace {
 void showMetalinkFile
 (const std::string& uri, const std::shared_ptr<Option>& op)
 {
-  std::vector<std::shared_ptr<MetalinkEntry> > metalinkEntries;
-  metalink::parseAndQuery(metalinkEntries, uri, op.get(),
-                          op->get(PREF_METALINK_BASE_URI));
-  std::vector<std::shared_ptr<FileEntry> > fileEntries;
-  MetalinkEntry::toFileEntry(fileEntries, metalinkEntries);
-  util::toStream(fileEntries.begin(), fileEntries.end(), *global::cout());
+  auto fileEntries = MetalinkEntry::toFileEntry
+    (metalink::parseAndQuery(uri, op.get(), op->get(PREF_METALINK_BASE_URI)));
+  util::toStream(std::begin(fileEntries), std::end(fileEntries),
+                 *global::cout());
   global::cout()->write("\n");
   global::cout()->flush();
 }

+ 2 - 2
src/DownloadContext.cc

@@ -276,9 +276,9 @@ void DownloadContext::setBasePath(const std::string& basePath)
   basePath_ = basePath;
 }
 
-void DownloadContext::setSignature(const std::shared_ptr<Signature>& signature)
+void DownloadContext::setSignature(std::unique_ptr<Signature> signature)
 {
-  signature_ = signature;
+  signature_ = std::move(signature);
 }
 
 void DownloadContext::updateDownloadLength(size_t bytes)

+ 3 - 3
src/DownloadContext.h

@@ -84,7 +84,7 @@ private:
 
   Timer downloadStopTime_;
 
-  std::shared_ptr<Signature> signature_;
+  std::unique_ptr<Signature> signature_;
   // This member variable is required to avoid to use parse Metalink
   // (including both Metalink XML and Metalink/HTTP) twice.
   bool acceptMetalink_;
@@ -169,9 +169,9 @@ public:
 
   void setBasePath(const std::string& basePath);
 
-  const std::shared_ptr<Signature>& getSignature() const { return signature_; }
+  const std::unique_ptr<Signature>& getSignature() const { return signature_; }
 
-  void setSignature(const std::shared_ptr<Signature>& signature);
+  void setSignature(std::unique_ptr<Signature> signature);
 
   RequestGroup* getOwnerRequestGroup() { return ownerRequestGroup_; }
 

+ 87 - 88
src/Metalink2RequestGroup.cc

@@ -58,6 +58,7 @@
 #include "fmt.h"
 #include "SegList.h"
 #include "DownloadFailureException.h"
+#include "Signature.h"
 #ifdef ENABLE_BITTORRENT
 # include "BtDependency.h"
 # include "download_helper.h"
@@ -79,7 +80,7 @@ public:
   AccumulateNonP2PUri(std::vector<std::string>& urisPtr)
     :urisPtr(urisPtr) {}
 
-  void operator()(const std::shared_ptr<MetalinkResource>& resource) {
+  void operator()(const std::unique_ptr<MetalinkResource>& resource) {
     switch(resource->type) {
     case MetalinkResource::TYPE_HTTP:
     case MetalinkResource::TYPE_HTTPS:
@@ -110,47 +111,51 @@ public:
 
 void
 Metalink2RequestGroup::generate
-(std::vector<std::shared_ptr<RequestGroup> >& groups,
+(std::vector<std::shared_ptr<RequestGroup>>& groups,
  const std::string& metalinkFile,
  const std::shared_ptr<Option>& option,
  const std::string& baseUri)
 {
-  std::vector<std::shared_ptr<MetalinkEntry> > entries;
-  metalink::parseAndQuery(entries, metalinkFile, option.get(), baseUri);
-  std::vector<std::shared_ptr<RequestGroup> > tempgroups;
-  createRequestGroup(tempgroups, entries, option);
+  std::vector<std::shared_ptr<RequestGroup>> tempgroups;
+  createRequestGroup(tempgroups,
+                     metalink::parseAndQuery(metalinkFile, option.get(),
+                                             baseUri),
+                     option);
   std::shared_ptr<MetadataInfo> mi;
   if(metalinkFile == DEV_STDIN) {
-    mi.reset(new MetadataInfo());
+    mi = std::make_shared<MetadataInfo>();
   } else {
     // TODO Downloads from local metalink file does not save neither
     // its gid nor MetadataInfo's gid.
-    mi.reset(new MetadataInfo(GroupId::create(), metalinkFile));
+    mi = std::make_shared<MetadataInfo>(GroupId::create(), metalinkFile);
   }
-  setMetadataInfo(tempgroups.begin(), tempgroups.end(), mi);
-  groups.insert(groups.end(), tempgroups.begin(), tempgroups.end());
+  setMetadataInfo(std::begin(tempgroups), std::end(tempgroups), mi);
+  groups.insert(std::end(groups),
+                std::begin(tempgroups), std::end(tempgroups));
 }
 
 void
 Metalink2RequestGroup::generate
-(std::vector<std::shared_ptr<RequestGroup> >& groups,
+(std::vector<std::shared_ptr<RequestGroup>>& groups,
  const std::shared_ptr<BinaryStream>& binaryStream,
  const std::shared_ptr<Option>& option,
  const std::string& baseUri)
 {
-  std::vector<std::shared_ptr<MetalinkEntry> > entries;
-  metalink::parseAndQuery(entries, binaryStream.get(), option.get(), baseUri);
-  std::vector<std::shared_ptr<RequestGroup> > tempgroups;
-  createRequestGroup(tempgroups, entries, option);
-  std::shared_ptr<MetadataInfo> mi(new MetadataInfo());
-  setMetadataInfo(tempgroups.begin(), tempgroups.end(), mi);
-  groups.insert(groups.end(), tempgroups.begin(), tempgroups.end());
+  std::vector<std::shared_ptr<RequestGroup>> tempgroups;
+  createRequestGroup(tempgroups,
+                     metalink::parseAndQuery(binaryStream.get(), option.get(),
+                                             baseUri),
+                     option);
+  auto mi = std::make_shared<MetadataInfo>();
+  setMetadataInfo(std::begin(tempgroups), std::end(tempgroups), mi);
+  groups.insert(std::end(groups),
+                std::begin(tempgroups), std::end(tempgroups));
 }
 
 void
 Metalink2RequestGroup::createRequestGroup
-(std::vector<std::shared_ptr<RequestGroup> >& groups,
- const std::vector<std::shared_ptr<MetalinkEntry> >& entries,
+(std::vector<std::shared_ptr<RequestGroup>>& groups,
+ std::vector<std::unique_ptr<MetalinkEntry>> entries,
  const std::shared_ptr<Option>& optionTemplate)
 {
   if(entries.empty()) {
@@ -159,57 +164,52 @@ Metalink2RequestGroup::createRequestGroup
   }
   std::vector<std::string> locations;
   if(optionTemplate->defined(PREF_METALINK_LOCATION)) {
-    const std::string& loc = optionTemplate->get(PREF_METALINK_LOCATION);
-    util::split(loc.begin(), loc.end(),
+    auto& loc = optionTemplate->get(PREF_METALINK_LOCATION);
+    util::split(std::begin(loc), std::end(loc),
                 std::back_inserter(locations), ',', true);
-    for(std::vector<std::string>::iterator i = locations.begin(),
-          eoi = locations.end(); i != eoi; ++i) {
-      util::lowercase(*i);
+    for(auto& s : locations) {
+      util::lowercase(s);
     }
   }
   std::string preferredProtocol;
   if(optionTemplate->get(PREF_METALINK_PREFERRED_PROTOCOL) != V_NONE) {
     preferredProtocol = optionTemplate->get(PREF_METALINK_PREFERRED_PROTOCOL);
   }
-  for(std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator i =
-        entries.begin(), eoi = entries.end(); i != eoi; ++i) {
-    (*i)->dropUnsupportedResource();
-    if((*i)->resources.empty() && (*i)->metaurls.empty()) {
+  for(auto& entry : entries) {
+    entry->dropUnsupportedResource();
+    if(entry->resources.empty() && entry->metaurls.empty()) {
       continue;
     }
-    (*i)->setLocationPriority
+    entry->setLocationPriority
       (locations, -MetalinkResource::getLowestPriority());
     if(!preferredProtocol.empty()) {
-      (*i)->setProtocolPriority
+      entry->setProtocolPriority
         (preferredProtocol, -MetalinkResource::getLowestPriority());
     }
   }
-  std::vector<std::shared_ptr<MetalinkEntry> > selectedEntries;
   SegList<int> sgl;
   util::parseIntSegments(sgl, optionTemplate->get(PREF_SELECT_FILE));
   sgl.normalize();
-  if(!sgl.hasNext()) {
-    selectedEntries.assign(entries.begin(), entries.end());
-  } else {
-    selectedEntries.reserve(entries.size());
+  if(sgl.hasNext()) {
+    size_t inspoint = 0;
     for(size_t i = 0, len = entries.size(); i < len && sgl.hasNext(); ++i) {
-      size_t j = sgl.peek()-1;
+      size_t j = sgl.peek() - 1;
       if(i == j) {
-        selectedEntries.push_back(entries[i]);
+        if(inspoint != i) {
+          entries[inspoint] = std::move(entries[i]);
+        }
+        ++inspoint;
         sgl.next();
       }
     }
+    entries.resize(inspoint);
   }
-  std::for_each(selectedEntries.begin(), selectedEntries.end(),
+  std::for_each(std::begin(entries), std::end(entries),
                 std::mem_fn(&MetalinkEntry::reorderMetaurlsByPriority));
-  std::vector<std::pair<std::string,
-    std::vector<std::shared_ptr<MetalinkEntry> > > > entryGroups;
-  metalink::groupEntryByMetaurlName(entryGroups, selectedEntries);
-  for(std::vector<std::pair<std::string,
-        std::vector<std::shared_ptr<MetalinkEntry> > > >::const_iterator itr =
-        entryGroups.begin(), eoi = entryGroups.end(); itr != eoi; ++itr) {
-    const std::string& metaurl = (*itr).first;
-    const std::vector<std::shared_ptr<MetalinkEntry> >& mes = (*itr).second;
+  auto entryGroups = metalink::groupEntryByMetaurlName(entries);
+  for(auto& entryGroup : entryGroups) {
+    auto& metaurl = entryGroup.first;
+    auto& mes = entryGroup.second;
     A2_LOG_INFO(fmt("Processing metaurl group metaurl=%s", metaurl.c_str()));
 #ifdef ENABLE_BITTORRENT
     std::shared_ptr<RequestGroup> torrentRg;
@@ -217,7 +217,7 @@ Metalink2RequestGroup::createRequestGroup
       std::vector<std::string> uris;
       uris.push_back(metaurl);
       {
-        std::vector<std::shared_ptr<RequestGroup> > result;
+        std::vector<std::shared_ptr<RequestGroup>> result;
         createRequestGroupForUri(result, optionTemplate, uris,
                                  /* ignoreForceSequential = */true,
                                  /* ignoreLocalPath = */true);
@@ -233,26 +233,24 @@ Metalink2RequestGroup::createRequestGroup
         // tranparent metalink
         torrentRg->getDownloadContext()->setAcceptMetalink(false);
         // make it in-memory download
-        std::shared_ptr<PreDownloadHandler> preh
-          (new MemoryBufferPreDownloadHandler());
-        std::shared_ptr<RequestGroupCriteria> cri(new TrueRequestGroupCriteria());
-        preh->setCriteria(cri);
+        auto preh = std::make_shared<MemoryBufferPreDownloadHandler>();
+        preh->setCriteria(std::make_shared<TrueRequestGroupCriteria>());
         torrentRg->addPreDownloadHandler(preh);
         groups.push_back(torrentRg);
       }
     }
 #endif // ENABLE_BITTORRENT
-    std::shared_ptr<Option> option = util::copy(optionTemplate);
-    std::shared_ptr<RequestGroup> rg(new RequestGroup(GroupId::create(), option));
+    auto option = util::copy(optionTemplate);
+    auto rg = std::make_shared<RequestGroup>(GroupId::create(), option);
     std::shared_ptr<DownloadContext> dctx;
     int numSplit = option->getAsInt(PREF_SPLIT);
     int maxConn = option->getAsInt(PREF_MAX_CONNECTION_PER_SERVER);
     if(mes.size() == 1) {
-      std::shared_ptr<MetalinkEntry> entry = mes[0];
+      auto entry = mes[0];
       A2_LOG_INFO(fmt(MSG_METALINK_QUEUEING, entry->getPath().c_str()));
       entry->reorderResourcesByPriority();
       std::vector<std::string> uris;
-      std::for_each(entry->resources.begin(), entry->resources.end(),
+      std::for_each(std::begin(entry->resources), std::end(entry->resources),
                     AccumulateNonP2PUri(uris));
       // If piece hash is specified in the metalink,
       // make segment size equal to piece hash size.
@@ -266,11 +264,11 @@ Metalink2RequestGroup::createRequestGroup
 #else
       pieceLength = option->getAsInt(PREF_PIECE_LENGTH);
 #endif // ENABLE_MESSAGE_DIGEST
-      dctx.reset(new DownloadContext
-                 (pieceLength,
-                  entry->getLength(),
-                  util::applyDir(option->get(PREF_DIR),
-                                 entry->file->getPath())));
+      dctx = std::make_shared<DownloadContext>
+        (pieceLength,
+         entry->getLength(),
+         util::applyDir(option->get(PREF_DIR),
+                        entry->file->getPath()));
       dctx->getFirstFileEntry()->setUris(uris);
       dctx->getFirstFileEntry()->setMaxConnectionPerServer(maxConn);
       if(option->getAsBool(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL)) {
@@ -282,47 +280,49 @@ Metalink2RequestGroup::createRequestGroup
                         entry->checksum->getDigest());
       }
       if(entry->chunkChecksum) {
-        dctx->setPieceHashes(entry->chunkChecksum->getHashType(),
-                             entry->chunkChecksum->getPieceHashes().begin(),
-                             entry->chunkChecksum->getPieceHashes().end());
+        dctx->setPieceHashes
+          (entry->chunkChecksum->getHashType(),
+           std::begin(entry->chunkChecksum->getPieceHashes()),
+           std::end(entry->chunkChecksum->getPieceHashes()));
       }
 #endif // ENABLE_MESSAGE_DIGEST
-      dctx->setSignature(entry->getSignature());
+      dctx->setSignature(entry->popSignature());
       rg->setNumConcurrentCommand
         (entry->maxConnections < 0 ?
          numSplit : std::min(numSplit, entry->maxConnections));
     } else {
-      dctx.reset(new DownloadContext());
+      dctx = std::make_shared<DownloadContext>();
       // piece length is overridden by the one in torrent file.
       dctx->setPieceLength(option->getAsInt(PREF_PIECE_LENGTH));
-      std::vector<std::shared_ptr<FileEntry> > fileEntries;
+      std::vector<std::shared_ptr<FileEntry>> fileEntries;
       int64_t offset = 0;
-      for(std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator i =
-            mes.begin(), eoi = mes.end(); i != eoi; ++i) {
+      for(auto entry : mes) {
         A2_LOG_INFO(fmt("Metalink: Queueing %s for download as a member.",
-                        (*i)->getPath().c_str()));
-        A2_LOG_DEBUG(fmt("originalName = %s", (*i)->metaurls[0]->name.c_str()));
-        (*i)->reorderResourcesByPriority();
+                        entry->getPath().c_str()));
+        A2_LOG_DEBUG(fmt("originalName = %s",
+                         entry->metaurls[0]->name.c_str()));
+        entry->reorderResourcesByPriority();
         std::vector<std::string> uris;
-        std::for_each((*i)->resources.begin(), (*i)->resources.end(),
+        std::for_each(std::begin(entry->resources),
+                      std::end(entry->resources),
                       AccumulateNonP2PUri(uris));
-        std::shared_ptr<FileEntry> fe
-          (new FileEntry
-           (util::applyDir(option->get(PREF_DIR), (*i)->file->getPath()),
-            (*i)->file->getLength(), offset, uris));
+        auto fe = std::make_shared<FileEntry>
+          (util::applyDir(option->get(PREF_DIR),
+                          entry->file->getPath()),
+           entry->file->getLength(), offset, uris);
         fe->setMaxConnectionPerServer(maxConn);
         if(option->getAsBool(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL)) {
           fe->setUniqueProtocol(true);
         }
-        fe->setOriginalName((*i)->metaurls[0]->name);
+        fe->setOriginalName(entry->metaurls[0]->name);
         fileEntries.push_back(fe);
         if(offset >
-           std::numeric_limits<int64_t>::max() - (*i)->file->getLength()) {
+           std::numeric_limits<int64_t>::max() - entry->file->getLength()) {
           throw DOWNLOAD_FAILURE_EXCEPTION(fmt(EX_TOO_LARGE_FILE, offset));
         }
-        offset += (*i)->file->getLength();
+        offset += entry->file->getLength();
       }
-      dctx->setFileEntries(fileEntries.begin(), fileEntries.end());
+      dctx->setFileEntries(std::begin(fileEntries), std::end(fileEntries));
       rg->setNumConcurrentCommand(numSplit);
     }
     rg->setDownloadContext(dctx);
@@ -335,7 +335,7 @@ Metalink2RequestGroup::createRequestGroup
     // Inject depenency between rg and torrentRg here if
     // torrentRg is true
     if(torrentRg) {
-      std::shared_ptr<Dependency> dep(new BtDependency(rg.get(), torrentRg));
+      auto dep = std::make_shared<BtDependency>(rg.get(), torrentRg);
       rg->dependsOn(dep);
       torrentRg->belongsTo(rg->getGID());
       // metadata download may take very long time. If URIs are
@@ -344,15 +344,14 @@ Metalink2RequestGroup::createRequestGroup
       time_t currentBtStopTimeout =
         torrentRg->getOption()->getAsInt(PREF_BT_STOP_TIMEOUT);
       if(currentBtStopTimeout == 0 || currentBtStopTimeout > btStopTimeout) {
-        std::vector<std::shared_ptr<FileEntry> >::const_iterator i;
-        std::vector<std::shared_ptr<FileEntry> >::const_iterator eoi
-          = dctx->getFileEntries().end();
-        for(i = dctx->getFileEntries().begin(); i != eoi; ++i) {
-          if((*i)->getRemainingUris().empty()) {
+        bool allHaveUri = true;
+        for(auto& fe : dctx->getFileEntries()) {
+          if(fe->getRemainingUris().empty()) {
+            allHaveUri = false;
             break;
           }
         }
-        if(i == dctx->getFileEntries().end()) {
+        if(allHaveUri) {
           torrentRg->getOption()->put
             (PREF_BT_STOP_TIMEOUT, util::itos(btStopTimeout));
         }

+ 4 - 4
src/Metalink2RequestGroup.h

@@ -52,18 +52,18 @@ class MetalinkEntry;
 class Metalink2RequestGroup {
 private:
   void
-  createRequestGroup(std::vector<std::shared_ptr<RequestGroup> >& groups,
-                     const std::vector<std::shared_ptr<MetalinkEntry> >& entries,
+  createRequestGroup(std::vector<std::shared_ptr<RequestGroup>>& groups,
+                     std::vector<std::unique_ptr<MetalinkEntry>> entries,
                      const std::shared_ptr<Option>& option);
 public:
   Metalink2RequestGroup();
 
-  void generate(std::vector<std::shared_ptr<RequestGroup> >& groups,
+  void generate(std::vector<std::shared_ptr<RequestGroup>>& groups,
                 const std::string& metalinkFile,
                 const std::shared_ptr<Option>& option,
                 const std::string& baseUri = A2STR::NIL);
 
-  void generate(std::vector<std::shared_ptr<RequestGroup> >& groups,
+  void generate(std::vector<std::shared_ptr<RequestGroup>>& groups,
                 const std::shared_ptr<BinaryStream>& binaryStream,
                 const std::shared_ptr<Option>& option,
                 const std::string& baseUri = A2STR::NIL);

+ 58 - 79
src/MetalinkEntry.cc

@@ -57,45 +57,6 @@ MetalinkEntry::MetalinkEntry():
 
 MetalinkEntry::~MetalinkEntry() {}
 
-namespace {
-class AddLocationPriority {
-private:
-  std::vector<std::string> locations_;
-  int priorityToAdd_;
-public:
-  AddLocationPriority
-  (const std::vector<std::string>& locations, int priorityToAdd):
-    locations_(locations), priorityToAdd_(priorityToAdd)
-  {
-    std::sort(locations_.begin(), locations_.end());
-  }
-
-  void operator()(std::shared_ptr<MetalinkResource>& res) {
-    if(std::binary_search
-       (locations_.begin(), locations_.end(), res->location)) {
-      res->priority += priorityToAdd_;
-    }
-  }
-};
-} // namespace
-
-MetalinkEntry& MetalinkEntry::operator=(const MetalinkEntry& metalinkEntry)
-{
-  if(this != &metalinkEntry) {
-    this->file = metalinkEntry.file;
-    this->version = metalinkEntry.version;
-    this->languages = metalinkEntry.languages;
-    this->oses = metalinkEntry.oses;
-    this->maxConnections = metalinkEntry.maxConnections;
-#ifdef ENABLE_MESSAGE_DIGEST
-    this->checksum = metalinkEntry.checksum;
-    this->chunkChecksum = metalinkEntry.chunkChecksum;
-#endif // ENABLE_MESSAGE_DIGEST
-    this->signature_ = metalinkEntry.signature_;
-  }
-  return *this;
-}
-
 const std::string& MetalinkEntry::getPath() const
 {
   return file->getPath();
@@ -109,41 +70,29 @@ int64_t MetalinkEntry::getLength() const
 void MetalinkEntry::setLocationPriority
 (const std::vector<std::string>& locations, int priorityToAdd)
 {
-  std::for_each(resources.begin(), resources.end(),
-                AddLocationPriority(locations, priorityToAdd));
-}
-
-namespace {
-class AddProtocolPriority {
-private:
-  std::string protocol_;
-  int priorityToAdd_;
-public:
-  AddProtocolPriority(const std::string& protocol, int prefToAdd):
-    protocol_(protocol), priorityToAdd_(prefToAdd) {}
-
-  void operator()(const std::shared_ptr<MetalinkResource>& res) const
-  {
-    if(protocol_ == MetalinkResource::getTypeString(res->type)) {
-      res->priority += priorityToAdd_;
+  for(auto& res : resources) {
+    if(std::find(std::begin(locations), std::end(locations), res->location)
+       != std::end(locations)) {
+      res->priority += priorityToAdd;
     }
   }
-};
-} // namespace
+}
 
 void MetalinkEntry::setProtocolPriority(const std::string& protocol,
-                                          int priorityToAdd)
+                                        int priorityToAdd)
 {
-  std::for_each(resources.begin(), resources.end(),
-                AddProtocolPriority(protocol, priorityToAdd));
+  for(auto& res : resources) {
+    if(protocol == MetalinkResource::getTypeString(res->type)) {
+      res->priority += priorityToAdd;
+    }
+  }
 }
 
 namespace {
 template<typename T>
 class PriorityHigher {
 public:
-  bool operator()(const std::shared_ptr<T>& res1,
-                  const std::shared_ptr<T>& res2)
+  bool operator()(const T& res1, const T& res2)
   {
     return res1->priority < res2->priority;
   }
@@ -151,15 +100,16 @@ public:
 } // namespace
 
 void MetalinkEntry::reorderResourcesByPriority() {
-  std::random_shuffle(resources.begin(), resources.end(),
+  std::random_shuffle(std::begin(resources), std::end(resources),
                       *SimpleRandomizer::getInstance());
-  std::sort(resources.begin(), resources.end(),
-            PriorityHigher<MetalinkResource>());
+  std::sort(std::begin(resources), std::end(resources),
+            PriorityHigher<std::unique_ptr<MetalinkResource>>{});
 }
 
 void MetalinkEntry::reorderMetaurlsByPriority()
 {
-  std::sort(metaurls.begin(), metaurls.end(),PriorityHigher<MetalinkMetaurl>());
+  std::sort(std::begin(metaurls), std::end(metaurls),
+            PriorityHigher<std::unique_ptr<MetalinkMetaurl>>{});
 }
 
 namespace {
@@ -184,24 +134,43 @@ public:
 };
 } // namespace
 
-void MetalinkEntry::dropUnsupportedResource() {
-  resources.erase(std::remove_if(resources.begin(), resources.end(),
-                                 std::not1(Supported())),
-                  resources.end());
+void MetalinkEntry::dropUnsupportedResource()
+{
+  resources.erase(std::remove_if
+                  (std::begin(resources), std::end(resources),
+                   [](const std::unique_ptr<MetalinkResource>& res)
+                   {
+                     switch(res->type) {
+                     case MetalinkResource::TYPE_FTP:
+                     case MetalinkResource::TYPE_HTTP:
+#ifdef ENABLE_SSL
+                     case MetalinkResource::TYPE_HTTPS:
+#endif // ENABLE_SSL
+#ifdef ENABLE_BITTORRENT
+                     case MetalinkResource::TYPE_BITTORRENT:
+#endif // ENABLE_BITTORRENT
+                       return false;
+                     default:
+                       return true;
+                     }
+                   }),
+                  std::end(resources));
 }
 
-void MetalinkEntry::toFileEntry
-(std::vector<std::shared_ptr<FileEntry> >& fileEntries,
- const std::vector<std::shared_ptr<MetalinkEntry> >& metalinkEntries)
+std::vector<std::unique_ptr<FileEntry>> MetalinkEntry::toFileEntry
+(std::vector<std::unique_ptr<MetalinkEntry>> metalinkEntries)
 {
-  std::transform(metalinkEntries.begin(), metalinkEntries.end(),
-                 std::back_inserter(fileEntries),
-                 std::mem_fn(&MetalinkEntry::getFile));
+  std::vector<std::unique_ptr<FileEntry>> res;
+  res.reserve(metalinkEntries.size());
+  for(auto& entry : metalinkEntries) {
+    res.push_back(entry->popFile());
+  }
+  return res;
 }
 
-void MetalinkEntry::setSignature(const std::shared_ptr<Signature>& signature)
+void MetalinkEntry::setSignature(std::unique_ptr<Signature> signature)
 {
-  signature_ = signature;
+  signature_ = std::move(signature);
 }
 
 bool MetalinkEntry::containsLanguage(const std::string& lang) const
@@ -214,4 +183,14 @@ bool MetalinkEntry::containsOS(const std::string& os) const
   return std::find(oses.begin(), oses.end(), os) != oses.end();
 }
 
+std::unique_ptr<Signature> MetalinkEntry::popSignature()
+{
+  return std::move(signature_);
+}
+
+std::unique_ptr<FileEntry> MetalinkEntry::popFile()
+{
+  return std::move(file);
+}
+
 } // namespace aria2

+ 15 - 14
src/MetalinkEntry.h

@@ -54,37 +54,37 @@ class Signature;
 
 class MetalinkEntry {
 public:
-  std::shared_ptr<FileEntry> file;
+  std::unique_ptr<FileEntry> file;
   std::string version;
   std::vector<std::string> languages;
   std::vector<std::string> oses;
   // True if size is specified in Metalink document.
   bool sizeKnown;
-  std::vector<std::shared_ptr<MetalinkResource> > resources;
-  std::vector<std::shared_ptr<MetalinkMetaurl> > metaurls;
+  std::vector<std::unique_ptr<MetalinkResource>> resources;
+  std::vector<std::unique_ptr<MetalinkMetaurl>> metaurls;
   int maxConnections; // Metalink3Spec
 #ifdef ENABLE_MESSAGE_DIGEST
-  std::shared_ptr<Checksum> checksum;
-  std::shared_ptr<ChunkChecksum> chunkChecksum;
+  std::unique_ptr<Checksum> checksum;
+  std::unique_ptr<ChunkChecksum> chunkChecksum;
 #endif // ENABLE_MESSAGE_DIGEST
 private:
-  std::shared_ptr<Signature> signature_;
+  std::unique_ptr<Signature> signature_;
 public:
   MetalinkEntry();
 
   ~MetalinkEntry();
 
-  MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry);
-
   const std::string& getPath() const;
 
   int64_t getLength() const;
 
-  const std::shared_ptr<FileEntry>& getFile() const
+  const std::unique_ptr<FileEntry>& getFile() const
   {
     return file;
   }
 
+  std::unique_ptr<FileEntry> popFile();
+
   void dropUnsupportedResource();
 
   void reorderResourcesByPriority();
@@ -100,16 +100,17 @@ public:
 
   void setProtocolPriority(const std::string& protocol, int priorityToAdd);
 
-  static void toFileEntry
-  (std::vector<std::shared_ptr<FileEntry> >& fileEntries,
-   const std::vector<std::shared_ptr<MetalinkEntry> >& metalinkEntries);
+  static std::vector<std::unique_ptr<FileEntry>> toFileEntry
+  (std::vector<std::unique_ptr<MetalinkEntry>> metalinkEntries);
 
-  void setSignature(const std::shared_ptr<Signature>& signature);
+  void setSignature(std::unique_ptr<Signature> signature);
 
-  const std::shared_ptr<Signature>& getSignature() const
+  const std::unique_ptr<Signature>& getSignature() const
   {
     return signature_;
   }
+
+  std::unique_ptr<Signature> popSignature();
 };
 
 } // namespace aria2

+ 32 - 30
src/MetalinkParserController.cc

@@ -57,20 +57,25 @@
 
 namespace aria2 {
 
-MetalinkParserController::MetalinkParserController():
-  metalinker_(new Metalinker())
+MetalinkParserController::MetalinkParserController()
+  : metalinker_{make_unique<Metalinker>()}
 {}
 
 MetalinkParserController::~MetalinkParserController() {}
 
 void MetalinkParserController::reset()
 {
-  metalinker_.reset(new Metalinker());
+  metalinker_ = make_unique<Metalinker>();
+}
+
+std::unique_ptr<Metalinker> MetalinkParserController::getResult()
+{
+  return std::move(metalinker_);
 }
 
 void MetalinkParserController::newEntryTransaction()
 {
-  tEntry_.reset(new MetalinkEntry());
+  tEntry_ = make_unique<MetalinkEntry>();
   tResource_.reset();
   tMetaurl_.reset();
 #ifdef ENABLE_MESSAGE_DIGEST
@@ -86,7 +91,7 @@ void MetalinkParserController::setFileNameOfEntry(const std::string& filename)
     return;
   }
   if(!tEntry_->file) {
-    tEntry_->file.reset(new FileEntry(util::escapePath(filename), 0, 0));
+    tEntry_->file = make_unique<FileEntry>(util::escapePath(filename), 0, 0);
   } else {
     tEntry_->file->setPath(util::escapePath(filename));
   }
@@ -147,8 +152,7 @@ void MetalinkParserController::commitEntryTransaction()
   commitChunkChecksumTransactionV4();
   commitChunkChecksumTransaction();
   commitSignatureTransaction();
-  metalinker_->addEntry(tEntry_);
-  tEntry_.reset();
+  metalinker_->addEntry(std::move(tEntry_));
 }
 
 void MetalinkParserController::cancelEntryTransaction()
@@ -167,7 +171,7 @@ void MetalinkParserController::newResourceTransaction()
   if(!tEntry_) {
     return;
   }
-  tResource_.reset(new MetalinkResource());
+  tResource_ = make_unique<MetalinkResource>();
 }
 
 void MetalinkParserController::setURLOfResource(const std::string& url)
@@ -237,16 +241,16 @@ void MetalinkParserController::commitResourceTransaction()
   }
 #ifdef ENABLE_BITTORRENT
   if(tResource_->type == MetalinkResource::TYPE_BITTORRENT) {
-    std::shared_ptr<MetalinkMetaurl> metaurl(new MetalinkMetaurl());
-    metaurl->url = tResource_->url;
+    auto metaurl = make_unique<MetalinkMetaurl>();
+    metaurl->url = std::move(tResource_->url);
     metaurl->priority = tResource_->priority;
     metaurl->mediatype = MetalinkMetaurl::MEDIATYPE_TORRENT;
-    tEntry_->metaurls.push_back(metaurl);
+    tEntry_->metaurls.push_back(std::move(metaurl));
   } else {
-    tEntry_->resources.push_back(tResource_);
+    tEntry_->resources.push_back(std::move(tResource_));
   }
 #else // !ENABLE_BITTORRENT
-  tEntry_->resources.push_back(tResource_);
+  tEntry_->resources.push_back(std::move(tResource_));
 #endif // !ENABLE_BITTORRENT
   tResource_.reset();
 }
@@ -262,7 +266,7 @@ void MetalinkParserController::newChecksumTransaction()
   if(!tEntry_) {
     return;
   }
-  tChecksum_.reset(new Checksum());
+  tChecksum_ = make_unique<Checksum>();
 #endif // ENABLE_MESSAGE_DIGEST
 }
 
@@ -304,7 +308,7 @@ void MetalinkParserController::commitChecksumTransaction()
   if(!tEntry_->checksum ||
      MessageDigest::isStronger(tChecksum_->getHashType(),
                                tEntry_->checksum->getHashType())) {
-    tEntry_->checksum = tChecksum_;
+    tEntry_->checksum = std::move(tChecksum_);
   }
   tChecksum_.reset();
 #endif // ENABLE_MESSAGE_DIGEST
@@ -323,7 +327,7 @@ void MetalinkParserController::newChunkChecksumTransactionV4()
   if(!tEntry_) {
     return;
   }
-  tChunkChecksumV4_.reset(new ChunkChecksum());
+  tChunkChecksumV4_ = make_unique<ChunkChecksum>();
   tempChunkChecksumsV4_.clear();
 #endif // ENABLE_MESSAGE_DIGEST
 }
@@ -380,10 +384,8 @@ void MetalinkParserController::commitChunkChecksumTransactionV4()
   if(!tEntry_->chunkChecksum ||
      MessageDigest::isStronger(tChunkChecksumV4_->getHashType(),
                                tEntry_->chunkChecksum->getHashType())) {
-    std::vector<std::string> pieceHashes(tempChunkChecksumsV4_.begin(),
-                                         tempChunkChecksumsV4_.end());
-    tChunkChecksumV4_->setPieceHashes(pieceHashes);
-    tEntry_->chunkChecksum = tChunkChecksumV4_;
+    tChunkChecksumV4_->setPieceHashes(std::move(tempChunkChecksumsV4_));
+    tEntry_->chunkChecksum = std::move(tChunkChecksumV4_);
   }
   tChunkChecksumV4_.reset();
 #endif // ENABLE_MESSAGE_DIGEST
@@ -402,7 +404,7 @@ void MetalinkParserController::newChunkChecksumTransaction()
   if(!tEntry_) {
     return;
   }
-  tChunkChecksum_.reset(new ChunkChecksum());
+  tChunkChecksum_ = make_unique<ChunkChecksum>();
   tempChunkChecksums_.clear();
 #endif // ENABLE_MESSAGE_DIGEST
 }
@@ -493,14 +495,15 @@ void MetalinkParserController::commitChunkChecksumTransaction()
   if(!tEntry_->chunkChecksum ||
      MessageDigest::isStronger(tChunkChecksum_->getHashType(),
                                tEntry_->chunkChecksum->getHashType())) {
-    std::sort(tempChunkChecksums_.begin(), tempChunkChecksums_.end());
+    std::sort(std::begin(tempChunkChecksums_), std::end(tempChunkChecksums_));
     std::vector<std::string> pieceHashes;
-    std::transform(tempChunkChecksums_.begin(), tempChunkChecksums_.end(),
+    std::transform(std::begin(tempChunkChecksums_),
+                   std::end(tempChunkChecksums_),
                    std::back_inserter(pieceHashes),
                    [](const std::pair<size_t, std::string>& p)
                    { return p.second; });
-    tChunkChecksum_->setPieceHashes(pieceHashes);
-    tEntry_->chunkChecksum = tChunkChecksum_;
+    tChunkChecksum_->setPieceHashes(std::move(pieceHashes));
+    tEntry_->chunkChecksum = std::move(tChunkChecksum_);
   }
   tChunkChecksum_.reset();
 #endif // ENABLE_MESSAGE_DIGEST
@@ -518,7 +521,7 @@ void MetalinkParserController::newSignatureTransaction()
   if(!tEntry_) {
     return;
   }
-  tSignature_.reset(new Signature());
+  tSignature_ = make_unique<Signature>();
 }
 
 void MetalinkParserController::setTypeOfSignature(const std::string& type)
@@ -550,8 +553,7 @@ void MetalinkParserController::commitSignatureTransaction()
   if(!tSignature_) {
     return;
   }
-  tEntry_->setSignature(tSignature_);
-  tSignature_.reset();
+  tEntry_->setSignature(std::move(tSignature_));
 }
 
 void MetalinkParserController::cancelSignatureTransaction()
@@ -564,7 +566,7 @@ void MetalinkParserController::newMetaurlTransaction()
   if(!tEntry_) {
     return;
   }
-  tMetaurl_.reset(new MetalinkMetaurl());
+  tMetaurl_ = make_unique<MetalinkMetaurl>();
 }
 
 void MetalinkParserController::setURLOfMetaurl(const std::string& url)
@@ -619,7 +621,7 @@ void MetalinkParserController::commitMetaurlTransaction()
   }
 #ifdef ENABLE_BITTORRENT
   if(tMetaurl_->mediatype == MetalinkMetaurl::MEDIATYPE_TORRENT) {
-    tEntry_->metaurls.push_back(tMetaurl_);
+    tEntry_->metaurls.push_back(std::move(tMetaurl_));
   }
 #endif // ENABLE_BITTORRENT
   tMetaurl_.reset();

+ 9 - 12
src/MetalinkParserController.h

@@ -57,21 +57,21 @@ class ChunkChecksum;
 
 class MetalinkParserController {
 private:
-  std::shared_ptr<Metalinker> metalinker_;
+  std::unique_ptr<Metalinker> metalinker_;
 
-  std::shared_ptr<MetalinkEntry> tEntry_;
+  std::unique_ptr<MetalinkEntry> tEntry_;
 
-  std::shared_ptr<MetalinkResource> tResource_;
+  std::unique_ptr<MetalinkResource> tResource_;
 
-  std::shared_ptr<MetalinkMetaurl> tMetaurl_;
+  std::unique_ptr<MetalinkMetaurl> tMetaurl_;
 #ifdef ENABLE_MESSAGE_DIGEST
-  std::shared_ptr<Checksum> tChecksum_;
+  std::unique_ptr<Checksum> tChecksum_;
 
-  std::shared_ptr<ChunkChecksum> tChunkChecksumV4_; // Metalink4Spec
+  std::unique_ptr<ChunkChecksum> tChunkChecksumV4_; // Metalink4Spec
 
   std::vector<std::string> tempChunkChecksumsV4_; // Metalink4Spec
 
-  std::shared_ptr<ChunkChecksum> tChunkChecksum_; // Metalink3Spec
+  std::unique_ptr<ChunkChecksum> tChunkChecksum_; // Metalink3Spec
 
   std::vector<std::pair<size_t, std::string> > tempChunkChecksums_;//Metalink3Spec
 
@@ -79,7 +79,7 @@ private:
 
 #endif // ENABLE_MESSAGE_DIGEST
 
-  std::shared_ptr<Signature> tSignature_;
+  std::unique_ptr<Signature> tSignature_;
   std::string baseUri_;
 public:
   MetalinkParserController();
@@ -88,10 +88,7 @@ public:
 
   void reset();
 
-  const std::shared_ptr<Metalinker>& getResult() const
-  {
-    return metalinker_;
-  }
+  std::unique_ptr<Metalinker> getResult();
 
   void newEntryTransaction();
 

+ 8 - 2
src/MetalinkParserStateMachine.cc

@@ -42,6 +42,7 @@
 #include "MetalinkParserStateV4Impl.h"
 #include "Metalinker.h"
 #include "MetalinkEntry.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -104,8 +105,8 @@ MetalinkParserState* MetalinkParserStateMachine::urlStateV4_ =
 MetalinkParserState* MetalinkParserStateMachine::metaurlStateV4_ =
   new MetaurlMetalinkParserStateV4();
 
-MetalinkParserStateMachine::MetalinkParserStateMachine():
-  ctrl_(new MetalinkParserController())
+MetalinkParserStateMachine::MetalinkParserStateMachine()
+  : ctrl_{make_unique<MetalinkParserController>()}
 {
   stateStack_.push(initialState_);
 }
@@ -551,6 +552,11 @@ std::string MetalinkParserStateMachine::getErrorString() const
   return error.str();
 }
 
+std::unique_ptr<Metalinker> MetalinkParserStateMachine::getResult()
+{
+  return ctrl_->getResult();
+}
+
 void MetalinkParserStateMachine::setBaseUri(const std::string& uri)
 {
   ctrl_->setBaseUri(uri);

+ 2 - 5
src/MetalinkParserStateMachine.h

@@ -51,7 +51,7 @@ class Metalinker;
 
 class MetalinkParserStateMachine : public ParserStateMachine {
 private:
-  std::shared_ptr<MetalinkParserController> ctrl_;
+  std::unique_ptr<MetalinkParserController> ctrl_;
 
   std::stack<MetalinkParserState*> stateStack_;
 
@@ -265,10 +265,7 @@ public:
 
   std::string getErrorString() const;
 
-  const std::shared_ptr<Metalinker>& getResult() const
-  {
-    return ctrl_->getResult();
-  }
+  std::unique_ptr<Metalinker> getResult();
 
   void setBaseUri(const std::string& uri);
 };

+ 2 - 2
src/MetalinkResource.h

@@ -63,8 +63,8 @@ public:
   ~MetalinkResource();
 
   // Don't allow copying
-  MetalinkResource(const MetalinkResource&);
-  MetalinkResource& operator=(const MetalinkResource&);
+  MetalinkResource(const MetalinkResource&) = delete;
+  MetalinkResource& operator=(const MetalinkResource&) = delete;
 
   static const std::string& getTypeString(TYPE type)
   {

+ 21 - 45
src/Metalinker.cc

@@ -43,56 +43,32 @@ Metalinker::Metalinker() {}
 
 Metalinker::~Metalinker() {}
 
-namespace {
-class EntryQuery:
-    public std::unary_function<std::shared_ptr<MetalinkEntry>, bool> {
-private:
-  std::string version;
-  std::string language;
-  std::string os;
-public:
-  EntryQuery(const std::string& version,
-             const std::string& language,
-             const std::string& os):
-    version(version),
-    language(language),
-    os(os) {}
-
-  bool operator()(const std::shared_ptr<MetalinkEntry>& entry) const {
-    if(!version.empty()) {
-      if(version != entry->version) {
-        return false;
-      }
-    }
-    if(!language.empty()) {
-      if(!entry->containsLanguage(language)) {
-        return false;
-      }
-    }
-    if(!os.empty()) {
-      if(!entry->containsOS(os)) {
-        return false;
-      }
+std::vector<std::unique_ptr<MetalinkEntry>>
+Metalinker::queryEntry(const std::string& version,
+                       const std::string& language,
+                       const std::string& os)
+{
+  std::vector<std::unique_ptr<MetalinkEntry>> res;
+  for(auto& entry : entries_) {
+    if((!version.empty() && version != entry->version) ||
+       (!language.empty() && !entry->containsLanguage(language)) ||
+       (!os.empty() && !entry->containsOS(os))) {
+      continue;
     }
-    return true;
+    res.push_back(std::move(entry));
   }
-};
-} // namespace
-
-void Metalinker::queryEntry
-(std::vector<std::shared_ptr<MetalinkEntry> >& queryResult,
- const std::string& version,
- const std::string& language,
- const std::string& os) const
-{
-  std::remove_copy_if(entries_.begin(), entries_.end(),
-                      std::back_inserter(queryResult),
-                      std::not1(EntryQuery(version, language, os)));
+  entries_.erase(std::remove_if(std::begin(entries_), std::end(entries_),
+                                [](const std::unique_ptr<MetalinkEntry>& entry)
+                                {
+                                  return !entry.get();
+                                }),
+                 std::end(entries_));
+  return res;
 }
 
-void Metalinker::addEntry(const std::shared_ptr<MetalinkEntry>& entry)
+void Metalinker::addEntry(std::unique_ptr<MetalinkEntry> entry)
 {
-  entries_.push_back(entry);
+  entries_.push_back(std::move(entry));
 }
 
 } // namespace aria2

+ 9 - 10
src/Metalinker.h

@@ -47,27 +47,26 @@ class MetalinkEntry;
 
 class Metalinker {
 private:
-  std::vector<std::shared_ptr<MetalinkEntry> > entries_;
+  std::vector<std::unique_ptr<MetalinkEntry>> entries_;
 public:
   Metalinker();
   ~Metalinker();
 
   // Don't allow copying
-  Metalinker(const Metalinker&);
-  Metalinker& operator=(const Metalinker&);
+  Metalinker(const Metalinker&) = delete;
+  Metalinker& operator=(const Metalinker&) = delete;
 
-  void queryEntry
-  (std::vector<std::shared_ptr<MetalinkEntry> >& queryResult,
-   const std::string& version,
-   const std::string& language,
-   const std::string& os) const;
+  std::vector<std::unique_ptr<MetalinkEntry>>
+  queryEntry(const std::string& version,
+             const std::string& language,
+             const std::string& os);
 
-  const std::vector<std::shared_ptr<MetalinkEntry> >& getEntries() const
+  const std::vector<std::unique_ptr<MetalinkEntry>>& getEntries() const
   {
     return entries_;
   }
 
-  void addEntry(const std::shared_ptr<MetalinkEntry>& entry);
+  void addEntry(std::unique_ptr<MetalinkEntry> entry);
 };
 
 } // namespace aria2

+ 1 - 2
src/RequestGroupMan.cc

@@ -257,8 +257,7 @@ private:
 
   void saveSignature(const std::shared_ptr<RequestGroup>& group)
   {
-    std::shared_ptr<Signature> sig =
-      group->getDownloadContext()->getSignature();
+    auto& sig = group->getDownloadContext()->getSignature();
     if(sig && !sig->getBody().empty()) {
       // filename of signature file is the path to download file followed by
       // ".sig".

+ 33 - 45
src/metalink_helper.cc

@@ -49,77 +49,65 @@ namespace metalink {
 
 namespace {
 
-void query
-(std::vector<std::shared_ptr<MetalinkEntry> >& result,
- const std::shared_ptr<Metalinker>& metalinker,
- const Option* option)
+std::vector<std::unique_ptr<MetalinkEntry>>
+query(const std::shared_ptr<Metalinker>& metalinker,
+      const Option* option)
 {
-  metalinker->queryEntry(result,
-                         option->get(PREF_METALINK_VERSION),
-                         option->get(PREF_METALINK_LANGUAGE),
-                         option->get(PREF_METALINK_OS));
+  return metalinker->queryEntry(option->get(PREF_METALINK_VERSION),
+                                option->get(PREF_METALINK_LANGUAGE),
+                                option->get(PREF_METALINK_OS));
 }
 
 } // namespace
 
-void parseAndQuery
-(std::vector<std::shared_ptr<MetalinkEntry> >& result,
- const std::string& filename,
+std::vector<std::unique_ptr<MetalinkEntry>> parseAndQuery
+(const std::string& filename,
  const Option* option,
  const std::string& baseUri)
 {
-  std::shared_ptr<Metalinker> metalinker = parseFile(filename, baseUri);
-  query(result, metalinker, option);
+  return query(parseFile(filename, baseUri), option);
 }
 
-void parseAndQuery
-(std::vector<std::shared_ptr<MetalinkEntry> >& result,
- BinaryStream* bs,
+std::vector<std::unique_ptr<MetalinkEntry>> parseAndQuery
+(BinaryStream* bs,
  const Option* option,
  const std::string& baseUri)
 {
-  std::shared_ptr<Metalinker> metalinker = parseBinaryStream(bs, baseUri);
-  query(result, metalinker, option);
+  return query(parseBinaryStream(bs, baseUri), option);
 }
 
-void groupEntryByMetaurlName
-(std::vector<
-  std::pair<std::string, std::vector<std::shared_ptr<MetalinkEntry> > > >& result,
- const std::vector<std::shared_ptr<MetalinkEntry> >& entries)
+std::vector<std::pair<std::string,
+                      std::vector<MetalinkEntry*>>> groupEntryByMetaurlName
+(const std::vector<std::unique_ptr<MetalinkEntry>>& entries)
 {
-  for(std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator eiter =
-        entries.begin(), eoi = entries.end(); eiter != eoi; ++eiter) {
-    if((*eiter)->metaurls.empty()) {
-      std::pair<std::string, std::vector<std::shared_ptr<MetalinkEntry> > > p;
-      p.second.push_back(*eiter);
-      result.push_back(p);
+  std::vector<std::pair<std::string,
+                        std::vector<MetalinkEntry*>>> result;
+  for(auto& entry : entries) {
+    if(entry->metaurls.empty()) {
+      // std::pair<std::string, std::vector<MetalinkEntry*>> p;
+      // p.second.push_back(entry.get());
+      result.push_back({"", {entry.get()}});
     } else {
-      std::vector<
-      std::pair<std::string,
-        std::vector<std::shared_ptr<MetalinkEntry> > > >::iterator i =
-        result.begin();
-      if((*eiter)->metaurls[0]->name.empty() ||
-         !(*eiter)->sizeKnown) {
-        i = result.end();
+      auto i = std::begin(result);
+      if(entry->metaurls[0]->name.empty() || !entry->sizeKnown) {
+        i = std::end(result);
       }
-      for(; i != result.end(); ++i) {
-        if((*i).first == (*eiter)->metaurls[0]->url &&
+      for(; i != std::end(result); ++i) {
+        if((*i).first == entry->metaurls[0]->url &&
            !(*i).second[0]->metaurls[0]->name.empty()) {
-          (*i).second.push_back(*eiter);
+          (*i).second.push_back(entry.get());
           break;
         }
       }
-      if(i == result.end()) {
-        std::pair<std::string, std::vector<std::shared_ptr<MetalinkEntry> > > p;
-        p.first = (*eiter)->metaurls[0]->url;
-        p.second.push_back(*eiter);
-        result.push_back(p);
+      if(i == std::end(result)) {
+        result.push_back({entry->metaurls[0]->url, {entry.get()}});
       }
     }
   }
+  return result;
 }
 
-std::shared_ptr<Metalinker> parseFile
+std::unique_ptr<Metalinker> parseFile
 (const std::string& filename,
  const std::string& baseUri)
 {
@@ -136,7 +124,7 @@ std::shared_ptr<Metalinker> parseFile
   return psm.getResult();
 }
 
-std::shared_ptr<Metalinker> parseBinaryStream
+std::unique_ptr<Metalinker> parseBinaryStream
 (BinaryStream* bs,
  const std::string& baseUri)
 {

+ 9 - 12
src/metalink_helper.h

@@ -52,28 +52,25 @@ class Metalinker;
 
 namespace metalink {
 
-void parseAndQuery
-(std::vector<std::shared_ptr<MetalinkEntry> >& result,
- const std::string& filename,
+std::vector<std::unique_ptr<MetalinkEntry>> parseAndQuery
+(const std::string& filename,
  const Option* option,
  const std::string& baseUri = A2STR::NIL);
 
-void parseAndQuery
-(std::vector<std::shared_ptr<MetalinkEntry> >& result,
- BinaryStream* bs,
+std::vector<std::unique_ptr<MetalinkEntry>> parseAndQuery
+(BinaryStream* bs,
  const Option* option,
  const std::string& baseUri = A2STR::NIL);
 
-void groupEntryByMetaurlName
-(std::vector<
-  std::pair<std::string, std::vector<std::shared_ptr<MetalinkEntry> > > >& result,
- const std::vector<std::shared_ptr<MetalinkEntry> >& entries);
+std::vector<std::pair<std::string,
+                      std::vector<MetalinkEntry*>>> groupEntryByMetaurlName
+(const std::vector<std::unique_ptr<MetalinkEntry>>& entries);
 
-std::shared_ptr<Metalinker> parseFile
+std::unique_ptr<Metalinker> parseFile
 (const std::string& filename,
  const std::string& baseUri = A2STR::NIL);
 
-std::shared_ptr<Metalinker> parseBinaryStream
+std::unique_ptr<Metalinker> parseBinaryStream
 (BinaryStream* bs,
  const std::string& baseUri = A2STR::NIL);
 

+ 24 - 23
test/MetalinkEntryTest.cc

@@ -3,6 +3,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include "MetalinkResource.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -31,44 +32,46 @@ public:
 
 CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkEntryTest );
 
-std::shared_ptr<MetalinkEntry> createTestEntry() {
-  std::shared_ptr<MetalinkEntry> entry(new MetalinkEntry());
-  std::shared_ptr<MetalinkResource> res1(new MetalinkResource());
+std::unique_ptr<MetalinkEntry> createTestEntry()
+{
+  auto entry = make_unique<MetalinkEntry>();
+  auto res1 = make_unique<MetalinkResource>();
   res1->url = "ftp://myhost/aria2.tar.bz2";
   res1->type = MetalinkResource::TYPE_FTP;
   res1->location = "ro";
   res1->priority = 50;
-  std::shared_ptr<MetalinkResource> res2(new MetalinkResource());
+  auto res2 = make_unique<MetalinkResource>();
   res2->url = "http://myhost/aria2.tar.bz2";
   res2->type = MetalinkResource::TYPE_HTTP;
   res2->location = "at";
   res2->priority = 1;
-  std::shared_ptr<MetalinkResource> res3(new MetalinkResource());
+  auto res3 = make_unique<MetalinkResource>();
   res3->url = "http://myhost/aria2.torrent";
   res3->type = MetalinkResource::TYPE_BITTORRENT;
   res3->location = "al";
   res3->priority = 40;
-  std::shared_ptr<MetalinkResource> res4(new MetalinkResource());
+  auto res4 = make_unique<MetalinkResource>();
   res4->url = "http://myhost/aria2.ext";
   res4->type = MetalinkResource::TYPE_NOT_SUPPORTED;
   res4->location = "ad";
   res4->priority = 90;
-  std::shared_ptr<MetalinkResource> res5(new MetalinkResource());
+  auto res5 = make_unique<MetalinkResource>();
   res5->url = "https://myhost/aria2.tar.bz2";
   res5->type = MetalinkResource::TYPE_HTTPS;
   res5->location = "jp";
   res5->priority = 10;
 
-  entry->resources.push_back(res1);
-  entry->resources.push_back(res2);
-  entry->resources.push_back(res3);
-  entry->resources.push_back(res4);
-  entry->resources.push_back(res5);
+  entry->resources.push_back(std::move(res1));
+  entry->resources.push_back(std::move(res2));
+  entry->resources.push_back(std::move(res3));
+  entry->resources.push_back(std::move(res4));
+  entry->resources.push_back(std::move(res5));
   return entry;
 }
 
-void MetalinkEntryTest::testDropUnsupportedResource() {
-  std::shared_ptr<MetalinkEntry> entry(createTestEntry());
+void MetalinkEntryTest::testDropUnsupportedResource()
+{
+  auto entry = createTestEntry();
 
   entry->dropUnsupportedResource();
 #if defined ENABLE_SSL && defined ENABLE_BITTORRENT
@@ -79,8 +82,7 @@ void MetalinkEntryTest::testDropUnsupportedResource() {
   CPPUNIT_ASSERT_EQUAL((size_t)2, entry->resources.size());
 #endif // ENABLE_MESSAGE_DIGEST
 
-  std::vector<std::shared_ptr<MetalinkResource> >::const_iterator itr =
-    entry->resources.begin();
+  auto itr = std::begin(entry->resources);
   CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP,
                        (*itr++)->type);
   CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP,
@@ -95,8 +97,9 @@ void MetalinkEntryTest::testDropUnsupportedResource() {
 #endif // ENABLE_SSL
 }
 
-void MetalinkEntryTest::testReorderResourcesByPriority() {
-  std::shared_ptr<MetalinkEntry> entry(createTestEntry());
+void MetalinkEntryTest::testReorderResourcesByPriority()
+{
+  auto entry = createTestEntry();
 
   entry->reorderResourcesByPriority();
 
@@ -109,11 +112,9 @@ void MetalinkEntryTest::testReorderResourcesByPriority() {
 
 void MetalinkEntryTest::testSetLocationPriority()
 {
-  std::shared_ptr<MetalinkEntry> entry(createTestEntry());
-
-  const char* locationsSrc[] = { "jp", "al", "ro" };
+  auto entry = createTestEntry();
 
-  std::vector<std::string> locations(&locationsSrc[0], &locationsSrc[3]);
+  auto locations = std::vector<std::string>{ "jp", "al", "ro" };
 
   entry->setLocationPriority(locations, -100);
 
@@ -131,7 +132,7 @@ void MetalinkEntryTest::testSetLocationPriority()
 
 void MetalinkEntryTest::testSetProtocolPriority()
 {
-  std::shared_ptr<MetalinkEntry> entry(createTestEntry());
+  auto entry = createTestEntry();
   entry->setProtocolPriority("http", -1);
   CPPUNIT_ASSERT_EQUAL(50, entry->resources[0]->priority); // ftp
   CPPUNIT_ASSERT_EQUAL(0, entry->resources[1]->priority); // http, -1

+ 25 - 33
test/MetalinkHelperTest.cc

@@ -6,6 +6,7 @@
 #include "Option.h"
 #include "prefs.h"
 #include "MetalinkMetaurl.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -30,8 +31,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkHelperTest );
 void MetalinkHelperTest::testParseAndQuery()
 {
   Option option;
-  std::vector<std::shared_ptr<MetalinkEntry> > result;
-  metalink::parseAndQuery(result, A2_TEST_DIR"/test.xml", &option);
+  auto result = metalink::parseAndQuery(A2_TEST_DIR"/test.xml", &option);
   CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
 }
 
@@ -39,67 +39,59 @@ void MetalinkHelperTest::testParseAndQuery_version()
 {
   Option option;
   option.put(PREF_METALINK_VERSION, "0.5.1");
-  std::vector<std::shared_ptr<MetalinkEntry> > result;
-  metalink::parseAndQuery(result, A2_TEST_DIR"/test.xml", &option);
+  auto result = metalink::parseAndQuery(A2_TEST_DIR"/test.xml", &option);
   CPPUNIT_ASSERT_EQUAL((size_t)1, result.size());
-  std::shared_ptr<MetalinkEntry> entry = result.front();
+  auto& entry = result.front();
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.1.tar.bz2"), entry->getPath());
 }
 
 void MetalinkHelperTest::testGroupEntryByMetaurlName()
 {
-  std::vector<std::shared_ptr<MetalinkEntry> > entries;
+  std::vector<std::unique_ptr<MetalinkEntry>> entries;
 
-  std::shared_ptr<MetalinkEntry> e1(new MetalinkEntry());
+  auto e1 = make_unique<MetalinkEntry>();
   e1->version = "1";
   e1->sizeKnown = true;
   // no name
   e1->metaurls.push_back
-    (std::shared_ptr<MetalinkMetaurl>
-     (new MetalinkMetaurl("http://meta1", "torrent", "", 1)));
+    (make_unique<MetalinkMetaurl>("http://meta1", "torrent", "", 1));
 
-  std::shared_ptr<MetalinkEntry> e2(new MetalinkEntry());
+  auto e2 = make_unique<MetalinkEntry>();
   e2->version = "2";
   e2->sizeKnown = true;
 
-  std::shared_ptr<MetalinkEntry> e3(new MetalinkEntry());
+  auto e3 = make_unique<MetalinkEntry>();
   e3->version = "3";
   e3->sizeKnown = true;
   e3->metaurls.push_back
-    (std::shared_ptr<MetalinkMetaurl>
-     (new MetalinkMetaurl("http://meta2", "torrent", "f3", 1)));
+    (make_unique<MetalinkMetaurl>("http://meta2", "torrent", "f3", 1));
 
-  std::shared_ptr<MetalinkEntry> e4(new MetalinkEntry());
+  auto e4 = make_unique<MetalinkEntry>();
   e4->version = "4";
   e4->sizeKnown = true;
   e4->metaurls.push_back
-    (std::shared_ptr<MetalinkMetaurl>
-     (new MetalinkMetaurl("http://meta1", "torrent", "f4", 1)));
+    (make_unique<MetalinkMetaurl>("http://meta1", "torrent", "f4", 1));
 
-  std::shared_ptr<MetalinkEntry> e5(new MetalinkEntry());
+  auto e5 = make_unique<MetalinkEntry>();
   e5->version = "5";
   // no size
   e5->metaurls.push_back
-    (std::shared_ptr<MetalinkMetaurl>
-     (new MetalinkMetaurl("http://meta1", "torrent", "f5", 1)));
+    (make_unique<MetalinkMetaurl>("http://meta1", "torrent", "f5", 1));
 
-  std::shared_ptr<MetalinkEntry> e6(new MetalinkEntry());
+  auto e6 = make_unique<MetalinkEntry>();
   e6->version = "6";
   e6->sizeKnown = true;
   e6->metaurls.push_back
-    (std::shared_ptr<MetalinkMetaurl>
-     (new MetalinkMetaurl("http://meta1", "torrent", "f6", 1)));
-
-  entries.push_back(e1);
-  entries.push_back(e2);
-  entries.push_back(e3);
-  entries.push_back(e4);
-  entries.push_back(e5);
-  entries.push_back(e6);
-
-  std::vector<std::pair<std::string,
-    std::vector<std::shared_ptr<MetalinkEntry> > > > result;
-  metalink::groupEntryByMetaurlName(result, entries);
+    (make_unique<MetalinkMetaurl>("http://meta1", "torrent", "f6", 1));
+
+  entries.push_back(std::move(e1));
+  entries.push_back(std::move(e2));
+  entries.push_back(std::move(e3));
+  entries.push_back(std::move(e4));
+  entries.push_back(std::move(e5));
+  entries.push_back(std::move(e6));
+
+  auto result = metalink::groupEntryByMetaurlName(entries);
 
   CPPUNIT_ASSERT_EQUAL(std::string("http://meta1"), result[0].first);
   CPPUNIT_ASSERT_EQUAL(std::string("1"), result[0].second[0]->version);

+ 84 - 84
test/MetalinkParserControllerTest.cc

@@ -63,10 +63,12 @@ void MetalinkParserControllerTest::testEntryTransaction()
   ctrl.setLanguageOfEntry("ja_JP");
   ctrl.setOSOfEntry("Linux");
   ctrl.commitEntryTransaction();
+  ctrl.newEntryTransaction();
+  ctrl.cancelEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
+    auto m = ctrl.getResult();
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-    std::shared_ptr<MetalinkEntry> e = m->getEntries().front();
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"), e->file->getPath());
     CPPUNIT_ASSERT_EQUAL((int64_t)(1024*1024LL), e->file->getLength());
     CPPUNIT_ASSERT_EQUAL((int64_t)0, e->file->getOffset());
@@ -74,9 +76,6 @@ void MetalinkParserControllerTest::testEntryTransaction()
     CPPUNIT_ASSERT_EQUAL(std::string("ja_JP"), e->languages[0]);
     CPPUNIT_ASSERT_EQUAL(std::string("Linux"), e->oses[0]);
   }
-  ctrl.newEntryTransaction();
-  ctrl.cancelEntryTransaction();
-  CPPUNIT_ASSERT_EQUAL((size_t)1, ctrl.getResult()->getEntries().size());
 }
 
 void MetalinkParserControllerTest::testResourceTransaction()
@@ -90,25 +89,22 @@ void MetalinkParserControllerTest::testResourceTransaction()
   ctrl.setPriorityOfResource(100);
   ctrl.setMaxConnectionsOfResource(1);
   ctrl.commitEntryTransaction();
-  {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().front()->resources.size());
-    std::shared_ptr<MetalinkResource> res = m->getEntries().front()->resources[0];
-    CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.tar.bz2"), res->url);
-    CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, res->type);
-    CPPUNIT_ASSERT_EQUAL(std::string("US"), res->location);
-    CPPUNIT_ASSERT_EQUAL(100, res->priority);
-    CPPUNIT_ASSERT_EQUAL(1, res->maxConnections);
-  }
   ctrl.newEntryTransaction();
   ctrl.newResourceTransaction();
   ctrl.cancelResourceTransaction();
   ctrl.commitEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
+    auto m = ctrl.getResult();
     CPPUNIT_ASSERT_EQUAL((size_t)2, m->getEntries().size());
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries()[0]->resources.size());
     CPPUNIT_ASSERT_EQUAL((size_t)0, m->getEntries()[1]->resources.size());
+
+    auto& res = m->getEntries()[0]->resources[0];
+    CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.tar.bz2"), res->url);
+    CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, res->type);
+    CPPUNIT_ASSERT_EQUAL(std::string("US"), res->location);
+    CPPUNIT_ASSERT_EQUAL(100, res->priority);
+    CPPUNIT_ASSERT_EQUAL(1, res->maxConnections);
   }
 }
 
@@ -132,22 +128,20 @@ void MetalinkParserControllerTest::testResourceTransaction_withBaseUri()
 #endif // ENABLE_BITTORRENT
   ctrl.commitEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
+    auto m = ctrl.getResult();
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries()[0]->resources.size());
-    std::shared_ptr<MetalinkResource> res = m->getEntries()[0]->resources[0];
+    auto& res = m->getEntries()[0]->resources[0];
     CPPUNIT_ASSERT_EQUAL(std::string("http://base/dir/aria2.tar.bz2"),
                          res->url);
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, res->type);
 
 #ifdef ENABLE_BITTORRENT
     CPPUNIT_ASSERT_EQUAL((size_t)2, m->getEntries()[0]->metaurls.size());
-    std::shared_ptr<MetalinkMetaurl> metaurl = m->getEntries()[0]->metaurls[0];
     CPPUNIT_ASSERT_EQUAL(std::string("http://base/meta/aria2.tar.bz2.torrent"),
-                         metaurl->url);
+                         m->getEntries()[0]->metaurls[0]->url);
 
-    metaurl = m->getEntries()[0]->metaurls[1];
     CPPUNIT_ASSERT_EQUAL(std::string("magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c"),
-                         metaurl->url);
+                         m->getEntries()[0]->metaurls[1]->url);
 #endif // ENABLE_BITTORRENT
   }
 }
@@ -163,30 +157,26 @@ void MetalinkParserControllerTest::testMetaurlTransaction()
   ctrl.setNameOfMetaurl("mybirthdaycake");
   ctrl.commitEntryTransaction();
 #ifdef ENABLE_BITTORRENT
-  {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-    CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries()[0]->metaurls.size());
-    std::shared_ptr<MetalinkMetaurl> metaurl = m->getEntries()[0]->metaurls[0];
-    CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/chocolate.torrent"),
-                         metaurl->url);
-    CPPUNIT_ASSERT_EQUAL(std::string("torrent"), metaurl->mediatype);
-    CPPUNIT_ASSERT_EQUAL(std::string("mybirthdaycake"), metaurl->name);
-    CPPUNIT_ASSERT_EQUAL(999, metaurl->priority);
-  }
   ctrl.newEntryTransaction();
   ctrl.newMetaurlTransaction();
   ctrl.cancelMetaurlTransaction();
   ctrl.commitEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    CPPUNIT_ASSERT_EQUAL((size_t)2, ctrl.getResult()->getEntries().size());
+    auto m = ctrl.getResult();
+    CPPUNIT_ASSERT_EQUAL((size_t)2, m->getEntries().size());
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries()[0]->metaurls.size());
     CPPUNIT_ASSERT_EQUAL((size_t)0, m->getEntries()[1]->metaurls.size());
+
+    auto& metaurl = m->getEntries()[0]->metaurls[0];
+    CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/chocolate.torrent"),
+                         metaurl->url);
+    CPPUNIT_ASSERT_EQUAL(std::string("torrent"), metaurl->mediatype);
+    CPPUNIT_ASSERT_EQUAL(std::string("mybirthdaycake"), metaurl->name);
+    CPPUNIT_ASSERT_EQUAL(999, metaurl->priority);
   }
 #else // !ENABLE_BITTORRENT
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
+    auto m = ctrl.getResult();
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
     CPPUNIT_ASSERT_EQUAL((size_t)0, m->getEntries()[0]->metaurls.size());
   }
@@ -202,25 +192,28 @@ void MetalinkParserControllerTest::testChecksumTransaction()
   ctrl.setTypeOfChecksum("md5");
   ctrl.setHashOfChecksum("acbd18db4cc2f85cedef654fccc4a4d8");
   ctrl.commitEntryTransaction();
-  {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    std::shared_ptr<Checksum> md = m->getEntries().front()->checksum;
-    CPPUNIT_ASSERT_EQUAL(std::string("md5"), md->getHashType());
-    CPPUNIT_ASSERT_EQUAL(std::string("acbd18db4cc2f85cedef654fccc4a4d8"),
-                         util::toHex(md->getDigest()));
-  }
+
   ctrl.newEntryTransaction();
   ctrl.newChecksumTransaction();
   ctrl.setTypeOfChecksum("md5");
   ctrl.setHashOfChecksum("badhash");
   ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[1]->checksum);
 
   ctrl.newEntryTransaction();
   ctrl.newChecksumTransaction();
   ctrl.cancelChecksumTransaction();
   ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[2]->checksum);
+  {
+    auto m = ctrl.getResult();
+    auto& md = m->getEntries()[0]->checksum;
+    CPPUNIT_ASSERT_EQUAL(std::string("md5"), md->getHashType());
+    CPPUNIT_ASSERT_EQUAL(std::string("acbd18db4cc2f85cedef654fccc4a4d8"),
+                         util::toHex(md->getDigest()));
+
+    CPPUNIT_ASSERT(!m->getEntries()[1]->checksum);
+
+    CPPUNIT_ASSERT(!m->getEntries()[2]->checksum);
+  }
 }
 
 void MetalinkParserControllerTest::testChunkChecksumTransaction()
@@ -236,9 +229,21 @@ void MetalinkParserControllerTest::testChunkChecksumTransaction()
   ctrl.addHashOfChunkChecksum(2, "2cbd18db4cc2f85cedef654fccc4a4d8");
   ctrl.addHashOfChunkChecksum(5, "5cbd18db4cc2f85cedef654fccc4a4d8");
   ctrl.commitEntryTransaction();
+
+  ctrl.newEntryTransaction();
+  ctrl.newChunkChecksumTransaction();
+  ctrl.setTypeOfChunkChecksum("md5");
+  ctrl.setLengthOfChunkChecksum(256*1024);
+  ctrl.addHashOfChunkChecksum(1, "badhash");
+  ctrl.commitEntryTransaction();
+
+  ctrl.newEntryTransaction();
+  ctrl.newChunkChecksumTransaction();
+  ctrl.cancelChunkChecksumTransaction();
+  ctrl.commitEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    std::shared_ptr<ChunkChecksum> md = m->getEntries().front()->chunkChecksum;
+    auto m = ctrl.getResult();
+    auto& md = m->getEntries()[0]->chunkChecksum;
     CPPUNIT_ASSERT_EQUAL(std::string("md5"), md->getHashType());
     CPPUNIT_ASSERT_EQUAL(256*1024, md->getPieceLength());
     CPPUNIT_ASSERT_EQUAL((size_t)5, md->countPieceHash());
@@ -252,20 +257,11 @@ void MetalinkParserControllerTest::testChunkChecksumTransaction()
                          md->getPieceHashes()[3]);
     CPPUNIT_ASSERT_EQUAL(std::string("5cbd18db4cc2f85cedef654fccc4a4d8"),
                          md->getPieceHashes()[4]);
-  }
-  ctrl.newEntryTransaction();
-  ctrl.newChunkChecksumTransaction();
-  ctrl.setTypeOfChunkChecksum("md5");
-  ctrl.setLengthOfChunkChecksum(256*1024);
-  ctrl.addHashOfChunkChecksum(1, "badhash");
-  ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[1]->chunkChecksum);
 
-  ctrl.newEntryTransaction();
-  ctrl.newChunkChecksumTransaction();
-  ctrl.cancelChunkChecksumTransaction();
-  ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[2]->chunkChecksum);
+    CPPUNIT_ASSERT(!m->getEntries()[1]->chunkChecksum);
+
+    CPPUNIT_ASSERT(!m->getEntries()[2]->chunkChecksum);
+  }
 }
 
 void MetalinkParserControllerTest::testChunkChecksumTransactionV4()
@@ -280,9 +276,22 @@ void MetalinkParserControllerTest::testChunkChecksumTransactionV4()
   ctrl.addHashOfChunkChecksumV4("9413ee70957a09d55704123687478e07f18c7b29");
   ctrl.addHashOfChunkChecksumV4("44213f9f4d59b557314fadcd233232eebcac8012");
   ctrl.commitEntryTransaction();
+
+  ctrl.newEntryTransaction();
+  ctrl.newChunkChecksumTransactionV4();
+  ctrl.setTypeOfChunkChecksumV4("sha-1");
+  ctrl.setLengthOfChunkChecksumV4(256*1024);
+  ctrl.addHashOfChunkChecksumV4("5bd9f7248df0f3a6a86ab6c95f48787d546efa14");
+  ctrl.addHashOfChunkChecksumV4("badhash");
+  ctrl.commitEntryTransaction();
+
+  ctrl.newEntryTransaction();
+  ctrl.newChunkChecksumTransactionV4();
+  ctrl.cancelChunkChecksumTransactionV4();
+  ctrl.commitEntryTransaction();
   {
-    std::shared_ptr<Metalinker> m = ctrl.getResult();
-    std::shared_ptr<ChunkChecksum> md = m->getEntries().front()->chunkChecksum;
+    auto m = ctrl.getResult();
+    auto& md = m->getEntries()[0]->chunkChecksum;
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), md->getHashType());
     CPPUNIT_ASSERT_EQUAL(256*1024, md->getPieceLength());
     CPPUNIT_ASSERT_EQUAL((size_t)3, md->countPieceHash());
@@ -295,21 +304,11 @@ void MetalinkParserControllerTest::testChunkChecksumTransactionV4()
     CPPUNIT_ASSERT_EQUAL
       (std::string("44213f9f4d59b557314fadcd233232eebcac8012"),
        util::toHex(md->getPieceHashes()[2]));
-  }
-  ctrl.newEntryTransaction();
-  ctrl.newChunkChecksumTransactionV4();
-  ctrl.setTypeOfChunkChecksumV4("sha-1");
-  ctrl.setLengthOfChunkChecksumV4(256*1024);
-  ctrl.addHashOfChunkChecksumV4("5bd9f7248df0f3a6a86ab6c95f48787d546efa14");
-  ctrl.addHashOfChunkChecksumV4("badhash");
-  ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[1]->chunkChecksum);
 
-  ctrl.newEntryTransaction();
-  ctrl.newChunkChecksumTransactionV4();
-  ctrl.cancelChunkChecksumTransactionV4();
-  ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[2]->chunkChecksum);
+    CPPUNIT_ASSERT(!m->getEntries()[1]->chunkChecksum);
+
+    CPPUNIT_ASSERT(!m->getEntries()[2]->chunkChecksum);
+  }
 }
 #endif // ENABLE_MESSAGE_DIGEST
 
@@ -334,19 +333,20 @@ void MetalinkParserControllerTest::testSignatureTransaction()
   // commitEntryTransaction also commits signature transaction.
   ctrl.commitEntryTransaction();
 
-  std::shared_ptr<Metalinker> m = ctrl.getResult();
-  CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-  std::shared_ptr<Signature> sig = m->getEntries().front()->getSignature();
-  CPPUNIT_ASSERT_EQUAL(std::string("pgp"), sig->getType());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2.sig"), sig->getFile());
-  CPPUNIT_ASSERT_EQUAL(pgpSignature, sig->getBody());
-
   // See when signature transaction is canceled:
   ctrl.newEntryTransaction();
   ctrl.newSignatureTransaction();
   ctrl.cancelSignatureTransaction();
   ctrl.commitEntryTransaction();
-  CPPUNIT_ASSERT(!ctrl.getResult()->getEntries()[1]->getSignature());
+
+  auto m = ctrl.getResult();
+  CPPUNIT_ASSERT_EQUAL((size_t)2, m->getEntries().size());
+  auto& sig = m->getEntries()[0]->getSignature();
+  CPPUNIT_ASSERT_EQUAL(std::string("pgp"), sig->getType());
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2.sig"), sig->getFile());
+  CPPUNIT_ASSERT_EQUAL(pgpSignature, sig->getBody());
+
+  CPPUNIT_ASSERT(!m->getEntries()[1]->getSignature());
 }
 
 } // namespace aria2

+ 59 - 82
test/MetalinkProcessorTest.cc

@@ -82,12 +82,9 @@ CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkProcessorTest );
 
 void MetalinkProcessorTest::testParseFileV4()
 {
-  std::shared_ptr<Metalinker> m = metalink::parseFile(A2_TEST_DIR"/metalink4.xml");
-  std::shared_ptr<MetalinkEntry> e;
-  std::shared_ptr<MetalinkResource> r;
-  std::shared_ptr<MetalinkMetaurl> mu;
+  auto m = metalink::parseFile(A2_TEST_DIR"/metalink4.xml");
   CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-  e = m->getEntries()[0];
+  auto& e = m->getEntries()[0];
   CPPUNIT_ASSERT_EQUAL(std::string("example.ext"), e->getPath());
   CPPUNIT_ASSERT_EQUAL((int64_t)786430LL, e->getLength());
   CPPUNIT_ASSERT_EQUAL(-1, e->maxConnections);
@@ -129,7 +126,7 @@ void MetalinkProcessorTest::testParseFileV4()
 		       e->getSignature()->getBody());
 
   CPPUNIT_ASSERT_EQUAL((size_t)2, e->resources.size());
-  r = e->resources[0];
+  auto& r = e->resources[0];
   CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftp.example.com/example.ext"),
 		       r->url);
   CPPUNIT_ASSERT_EQUAL(std::string("de"), r->location);
@@ -139,7 +136,7 @@ void MetalinkProcessorTest::testParseFileV4()
   CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
 #ifdef ENABLE_BITTORRENT
   CPPUNIT_ASSERT_EQUAL((size_t)1, e->metaurls.size());
-  mu = e->metaurls[0];
+  auto& mu = e->metaurls[0];
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.com/example.ext.torrent"),
 		       mu->url);
   CPPUNIT_ASSERT_EQUAL(2, mu->priority);
@@ -151,7 +148,7 @@ void MetalinkProcessorTest::testParseFileV4()
 
 void MetalinkProcessorTest::testParseFileV4_attrs()
 {
-  std::shared_ptr<Metalinker> m;
+  std::unique_ptr<Metalinker> m;
   ByteArrayDiskWriter dw;
   {
     // Testing file@name
@@ -492,13 +489,10 @@ void MetalinkProcessorTest::testParseFileV4_attrs()
 void MetalinkProcessorTest::testParseFile()
 {
   try {
-    std::shared_ptr<Metalinker> metalinker =
-      metalink::parseFile(A2_TEST_DIR"/test.xml");
+    auto metalinker = metalink::parseFile(A2_TEST_DIR"/test.xml");
+    auto entryItr = std::begin(metalinker->getEntries());
 
-    std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator entryItr =
-      metalinker->getEntries().begin();
-
-    std::shared_ptr<MetalinkEntry> entry1 = *entryItr;
+    auto& entry1 = *entryItr;
     CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
     CPPUNIT_ASSERT_EQUAL((int64_t)0LL, entry1->getLength());
     CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), entry1->version);
@@ -527,9 +521,8 @@ void MetalinkProcessorTest::testParseFile()
         "\t"),
        entry1->getSignature()->getBody());
 
-    std::vector<std::shared_ptr<MetalinkResource> >::iterator resourceItr1 =
-      entry1->resources.begin();
-    std::shared_ptr<MetalinkResource> resource1 = *resourceItr1;
+    auto resourceItr1 = std::begin(entry1->resources);
+    auto& resource1 = *resourceItr1;
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
     CPPUNIT_ASSERT_EQUAL(std::string("jp"), resource1->location);
     CPPUNIT_ASSERT_EQUAL(1, resource1->priority);
@@ -537,8 +530,8 @@ void MetalinkProcessorTest::testParseFile()
                          resource1->url);
     CPPUNIT_ASSERT_EQUAL(1, resource1->maxConnections);
 
-    resourceItr1++;
-    std::shared_ptr<MetalinkResource> resource2 = *resourceItr1;
+    ++resourceItr1;
+    auto& resource2 = *resourceItr1;
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
     CPPUNIT_ASSERT_EQUAL(std::string("us"), resource2->location);
     CPPUNIT_ASSERT_EQUAL(1, resource2->priority);
@@ -546,9 +539,9 @@ void MetalinkProcessorTest::testParseFile()
                          resource2->url);
     CPPUNIT_ASSERT_EQUAL(-1, resource2->maxConnections);
 
-    entryItr++;
+    ++entryItr;
 
-    std::shared_ptr<MetalinkEntry> entry2 = *entryItr;
+    auto& entry2 = *entryItr;
     CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.1.tar.bz2"), entry2->getPath());
     CPPUNIT_ASSERT_EQUAL((int64_t)345689LL, entry2->getLength());
     CPPUNIT_ASSERT_EQUAL(std::string("0.5.1"), entry2->version);
@@ -569,20 +562,20 @@ void MetalinkProcessorTest::testParseFile()
     // See that signature is null
     CPPUNIT_ASSERT(!entry2->getSignature());
 
-    entryItr++;
+    ++entryItr;
 
     // test case: verification hash is not provided
-    std::shared_ptr<MetalinkEntry> entry3 = *entryItr;
+    auto& entry3 = *entryItr;
     CPPUNIT_ASSERT_EQUAL(std::string("NoVerificationHash"), entry3->getPath());
 #ifdef ENABLE_MESSAGE_DIGEST
     CPPUNIT_ASSERT(!entry3->checksum);
     CPPUNIT_ASSERT(!entry3->chunkChecksum);
 #endif // ENABLE_MESSAGE_DIGEST
 
-    entryItr++;
+    ++entryItr;
 
     // test case: unsupported verification hash is included
-    std::shared_ptr<MetalinkEntry> entry4 = *entryItr;
+    auto& entry4 = *entryItr;
     CPPUNIT_ASSERT_EQUAL(std::string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
 #ifdef ENABLE_MESSAGE_DIGEST
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), entry4->checksum->getHashType());
@@ -599,10 +592,10 @@ void MetalinkProcessorTest::testParseFile()
 
 void MetalinkProcessorTest::testParseFile_dirtraversal()
 {
-  std::shared_ptr<Metalinker> metalinker =
+  auto metalinker =
     metalink::parseFile(A2_TEST_DIR"/metalink3-dirtraversal.xml");
   CPPUNIT_ASSERT_EQUAL((size_t)1, metalinker->getEntries().size());
-  std::shared_ptr<MetalinkEntry> e = metalinker->getEntries()[0];
+  auto& e = metalinker->getEntries()[0];
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.3.tar.bz2"), e->getPath());
   CPPUNIT_ASSERT(e->getSignature());
   CPPUNIT_ASSERT_EQUAL(std::string(""), e->getSignature()->getFile());
@@ -615,11 +608,8 @@ void MetalinkProcessorTest::testParseBinaryStream()
   dw.openExistingFile();
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-
-    std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator entryItr =
-      m->getEntries().begin();
-    std::shared_ptr<MetalinkEntry> entry1 = *entryItr;
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& entry1 = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
@@ -632,7 +622,7 @@ void MetalinkProcessorTest::testMalformedXML()
   dw.setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></file></metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
+    metalink::parseBinaryStream(&dw);
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
@@ -645,7 +635,7 @@ void MetalinkProcessorTest::testMalformedXML2()
   dw.setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></files>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
+    metalink::parseBinaryStream(&dw);
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
@@ -654,7 +644,6 @@ void MetalinkProcessorTest::testMalformedXML2()
 
 void MetalinkProcessorTest::testBadSizeV4()
 {
-  std::shared_ptr<Metalinker> m;
   ByteArrayDiskWriter dw;
 
   const char* tmpl =
@@ -667,11 +656,11 @@ void MetalinkProcessorTest::testBadSizeV4()
     "</metalink>";
 
   dw.setString(fmt(tmpl, "9223372036854775807"));
-  m = metalink::parseBinaryStream(&dw);
+  metalink::parseBinaryStream(&dw);
 
   dw.setString(fmt(tmpl, "-1"));
   try {
-    m = metalink::parseBinaryStream(&dw);
+    metalink::parseBinaryStream(&dw);
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(RecoverableException& e) {}
 }
@@ -691,17 +680,13 @@ void MetalinkProcessorTest::testBadSize()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-
-    std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator entryItr =
-      m->getEntries().begin();
-    std::shared_ptr<MetalinkEntry> e = *entryItr;
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
     CPPUNIT_ASSERT_EQUAL((int64_t)0LL, e->getLength());
     CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), e->version);
     CPPUNIT_ASSERT_EQUAL(std::string("en-US"), e->languages[0]);
     CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), e->oses[0]);
-
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
   }
@@ -723,11 +708,8 @@ void MetalinkProcessorTest::testBadMaxConn()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-
-    std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator entryItr =
-      m->getEntries().begin();
-    std::shared_ptr<MetalinkEntry> e = *entryItr;
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL((int64_t)43743838LL, e->getLength());
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
@@ -755,11 +737,9 @@ void MetalinkProcessorTest::testNoName()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
+    auto m = metalink::parseBinaryStream(&dw);
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-    std::vector<std::shared_ptr<MetalinkEntry> >::const_iterator entryItr =
-      m->getEntries().begin();
-    std::shared_ptr<MetalinkEntry> e = *entryItr;
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
@@ -785,9 +765,9 @@ void MetalinkProcessorTest::testBadURLPrefs()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<MetalinkResource> r = e->resources[0];
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
+    auto& r = e->resources[0];
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::getLowestPriority(), r->priority);
     CPPUNIT_ASSERT_EQUAL(1, r->maxConnections);
@@ -817,9 +797,9 @@ void MetalinkProcessorTest::testBadURLMaxConn()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<MetalinkResource> r = e->resources[0];
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
+    auto& r = e->resources[0];
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
     CPPUNIT_ASSERT_EQUAL(1, r->priority);
     CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
@@ -850,14 +830,14 @@ void MetalinkProcessorTest::testUnsupportedType()
                 "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL((size_t)3, e->resources.size());
-    std::shared_ptr<MetalinkResource> r1 = e->resources[0];
+    auto& r1 = e->resources[0];
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r1->type);
-    std::shared_ptr<MetalinkResource> r2 = e->resources[1];
+    auto& r2 = e->resources[1];
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_NOT_SUPPORTED, r2->type);
-    std::shared_ptr<MetalinkResource> r3 = e->resources[2];
+    auto& r3 = e->resources[2];
     CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, r3->type);
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
@@ -882,10 +862,9 @@ void MetalinkProcessorTest::testMultiplePieces()
 
   try {
     // aria2 prefers sha1
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<ChunkChecksum> c = e->chunkChecksum;
-
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
+    auto& c = e->chunkChecksum;
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getHashType());
     CPPUNIT_ASSERT_EQUAL(1024, c->getPieceLength());
   } catch(Exception& e) {
@@ -914,10 +893,9 @@ void MetalinkProcessorTest::testBadPieceNo()
      "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<ChunkChecksum> c = e->chunkChecksum;
-
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
+    auto& c = e->chunkChecksum;
     CPPUNIT_ASSERT(c);
     CPPUNIT_ASSERT_EQUAL(1024, c->getPieceLength());
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getHashType());
@@ -946,10 +924,10 @@ void MetalinkProcessorTest::testBadPieceLength()
      "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
+    auto m = metalink::parseBinaryStream(&dw);
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<ChunkChecksum> c = e->chunkChecksum;
+    auto& e = m->getEntries()[0];
+    auto& c = e->chunkChecksum;
     CPPUNIT_ASSERT(c);
     CPPUNIT_ASSERT_EQUAL(1024, c->getPieceLength());
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getHashType());
@@ -978,10 +956,9 @@ void MetalinkProcessorTest::testUnsupportedType_piece()
      "</metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
-    std::shared_ptr<ChunkChecksum> c = e->chunkChecksum;
-
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
+    auto& c = e->chunkChecksum;
     CPPUNIT_ASSERT(c);
     CPPUNIT_ASSERT_EQUAL(1024, c->getPieceLength());
     CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getHashType());
@@ -1006,8 +983,8 @@ void MetalinkProcessorTest::testLargeFileSize()
      "</files>"
      "</metalink>");
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
+    auto m = metalink::parseBinaryStream(&dw);
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL, e->getLength());
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());
@@ -1029,9 +1006,9 @@ void MetalinkProcessorTest::testXmlPrefixV3()
                 "</m:metalink>");
 
   try {
-    std::shared_ptr<Metalinker> m = metalink::parseBinaryStream(&dw);
+    auto m = metalink::parseBinaryStream(&dw);
     CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size());
-    std::shared_ptr<MetalinkEntry> e = m->getEntries()[0];
+    auto& e = m->getEntries()[0];
     CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL, e->getLength());
   } catch(Exception& e) {
     CPPUNIT_FAIL(e.stackTrace());

+ 11 - 12
test/MetalinkerTest.cc

@@ -3,6 +3,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include "MetalinkEntry.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -25,18 +26,19 @@ public:
 
 CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkerTest );
 
-void MetalinkerTest::testQueryEntry() {
-  std::shared_ptr<Metalinker> metalinker(new Metalinker());
-  std::shared_ptr<MetalinkEntry> entry1(new MetalinkEntry());
+void MetalinkerTest::testQueryEntry()
+{
+  Metalinker metalinker;
+  auto entry1 = make_unique<MetalinkEntry>();
   entry1->version = "0.5.2";
   entry1->languages.push_back("en-US");
   entry1->oses.push_back("Linux-x86");
-  std::shared_ptr<MetalinkEntry> entry2(new MetalinkEntry());
+  auto entry2 = make_unique<MetalinkEntry>();
   entry2->version = "0.5.1";
   entry2->languages.push_back("ja-JP");
   entry2->oses.push_back("Linux-m68k");
-  metalinker->addEntry(entry1);
-  metalinker->addEntry(entry2);
+  metalinker.addEntry(std::move(entry1));
+  metalinker.addEntry(std::move(entry2));
 
   std::string version;
   std::string language;
@@ -46,8 +48,7 @@ void MetalinkerTest::testQueryEntry() {
   language = "ja-JP";
   os = "Linux-m68k";
   {
-    std::vector<std::shared_ptr<MetalinkEntry> > result;
-    metalinker->queryEntry(result, version, language, os);
+    auto result = metalinker.queryEntry(version, language, os);
     CPPUNIT_ASSERT_EQUAL((size_t)1, result.size());
     CPPUNIT_ASSERT_EQUAL(std::string("0.5.1"), result.at(0)->version);
     CPPUNIT_ASSERT_EQUAL(std::string("ja-JP"), result.at(0)->languages[0]);
@@ -57,8 +58,7 @@ void MetalinkerTest::testQueryEntry() {
   language = "";
   os = "";
   {
-    std::vector<std::shared_ptr<MetalinkEntry> > result;
-    metalinker->queryEntry(result, version, language, os);
+    auto result = metalinker.queryEntry(version, language, os);
     CPPUNIT_ASSERT_EQUAL((size_t)0, result.size());
   }
 
@@ -66,8 +66,7 @@ void MetalinkerTest::testQueryEntry() {
   language = "";
   os = "";
   {
-    std::vector<std::shared_ptr<MetalinkEntry> > result;
-    metalinker->queryEntry(result, version, language, os);
+    auto result = metalinker.queryEntry(version, language, os);
     CPPUNIT_ASSERT_EQUAL((size_t)1, result.size());
     CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), result.at(0)->version);
     CPPUNIT_ASSERT_EQUAL(std::string("en-US"), result.at(0)->languages[0]);