~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to include/libtorrent/create_torrent.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2010-08-10 12:59:37 UTC
  • mfrom: (1.3.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810125937-jbcmmf17y8yo9hgz
Tags: 0.15.0-0ubuntu1
* New upstream version.
* debian/patches/100_fix_html_docs.patch: refreshed.
* debian/control: bump up standards-version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include "libtorrent/config.hpp"
41
41
#include "libtorrent/storage.hpp"
42
42
#include "libtorrent/hasher.hpp"
 
43
#include "libtorrent/utf8.hpp"
 
44
#include "libtorrent/allocator.hpp"
43
45
 
44
46
#include <vector>
45
47
#include <string>
52
54
#include <boost/filesystem/path.hpp>
53
55
#include <boost/filesystem/operations.hpp>
54
56
#include <boost/optional.hpp>
55
 
#include <boost/date_time/posix_time/posix_time.hpp>
 
57
#include <boost/date_time/posix_time/posix_time_types.hpp>
56
58
#include <boost/scoped_ptr.hpp>
 
59
#include <boost/config.hpp>
57
60
 
58
61
#ifdef _MSC_VER
59
62
#pragma warning(pop)
63
66
{
64
67
        namespace fs = boost::filesystem;
65
68
        namespace pt = boost::posix_time;
 
69
        class torrent_info;
66
70
 
67
71
        struct TORRENT_EXPORT create_torrent
68
72
        {
69
 
                create_torrent(file_storage& fs, int piece_size);
70
 
                create_torrent(file_storage& fs);
 
73
                enum {
 
74
                        optimize = 1
 
75
                        , merkle = 2
 
76
                        , modification_time = 4
 
77
                        , symlinks = 8
 
78
                };
 
79
 
 
80
                create_torrent(file_storage& fs, int piece_size = 0
 
81
                        , int pad_file_limit = -1, int flags = optimize);
 
82
                create_torrent(torrent_info const& ti);
71
83
                entry generate() const;
72
84
 
73
85
                file_storage const& files() const { return m_files; }
88
100
        private:
89
101
 
90
102
                file_storage& m_files;
 
103
                // if m_info_dict is initialized, it is 
 
104
                // used instead of m_files to generate
 
105
                // the info dictionary
 
106
                entry m_info_dict;
91
107
 
92
108
                // the urls to the trackers
93
109
                typedef std::pair<std::string, int> announce_entry;
124
140
                // to know if it should be written as a multifile torrent
125
141
                // or not. e.g. test/test  there's one file and one directory
126
142
                // and they have the same name.
127
 
                bool m_multifile;
 
143
                bool m_multifile:1;
128
144
                
129
145
                // this is true if the torrent is private. i.e., is should not
130
146
                // be announced on the dht
131
 
                bool m_private;
 
147
                bool m_private:1;
 
148
 
 
149
                // if set to one, a merkle torrent will be generated
 
150
                bool m_merkle_torrent:1;
 
151
 
 
152
                // if set, include the 'mtime' modification time in the
 
153
                // torrent file
 
154
                bool m_include_mtime:1;
 
155
 
 
156
                // if set, symbolic links are declared as such in
 
157
                // the torrent file. The full data of the pointed-to
 
158
                // file is still included
 
159
                bool m_include_symlinks:1;
132
160
        };
133
161
 
134
162
        namespace detail
135
163
        {
136
164
                inline bool default_pred(boost::filesystem::path const&) { return true; }
 
165
#if TORRENT_USE_WPATH
 
166
                inline bool wdefault_pred(boost::filesystem::wpath const&) { return true; }
 
167
#endif
 
168
 
 
169
                inline bool ignore_subdir(std::string const& leaf)
 
170
                { return leaf == ".." || leaf == "."; }
 
171
 
 
172
                inline bool ignore_subdir(std::wstring const& leaf)
 
173
                { return leaf == L".." || leaf == L"."; }
137
174
 
138
175
                inline void nop(int i) {}
139
176
 
140
 
                template <class Pred>
141
 
                void add_files_impl(file_storage& fs, boost::filesystem::path const& p
142
 
                        , boost::filesystem::path const& l, Pred pred)
 
177
                int TORRENT_EXPORT get_file_attributes(boost::filesystem::path const& p);
 
178
#if TORRENT_USE_WPATH
 
179
                int TORRENT_EXPORT get_file_attributes(boost::filesystem::wpath const& p);
 
180
#endif
 
181
 
 
182
                std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::path const& p);
 
183
#if TORRENT_USE_WPATH
 
184
                std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::wpath const& p);
 
185
#endif
 
186
 
 
187
                fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem::path const& p);
 
188
#if TORRENT_USE_WPATH
 
189
                fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem::wpath const& p);
 
