Changeset 342


Ignore:
Timestamp:
12/01/07 15:45:21 (12 years ago)
Author:
Eoin
Message:

Switch to shared_ptr managed TorrentInternal? class provisionally working.

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/halTorrent.cpp

    r341 r342  
    11821182        {        
    11831183         
    1184         TorrentInternal torrent(file, saveDirectory, pimpl->workingDirectory, compactStorage); 
     1184        TorrentInternal_ptr TIp(new TorrentInternal(file, saveDirectory, pimpl->workingDirectory, compactStorage)); 
    11851185         
    11861186        std::pair<TorrentManager::torrentByName::iterator, bool> p = 
    1187                 pimpl->theTorrents.insert(torrent); 
     1187                pimpl->theTorrents.insert(TIp); 
    11881188         
    11891189        if (p.second) 
    11901190        { 
    1191                 TorrentInternal& me = pimpl->theTorrents.get(torrent.name()); 
     1191                TorrentInternal& me = pimpl->theTorrents.get(TIp->name()); 
    11921192                 
    11931193                me.setTransferSpeed(bittorrent().defTorrentDownload(), bittorrent().defTorrentUpload()); 
     
    12991299        for (TorrentManager::torrentByName::iterator i=pimpl->theTorrents.begin(), e=pimpl->theTorrents.end(); i != e; ++i) 
    13001300        { 
    1301                 wstring utf8Name = (*i).torrent.name(); 
    1302                 TorrentDetail_ptr pT = (*i).torrent.getTorrentDetail_ptr(); 
     1301                wstring utf8Name = (*i).torrent->name(); 
     1302                TorrentDetail_ptr pT = (*i).torrent->getTorrentDetail_ptr(); 
    13031303                 
    13041304                if (selected.find(utf8Name) != selected.end()) 
     
    13101310                        torrentDetails_.selectedTorrent_ = pT; 
    13111311                 
    1312                 torrentDetails_.torrentMap_[(*i).torrent.name()] = pT; 
     1312                torrentDetails_.torrentMap_[(*i).torrent->name()] = pT; 
    13131313                torrentDetails_.torrents_.push_back(pT); 
    13141314        } 
     
    13251325        for (TorrentManager::torrentByName::iterator i=pimpl->theTorrents.begin(), e=pimpl->theTorrents.end(); i != e;) 
    13261326        { 
    1327                 wpath file = wpath(pimpl->workingDirectory)/L"torrents"/(*i).torrent.filename(); 
     1327                wpath file = wpath(pimpl->workingDirectory)/L"torrents"/(*i).torrent->filename(); 
     1328                 
     1329                 
     1330                event().post(shared_ptr<EventDetail>( 
     1331                        new EventMsg(wformat(L"rAll -> %1% - %2%.") % (*i).torrent->filename() % (*i).torrent->state())));       
    13281332                                 
    13291333                if (exists(file)) 
     
    13321336                        { 
    13331337                                 
    1334                         (*i).torrent.prepare(file, (*i).torrent.saveDirectory());        
    1335  
    1336                         switch ((*i).torrent.state()) 
     1338                        (*i).torrent->prepare(file, (*i).torrent->saveDirectory());      
     1339 
     1340                        switch ((*i).torrent->state()) 
    13371341                        { 
    13381342                                case TorrentDetail::torrent_stopped: 
     
    13401344                                case TorrentDetail::torrent_paused: 
    13411345                                case TorrentDetail::torrent_pausing: 
    1342                                         (*i).torrent.addToSession(true); 
     1346                                        (*i).torrent->addToSession(true); 
    13431347                                        break; 
    13441348                                case TorrentDetail::torrent_active: 
    1345                                         (*i).torrent.addToSession(false); 
     1349                                        (*i).torrent->addToSession(false); 
    13461350                                        break; 
    13471351                        }; 
     
    13841388                i != e; ++i) 
    13851389        { 
    1386                 if ((*i).torrent.inSession()) 
    1387                 { 
    1388                         (*i).torrent.handle().pause(); // Internal pause, not registered in Torrents.xml 
     1390                if ((*i).torrent->inSession()) 
     1391                { 
     1392                        (*i).torrent->handle().pause(); // Internal pause, not registered in Torrents.xml 
    13891393                } 
    13901394        } 
     
    13971401                { 
    13981402                        // NB. this checks for an internal paused state. 
    1399                         nonePaused &= ((*i).torrent.inSession() ? (*i).torrent.handle().is_paused() : true); 
     1403                        nonePaused &= ((*i).torrent->inSession() ? (*i).torrent->handle().is_paused() : true); 
    14001404                } 
    14011405                 
     
    14091413                i != e; ++i) 
    14101414        { 
    1411                 if ((*i).torrent.inSession()) 
    1412                 { 
    1413                         (*i).torrent.removeFromSession(); 
    1414                         (*i).torrent.writeResumeData(); 
     1415                if ((*i).torrent->inSession()) 
     1416                { 
     1417                        (*i).torrent->removeFromSession(); 
     1418                        (*i).torrent->writeResumeData(); 
    14151419                } 
    14161420        } 
     
    17071711                i != e; ++i) 
    17081712        {                
    1709                 if ((*i).torrent.inSession()) 
    1710                         (*i).torrent.pause(); 
     1713                if ((*i).torrent->inSession()) 
     1714                        (*i).torrent->pause(); 
    17111715        } 
    17121716         
     
    17211725                i != e; ++i) 
    17221726        { 
    1723                 if ((*i).torrent.inSession() && (*i).torrent.state() == TorrentDetail::torrent_paused) 
    1724                         (*i).torrent.resume(); 
     1727                if ((*i).torrent->inSession() && (*i).torrent->state() == TorrentDetail::torrent_paused) 
     1728                        (*i).torrent->resume(); 
    17251729        } 
    17261730         
  • src/halTorrentInternal.hpp

    r341 r342  
    4141#include <boost/multi_index/member.hpp> 
    4242#include <boost/multi_index/tag.hpp> 
     43#include <boost/serialization/shared_ptr.hpp> 
    4344 
    4445#include "HaliteIni.hpp" 
     
    4647namespace hal  
    4748{ 
     49class TorrentInternalOld; 
    4850class TorrentInternal; 
     51 
    4952} 
    5053 
    51 BOOST_CLASS_VERSION(hal::TorrentInternal, 9) 
     54BOOST_CLASS_VERSION(hal::TorrentInternalOld, 9) 
     55 
    5256 
    5357namespace hal  
     
    110114using boost::serialization::make_nvp; 
    111115 
    112 class TorrentInternal 
     116         
     117template<typename T> 
     118class TransferTracker 
    113119{ 
    114         friend class BitTorrent_impl; 
    115          
    116         template<typename T> 
    117         class TransferTracker 
    118         { 
    119         public: 
    120                 TransferTracker() : 
    121                         total_(0), 
    122                         total_offset_(0) 
    123                 {} 
    124                  
    125                 TransferTracker(T total) : 
    126                         total_(total), 
    127                         total_offset_(0) 
    128                 {} 
    129                  
    130                 TransferTracker(T total, T offset) : 
    131                         total_(total), 
    132                         total_offset_(offset) 
    133                 {} 
    134                  
    135                 void reset(T total) const 
    136                 { 
    137                         total_ = total; 
    138                         total_offset_ = 0; 
    139                 } 
    140                  
    141                 T update(T rel_total) const 
    142                 { 
    143                         total_ += (rel_total - total_offset_); 
    144                         total_offset_ = rel_total; 
    145                          
    146                         return total_; 
    147                 } 
    148                  
    149                 void setOffset(T offset) const 
    150                 { 
    151                         total_offset_ = offset; 
    152                 } 
    153                  
    154                 operator T() const { return total_; } 
    155                  
    156                 friend class boost::serialization::access; 
    157                 template<class Archive> 
    158                 void serialize(Archive& ar, const unsigned int version) 
    159                 { 
    160                         ar & make_nvp("total", total_); 
    161                 } 
    162                  
    163         private: 
    164                 mutable T total_; 
    165                 mutable T total_offset_; 
    166         }; 
    167          
    168         class DurationTracker 
    169         { 
    170         public: 
    171                 DurationTracker() : 
    172                         total_(boost::posix_time::time_duration(0,0,0,0),  
    173                                 boost::posix_time::time_duration(0,0,0,0)) 
    174                 {} 
    175                  
    176                 boost::posix_time::time_duration update() const 
    177                 { 
    178                         if (start_.is_not_a_date_time())  
    179                                 start_ = boost::posix_time::second_clock::universal_time(); 
    180  
    181                         if (static_cast<boost::posix_time::time_duration>(total_).is_special())  
    182                                 total_.setOffset(boost::posix_time::time_duration(0,0,0,0)); 
    183                          
    184                         return total_.update(boost::posix_time::second_clock::universal_time() - start_); 
    185                 } 
    186                  
    187                 void reset() const 
    188                 { 
     120public: 
     121        TransferTracker() : 
     122                total_(0), 
     123                total_offset_(0) 
     124        {} 
     125         
     126        TransferTracker(T total) : 
     127                total_(total), 
     128                total_offset_(0) 
     129        {} 
     130         
     131        TransferTracker(T total, T offset) : 
     132                total_(total), 
     133                total_offset_(offset) 
     134        {} 
     135         
     136        void reset(T total) const 
     137        { 
     138                total_ = total; 
     139                total_offset_ = 0; 
     140        } 
     141         
     142        T update(T rel_total) const 
     143        { 
     144                total_ += (rel_total - total_offset_); 
     145                total_offset_ = rel_total; 
     146                 
     147                return total_; 
     148        } 
     149         
     150        void setOffset(T offset) const 
     151        { 
     152                total_offset_ = offset; 
     153        } 
     154         
     155        operator T() const { return total_; } 
     156         
     157        friend class boost::serialization::access; 
     158        template<class Archive> 
     159        void serialize(Archive& ar, const unsigned int version) 
     160        { 
     161                ar & make_nvp("total", total_); 
     162        } 
     163         
     164private: 
     165        mutable T total_; 
     166        mutable T total_offset_; 
     167}; 
     168 
     169class DurationTracker 
     170{ 
     171public: 
     172        DurationTracker() : 
     173                total_(boost::posix_time::time_duration(0,0,0,0),  
     174                        boost::posix_time::time_duration(0,0,0,0)) 
     175        {} 
     176         
     177        boost::posix_time::time_duration update() const 
     178        { 
     179                if (start_.is_not_a_date_time())  
     180                        start_ = boost::posix_time::second_clock::universal_time(); 
     181 
     182                if (static_cast<boost::posix_time::time_duration>(total_).is_special())  
    189183                        total_.setOffset(boost::posix_time::time_duration(0,0,0,0)); 
    190                         start_ = boost::posix_time::second_clock::universal_time(); 
    191                 } 
    192                  
    193                 friend class boost::serialization::access; 
    194                 template<class Archive> 
    195                 void serialize(Archive& ar, const unsigned int version) 
    196                 { 
    197                         ar & make_nvp("total", total_); 
    198                 } 
    199                  
    200                 operator boost::posix_time::time_duration() const { return total_; } 
    201                  
    202         private: 
    203                 TransferTracker<boost::posix_time::time_duration> total_;        
    204                 mutable boost::posix_time::ptime start_;                 
    205         }; 
    206          
    207 public: 
    208         #define TORRENT_INTERNALS_DEFAULTS \ 
    209                 originalFilename_(L""), \ 
    210                 transferLimit_(std::pair<float, float>(-1, -1)), \ 
    211                 connections_(-1), \ 
    212                 uploads_(-1), \ 
    213                 ratio_(0), \ 
    214                 resolve_countries_(true), \ 
    215                 state_(TorrentDetail::torrent_active), \ 
    216                 totalUploaded_(0), \ 
    217                 totalBase_(0), \ 
    218                 progress_(0), \ 
    219                 startTime_(boost::posix_time::second_clock::universal_time()) 
    220                  
    221         TorrentInternal() :      
    222                 TORRENT_INTERNALS_DEFAULTS, 
    223                 compactStorage_(true), 
    224                 in_session_(false) 
    225         {} 
    226          
    227         TorrentInternal(wpath filename, wpath saveDirectory, wpath workingDirectory, bool compactStorage) : 
    228                 TORRENT_INTERNALS_DEFAULTS, 
    229                 save_directory_(saveDirectory.string()), 
    230                 compactStorage_(compactStorage),                 
    231                 in_session_(false) 
    232         { 
    233                 assert(the_session_); 
    234                  
    235                 prepare(filename, save_directory_); 
    236         } 
    237          
    238         #undef TORRENT_INTERNALS_DEFAULTS 
    239          
    240         TorrentDetail_ptr getTorrentDetail_ptr(); 
    241         void setTransferSpeed(float down, float up); 
    242         void setConnectionLimit(int maxConn, int maxUpload); 
    243         pair<float, float> getTransferSpeed(); 
    244         pair<int, int> getConnectionLimit(); 
    245          
    246         const wstring& name() const { return name_; } 
    247          
    248         void setRatio(float ratio)  
    249         {  
    250                 if (ratio < 0) ratio = 0; 
    251                 ratio_ = ratio;  
    252                  
    253                 applyRatio(); 
    254         } 
    255          
    256         float getRatio() 
    257         { 
    258                 return ratio_; 
    259         } 
    260          
    261         void addToSession(bool paused = false) 
    262         { 
    263                 if (!in_session_ && the_session_)  
    264                 { 
    265                         string dir = to_utf8(save_directory_); 
    266                          
    267                         lbt::storage_mode_t storage = lbt::storage_mode_sparse; 
    268                          
    269                         if (compactStorage_) 
    270                                 storage = lbt::storage_mode_compact; 
    271                          
    272                         handle_ = the_session_->add_torrent(metadata_, dir, resumedata_, storage, paused);                       
    273                         assert(handle_.is_valid()); 
    274                          
    275                         clearResumeData(); 
    276                          
    277                         in_session_ = true; 
    278                         if (paused) 
    279                                 state_ = TorrentDetail::torrent_paused;  
    280                                  
    281                         applySettings(); 
    282                 }        
    283         } 
    284          
    285         void removeFromSession() 
    286         { 
    287                 assert(inSession()); 
    288                  
    289                 resumedata_ = handle_.write_resume_data(); // Update the fast-resume data 
    290                 writeResumeData(); 
    291                  
    292                 the_session_->remove_torrent(handle_); 
    293                 in_session_ = false;             
    294                  
    295                 assert(!inSession());    
    296         } 
    297          
    298         bool inSession() const  
    299         {  
    300                 if (in_session_ && (the_session_ != 0)) 
    301                 { 
    302                         assert(handle_.is_valid()); 
    303                         return true; 
    304                 } 
    305                  
    306                 return false; 
    307         } 
    308          
    309         void resume() 
    310         { 
    311                 if (state_ == TorrentDetail::torrent_stopped) 
    312                 {        
    313                         addToSession(false); 
    314                         assert(inSession());                     
    315                 } 
    316                 else 
    317                 { 
    318                         assert(inSession()); 
    319                         handle_.resume(); 
    320                 }        
    321                  
    322                 state_ = TorrentDetail::torrent_active;                  
    323                 assert(!handle_.is_paused()); 
    324         } 
    325          
    326         void pause() 
    327         { 
    328                 if (state_ == TorrentDetail::torrent_stopped) 
    329                 {        
    330                         addToSession(true); 
    331                         assert(inSession()); 
    332                         state_ = TorrentDetail::torrent_paused;  
    333                 } 
    334                 else 
    335                 { 
    336                         assert(inSession()); 
    337                         handle_.pause(); 
    338                         state_ = TorrentDetail::torrent_pausing;         
    339                 }        
    340                  
    341                 assert(handle_.is_paused()); 
    342         } 
    343          
    344         void stop() 
    345         { 
    346                 if (state_ != TorrentDetail::torrent_stopped) 
    347                 { 
    348                         if (state_ == TorrentDetail::torrent_active) 
    349                         { 
    350                                 assert(inSession()); 
    351                                 handle_.pause(); 
    352                                 state_ = TorrentDetail::torrent_stopping; 
    353                         } 
    354                         else if (state_ == TorrentDetail::torrent_paused) 
    355                         {                        
    356                                 removeFromSession(); 
    357  
    358                                 state_ = TorrentDetail::torrent_stopped;                                 
    359                         } 
    360                 } 
    361         } 
    362          
    363         void writeResumeData() 
    364         {                                
    365                 wpath resumeDir = workingDir_/L"resume"; 
    366                  
    367                 if (!exists(resumeDir)) 
    368                         create_directory(resumeDir); 
    369                                  
    370                 bool halencode_result = halencode(resumeDir/filename_, resumedata_); 
    371                 assert(halencode_result); 
    372         } 
    373          
    374         void clearResumeData() 
    375         { 
    376                 wpath resumeFile = workingDir_/L"resume"/filename_; 
    377                  
    378                 if (exists(resumeFile)) 
    379                         remove(resumeFile); 
    380         } 
    381          
    382         void finished() 
    383         { 
    384                 if (finishTime_.is_special()) 
    385                         finishTime_ = boost::posix_time::second_clock::universal_time(); 
    386         } 
    387          
    388         bool isActive() const { return state_ == TorrentDetail::torrent_active; } 
    389          
    390         unsigned state() const { return state_; } 
    391          
    392         void setTrackerLogin(wstring username, wstring password) 
    393         { 
    394                 trackerUsername_ = username; 
    395                 trackerPassword_ = password; 
    396                  
    397                 applyTrackerLogin(); 
    398         }        
    399          
    400         pair<wstring, wstring> getTrackerLogin() const 
    401         { 
    402                 return make_pair(trackerUsername_, trackerPassword_); 
    403         } 
    404          
    405         const std::wstring& filename() const { return filename_; } 
    406          
    407         const std::wstring& originalFilename() const { return originalFilename_; } 
    408          
    409         const lbt::torrent_handle& handle() const { return handle_; } 
    410  
    411         void resetTrackers() 
    412         { 
    413                 if (inSession()) 
    414                 { 
    415                         handle_.replace_trackers(torrent_trackers_);             
    416                         trackers_.clear(); 
    417                 } 
    418         } 
    419          
    420         void setTrackers(const std::vector<TrackerDetail>& trackerDetails) 
    421         { 
    422                 trackers_.clear(); 
    423                 trackers_.assign(trackerDetails.begin(), trackerDetails.end()); 
    424                  
    425                 applyTrackers(); 
    426         } 
    427          
    428         const std::vector<TrackerDetail>& getTrackers() 
    429         { 
    430                 if (inSession() && trackers_.empty()) 
    431                 { 
    432                         std::vector<lbt::announce_entry> trackers = handle_.trackers(); 
    433                          
    434                         foreach (const lbt::announce_entry& entry, trackers) 
    435                         { 
    436                                 trackers_.push_back( 
    437                                         TrackerDetail(hal::from_utf8(entry.url), entry.tier)); 
    438                         } 
    439                 }                
    440                 return trackers_; 
    441         } 
    442          
    443         void setFilePriorities(std::vector<int> fileIndices, int priority) 
    444         { 
    445                 if (!filePriorities_.empty()) 
    446                 { 
    447                         foreach(int i, fileIndices) 
    448                                 filePriorities_[i] = priority; 
    449                                  
    450                         applyFilePriorities(); 
    451                 } 
    452         } 
    453  
    454         const wstring& saveDirectory() { return save_directory_; } 
    455          
     184                 
     185                return total_.update(boost::posix_time::second_clock::universal_time() - start_); 
     186        } 
     187         
     188        void reset() const 
     189        { 
     190                total_.setOffset(boost::posix_time::time_duration(0,0,0,0)); 
     191                start_ = boost::posix_time::second_clock::universal_time(); 
     192        } 
     193         
     194        friend class boost::serialization::access; 
     195        template<class Archive> 
     196        void serialize(Archive& ar, const unsigned int version) 
     197        { 
     198                ar & make_nvp("total", total_); 
     199        } 
     200         
     201        operator boost::posix_time::time_duration() const { return total_; } 
     202         
     203private: 
     204        TransferTracker<boost::posix_time::time_duration> total_;        
     205        mutable boost::posix_time::ptime start_;                 
     206}; 
     207         
     208class TorrentInternalOld 
     209{ 
     210public:  
    456211    friend class boost::serialization::access; 
    457212    template<class Archive> 
     
    526281    } 
    527282         
     283        void extractNames(lbt::entry& metadata) 
     284        {                
     285                lbt::torrent_info info(metadata);                                
     286                name_ = hal::from_utf8_safe(info.name()); 
     287                 
     288                filename_ = name_; 
     289                if (!boost::find_last(filename_, L".torrent"))  
     290                                filename_ += L".torrent"; 
     291                 
     292                event().post(shared_ptr<EventDetail>(new EventMsg( 
     293                        wformat(L"Loaded names: %1%, %2%") % name_ % filename_))); 
     294        } 
     295         
    528296        void updatePreVersion7Files(wstring originalFilename) 
    529297        { 
     
    554322        } 
    555323         
     324        std::pair<float, float> transferLimit_; 
     325         
     326        unsigned state_; 
     327        int connections_; 
     328        int uploads_; 
     329        bool in_session_; 
     330        float ratio_; 
     331        bool resolve_countries_; 
     332         
     333        std::wstring filename_; 
     334        std::wstring name_; 
     335        std::wstring save_directory_; 
     336        std::wstring originalFilename_; 
     337        lbt::torrent_handle handle_;     
     338         
     339        lbt::entry metadata_; 
     340        lbt::entry resumedata_; 
     341         
     342        std::wstring trackerUsername_;   
     343        std::wstring trackerPassword_; 
     344         
     345        boost::int64_t totalUploaded_; 
     346        boost::int64_t totalBase_; 
     347         
     348        TransferTracker<boost::int64_t> payloadUploaded_; 
     349        TransferTracker<boost::int64_t> payloadDownloaded_; 
     350        TransferTracker<boost::int64_t> uploaded_; 
     351        TransferTracker<boost::int64_t> downloaded_; 
     352         
     353        boost::posix_time::ptime startTime_; 
     354        boost::posix_time::ptime finishTime_; 
     355        DurationTracker activeDuration_; 
     356        DurationTracker seedingDuration_; 
     357         
     358        std::vector<TrackerDetail> trackers_; 
     359        std::vector<lbt::announce_entry> torrent_trackers_; 
     360        std::vector<lbt::peer_info> peers_;      
     361        std::vector<int> filePriorities_; 
     362         
     363        float progress_; 
     364         
     365        lbt::torrent_info infoMemory_; 
     366        lbt::torrent_status statusMemory_; 
     367        FileDetails fileDetailsMemory_; 
     368         
     369        bool compactStorage_; 
     370}; 
     371 
     372class TorrentInternal :  
     373        boost::noncopyable 
     374{ 
     375        friend class BitTorrent_impl;    
     376public: 
     377        #define TORRENT_INTERNALS_DEFAULTS \ 
     378                originalFilename_(L""), \ 
     379                transferLimit_(std::pair<float, float>(-1, -1)), \ 
     380                connections_(-1), \ 
     381                uploads_(-1), \ 
     382                ratio_(0), \ 
     383                resolve_countries_(true), \ 
     384                state_(TorrentDetail::torrent_active), \ 
     385                totalUploaded_(0), \ 
     386                totalBase_(0), \ 
     387                progress_(0), \ 
     388                startTime_(boost::posix_time::second_clock::universal_time()) 
     389                 
     390        TorrentInternal() :      
     391                TORRENT_INTERNALS_DEFAULTS, 
     392                compactStorage_(true), 
     393                in_session_(false) 
     394        {} 
     395         
     396        TorrentInternal(wpath filename, wpath saveDirectory, wpath workingDirectory, bool compactStorage) : 
     397                TORRENT_INTERNALS_DEFAULTS, 
     398                save_directory_(saveDirectory.string()), 
     399                compactStorage_(compactStorage),                 
     400                in_session_(false) 
     401        { 
     402                assert(the_session_); 
     403                 
     404                prepare(filename, save_directory_); 
     405        } 
     406         
     407        TorrentInternal(const TorrentInternalOld& t) : 
     408                transferLimit_(t.transferLimit_), 
     409                state_(t.state_), 
     410                connections_(t.connections_), 
     411                uploads_(t.uploads_), 
     412                in_session_(false), 
     413                ratio_(t.ratio_), 
     414                resolve_countries_(t.resolve_countries_), 
     415                filename_(t.filename_), 
     416                name_(t.name_), 
     417                save_directory_(t.save_directory_), 
     418                originalFilename_(t.originalFilename_), 
     419                handle_(t.handle_), 
     420                metadata_(t.metadata_), 
     421                resumedata_(t.resumedata_), 
     422                trackerUsername_(t.trackerUsername_),    
     423                trackerPassword_(t.trackerPassword_), 
     424                totalUploaded_(t.totalUploaded_), 
     425                totalBase_(t.totalBase_), 
     426                payloadUploaded_(t.payloadUploaded_), 
     427                payloadDownloaded_(t.payloadDownloaded_), 
     428                uploaded_(t.uploaded_), 
     429                downloaded_(t.downloaded_), 
     430                startTime_(t.startTime_), 
     431                finishTime_(t.finishTime_), 
     432                activeDuration_(t.activeDuration_), 
     433                seedingDuration_(t.seedingDuration_), 
     434                trackers_(t.trackers_), 
     435                torrent_trackers_(t.torrent_trackers_), 
     436                peers_(t.peers_), 
     437                filePriorities_(t.filePriorities_), 
     438                progress_(t.progress_), 
     439                infoMemory_(t.infoMemory_), 
     440                statusMemory_(t.statusMemory_), 
     441                fileDetailsMemory_(t.fileDetailsMemory_), 
     442                compactStorage_(t.compactStorage_) 
     443        {} 
     444         
     445        #undef TORRENT_INTERNALS_DEFAULTS 
     446         
     447        TorrentDetail_ptr getTorrentDetail_ptr(); 
     448        void setTransferSpeed(float down, float up); 
     449        void setConnectionLimit(int maxConn, int maxUpload); 
     450        pair<float, float> getTransferSpeed(); 
     451        pair<int, int> getConnectionLimit(); 
     452         
     453        const wstring& name() const { return name_; } 
     454         
     455        void setRatio(float ratio)  
     456        {  
     457                if (ratio < 0) ratio = 0; 
     458                ratio_ = ratio;  
     459                 
     460                applyRatio(); 
     461        } 
     462         
     463        float getRatio() 
     464        { 
     465                return ratio_; 
     466        } 
     467         
     468        void addToSession(bool paused = false) 
     469        { 
     470                mutex_t::scoped_lock l(mutex_); 
     471                 
     472                event().post(shared_ptr<EventDetail>( 
     473                        new EventMsg(wformat(L"    +-> %1%.") % paused)));       
     474                 
     475                if (!in_session_ && the_session_)  
     476                { 
     477                        event().post(shared_ptr<EventDetail>( 
     478                                new EventMsg(wformat(L"    +-> in session."))));         
     479                         
     480                        string dir = to_utf8(save_directory_); 
     481                         
     482                        lbt::storage_mode_t storage = lbt::storage_mode_sparse; 
     483                         
     484                        if (compactStorage_) 
     485                                storage = lbt::storage_mode_compact; 
     486                         
     487                        handle_ = the_session_->add_torrent(metadata_, dir, resumedata_, storage, paused);                       
     488                        assert(handle_.is_valid()); 
     489                         
     490                        clearResumeData(); 
     491                         
     492                        in_session_ = true; 
     493                        if (paused) 
     494                                state_ = TorrentDetail::torrent_paused;  
     495                                 
     496                        applySettings(); 
     497                }        
     498                        event().post(shared_ptr<EventDetail>( 
     499                                new EventMsg(wformat(L"    +-> leaving addToSsession.")))); 
     500        } 
     501         
     502        void removeFromSession() 
     503        { 
     504                mutex_t::scoped_lock l(mutex_); 
     505                assert(inSession()); 
     506                 
     507                resumedata_ = handle_.write_resume_data(); // Update the fast-resume data 
     508                writeResumeData(); 
     509                 
     510                the_session_->remove_torrent(handle_); 
     511                in_session_ = false;             
     512                 
     513                assert(!inSession());    
     514        } 
     515         
     516        bool inSession() const 
     517        {  
     518                mutex_t::scoped_lock l(mutex_); 
     519                 
     520                if (in_session_ && (the_session_ != 0)) 
     521                { 
     522                //      assert(handle_.is_valid());                      
     523                        return true; 
     524                } 
     525                 
     526                return false; 
     527        } 
     528         
     529        void resume() 
     530        { 
     531                mutex_t::scoped_lock l(mutex_); 
     532                if (state_ == TorrentDetail::torrent_stopped) 
     533                {        
     534                        addToSession(false); 
     535                        assert(inSession());                     
     536                } 
     537                else 
     538                { 
     539                        assert(inSession()); 
     540                        handle_.resume(); 
     541                }        
     542                 
     543                state_ = TorrentDetail::torrent_active;                  
     544                assert(!handle_.is_paused()); 
     545        } 
     546         
     547        void pause() 
     548        { 
     549                mutex_t::scoped_lock l(mutex_); 
     550                if (state_ == TorrentDetail::torrent_stopped) 
     551                {        
     552                        addToSession(true); 
     553                        assert(inSession()); 
     554                        state_ = TorrentDetail::torrent_paused;  
     555                } 
     556                else 
     557                { 
     558                        assert(inSession()); 
     559                        handle_.pause(); 
     560                        state_ = TorrentDetail::torrent_pausing;         
     561                }        
     562                 
     563                assert(handle_.is_paused()); 
     564        } 
     565         
     566        void stop() 
     567        { 
     568                mutex_t::scoped_lock l(mutex_); 
     569                if (state_ != TorrentDetail::torrent_stopped) 
     570                { 
     571                        if (state_ == TorrentDetail::torrent_active) 
     572                        { 
     573                                assert(inSession()); 
     574                                handle_.pause(); 
     575                                state_ = TorrentDetail::torrent_stopping; 
     576                        } 
     577                        else if (state_ == TorrentDetail::torrent_paused) 
     578                        {                        
     579                                removeFromSession(); 
     580 
     581                                state_ = TorrentDetail::torrent_stopped;                                 
     582                        } 
     583                } 
     584        } 
     585         
     586        void writeResumeData() 
     587        {                                
     588                wpath resumeDir = workingDir_/L"resume"; 
     589                 
     590                if (!exists(resumeDir)) 
     591                        create_directory(resumeDir); 
     592                                 
     593                bool halencode_result = halencode(resumeDir/filename_, resumedata_); 
     594                assert(halencode_result); 
     595        } 
     596         
     597        void clearResumeData() 
     598        { 
     599                wpath resumeFile = workingDir_/L"resume"/filename_; 
     600                 
     601                if (exists(resumeFile)) 
     602                        remove(resumeFile); 
     603        } 
     604         
     605        void finished() 
     606        { 
     607                if (finishTime_.is_special()) 
     608                        finishTime_ = boost::posix_time::second_clock::universal_time(); 
     609        } 
     610         
     611        bool isActive() const { return state_ == TorrentDetail::torrent_active; } 
     612         
     613        unsigned state() const { return state_; } 
     614         
     615        void setTrackerLogin(wstring username, wstring password) 
     616        { 
     617                trackerUsername_ = username; 
     618                trackerPassword_ = password; 
     619                 
     620                applyTrackerLogin(); 
     621        }        
     622         
     623        pair<wstring, wstring> getTrackerLogin() const 
     624        { 
     625                return make_pair(trackerUsername_, trackerPassword_); 
     626        } 
     627         
     628        const std::wstring& filename() const { return filename_; } 
     629         
     630        const std::wstring& originalFilename() const { return originalFilename_; } 
     631         
     632        const lbt::torrent_handle& handle() const { return handle_; } 
     633 
     634        void resetTrackers() 
     635        { 
     636                if (inSession()) 
     637                { 
     638                        handle_.replace_trackers(torrent_trackers_);             
     639                        trackers_.clear(); 
     640                } 
     641        } 
     642         
     643        void setTrackers(const std::vector<TrackerDetail>& trackerDetails) 
     644        { 
     645                trackers_.clear(); 
     646                trackers_.assign(trackerDetails.begin(), trackerDetails.end()); 
     647                 
     648                applyTrackers(); 
     649        } 
     650         
     651        const std::vector<TrackerDetail>& getTrackers() 
     652        { 
     653                if (inSession() && trackers_.empty()) 
     654                { 
     655                        std::vector<lbt::announce_entry> trackers = handle_.trackers(); 
     656                         
     657                        foreach (const lbt::announce_entry& entry, trackers) 
     658                        { 
     659                                trackers_.push_back( 
     660                                        TrackerDetail(hal::from_utf8(entry.url), entry.tier)); 
     661                        } 
     662                }                
     663                return trackers_; 
     664        } 
     665         
     666        void setFilePriorities(std::vector<int> fileIndices, int priority) 
     667        { 
     668                if (!filePriorities_.empty()) 
     669                { 
     670                        foreach(int i, fileIndices) 
     671                                filePriorities_[i] = priority; 
     672                                 
     673                        applyFilePriorities(); 
     674                } 
     675        } 
     676 
     677        const wstring& saveDirectory() { return save_directory_; } 
     678         
     679    friend class boost::serialization::access; 
     680    template<class Archive> 
     681    void serialize(Archive& ar, const unsigned int version) 
     682    { 
     683        ar & make_nvp("transferLimit", transferLimit_); 
     684        ar & make_nvp("connections", connections_); 
     685        ar & make_nvp("uploads", uploads_);                      
     686                ar & make_nvp("filename", filename_);            
     687        ar & make_nvp("saveDirectory", save_directory_); 
     688                 
     689                ar & make_nvp("payloadUploaded_", payloadUploaded_); 
     690                ar & make_nvp("payloadDownloaded_", payloadDownloaded_); 
     691                ar & make_nvp("uploaded_", uploaded_); 
     692                ar & make_nvp("downloaded_", downloaded_);       
     693                ar & make_nvp("ratio", ratio_);  
     694                ar & make_nvp("trackerUsername", trackerUsername_); 
     695                ar & make_nvp("trackerPassword", trackerPassword_); 
     696                 
     697                ar & make_nvp("state", state_); 
     698                ar & make_nvp("trackers", trackers_); 
     699                 
     700                ar & make_nvp("resolve_countries", resolve_countries_); 
     701                 
     702                ar & make_nvp("file_priorities", filePriorities_); 
     703                 
     704                ar & make_nvp("startTime", startTime_); 
     705                ar & make_nvp("activeDuration", activeDuration_); 
     706                ar & make_nvp("seedingDuration", seedingDuration_); 
     707                 
     708                ar & make_nvp("name", name_); 
     709                ar & make_nvp("compactStorage", compactStorage_); 
     710                ar & make_nvp("finishTime", finishTime_); 
     711                 
     712                ar & make_nvp("progress", progress_); 
     713    } 
     714 
    556715        void setEntryData(libtorrent::entry metadata, libtorrent::entry resumedata) 
    557716        {                
     
    648807        void prepare(wpath filename, wpath saveDirectory) 
    649808        { 
     809                mutex_t::scoped_lock l(mutex_); 
     810                 
    650811                if (exists(filename))  
    651812                        metadata_ = haldecode(filename); 
     
    674835        void extractNames(lbt::entry& metadata) 
    675836        { 
     837                mutex_t::scoped_lock l(mutex_); 
     838                 
    676839                lbt::torrent_info info(metadata);                                
    677840                name_ = hal::from_utf8_safe(info.name()); 
     
    782945        void completedPauseEvent() 
    783946        { 
     947                mutex_t::scoped_lock l(mutex_); 
     948                 
    784949                event().post(shared_ptr<EventDetail>( 
    785950                        new EventInfo(L"completedPauseEvent"))); 
     
    802967        static libtorrent::session* the_session_; 
    803968        static wpath workingDir_; 
     969         
     970        mutable mutex_t mutex_; 
    804971         
    805972        std::pair<float, float> transferLimit_; 
     
    8511018}; 
    8521019 
    853 typedef std::map<std::string, TorrentInternal> TorrentMap; 
    854 typedef std::pair<std::string, TorrentInternal> TorrentPair; 
     1020typedef std::map<std::string, TorrentInternalOld> TorrentMap; 
     1021typedef std::pair<std::string, TorrentInternalOld> TorrentPair; 
     1022typedef shared_ptr<TorrentInternal> TorrentInternal_ptr; 
    8551023 
    8561024class TorrentManager :  
     
    8591027        typedef TorrentManager thisClass; 
    8601028        typedef CHaliteIni<thisClass> iniClass; 
    861          
     1029 
    8621030        struct TorrentHolder 
    8631031        { 
    864                 mutable TorrentInternal torrent; 
     1032                mutable TorrentInternal_ptr torrent; 
    8651033                 
    8661034                wstring filename; 
    8671035                wstring name;            
    8681036                 
    869                 TorrentHolder() : 
    870                         torrent(), filename(torrent.filename()), name(torrent.name()) 
     1037                TorrentHolder() 
    8711038                {} 
    8721039                 
    873                 explicit TorrentHolder(const TorrentInternal& t) : 
    874                         torrent(t), filename(torrent.filename()), name(torrent.name()) 
     1040                explicit TorrentHolder(TorrentInternal_ptr t) : 
     1041                        torrent(t), filename(torrent->filename()), name(torrent->name()) 
    8751042                {} 
    8761043                                                 
     
    8791046                void serialize(Archive& ar, const unsigned int version) 
    8801047                { 
    881                         ar & make_nvp("torrent", torrent); 
     1048                        if (version < 1) 
     1049                        { 
     1050                                TorrentInternalOld t; 
     1051                                ar & make_nvp("torrent", t); 
     1052                                 
     1053                                torrent.reset(new TorrentInternal(t)); 
     1054                        } 
     1055                        else 
     1056                        { 
     1057                                ar & make_nvp("torrent", torrent); 
     1058                        }  
     1059                         
    8821060                        ar & make_nvp("filename", filename); 
    8831061                        ar & make_nvp("name", name); 
     
    9171095                 
    9181096                for (TorrentMap::const_iterator i=map.begin(), e=map.end(); i != e; ++i) 
    919                 {                
     1097                {        
     1098                        TorrentInternal_ptr TIp(new TorrentInternal((*i).second)); 
     1099                         
    9201100                        event().post(shared_ptr<EventDetail>(new EventMsg( 
    921                                 wformat(L"Converting %1%.") % (*i).second.name()))); 
    922                          
    923                         torrents_.insert(TorrentHolder((*i).second)); 
     1101                                wformat(L"Converting %1%.") % TIp->name()))); 
     1102                         
     1103                        torrents_.insert(TorrentHolder(TIp)); 
    9241104                } 
    9251105                 
     
    9321112        } 
    9331113         
    934         std::pair<torrentByName::iterator, bool> insert(const TorrentInternal& t) 
     1114        std::pair<torrentByName::iterator, bool> insert(TorrentInternal_ptr t) 
    9351115        { 
    9361116                return insert(TorrentHolder(t)); 
     
    9431123                if (it != torrents_.get<byFilename>().end()) 
    9441124                { 
    945                         return (*it).torrent; 
     1125                        return *(*it).torrent; 
    9461126                } 
    9471127                 
     
    9551135                if (it != torrents_.get<byName>().end()) 
    9561136                { 
    957                         return (*it).torrent; 
     1137                        return *(*it).torrent; 
    9581138                } 
    9591139                 
     
    9641144                { 
    9651145                event().post(shared_ptr<EventDetail>( 
    966                         new EventMsg(wformat(L"-> %1% - %2%.") % (*i).name % (*i).torrent.name())));     
     1146                        new EventMsg(wformat(L"-> %1% - %2%.") % (*i).name % (*i).torrent->name())));    
    9671147                } 
    9681148                 
     
    10111191void TorrentInternal::setConnectionLimit(int maxConn, int maxUpload) 
    10121192{ 
    1013         connections_ =  maxConn; 
     1193        connections_ = maxConn; 
    10141194        uploads_ = maxUpload; 
    10151195         
     
    11381318        { 
    11391319                event().post(shared_ptr<EventDetail>( 
    1140                         new EventInvalidTorrent(Event::critical, Event::invalidTorrent, "addTorrent", "addTorrent")));\ 
     1320                        new EventInvalidTorrent(Event::critical, Event::invalidTorrent, to_utf8(name_), "getTorrentDetail_ptr"))); 
    11411321        } 
    11421322        catch (const std::exception& e) 
    11431323        { 
    11441324                event().post(shared_ptr<EventDetail>( 
    1145                         new EventTorrentException(Event::critical, Event::torrentException, e.what(), "addTorrent", "addTorrent"))); 
     1325                        new EventTorrentException(Event::critical, Event::torrentException, e.what(), to_utf8(name_), "getTorrentDetail_ptr"))); 
    11461326        } 
    11471327         
     
    11511331} // namespace hal 
    11521332 
     1333BOOST_CLASS_VERSION(hal::TorrentManager::TorrentHolder, 1) 
     1334 
    11531335#endif // RC_INVOKED 
    11541336 
Note: See TracChangeset for help on using the changeset viewer.