Changeset 1021
- Timestamp:
- 12/23/07 03:05:00 (4 years ago)
- Location:
- trunk
- Files:
-
- 8 modified
-
libtorrent/src/torrent/data/file.cc (modified) (1 diff)
-
libtorrent/src/torrent/data/file.h (modified) (6 diffs)
-
libtorrent/src/torrent/data/file_list.cc (modified) (11 diffs)
-
libtorrent/src/torrent/data/file_list.h (modified) (3 diffs)
-
libtorrent/src/torrent/resume.cc (modified) (1 diff)
-
rtorrent/doc/rtorrent.1.xml (modified) (1 diff)
-
rtorrent/src/command_download.cc (modified) (2 diffs)
-
rtorrent/src/core/download.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtorrent/src/torrent/data/file.cc
r1019 r1021 143 143 } 144 144 145 void 146 File::set_match_depth(File* left, File* right) { 147 uint32_t level = 0; 148 149 Path::const_iterator itrLeft = left->path()->begin(); 150 Path::const_iterator itrRight = right->path()->begin(); 151 152 while (itrLeft != left->path()->end() && itrRight != right->path()->end() && *itrLeft == *itrRight) { 153 itrLeft++; 154 itrRight++; 155 level++; 156 } 157 158 left->m_matchDepthNext = level; 159 right->m_matchDepthPrev = level; 160 } 161 145 162 bool 146 163 File::resize_file() { -
trunk/libtorrent/src/torrent/data/file.h
r1019 r1021 49 49 typedef std::pair<uint32_t, uint32_t> range_type; 50 50 51 static const int flag_create_queued = (1 << 0); 52 static const int flag_resize_queued = (1 << 1); 53 static const int flag_previously_created = (1 << 2); 51 static const int flag_active = (1 << 0); 52 static const int flag_create_queued = (1 << 1); 53 static const int flag_resize_queued = (1 << 2); 54 static const int flag_previously_created = (1 << 3); 54 55 55 56 File(); … … 66 67 bool is_previously_created() const { return m_flags & flag_previously_created; } 67 68 69 bool has_flags(int flags) { return m_flags & flags; } 70 68 71 void set_flags(int flags); 69 72 void unset_flags(int flags); … … 77 80 78 81 uint32_t completed_chunks() const { return m_completed; } 82 void set_completed_chunks(uint32_t v); 79 83 80 84 const range_type& range() const { return m_range; } … … 109 113 110 114 protected: 115 void set_flags_protected(int flags) { m_flags |= flags; } 116 void unset_flags_protected(int flags) { m_flags &= ~flags; } 117 111 118 void set_frozen_path(const std::string& path) { m_frozenPath = path; } 112 119 … … 115 122 void set_range(uint32_t chunkSize); 116 123 117 void set_completed(uint32_t v) { m_completed = v; } 118 void inc_completed() { m_completed++; } 124 void set_completed_protected(uint32_t v) { m_completed = v; } 125 void inc_completed_protected() { m_completed++; } 126 127 static void set_match_depth(File* left, File* right); 119 128 120 129 void set_match_depth_prev(uint32_t l) { m_matchDepthPrev = l; } … … 154 163 inline void 155 164 File::set_flags(int flags) { 156 m_flags |= flags & (flag_create_queued | flag_resize_queued);165 set_flags_protected(flags & (flag_create_queued | flag_resize_queued)); 157 166 } 158 167 159 168 inline void 160 169 File::unset_flags(int flags) { 161 m_flags |= flags & (flag_create_queued | flag_resize_queued); 170 unset_flags_protected(flags & (flag_create_queued | flag_resize_queued)); 171 } 172 173 inline void 174 File::set_completed_chunks(uint32_t v) { 175 if (!has_flags(flag_active) && v <= size_chunks()) 176 m_completed = v; 162 177 } 163 178 -
trunk/libtorrent/src/torrent/data/file_list.cc
r1019 r1021 275 275 newFile->set_match_depth_prev(0); 276 276 else 277 set_match_depth(*(first - 1), newFile);277 File::set_match_depth(*(first - 1), newFile); 278 278 279 279 if (first + 1 == end()) 280 280 newFile->set_match_depth_next(0); 281 281 else 282 set_match_depth(newFile, *(first + 1));282 File::set_match_depth(newFile, *(first + 1)); 283 283 284 284 return first; … … 294 294 295 295 if (first != begin()) 296 set_match_depth(*(first - 1), *first);296 File::set_match_depth(*(first - 1), *first); 297 297 298 298 while (first != last && ++first != end()) 299 set_match_depth(*(first - 1), *first);299 File::set_match_depth(*(first - 1), *first); 300 300 301 301 verify_file_list(this); 302 302 } 303 303 304 void 305 FileList::set_file_completed_chunks(iterator itr, uint32_t v) { 306 if (is_open()) 307 return; 308 309 (*itr)->set_completed(v); 304 bool 305 FileList::make_root_path() { 306 if (!is_open()) 307 return false; 308 309 return ::mkdir(m_rootDir.c_str(), 0777) == 0 || errno == EEXIST; 310 } 311 312 bool 313 FileList::make_all_paths() { 314 if (!is_open()) 315 return false; 316 317 Path dummyPath; 318 const Path* lastPath = &dummyPath; 319 320 for (iterator itr = begin(), last = end(); itr != last; ++itr) { 321 File* entry = *itr; 322 323 // No need to create directories if the entry has already been 324 // opened. 325 if (entry->is_open()) 326 continue; 327 328 if (entry->path()->empty()) 329 throw storage_error("Found an empty filename."); 330 331 Path::const_iterator lastPathItr = lastPath->begin(); 332 Path::const_iterator firstMismatch = entry->path()->begin(); 333 334 // Couldn't find a suitable stl algo, need to write my own. 335 while (firstMismatch != entry->path()->end() && lastPathItr != lastPath->end() && *firstMismatch == *lastPathItr) { 336 lastPathItr++; 337 firstMismatch++; 338 } 339 340 rak::error_number::clear_global(); 341 342 make_directory(entry->path()->begin(), entry->path()->end(), firstMismatch); 343 344 lastPath = entry->path(); 345 } 346 347 return true; 310 348 } 311 349 … … 354 392 355 393 try { 356 if (!(flags & open_no_create) && 357 ::mkdir(m_rootDir.c_str(), 0777) != 0 && errno != EEXIST) 394 if (!(flags & open_no_create) && !make_root_path()) 358 395 throw storage_error("Could not create directory '" + m_rootDir + "': " + std::strerror(errno)); 359 396 … … 389 426 // it here if necessary. 390 427 428 entry->set_flags_protected(File::flag_active); 429 391 430 if (!open_file(&*entry, lastPath, flags)) { 392 431 // This needs to check if the error was due to open_no_create … … 404 443 405 444 } catch (local_error& e) { 406 for (iterator itr = begin(), last = end(); itr != last; ++itr) 445 for (iterator itr = begin(), last = end(); itr != last; ++itr) { 446 (*itr)->unset_flags_protected(File::flag_active); 407 447 manager->file_manager()->close(*itr); 448 } 408 449 409 450 // Set to false here in case we tried to open the FileList for the … … 422 463 423 464 for (iterator itr = begin(), last = end(); itr != last; ++itr) { 465 (*itr)->unset_flags_protected(File::flag_active); 424 466 manager->file_manager()->close(*itr); 425 426 // Keep the progress so the user can see it even though he closes427 // the torrent.428 // (*itr)->set_completed(0);429 467 } 430 468 431 469 m_isOpen = false; 432 470 m_indirectLinks.clear(); 433 }434 435 bool436 FileList::resize_all() {437 bool success = true;438 439 // Remove this function.440 441 // for (iterator itr = begin(); itr != end(); itr++)442 // if (!(*itr)->frozen_path().empty() &&443 // !(*itr)->resize_file())444 // success = false;445 446 return success;447 471 } 448 472 … … 476 500 bool 477 501 FileList::open_file(File* node, const Path& lastPath, int flags) { 478 const Path* path = node->path();479 480 Path::const_iterator lastItr = lastPath.begin();481 Path::const_iterator firstMismatch = path->begin();482 483 // Couldn't find a suitable stl algo, need to write my own.484 while (firstMismatch != path->end() && lastItr != lastPath.end() && *firstMismatch == *lastItr) {485 lastItr++;486 firstMismatch++;487 }488 489 502 rak::error_number::clear_global(); 490 503 491 if (!(flags & open_no_create)) 504 if (!(flags & open_no_create)) { 505 const Path* path = node->path(); 506 507 Path::const_iterator lastItr = lastPath.begin(); 508 Path::const_iterator firstMismatch = path->begin(); 509 510 // Couldn't find a suitable stl algo, need to write my own. 511 while (firstMismatch != path->end() && lastItr != lastPath.end() && *firstMismatch == *lastItr) { 512 lastItr++; 513 firstMismatch++; 514 } 515 492 516 make_directory(path->begin(), path->end(), firstMismatch); 517 } 493 518 494 519 // Some torrents indicate an empty directory by having a path with 495 520 // an empty last element. This entry must be zero length. 496 if ( path->back().empty())521 if (node->path()->back().empty()) 497 522 return node->size_bytes() == 0; 498 523 … … 596 621 std::for_each(firstItr, 597 622 lastItr == end() ? end() : (lastItr + 1), 598 std::mem_fun(&File::inc_completed ));623 std::mem_fun(&File::inc_completed_protected)); 599 624 600 625 return lastItr; … … 608 633 if (m_bitfield.is_all_set()) { 609 634 for (iterator itr = begin(), last = end(); itr != last; ++itr) 610 (*itr)->set_completed ((*itr)->size_chunks());635 (*itr)->set_completed_protected((*itr)->size_chunks()); 611 636 612 637 } else { … … 614 639 // this on close, etc. 615 640 for (iterator itr = begin(), last = end(); itr != last; ++itr) 616 (*itr)->set_completed (0);641 (*itr)->set_completed_protected(0); 617 642 618 643 if (m_bitfield.is_all_unset()) … … 627 652 } 628 653 629 void 630 FileList::set_match_depth(File* left, File* right) { 631 uint32_t level = 0; 632 633 Path::const_iterator itrLeft = left->path()->begin(); 634 Path::const_iterator itrRight = right->path()->begin(); 635 636 while (itrLeft != left->path()->end() && itrRight != right->path()->end() && *itrLeft == *itrRight) { 637 itrLeft++; 638 itrRight++; 639 level++; 640 } 641 642 left->set_match_depth_next(level); 643 right->set_match_depth_prev(level); 644 } 645 646 } 654 } -
trunk/libtorrent/src/torrent/data/file_list.h
r1017 r1021 142 142 void update_paths(iterator first, iterator last); 143 143 144 void set_file_completed_chunks(iterator itr, uint32_t v); 144 bool make_root_path(); 145 bool make_all_paths(); 145 146 146 147 protected: … … 152 153 void open(int flags) LIBTORRENT_NO_EXPORT; 153 154 void close() LIBTORRENT_NO_EXPORT; 154 155 bool resize_all() LIBTORRENT_NO_EXPORT;156 155 157 156 Bitfield* mutable_bitfield() { return &m_bitfield; } … … 170 169 void make_directory(Path::const_iterator pathBegin, Path::const_iterator pathEnd, Path::const_iterator startItr) LIBTORRENT_NO_EXPORT; 171 170 MemoryChunk create_chunk_part(FileList::iterator itr, uint64_t offset, uint32_t length, int prot) LIBTORRENT_NO_EXPORT; 172 173 void set_match_depth(File* left, File* right);174 171 175 172 bool m_isOpen; -
trunk/libtorrent/src/torrent/resume.cc
r1020 r1021 239 239 240 240 if (filesItr->has_key_value("completed")) 241 fileList->set_file_completed_chunks(listItr, std::max<int64_t>(filesItr->get_key_value("completed"), (*listItr)->size_chunks()));241 (*listItr)->set_completed_chunks(filesItr->get_key_value("completed")); 242 242 } 243 243 } -
trunk/rtorrent/doc/rtorrent.1.xml
r1013 r1021 1013 1013 1014 1014 <varlistentry> 1015 <term>umask = <replaceable>0 644</replaceable></term>1015 <term>umask = <replaceable>0022</replaceable></term> 1016 1016 <listitem><para> 1017 1017 -
trunk/rtorrent/src/command_download.cc
r1017 r1021 176 176 } 177 177 178 void 179 apply_d_directory(core::Download* download, const std::string& name) { 180 if (!download->file_list()->is_multi_file()) 181 download->set_root_directory(name); 182 else if (name.empty() || *name.rbegin() == '/') 183 download->set_root_directory(name + download->download()->name()); 184 else 185 download->set_root_directory(name + "/" + download->download()->name()); 186 } 187 178 188 const char* 179 189 retrieve_d_connection_type(core::Download* download) { … … 508 518 ADD_CD_VALUE_UNI("tracker_size", std::mem_fun(&core::Download::tracker_list_size)); 509 519 510 ADD_CD_STRING_BI("directory", std::mem_fun(&core::Download::set_root_directory), rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::root_dir))); 520 ADD_CD_STRING_BI("directory", std::ptr_fun(&apply_d_directory), rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::root_dir))); 521 ADD_CD_STRING_BI("directory_base", std::mem_fun(&core::Download::set_root_directory), rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::root_dir))); 522 511 523 ADD_CD_VALUE_BI("priority", std::mem_fun(&core::Download::set_priority), std::mem_fun(&core::Download::priority)); 512 524 ADD_CD_STRING_UNI("priority_str", std::ptr_fun(&retrieve_d_priority_str)); -
trunk/rtorrent/src/core/download.cc
r1012 r1021 156 156 } 157 157 158 // Clean up.159 158 void 160 159 Download::set_root_directory(const std::string& path) { … … 162 161 163 162 control->core()->download_list()->close_directly(this); 164 165 if (path.empty()) { 166 fileList->set_root_dir("./" + (fileList->is_multi_file() ? m_download.name() : std::string())); 167 168 } else { 169 std::string fullPath = rak::path_expand(path); 170 171 fileList->set_root_dir(fullPath + 172 (*fullPath.rbegin() != '/' ? "/" : "") + 173 (fileList->is_multi_file() ? m_download.name() : std::string())); 174 } 163 fileList->set_root_dir(rak::path_expand(path)); 175 164 176 165 bencode()->get_key("rtorrent").insert_key("directory", path);
