optimized struct layout of torrent_info. removed boost.date_type types from public interface (replaced by time_t)

This commit is contained in:
Arvid Norberg 2010-08-21 22:10:16 +00:00
parent afd5567969
commit f70fbb45c0
9 changed files with 235 additions and 138 deletions

View File

@ -1532,8 +1532,7 @@ The ``torrent_info`` has the following synopsis::
std::vector<std::pair<std::string, int> > const& nodes() const; std::vector<std::pair<std::string, int> > const& nodes() const;
void add_node(std::pair<std::string, int> const& node); void add_node(std::pair<std::string, int> const& node);
boost::optional<boost::posix_time::ptime> boost::optional<time_t> creation_date() const;
creation_date() const;
int piece_size(unsigned int index) const; int piece_size(unsigned int index) const;
sha1_hash const& hash_for_piece(unsigned int index) const; sha1_hash const& hash_for_piece(unsigned int index) const;
@ -1915,22 +1914,22 @@ name() comment() creation_date() creator()
std::string const& name() const; std::string const& name() const;
std::string const& comment() const; std::string const& comment() const;
boost::optional<boost::posix_time::ptime> creation_date() const; std::string const& creator() const;
boost::optional<time_t> creation_date() const;
``name()`` returns the name of the torrent. ``name()`` returns the name of the torrent.
``comment()`` returns the comment associated with the torrent. If there's no comment, ``comment()`` returns the comment associated with the torrent. If there's no comment,
it will return an empty string. ``creation_date()`` returns a `boost::posix_time::ptime`__ it will return an empty string. ``creation_date()`` returns the creation date of
object, representing the time when this torrent file was created. If there's no time stamp the torrent as time_t (`posix time`_). If there's no time stamp in the torrent file,
in the torrent file, this will return a date of January 1:st 1970. the optional object will be uninitialized.
Both the name and the comment is UTF-8 encoded strings. Both the name and the comment is UTF-8 encoded strings.
``creator()`` returns the creator string in the torrent. If there is no creator string ``creator()`` returns the creator string in the torrent. If there is no creator string
it will return an empty string. it will return an empty string.
__ http://www.boost.org/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class .. _`posix time`: http://www.opengroup.org/onlinepubs/009695399/functions/time.html
priv() priv()
------ ------

View File