190
#endif
 
191
 
 
192
                template <class Pred, class Str, class PathTraits>
 
193
                void add_files_impl(file_storage& fs, boost::filesystem::basic_path<Str, PathTraits> const& p
 
194
                        , boost::filesystem::basic_path<Str, PathTraits> const& l, Pred pred)
143
195
                {
144
 
                        using boost::filesystem::path;
145
 
                        using boost::filesystem::directory_iterator;
146
 
                        if (!pred(l)) return;
147
 
                        path f(p / l);
 
196
                        using boost::filesystem::basic_path;
 
197
                        using boost::filesystem::basic_directory_iterator;
 
198
                        basic_path<Str, PathTraits> f(p / l);
 
199
                        if (!pred(f)) return;
148
200
                        if (is_directory(f))
149
201
                        {
150
 
                                for (directory_iterator i(f), end; i != end; ++i)
 
202
                                for (basic_directory_iterator<basic_path<Str, PathTraits> > i(f), end; i != end; ++i)
151
203
                                {
152
204
#if BOOST_VERSION < 103600
153
 
                                        std::string leaf = i->path().leaf();
 
205
                                        Str const& leaf = i->path().leaf();
154
206
#else
155
 
                                        std::string leaf = i->path().filename();
 
207
                                        Str const& leaf = i->path().filename();
156
208
#endif
157
 
                                        if (leaf == ".." || leaf == ".") continue;
 
209
                                        if (ignore_subdir(leaf)) continue;
158
210
                                        add_files_impl(fs, p, l / leaf, pred);
159
211
                                }
160
212
                        }
161
213
                        else
162
214
                        {
163
 
                                fs.add_file(l, file_size(f));
 
215
                                int file_flags = get_file_attributes(f);
 
216
                                std::time_t mtime = get_file_mtime(f);
 
217
                                //Masking all bits to check if the file is a symlink
 
218
                                if(file_flags & file_storage::attribute_symlink) 
 
219
                                {
 
220
                                        fs::path sym_path = get_symlink_path(f);
 
221
                                        fs.add_file(l, 0 ,file_flags, mtime, sym_path);
 
222
                                }
 
223
                                else
 
224
                                {
 
225
                                        fs.add_file(l, file_size(f), file_flags, mtime);
 
226
                                }
164
227
                        }
165
228
                }
166
229
        }
167
230
 
 
231
        // path versions
 
232
 
168
233
        template <class Pred>
169
234
        void add_files(file_storage& fs, boost::filesystem::path const& file, Pred p)
170
235
        {
 
236
                using boost::filesystem::path;
171
237
                boost::filesystem::path f = file;
172
238
#if BOOST_VERSION < 103600
173
239
                if (f.leaf() == ".") f = f.branch_path();
174
 
                detail::add_files_impl(fs, complete(f).branch_path(), f.leaf(), p);
 
240
                detail::add_files_impl(fs, complete(f).branch_path(), path(f.leaf()), p);
175
241
#else
176
242
                if (f.filename() == ".") f = f.parent_path();
177
 
                detail::add_files_impl(fs, complete(f).parent_path(), f.filename(), p);
 
243
                detail::add_files_impl(fs, complete(f).parent_path(), path(f.filename()), p);
178
244
#endif
179
245
        }
180
246
 
181
247
        inline void add_files(file_storage& fs, boost::filesystem::path const& file)
182
248
        {
 
249
                using boost::filesystem::path;
183
250
                boost::filesystem::path f = file;
184
251
#if BOOST_VERSION < 103600
185
252
                if (f.leaf() == ".") f = f.branch_path();
186
 
                detail::add_files_impl(fs, complete(f).branch_path(), f.leaf(), detail::default_pred);
 
253
                detail::add_files_impl(fs, complete(f).branch_path(), path(f.leaf()), detail::default_pred);
187
254
#else
188
255
                if (f.filename() == ".") f = f.parent_path();
189
 
                detail::add_files_impl(fs, complete(f).parent_path(), f.filename(), detail::default_pred);
 
256
                detail::add_files_impl(fs, complete(f).parent_path(), path(f.filename()), detail::default_pred);
190
257
#endif
191
258
        }
192
259
        
 
260
        struct piece_holder
 
261
        {
 
262
                piece_holder(int bytes): m_piece(page_aligned_allocator::malloc(bytes)) {}
 
263
                ~piece_holder() { page_aligned_allocator::free(m_piece); }
 
264
                char* bytes() { return m_piece; }
 
265
        private:
 
266
                char* m_piece;
 
267
        };
 
268
 
193
269
        template <class Fun>
194
270
        void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f
195
271
                , error_code& ec)
200
276
 
201
277
                // calculate the hash for all pieces
