source: trunk/src/halTorrentInternal.hpp @ 749

Revision 749, 21.7 KB checked in by Eoin, 11 years ago (diff)

Added override for torrent paused state in resume data file.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2009.
3// Distributed under the Boost Software License, Version 1.0.
4//    (See accompanying file LICENSE_1_0.txt or copy at
5//          http://www.boost.org/LICENSE_1_0.txt)
6
7#pragma once
8
9#include "halTorrentDefines.hpp"
10
11#ifndef HAL_TORRENT_STATE_LOGGING
12#       define TORRENT_STATE_LOG(s)
13#else
14#       include "../halEvent.hpp"
15#       define TORRENT_STATE_LOG(msg) \
16        hal::event_log().post(boost::shared_ptr<hal::EventDetail>( \
17                        new hal::EventMsg(msg, hal::event_logger::torrent_dev)))
18#endif
19
20#pragma warning (push, 1)
21#       include <libtorrent/file.hpp>
22#       include <libtorrent/hasher.hpp>
23#       include <libtorrent/storage.hpp>
24#       include <libtorrent/file_pool.hpp>
25#       include <libtorrent/alert_types.hpp>
26#       include <libtorrent/entry.hpp>
27#       include <libtorrent/bencode.hpp>
28#       include <libtorrent/session.hpp>
29#       include <libtorrent/ip_filter.hpp>
30#       include <libtorrent/torrent_handle.hpp>
31#       include <libtorrent/peer_connection.hpp>
32#       include <libtorrent/extensions/metadata_transfer.hpp>
33#       include <libtorrent/extensions/ut_pex.hpp>
34#pragma warning (pop)
35
36#include <boost/statechart/event.hpp>
37#include <boost/statechart/state_machine.hpp>
38#include <boost/statechart/simple_state.hpp>
39#include <boost/statechart/transition.hpp>
40#include <boost/statechart/state.hpp>
41#include <boost/statechart/custom_reaction.hpp>
42
43#include <boost/mpl/list.hpp>
44
45#include "halIni.hpp"
46#include "halTypes.hpp"
47#include "halSignaler.hpp"
48#include "halTorrentIntEvents.hpp"
49
50namespace hal
51{
52class TorrentInternalOld;
53class torrent_internal;
54class torrent_manager;
55}
56
57BOOST_CLASS_VERSION(hal::TorrentInternalOld, 9)
58BOOST_CLASS_VERSION(hal::torrent_internal, 2)
59
60namespace hal
61{
62
63namespace libt = libtorrent;
64namespace sc = boost::statechart;
65namespace mpl = boost::mpl;
66
67
68inline libt::entry haldecode(const wpath &file) 
69{
70        fs::ifstream ifs(file, fs::ifstream::binary);
71        if (ifs.is_open()) 
72        {
73                ifs.unsetf(fs::ifstream::skipws);
74                return libt::bdecode(std::istream_iterator<char>(ifs), std::istream_iterator<char>());
75        }
76        else return libt::entry();
77}
78
79inline bool halencode(const wpath &file, const libt::entry &e) 
80{
81        fs::ofstream ofs(file, fs::ofstream::binary);
82
83        if (!ofs.is_open()) 
84                return false;
85       
86        libt::bencode(std::ostream_iterator<char>(ofs), e);
87        return true;
88}
89
90inline path path_to_utf8(const wpath& wp)
91{
92        return path(to_utf8(wp.string()));
93}
94
95inline wpath path_from_utf8(const path& p)
96{
97        return wpath(from_utf8(p.string()));
98}
99
100inline std::pair<std::string, std::string> extract_names(const wpath &file)
101{
102        if (fs::exists(file)) 
103        {       
104                libt::torrent_info info(path_to_utf8(file));
105
106                std::string name = info.name(); 
107                std::string filename = name;
108
109                if (!boost::find_last(filename, ".torrent")) 
110                                filename += ".torrent";
111               
112                event_log().post(shared_ptr<EventDetail>(new EventMsg(
113                        hal::wform(L"Loaded names: %1%, %2%") % from_utf8(name) % from_utf8(filename))));
114
115                return std::make_pair(name, filename);
116        }
117        else
118                return std::make_pair("", "");
119}
120
121inline libt::storage_mode_t hal_allocation_to_libt(bit::allocations alloc)
122{
123        switch (alloc)
124        {
125        case bit::full_allocation:
126                return libt::storage_mode_allocate;
127        case bit::compact_allocation:
128                return libt::storage_mode_compact;
129        case bit::sparse_allocation:
130        default:
131                return libt::storage_mode_sparse;
132        }
133}
134
135class invalid_torrent : public std::exception
136{
137public:
138        invalid_torrent(const wstring& who) :
139                who_(who)
140        {}
141       
142        virtual ~invalid_torrent() throw () {}
143
144        wstring who() const throw ()
145        {
146                return who_;
147        }       
148       
149private:
150        wstring who_;   
151};
152       
153template<typename T>
154class transfer_tracker
155{
156public:
157        transfer_tracker() :
158                total_(0),
159                total_offset_(0)
160        {}
161       
162        transfer_tracker(T total) :
163                total_(total),
164                total_offset_(0)
165        {}
166       
167        transfer_tracker(T total, T offset) :
168                total_(total),
169                total_offset_(offset)
170        {}
171       
172        void reset(T total) const
173        {
174                total_ = total;
175                total_offset_ = 0;
176        }
177       
178        T update(T rel_total) const
179        {
180                total_ += (rel_total - total_offset_);
181                total_offset_ = rel_total;
182               
183                return total_;
184        }
185       
186        void setOffset(T offset) const
187        {
188                total_offset_ = offset;
189        }
190       
191        operator T() const { return total_; }
192       
193        friend class boost::serialization::access;
194        template<class Archive>
195        void serialize(Archive& ar, const unsigned int version)
196        {
197                ar & boost::serialization::make_nvp("total", total_);
198        }
199       
200private:
201        mutable T total_;
202        mutable T total_offset_;
203};
204
205class duration_tracker
206{
207public:
208        duration_tracker() :
209                total_(boost::posix_time::time_duration(0,0,0,0), 
210                        boost::posix_time::time_duration(0,0,0,0))
211        {}
212       
213        boost::posix_time::time_duration update() const
214        {
215                if (start_.is_not_a_date_time()) 
216                        start_ = boost::posix_time::second_clock::universal_time();
217
218                if (static_cast<boost::posix_time::time_duration>(total_).is_special()) 
219                        total_.setOffset(boost::posix_time::time_duration(0,0,0,0));
220               
221                return total_.update(boost::posix_time::second_clock::universal_time() - start_);
222        }
223       
224        void reset() const
225        {
226                total_.setOffset(boost::posix_time::time_duration(0,0,0,0));
227                start_ = boost::posix_time::second_clock::universal_time();
228        }
229       
230        friend class boost::serialization::access;
231        template<class Archive>
232        void serialize(Archive& ar, const unsigned int version)
233        {
234                ar & boost::serialization::make_nvp("total", total_);
235        }
236       
237        operator boost::posix_time::time_duration() const { return total_; }
238       
239private:
240        transfer_tracker<boost::posix_time::time_duration> total_;     
241        mutable boost::posix_time::ptime start_;               
242};
243       
244struct signalers
245{
246        signaler<> torrent_finished;
247
248        boost::signal<void ()> torrent_paused;
249        boost::signal<void ()> resume_data;
250};
251
252class torrent_internal;
253typedef shared_ptr<torrent_internal> torrent_internal_ptr;
254
255struct torrent_standalone :
256        public hal::IniBase<torrent_standalone>
257{
258        typedef torrent_standalone thisClass;
259        typedef hal::IniBase<thisClass> iniClass;
260
261        torrent_standalone() :
262                iniClass("torrent")
263        {}
264
265        torrent_standalone(torrent_internal_ptr t) :
266                iniClass("torrent"),
267                torrent(t),
268                save_time(pt::second_clock::universal_time())
269        {}
270
271        torrent_internal_ptr torrent;
272        pt::ptime save_time;
273
274    friend class boost::serialization::access;
275    template<class Archive>
276    void serialize(Archive& ar, const unsigned int version)
277    {
278                ar & boost::serialization::make_nvp("torrent", torrent);
279                ar & boost::serialization::make_nvp("save_time", save_time);
280    }
281};
282
283struct out_of_session;
284
285class torrent_internal :
286        public boost::enable_shared_from_this<torrent_internal>,
287        public sc::state_machine<torrent_internal, out_of_session>
288{
289        friend class bit::torrent::exec_around_ptr::proxy;
290
291        friend struct out_of_session;   
292        friend struct in_the_session;
293       
294        friend struct active;
295        friend struct pausing;
296        friend struct paused;
297        friend struct stopping;
298        friend struct stopped;
299        friend struct in_error;
300        friend struct not_started;
301        friend struct resume_data_waiting;
302        friend struct resume_data_idling;
303
304private:
305        #define TORRENT_INTERNALS_DEFAULTS \
306                original_filename_(L""), \
307                transfer_limit_(std::pair<float, float>(-1, -1)), \
308                connections_(-1), \
309                uploads_(-1), \
310                ratio_(0), \
311                resolve_countries_(true), \
312                total_uploaded_(0), \
313                total_base_(0), \
314                progress_(0), \
315                managed_(false), \
316                start_time_(boost::posix_time::second_clock::universal_time()), \
317                in_session_(false), \
318                queue_position_(0)
319               
320        torrent_internal() :   
321                TORRENT_INTERNALS_DEFAULTS,
322                allocation_(bit::sparse_allocation)
323        {
324                state(torrent_details::torrent_stopped);
325        }
326
327        torrent_internal(wpath filename, wpath saveDirectory, bit::allocations alloc, wpath move_to_directory=L"") :
328                TORRENT_INTERNALS_DEFAULTS,
329                save_directory_(saveDirectory.string()),
330                move_to_directory_(move_to_directory.string()),
331                allocation_(alloc)
332        {
333                state(torrent_details::torrent_stopped);
334                assert(the_session_);
335
336                prepare(filename);
337        }
338
339        #undef TORRENT_INTERNALS_DEFAULTS
340
341public:
342        void locked_process_event(const sc::event_base & e)
343        {
344                mutex_t::scoped_lock l(mutex_);
345                process_event(e);
346        }
347
348        ~torrent_internal()
349        {
350                terminate();
351                TORRENT_STATE_LOG(L"Torrent state machine terminate");
352        }
353       
354        torrent_details_ptr get_torrent_details_ptr();
355
356        void adjust_queue_position(bit::queue_adjustments adjust);
357
358        void set_transfer_speed(float down, float up)
359        {       
360                mutex_t::scoped_lock l(mutex_);
361
362                transfer_limit_ = std::make_pair(down, up);
363               
364                apply_transfer_speed();
365        }
366
367        void set_connection_limit(int maxConn, int maxUpload)           
368        {
369                mutex_t::scoped_lock l(mutex_);
370
371                connections_ = maxConn;
372                uploads_ = maxUpload;
373               
374                apply_connection_limit();
375        }
376
377        std::pair<float, float> get_transfer_speed()
378        {
379                return transfer_limit_;
380        }
381
382        std::pair<int, int> get_connection_limit()
383        {
384                return std::make_pair(connections_, uploads_);
385        }
386       
387        const wstring& name() const { return name_; }
388       
389        void set_ratio(float ratio) 
390        { 
391                if (ratio < 0) ratio = 0;
392                ratio_ = ratio; 
393               
394                apply_ratio();
395        }
396       
397        float get_ratio()
398        {
399                return ratio_;
400        }
401
402        void set_managed(bool m)
403        {
404                mutex_t::scoped_lock l(mutex_);
405                managed_ = m;
406               
407                if (in_session()) handle_.auto_managed(managed_);
408        }
409
410        bool is_managed()
411        {
412                if (in_session())
413                {
414                        managed_ = handle_.is_auto_managed();
415                }
416
417                return managed_;
418        }
419       
420        void add_to_session(bool paused = false);
421       
422        bool remove_from_session(bool write_data=true);
423
424        bool in_session() const
425        { 
426                mutex_t::scoped_lock l(mutex_);
427
428                return (in_session_ && the_session_ && handle_.is_valid());
429        }
430
431        void resume()
432        {
433                HAL_DEV_MSG(hal::wform(L"resume() - %1%") % name_);
434               
435                locked_process_event(ev_resume());
436        }
437       
438        void pause()
439        {
440                HAL_DEV_MSG(hal::wform(L"pause() - %1%") % name_);
441               
442                locked_process_event(ev_pause());               
443        }
444       
445        void stop()
446        {
447                HAL_DEV_MSG(hal::wform(L"stop() - %1%") % name_);
448               
449                locked_process_event(ev_stop());
450        }
451       
452        void start()
453        {
454                HAL_DEV_MSG(hal::wform(L"stop() - %1%") % name_);
455               
456                locked_process_event(ev_start());
457        }
458
459        void set_state_stopped()
460        {
461                state(torrent_details::torrent_stopped);
462        }
463
464        void force_recheck()
465        {
466                mutex_t::scoped_lock l(mutex_);
467                HAL_DEV_MSG(hal::wform(L"force_recheck() - %1%") % name_);
468               
469                process_event(ev_force_recheck());     
470        }
471       
472        void write_resume_data(const libt::entry& ent)
473        {                                       
474                HAL_DEV_MSG(L"write_resume_data()");
475
476                wpath resume_dir = hal::app().get_working_directory()/L"resume";
477               
478                if (!exists(resume_dir))
479                        create_directory(resume_dir);
480
481                boost::filesystem::ofstream out(resume_dir/(name_ + L".fastresume"), std::ios_base::binary);
482                out.unsetf(std::ios_base::skipws);
483                bencode(std::ostream_iterator<char>(out), ent);
484
485                HAL_DEV_MSG(L"Written!");
486        }
487
488        void save_resume_data()
489        {
490                handle_.save_resume_data();
491        }
492       
493        void clear_resume_data()
494        {
495                wpath resume_file = hal::app().get_working_directory() / L"resume" / (name_ + L".fastresume");
496               
497                if (exists(resume_file))
498                        remove(resume_file);
499        }
500
501        void delete_torrent_file()
502        {               
503                wpath torrent_file = hal::app().get_working_directory() / L"torrents" / filename_;
504               
505                if (exists(torrent_file))
506                        remove(torrent_file);
507        }
508
509        const wpath get_save_directory()
510        {
511                return save_directory_;
512        }
513
514        void set_save_directory(wpath s, bool force=false)
515        {
516                if (in_session() && !is_finished() &&
517                                s != path_from_utf8(handle_.save_path()))
518                {
519                        handle_.move_storage(path_to_utf8(s));
520                        save_directory_ = s;
521                }
522                else if (!in_session() && force)
523                {
524                        save_directory_ = s;
525                }
526        }
527
528        const wpath get_move_to_directory()
529        {
530                return move_to_directory_;
531        }
532       
533        void set_move_to_directory(wpath m)
534        {
535                if (is_finished() && !m.empty())
536                {
537                        if (m != path_from_utf8(handle_.save_path()))
538                        {
539                                handle_.move_storage(path_to_utf8(m));
540                                save_directory_ = move_to_directory_ = m;
541                        }
542                }
543                else
544                {
545                        move_to_directory_ = m;
546                }
547        }
548
549        bool is_finished()
550        {
551                if (in_session())
552                {
553                        libt::torrent_status::state_t s = handle_.status().state;
554
555                        return (s == libt::torrent_status::seeding ||
556                                                s == libt::torrent_status::finished);
557                }
558                else 
559                        return false;
560        }
561       
562        void finished()
563        {
564                if (finish_time_.is_special())
565                        finish_time_ = boost::posix_time::second_clock::universal_time();
566
567                if (is_finished())
568                {
569                        if (!move_to_directory_.empty() && 
570                                        move_to_directory_ !=  path_from_utf8(handle_.save_path()))
571                        {
572                                handle_.move_storage(path_to_utf8(move_to_directory_));
573                                save_directory_ = move_to_directory_;
574                        }
575                }
576        }
577       
578        bool is_active() const { return state() == torrent_details::torrent_active; }
579
580        unsigned get_state()
581        {
582                return state_;
583        }
584       
585        void set_tracker_login(wstring username, wstring password)
586        {
587                tracker_username_ = username;
588                tracker_password_ = password;
589               
590                apply_tracker_login();
591        }       
592       
593        std::pair<wstring, wstring> get_tracker_login() const
594        {
595                return make_pair(tracker_username_, tracker_password_);
596        }
597       
598        const wstring& filename() const { return filename_; }
599       
600        const wstring& original_filename() const { return original_filename_; }
601       
602        const libt::torrent_handle& handle() const { return handle_; }
603
604        void reset_trackers()
605        {
606                if (in_session())
607                {
608                        handle_.replace_trackers(torrent_trackers_);           
609                        trackers_.clear();
610                }
611        }
612       
613        void set_trackers(const std::vector<tracker_detail>& tracker_details)
614        {
615                trackers_.clear();
616                trackers_.assign(tracker_details.begin(), tracker_details.end());
617               
618                apply_trackers();
619        }
620       
621        const std::vector<tracker_detail>& get_trackers()
622        {
623                if (trackers_.empty() && info_memory_)
624                {
625                        std::vector<libt::announce_entry> trackers = info_memory_->trackers();
626                       
627                        foreach (const libt::announce_entry& entry, trackers)
628                        {
629                                trackers_.push_back(
630                                        tracker_detail(hal::from_utf8(entry.url), entry.tier));
631                        }
632                }               
633                return trackers_;
634        }
635       
636        void set_file_priorities(std::vector<int> fileIndices, int priority)
637        {
638                if (!file_priorities_.empty())
639                {
640                        foreach(int i, fileIndices)
641                                file_priorities_[i] = priority;
642                               
643                        apply_file_priorities();
644                }
645        }
646
647        const wpath& save_directory() { return save_directory_; }
648       
649        friend class boost::serialization::access;
650        template<class Archive>
651        void serialize(Archive& ar, const unsigned int version)
652        {
653                using boost::serialization::make_nvp;
654
655                if (version > 1) {
656                        ar & make_nvp("transfer_limits", transfer_limit_);
657                        ar & make_nvp("connection_limits", connections_);
658                        ar & make_nvp("upload_limits", uploads_);       
659
660                        ar & make_nvp("name", name_);
661                        ar & make_nvp("filename", filename_);   
662
663                        ar & make_nvp("ratio", ratio_); 
664                        ar & make_nvp("progress", progress_);
665                        ar & make_nvp("state", state_);
666        //                      ar & make_nvp("compact_storage", compact_storage_);     
667                        ar & make_nvp("allocation_type", allocation_); 
668                        ar & make_nvp("resolve_countries", resolve_countries_); 
669
670                        ar & make_nvp("tracker_username", tracker_username_);
671                        ar & make_nvp("tracker_password", tracker_password_);
672                        ar & make_nvp("trackers", trackers_);
673
674                        ar & make_nvp("save_directory", save_directory_);
675                        ar & make_nvp("move_to_directory", move_to_directory_);
676                       
677                        ar & make_nvp("payload_uploaded", payload_uploaded_);
678                        ar & make_nvp("payload_downloaded", payload_downloaded_);
679                        ar & make_nvp("uploaded", uploaded_);
680                        ar & make_nvp("downloaded", downloaded_);                       
681                                       
682                        ar & make_nvp("file_priorities", file_priorities_);
683                       
684                        ar & make_nvp("start_time", start_time_);
685                        ar & make_nvp("finish_time", finish_time_);
686                        ar & make_nvp("active_duration", active_duration_);
687                        ar & make_nvp("seeding_duration", seeding_duration_);
688                        ar & make_nvp("managed", managed_);                             
689                } 
690                else 
691                {
692                        ar & make_nvp("transferLimit", transfer_limit_);
693                        ar & make_nvp("connections", connections_);
694                        ar & make_nvp("uploads", uploads_);                     
695                        ar & make_nvp("filename", filename_);   
696
697                        wstring s;
698                        ar & make_nvp("saveDirectory", s);
699                        save_directory_ = s;
700
701                        if (version == 2) {
702                                wstring m;
703                                ar & make_nvp("moveToDirectory", m);
704                                move_to_directory_ = m;
705                        } else {
706                                move_to_directory_ = save_directory_;
707                        }
708                       
709                        ar & make_nvp("payload_uploaded_", payload_uploaded_);
710                        ar & make_nvp("payload_downloaded_", payload_downloaded_);
711                        ar & make_nvp("uploaded_", uploaded_);
712                        ar & make_nvp("downloaded_", downloaded_);     
713                        ar & make_nvp("ratio", ratio_); 
714                        ar & make_nvp("trackerUsername", tracker_username_);
715                        ar & make_nvp("trackerPassword", tracker_password_);
716                       
717                        ar & make_nvp("state", state_);
718                        ar & make_nvp("trackers", trackers_);
719                       
720                        ar & make_nvp("resolve_countries", resolve_countries_);
721                       
722                        ar & make_nvp("file_priorities", file_priorities_);
723                       
724                        ar & make_nvp("start_time", start_time_);
725                        ar & make_nvp("activeDuration", active_duration_);
726                        ar & make_nvp("seedingDuration", seeding_duration_);
727                       
728                        ar & make_nvp("name", name_);
729                        ar & make_nvp("compactStorage", compact_storage_);
730                        ar & make_nvp("finish_time", finish_time_);
731                       
732                        ar & make_nvp("progress", progress_);
733                }
734        }
735
736        void set_entry_data(boost::intrusive_ptr<libt::torrent_info> metadata, libtorrent::entry resumedata)
737        {               
738                info_memory_ = metadata;
739        }
740
741        std::vector<libt::peer_info>& peers() { return peers_; }
742       
743        boost::tuple<size_t, size_t, size_t, size_t> update_peers();
744       
745        void get_peer_details(peer_details_vec& peer_details) const
746        {
747                if (in_session())
748                {
749                        foreach (libt::peer_info peer, peers_) 
750                        {
751                                peer_details.insert(peer);
752                        }       
753                }
754        }
755
756        void get_file_details(file_details_vec& files);
757        file_details_vec get_file_details();
758       
759        void prepare(wpath filename);
760
761        void set_resolve_countries(bool b)
762        {
763                resolve_countries_ = b;
764                apply_resolve_countries();
765        }
766       
767        void extract_names(boost::intrusive_ptr<libt::torrent_info> metadata);
768       
769        boost::intrusive_ptr<libt::torrent_info> info_memory()
770        {
771                if (!info_memory_) 
772                        info_memory_ = boost::intrusive_ptr<libt::torrent_info>
773                                (new libt::torrent_info(path_to_utf8(filename())));
774               
775                return info_memory_;
776        }
777       
778        signalers& signals()
779        {
780                mutex_t::scoped_lock l(mutex_);
781                return signals_;
782        }       
783       
784        unsigned state() const 
785        { 
786/*              if (!in_session())
787                {
788                        if (state_ != torrent_details::torrent_stopped)
789                        {                       
790                                HAL_DEV_MSG(L"Should really be stopped!");
791                                state_ = torrent_details::torrent_stopped;
792                        }
793                }
794*/             
795                return state_; 
796        }
797
798        wstring check_error() 
799        {               
800                if (in_session())
801                {
802                        status_memory_ = handle_.status();
803                        return from_utf8(status_memory_.error);
804                }
805                else
806                        return L"";
807        }
808
809        bool awaiting_resume_data() { return (state_downcast<const resume_data_waiting*>() != 0); }
810
811        void output_torrent_debug_details()
812        {
813                HAL_DEV_MSG(wform(L"Name %1%") % name_);
814                HAL_DEV_MSG(wform(L" >> In session       %1%") % in_session());
815
816                if (in_session())
817                {
818
819                wstring state_str;
820
821                switch (state())
822                {
823                case torrent_details::torrent_active:
824                        state_str = L"Active";
825                        break;
826
827                case torrent_details::torrent_not_started:
828                        state_str = L"Not Started!";
829                        break;
830
831                case torrent_details::torrent_paused:
832                        state_str = app().res_wstr(HAL_TORRENT_PAUSED);
833                        break;
834                       
835                case torrent_details::torrent_pausing:
836                        state_str = app().res_wstr(HAL_TORRENT_PAUSING);
837                        break;
838                       
839                case torrent_details::torrent_stopped:
840                        state_str = app().res_wstr(HAL_TORRENT_STOPPED);
841                        break;
842                       
843                case torrent_details::torrent_stopping:
844                        state_str = app().res_wstr(HAL_TORRENT_STOPPING);
845                        break;
846                       
847                case torrent_details::torrent_in_error:
848                        state_str = app().res_wstr(HAL_TORRENT_IN_ERROR);
849                        break;
850                       
851                default:
852                        state_str = L"Bad State!";
853                        break;
854                };
855               
856                HAL_DEV_MSG(wform(L" >> State                   %1%") % state_str);
857                HAL_DEV_MSG(wform(L" >> Paused in session       %1%") % handle_.is_paused());
858                HAL_DEV_MSG(wform(L" >> Error state             %1%") % check_error());
859
860                }
861        }
862
863        static boost::optional<libt::session>* the_session_;   
864
865        friend class torrent_manager;
866
867private:
868        void apply_settings(); 
869        void apply_transfer_speed();
870        void apply_connection_limit(); 
871        void apply_ratio();     
872        void apply_trackers(); 
873        void apply_tracker_login();     
874        void apply_file_priorities();   
875        void apply_resolve_countries();
876        void state(unsigned s);
877
878        void initialize_state_machine(torrent_internal_ptr p)
879        {
880                own_weak_ptr_ = boost::weak_ptr<torrent_internal>(p);
881
882                TORRENT_STATE_LOG(L"Torrent state machine initiate");
883                initiate();
884        }
885
886        mutable mutex_t mutex_;
887        signalers signals_;
888
889        boost::weak_ptr<torrent_internal> own_weak_ptr_;
890       
891        std::pair<float, float> transfer_limit_;
892       
893        mutable unsigned state_;
894        int connections_;
895        int uploads_;
896        bool in_session_;
897        float ratio_;
898        bool resolve_countries_;
899       
900        wstring filename_;
901        wstring name_;
902        wpath save_directory_;
903        wpath move_to_directory_;
904        wstring original_filename_;
905        libt::torrent_handle handle_;   
906        wstring tracker_username_;     
907        wstring tracker_password_;
908       
909        boost::int64_t total_uploaded_;
910        boost::int64_t total_base_;
911       
912        transfer_tracker<boost::int64_t> payload_uploaded_;
913        transfer_tracker<boost::int64_t> payload_downloaded_;
914        transfer_tracker<boost::int64_t> uploaded_;
915        transfer_tracker<boost::int64_t> downloaded_;
916       
917        pt::ptime start_time_;
918        pt::ptime finish_time_;
919        duration_tracker active_duration_;
920        duration_tracker seeding_duration_;
921       
922        std::vector<tracker_detail> trackers_;
923        std::vector<libt::announce_entry> torrent_trackers_;
924        std::vector<libt::peer_info> peers_;   
925        std::vector<int> file_priorities_;
926       
927        float progress_;       
928        int queue_position_;
929        bool compact_storage_;
930        bool managed_;
931        bit::allocations allocation_;
932       
933        boost::intrusive_ptr<libt::torrent_info> info_memory_;
934        libt::torrent_status status_memory_;
935        file_details_vec file_details_memory_;
936};
937
938} // namespace hal
939
940#include "halTorrentIntStates.hpp"
941
Note: See TracBrowser for help on using the repository browser.