@ -304,6 +304,9 @@ namespace libtorrent
void save_state(entry* e, boost::uint32_t flags) const; void save_state(entry* e, boost::uint32_t flags) const;
void load_state(lazy_entry const* e); void load_state(lazy_entry const* e);
// TODO: just use a single proxy for everything. That's essentially how
// it works behind the scene anyway, with the udp socket being used for
// both DHT, uTP peers and udp trackers.
void set_peer_proxy(proxy_settings const& s) void set_peer_proxy(proxy_settings const& s)
{ {
m_peer_proxy = s; m_peer_proxy = s;

View File

@ -0,0 +1,67 @@
/*
Copyright (c) 2010, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_COPY_PTR
#define TORRENT_COPY_PTR
namespace libtorrent
{
template <class T>
struct copy_ptr
{
copy_ptr(): m_ptr(0) {}
copy_ptr(T* t): m_ptr(t) {}
copy_ptr(copy_ptr const& p): m_ptr(p.m_ptr ? new T(*p.m_ptr) : 0) {}
void reset(T* t = 0) { delete m_ptr; m_ptr = t; }
copy_ptr& operator=(copy_ptr const& p)
{
delete m_ptr;
m_ptr = p.m_ptr ? new T(*p.m_ptr) : 0;
return *this;
}
T& operator*() { return *m_ptr; }
void swap(copy_ptr<T>& p)
{
T* tmp = m_ptr;
m_ptr = p.m_ptr;
p.m_ptr = tmp;
}
T const& operator*() const { return *m_ptr; }
operator bool() const { return m_ptr; }
~copy_ptr() { delete m_ptr; }
private:
T* m_ptr;
};
}
#endif // TORRENT_COPY_PTR

View File

@ -52,7 +52,6 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma warning(push, 1) #pragma warning(push, 1)
#endif #endif
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
@ -127,7 +126,7 @@ namespace libtorrent
// if a creation date is found in the torrent file // if a creation date is found in the torrent file
// this will be set to that, otherwise it'll be // this will be set to that, otherwise it'll be
// 1970, Jan 1 // 1970, Jan 1
boost::posix_time::ptime m_creation_date; time_t m_creation_date;
// if a comment is found in the torrent file // if a comment is found in the torrent file
// this will be set to that comment // this will be set to that comment

View File

@ -36,12 +36,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <string> #include <string>
#include <vector> #include <vector>
#include <ctime> #include <ctime>
#include <boost/shared_ptr.hpp>
#include "libtorrent/size_type.hpp" #include "libtorrent/size_type.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/peer_request.hpp" #include "libtorrent/peer_request.hpp"
#include "libtorrent/peer_id.hpp" #include "libtorrent/peer_id.hpp"
#include "libtorrent/copy_ptr.hpp"
namespace libtorrent namespace libtorrent
{ {
@ -54,15 +54,15 @@ namespace libtorrent
{} {}
std::string path; std::string path;
std::string symlink_path;
copy_ptr<sha1_hash> filehash;
size_type offset; // the offset of this file inside the torrent size_type offset; // the offset of this file inside the torrent
size_type size; // the size of this file size_type size; // the size of this file
// the offset in the file where the storage starts. // the offset in the file where the storage starts.
// This is always 0 unless parts of the torrent is // This is always 0 unless parts of the torrent is
// compressed into a single file, such as a so-called part file. // compressed into a single file, such as a so-called part file.
size_type file_base; size_type file_base;
std::time_t mtime; time_t mtime;
std::string symlink_path;
boost::shared_ptr<sha1_hash> filehash;
bool pad_file:1; bool pad_file:1;
bool hidden_attribute:1; bool hidden_attribute:1;
bool executable_attribute:1; bool executable_attribute:1;
@ -154,17 +154,18 @@ namespace libtorrent
void optimize(int pad_file_limit = -1); void optimize(int pad_file_limit = -1);
private: private:
int m_piece_length;
// the list of files that this torrent consists of // the list of files that this torrent consists of
std::vector<file_entry> m_files; std::vector<file_entry> m_files;
std::string m_name;
// the sum of all filesizes // the sum of all filesizes
size_type m_total_size; size_type m_total_size;
// the number of pieces in the torrent // the number of pieces in the torrent
int m_num_pieces; int m_num_pieces;
std::string m_name;
int m_piece_length;
}; };
} }

View File

@ -42,7 +42,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/shared_array.hpp> #include <boost/shared_array.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -57,11 +56,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/intrusive_ptr_base.hpp" #include "libtorrent/intrusive_ptr_base.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/file_storage.hpp" #include "libtorrent/file_storage.hpp"
#include "libtorrent/copy_ptr.hpp"
namespace libtorrent namespace libtorrent
{ {
namespace pt = boost::posix_time;
enum enum
{ {
// wait 60 seconds before retrying a failed tracker // wait 60 seconds before retrying a failed tracker
@ -80,16 +78,25 @@ namespace libtorrent
, tier(0) , tier(0)
, fail_limit(0) , fail_limit(0)
, fails(0) , fails(0)
, updating(false)
, source(0) , source(0)
, verified(false) , verified(false)
, updating(false)
, start_sent(false) , start_sent(false)
, complete_sent(false) , complete_sent(false)
, send_stats(true) , send_stats(true)
{} {}
// tracker URL as it appeared in the torrent file
std::string url; std::string url;
// if this tracker has returned an error or warning message
// that message is stored here
std::string message;
// if this tracker failed the last time it was contacted
// this error code specifies what error occurred
error_code last_error;
int next_announce_in() const; int next_announce_in() const;
int min_announce_in() const; int min_announce_in() const;
@ -99,21 +106,19 @@ namespace libtorrent
// no announces before this time // no announces before this time
ptime min_announce; ptime min_announce;
// if this tracker failed the last time it was contacted // the tier this tracker belongs to
// this error code specifies what error occurred
error_code last_error;
// if this tracker has returned an error or warning message
// that message is stored here
std::string message;
boost::uint8_t tier; boost::uint8_t tier;
// the number of times this tracker can fail // the number of times this tracker can fail
// in a row before it's removed. 0 means unlimited // in a row before it's removed. 0 means unlimited
boost::uint8_t fail_limit; boost::uint8_t fail_limit;
// the number of times in a row this tracker has failed // the number of times in a row this tracker has failed
boost::uint8_t fails; boost::uint8_t fails:7;
// true if we're currently trying to announce with
// this tracker
bool updating:1;
enum tracker_source enum tracker_source
{ {
@ -122,17 +127,14 @@ namespace libtorrent
source_magnet_link = 4, source_magnet_link = 4,
source_tex = 8 source_tex = 8
}; };
// where did we get this tracker from // where did we get this tracker from
boost::uint8_t source; boost::uint8_t source:4;
// is set to true if we have ever received a response from // is set to true if we have ever received a response from
// this tracker // this tracker
bool verified:1; bool verified:1;
// true if we're currently trying to announce with
// this tracker
bool updating:1;
// this is true if event start has been sent to the tracker // this is true if event start has been sent to the tracker
bool start_sent:1; bool start_sent:1;
@ -301,7 +303,7 @@ namespace libtorrent
} }
} }
boost::optional<pt::ptime> creation_date() const; boost::optional<time_t> creation_date() const;
const std::string& creator() const const std::string& creator() const
{ return m_created_by; } { return m_created_by; }
@ -339,7 +341,13 @@ namespace libtorrent
std::map<int, sha1_hash> build_merkle_list(int piece) const; std::map<int, sha1_hash> build_merkle_list(int piece) const;
bool is_merkle_torrent() const { return !m_merkle_tree.empty(); } bool is_merkle_torrent() const { return !m_merkle_tree.empty(); }
// if we're logging member offsets, we need access to them
#if !defined NDEBUG \
&& !defined TORRENT_LOGGING \
&& !defined TORRENT_VERBOSE_LOGGING \
&& !defined TORRENT_ERROR_LOGGING
private: private:
#endif
// not assignable // not assignable
torrent_info const& operator=(torrent_info const&); torrent_info const& operator=(torrent_info const&);
@ -352,7 +360,7 @@ namespace libtorrent
// if m_files is modified, it is first copied into // if m_files is modified, it is first copied into
// m_orig_files so that the original name and // m_orig_files so that the original name and
// filenames are preserved. // filenames are preserved.
boost::shared_ptr<const file_storage> m_orig_files; copy_ptr<const file_storage> m_orig_files;
// the urls to the trackers // the urls to the trackers
std::vector<announce_entry> m_urls; std::vector<announce_entry> m_urls;
@ -360,13 +368,19 @@ namespace libtorrent
std::vector<std::string> m_http_seeds; std::vector<std::string> m_http_seeds;
nodes_t m_nodes; nodes_t m_nodes;
// the hash that identifies this torrent // if this is a merkle torrent, this is the merkle
sha1_hash m_info_hash; // tree. It has space for merkle_num_nodes(merkle_num_leafs(num_pieces))
// hashes
std::vector<sha1_hash> m_merkle_tree;
// if a creation date is found in the torrent file // this is a copy of the info section from the torrent.
// this will be set to that, otherwise it'll be // it use maintained in this flat format in order to
// 1970, Jan 1 // make it available through the metadata extension
pt::ptime m_creation_date; boost::shared_array<char> m_info_section;
// this is a pointer into the m_info_section buffer
// pointing to the first byte of the first sha-1 hash
char const* m_piece_hashes;
// if a comment is found in the torrent file // if a comment is found in the torrent file
// this will be set to that comment // this will be set to that comment
@ -376,44 +390,41 @@ namespace libtorrent
// to create the torrent file // to create the torrent file
std::string m_created_by; std::string m_created_by;
// the info section parsed. points into m_info_section
// parsed lazily
mutable lazy_entry m_info_dict;
// if a creation date is found in the torrent file
// this will be set to that, otherwise it'll be
// 1970, Jan 1
time_t m_creation_date;
// the hash that identifies this torrent
sha1_hash m_info_hash;
// the index to the first leaf. This is where the hash for the
// first piece is stored
boost::uint32_t m_merkle_first_leaf:24;
// the number of bytes in m_info_section
boost::uint32_t m_info_section_size:24;
// this is used when creating a torrent. If there's // this is used when creating a torrent. If there's
// only one file there are cases where it's impossible // only one file there are cases where it's impossible
// to know if it should be written as a multifile torrent // to know if it should be written as a multifile torrent
// or not. e.g. test/test there's one file and one directory // or not. e.g. test/test there's one file and one directory
// and they have the same name. // and they have the same name.
bool m_multifile; bool m_multifile:1;
// this is true if the torrent is private. i.e., is should not // this is true if the torrent is private. i.e., is should not
// be announced on the dht // be announced on the dht
bool m_private; bool m_private:1;
// this is true if one of the trackers has an .i2p top // this is true if one of the trackers has an .i2p top
// domain in its hostname. This means the DHT and LSD // domain in its hostname. This means the DHT and LSD
// features are disabled for this torrent (unless the // features are disabled for this torrent (unless the
// settings allows mixing i2p peers with regular peers) // settings allows mixing i2p peers with regular peers)
bool m_i2p; bool m_i2p:1;
// this is a copy of the info section from the torrent.
// it use maintained in this flat format in order to
// make it available through the metadata extension
boost::shared_array<char> m_info_section;
int m_info_section_size;
// this is a pointer into the m_info_section buffer
// pointing to the first byte of the first sha-1 hash
char const* m_piece_hashes;
// if this is a merkle torrent, this is the merkle
// tree. It has space for merkle_num_nodes(merkle_num_leafs(num_pieces))
// hashes
std::vector<sha1_hash> m_merkle_tree;
// the index to the first leaf. This is where the hash for the
// first piece is stored
int m_merkle_first_leaf;
// the info section parsed. points into m_info_section
// parsed lazily
mutable lazy_entry m_info_dict;
}; };
} }

View File

@ -35,8 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/storage.hpp" #include "libtorrent/storage.hpp"
#include "libtorrent/escape_string.hpp" #include "libtorrent/escape_string.hpp"
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/gregorian/greg_date.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/next_prior.hpp> #include <boost/next_prior.hpp>
@ -45,8 +43,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define MAX_SYMLINK_PATH 200 #define MAX_SYMLINK_PATH 200
namespace gr = boost::gregorian;
namespace libtorrent namespace libtorrent
{ {
// defined in torrent_info.cpp // defined in torrent_info.cpp
@ -109,7 +105,7 @@ namespace libtorrent
create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit, int flags) create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit, int flags)
: m_files(fs) : m_files(fs)
, m_creation_date(pt::second_clock::universal_time()) , m_creation_date(time(0))
, m_multifile(fs.num_files() > 1) , m_multifile(fs.num_files() > 1)
, m_private(false) , m_private(false)
, m_merkle_torrent(flags & merkle) , m_merkle_torrent(flags & merkle)
@ -164,7 +160,7 @@ namespace libtorrent
create_torrent::create_torrent(torrent_info const& ti) create_torrent::create_torrent(torrent_info const& ti)
: m_files(const_cast<file_storage&>(ti.files())) : m_files(const_cast<file_storage&>(ti.files()))
, m_creation_date(pt::second_clock::universal_time()) , m_creation_date(time(0))
, m_multifile(ti.num_files() > 1) , m_multifile(ti.num_files() > 1)
, m_private(ti.priv()) , m_private(ti.priv())
, m_merkle_torrent(ti.is_merkle_torrent()) , m_merkle_torrent(ti.is_merkle_torrent())
@ -248,8 +244,7 @@ namespace libtorrent
if (!m_comment.empty()) if (!m_comment.empty())
dict["comment"] = m_comment; dict["comment"] = m_comment;
dict["creation date"] = dict["creation date"] = m_creation_date;
(m_creation_date - pt::ptime(gr::date(1970, gr::Jan, 1))).total_seconds();
if (!m_created_by.empty()) if (!m_created_by.empty())
dict["created by"] = m_created_by; dict["created by"] = m_created_by;

View File

@ -633,6 +633,30 @@ namespace aux {
#define PRINT_SIZEOF(x) (*m_logger) << "sizeof(" #x "): " << sizeof(x) << "\n"; #define PRINT_SIZEOF(x) (*m_logger) << "sizeof(" #x "): " << sizeof(x) << "\n";
#define PRINT_OFFSETOF(x, y) (*m_logger) << " offsetof(" #x "," #y "): " << offsetof(x, y) << "\n"; #define PRINT_OFFSETOF(x, y) (*m_logger) << " offsetof(" #x "," #y "): " << offsetof(x, y) << "\n";
PRINT_SIZEOF(announce_entry)
PRINT_OFFSETOF(announce_entry, url)
PRINT_OFFSETOF(announce_entry, message)
PRINT_OFFSETOF(announce_entry, last_error)
PRINT_OFFSETOF(announce_entry, next_announce)
PRINT_OFFSETOF(announce_entry, min_announce)
PRINT_OFFSETOF(announce_entry, tier)
PRINT_OFFSETOF(announce_entry, fail_limit)
PRINT_SIZEOF(torrent_info)
PRINT_OFFSETOF(torrent_info, m_files)
PRINT_OFFSETOF(torrent_info, m_orig_files)
PRINT_OFFSETOF(torrent_info, m_url_seeds)
PRINT_OFFSETOF(torrent_info, m_http_seeds)
PRINT_OFFSETOF(torrent_info, m_nodes)
PRINT_OFFSETOF(torrent_info, m_merkle_tree)
PRINT_OFFSETOF(torrent_info, m_info_section)
PRINT_OFFSETOF(torrent_info, m_piece_hashes)
PRINT_OFFSETOF(torrent_info, m_info_dict)
PRINT_OFFSETOF(torrent_info, m_creation_date)
PRINT_OFFSETOF(torrent_info, m_comment)
PRINT_OFFSETOF(torrent_info, m_created_by)
PRINT_OFFSETOF(torrent_info, m_info_hash)
PRINT_SIZEOF(union_endpoint) PRINT_SIZEOF(union_endpoint)
PRINT_SIZEOF(request_callback) PRINT_SIZEOF(request_callback)
PRINT_SIZEOF(stat) PRINT_SIZEOF(stat)

View File

@ -49,9 +49,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/date_time/time_clock.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -71,8 +68,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/parse_url.hpp" #include "libtorrent/parse_url.hpp"
#endif #endif
namespace gr = boost::gregorian;
namespace libtorrent namespace libtorrent
{ {
@ -436,17 +431,17 @@ namespace libtorrent
, m_url_seeds(t.m_url_seeds) , m_url_seeds(t.m_url_seeds)
, m_http_seeds(t.m_http_seeds) , m_http_seeds(t.m_http_seeds)
, m_nodes(t.m_nodes) , m_nodes(t.m_nodes)
, m_info_hash(t.m_info_hash) , m_merkle_tree(t.m_merkle_tree)
, m_creation_date(t.m_creation_date) , m_piece_hashes(t.m_piece_hashes)
, m_comment(t.m_comment) , m_comment(t.m_comment)
, m_created_by(t.m_created_by) , m_created_by(t.m_created_by)
, m_creation_date(t.m_creation_date)
, m_info_hash(t.m_info_hash)
, m_merkle_first_leaf(t.m_merkle_first_leaf)
, m_info_section_size(t.m_info_section_size)
, m_multifile(t.m_multifile) , m_multifile(t.m_multifile)
, m_private(t.m_private) , m_private(t.m_private)
, m_i2p(t.m_i2p) , m_i2p(t.m_i2p)
, m_info_section_size(t.m_info_section_size)
, m_piece_hashes(t.m_piece_hashes)
, m_merkle_tree(t.m_merkle_tree)
, m_merkle_first_leaf(t.m_merkle_first_leaf)
{ {
if (m_info_section_size > 0) if (m_info_section_size > 0)
{ {
@ -479,13 +474,13 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// standard constructor that parses a torrent file // standard constructor that parses a torrent file
torrent_info::torrent_info(entry const& torrent_file) torrent_info::torrent_info(entry const& torrent_file)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_merkle_first_leaf(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
, m_merkle_first_leaf(0)
{ {
std::vector<char> tmp; std::vector<char> tmp;
std::back_insert_iterator<std::vector<char> > out(tmp); std::back_insert_iterator<std::vector<char> > out(tmp);
@ -511,13 +506,13 @@ namespace libtorrent
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
torrent_info::torrent_info(lazy_entry const& torrent_file) torrent_info::torrent_info(lazy_entry const& torrent_file)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_merkle_first_leaf(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
, m_merkle_first_leaf(0)
{ {
error_code ec; error_code ec;
if (!parse_torrent_file(torrent_file, ec)) if (!parse_torrent_file(torrent_file, ec))
@ -525,13 +520,13 @@ namespace libtorrent
} }
torrent_info::torrent_info(char const* buffer, int size) torrent_info::torrent_info(char const* buffer, int size)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_merkle_first_leaf(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
, m_merkle_first_leaf(0)
{ {
error_code ec; error_code ec;
lazy_entry e; lazy_entry e;
@ -543,12 +538,12 @@ namespace libtorrent
} }
torrent_info::torrent_info(std::string const& filename) torrent_info::torrent_info(std::string const& filename)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
{ {
std::vector<char> buf; std::vector<char> buf;
int ret = load_file(filename, buf); int ret = load_file(filename, buf);
@ -564,13 +559,13 @@ namespace libtorrent
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
torrent_info::torrent_info(std::wstring const& filename) torrent_info::torrent_info(std::wstring const& filename)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_merkle_first_leaf(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
, m_merkle_first_leaf(0)
{ {
std::vector<char> buf; std::vector<char> buf;
std::string utf8; std::string utf8;
@ -590,24 +585,24 @@ namespace libtorrent
#endif #endif
torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec) torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
{ {
parse_torrent_file(torrent_file, ec); parse_torrent_file(torrent_file, ec);
} }
torrent_info::torrent_info(char const* buffer, int size, error_code& ec) torrent_info::torrent_info(char const* buffer, int size, error_code& ec)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_merkle_first_leaf(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
, m_merkle_first_leaf(0)
{ {
lazy_entry e; lazy_entry e;
if (lazy_bdecode(buffer, buffer + size, e) != 0) if (lazy_bdecode(buffer, buffer + size, e) != 0)
@ -619,12 +614,12 @@ namespace libtorrent
} }
torrent_info::torrent_info(std::string const& filename, error_code& ec) torrent_info::torrent_info(std::string const& filename, error_code& ec)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
{ {
std::vector<char> buf; std::vector<char> buf;
int ret = load_file(filename, buf); int ret = load_file(filename, buf);
@ -641,12 +636,12 @@ namespace libtorrent
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
torrent_info::torrent_info(std::wstring const& filename, error_code& ec) torrent_info::torrent_info(std::wstring const& filename, error_code& ec)
: m_creation_date(pt::ptime(pt::not_a_date_time)) : m_piece_hashes(0)
, m_creation_date(0)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
{ {
std::vector<char> buf; std::vector<char> buf;
std::string utf8; std::string utf8;
@ -664,20 +659,18 @@ namespace libtorrent
} }
#endif #endif
typedef boost::date_time::second_clock<pt::ptime> second_clock;
// constructor used for creating new torrents // constructor used for creating new torrents
// will not contain any hashes, comments, creation date // will not contain any hashes, comments, creation date
// just the necessary to use it with piece manager // just the necessary to use it with piece manager
// used for torrents with no metadata // used for torrents with no metadata
torrent_info::torrent_info(sha1_hash const& info_hash) torrent_info::torrent_info(sha1_hash const& info_hash)
: m_info_hash(info_hash) : m_piece_hashes(0)
, m_creation_date(second_clock::universal_time()) , m_creation_date(time(0))
, m_info_hash(info_hash)
, m_info_section_size(0)
, m_multifile(false) , m_multifile(false)
, m_private(false) , m_private(false)
, m_i2p(false) , m_i2p(false)
, m_info_section_size(0)
, m_piece_hashes(0)
{} {}
torrent_info::~torrent_info() torrent_info::~torrent_info()
@ -689,6 +682,11 @@ namespace libtorrent
m_orig_files.reset(new file_storage(m_files)); m_orig_files.reset(new file_storage(m_files));
} }
#define SWAP(a, b) \
tmp = a; \
a = b; \
b = tmp;
void torrent_info::swap(torrent_info& ti) void torrent_info::swap(torrent_info& ti)
{ {
using std::swap; using std::swap;
@ -701,17 +699,20 @@ namespace libtorrent
swap(m_creation_date, ti.m_creation_date); swap(m_creation_date, ti.m_creation_date);
m_comment.swap(ti.m_comment); m_comment.swap(ti.m_comment);
m_created_by.swap(ti.m_created_by); m_created_by.swap(ti.m_created_by);
swap(m_multifile, ti.m_multifile); boost::uint32_t tmp;
swap(m_private, ti.m_private); SWAP(m_multifile, ti.m_multifile);
swap(m_i2p, ti.m_i2p); SWAP(m_private, ti.m_private);
SWAP(m_i2p, ti.m_i2p);
swap(m_info_section, ti.m_info_section); swap(m_info_section, ti.m_info_section);
swap(m_info_section_size, ti.m_info_section_size); SWAP(m_info_section_size, ti.m_info_section_size);
swap(m_piece_hashes, ti.m_piece_hashes); swap(m_piece_hashes, ti.m_piece_hashes);
m_info_dict.swap(ti.m_info_dict); m_info_dict.swap(ti.m_info_dict);
swap(m_merkle_tree, ti.m_merkle_tree); swap(m_merkle_tree, ti.m_merkle_tree);
swap(m_merkle_first_leaf, ti.m_merkle_first_leaf); SWAP(m_merkle_first_leaf, ti.m_merkle_first_leaf);
} }
#undef SWAP
bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec) bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec)
{ {
if (info.type() != lazy_entry::dict_t) if (info.type() != lazy_entry::dict_t)
@ -1045,8 +1046,7 @@ namespace libtorrent
size_type cd = torrent_file.dict_find_int_value("creation date", -1); size_type cd = torrent_file.dict_find_int_value("creation date", -1);
if (cd >= 0) if (cd >= 0)
{ {
m_creation_date = pt::ptime(gr::date(1970, gr::Jan, 1)) m_creation_date = long(cd);
+ pt::seconds(long(cd));
} }
// if there are any url-seeds, extract them // if there are any url-seeds, extract them
@ -1098,14 +1098,14 @@ namespace libtorrent
return parse_info_section(*info, ec); return parse_info_section(*info, ec);
} }
boost::optional<pt::ptime> boost::optional<time_t>
torrent_info::creation_date() const torrent_info::creation_date() const
{ {
if (m_creation_date != pt::ptime(gr::date(pt::not_a_date_time))) if (m_creation_date != 0)
{ {
return boost::optional<pt::ptime>(m_creation_date); return boost::optional<time_t>(m_creation_date);
} }
return boost::optional<pt::ptime>(); return boost::optional<time_t>();
} }
void torrent_info::add_tracker(std::string const& url, int tier) void torrent_info::add_tracker(std::string const& url, int tier)
@ -1132,8 +1132,6 @@ namespace libtorrent
} }
if (!m_comment.empty()) if (!m_comment.empty())
os << "comment: " << m_comment << "\n"; os << "comment: " << m_comment << "\n";
// if (m_creation_date != pt::ptime(gr::date(pt::not_a_date_time)))
// os << "creation date: " << to_simple_string(m_creation_date) << "\n";
os << "private: " << (m_private?"yes":"no") << "\n"; os << "private: " << (m_private?"yes":"no") << "\n";
os << "number of pieces: " << num_pieces() << "\n"; os << "number of pieces: " << num_pieces() << "\n";
os << "piece length: " << piece_length() << "\n"; os << "piece length: " << piece_length() << "\n";