202
278
                int num = t.num_pieces();
 
279
                piece_holder buf(t.piece_length());
 
280
                for (int i = 0; i < num; ++i)
 
281
                {
 
282
                        // read hits the disk and will block. Progress should
 
283
                        // be updated in between reads
 
284
                        st->read(buf.bytes(), i, 0, t.piece_size(i));
 
285
                        if (st->error())
 
286
                        {
 
287
                                ec = st->error();
 
288
                                return;
 
289
                        }
 
290
                        hasher h(buf.bytes(), t.piece_size(i));
 
291
                        t.set_hash(i, h.final());
 
292
                        f(i);
 
293
                }
 
294
        }
 
295
 
 
296
#ifndef BOOST_NO_EXCEPTIONS
 
297
        template <class Fun>
 
298
        void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f)
 
299
        {
 
300
                error_code ec;
 
301
                set_piece_hashes(t, p, f, ec);
 
302
                if (ec) throw libtorrent_exception(ec);
 
303
        }
 
304
 
 
305
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p)
 
306
        {
 
307
                error_code ec;
 
308
                set_piece_hashes(t, p, detail::nop, ec);
 
309
                if (ec) throw libtorrent_exception(ec);
 
310
        }
 
311
#endif
 
312
 
 
313
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, error_code& ec)
 
314
        {
 
315
                set_piece_hashes(t, p, detail::nop, ec);
 
316
        }
 
317
 
 
318
#if TORRENT_USE_WPATH
 
319
        // wpath versions
 
320
 
 
321
        template <class Pred>
 
322
        void add_files(file_storage& fs, boost::filesystem::wpath const& file, Pred p)
 
323
        {
 
324
                using boost::filesystem::wpath;
 
325
                wpath f = file;
 
326
#if BOOST_VERSION < 103600
 
327
                if (f.leaf() == L".") f = f.branch_path();
 
328
                detail::add_files_impl(fs, complete(f).branch_path(), wpath(f.leaf()), p);
 
329
#else
 
330
                if (f.filename() == L".") f = f.parent_path();
 
331
                detail::add_files_impl(fs, complete(f).parent_path(), wpath(f.filename()), p);
 
332
#endif
 
333
        }
 
334
 
 
335
        inline void add_files(file_storage& fs, boost::filesystem::wpath const& file)
 
336
        {
 
337
                using boost::filesystem::wpath;
 
338
                wpath f = file;
 
339
#if BOOST_VERSION < 103600
 
340
                if (f.leaf() == L".") f = f.branch_path();
 
341
                detail::add_files_impl(fs, complete(f).branch_path(), wpath(f.leaf()), detail::wdefault_pred);
 
342
#else
 
343
                if (f.filename() == L".") f = f.parent_path();
 
344
                detail::add_files_impl(fs, complete(f).parent_path(), wpath(f.filename()), detail::wdefault_pred);
 
345
#endif
 
346
        }
 
347
        
 
348
        template <class Fun>
 
349
        void set_piece_hashes(create_torrent& t, boost::filesystem::wpath const& p, Fun f
 
350
                , error_code& ec)
 
351
        {
 
352
                file_pool fp;
 
353
                std::string utf8;
 
354
                wchar_utf8(p.string(), utf8);
 
355
                boost::scoped_ptr<storage_interface> st(
 
356
                        default_storage_constructor(const_cast<file_storage&>(t.files()), 0, utf8, fp));
 
357
 
 
358
                // calculate the hash for all pieces
 
359
                int num = t.num_pieces();
203
360
                std::vector<char> buf(t.piece_length());
204
361
                for (int i = 0; i < num; ++i)
205
362
                {
219
376
 
220
377
#ifndef BOOST_NO_EXCEPTIONS
221
378
        template <class Fun>
222
 
        void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f)
 
379
        void set_piece_hashes(create_torrent& t, boost::filesystem::wpath const& p, Fun f)
223
380
        {
224
381
                error_code ec;
225
382
                set_piece_hashes(t, p, f, ec);
226
383
                if (ec) throw libtorrent_exception(ec);
227
384
        }
228
385
 
229
 
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p)
 
386
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::wpath const& p)
230
387
        {
231
388
                error_code ec;
232
389
                set_piece_hashes(t, p, detail::nop, ec);
234
391
        }
235
392
#endif
236
393
 
237
 
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, error_code& ec)
 
394
        inline void set_piece_hashes(create_torrent& t, boost::filesystem::wpath const& p, error_code& ec)
238
395
        {
239
396
                set_piece_hashes(t, p, detail::nop, ec);
240
397
        }
 
398
 
 
399
#endif // TORRENT_USE_WPATH
 
400
 
241
401
}
242
402
 
243
403
#endif
244