Show
Ignore:
Timestamp:
12/23/07 03:05:00 (4 years ago)
Author:
rakshasa
Message:

* Added "d.set_directory_base" command that handles single and multi
file torrent equally.

* Fixed man page entry on 'umask', it should be 0022 not 0664.

* Cleaned up File and FileList? classes.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/libtorrent/src/torrent/data/file_list.cc

    r1019 r1021  
    275275    newFile->set_match_depth_prev(0); 
    276276  else 
    277     set_match_depth(*(first - 1), newFile); 
     277    File::set_match_depth(*(first - 1), newFile); 
    278278 
    279279  if (first + 1 == end()) 
    280280    newFile->set_match_depth_next(0); 
    281281  else 
    282     set_match_depth(newFile, *(first + 1)); 
     282    File::set_match_depth(newFile, *(first + 1)); 
    283283 
    284284  return first; 
     
    294294 
    295295  if (first != begin()) 
    296     set_match_depth(*(first - 1), *first); 
     296    File::set_match_depth(*(first - 1), *first); 
    297297 
    298298  while (first != last && ++first != end()) 
    299     set_match_depth(*(first - 1), *first); 
     299    File::set_match_depth(*(first - 1), *first); 
    300300 
    301301  verify_file_list(this); 
    302302} 
    303303 
    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); 
     304bool 
     305FileList::make_root_path() { 
     306  if (!is_open()) 
     307    return false; 
     308 
     309  return ::mkdir(m_rootDir.c_str(), 0777) == 0 || errno == EEXIST; 
     310} 
     311 
     312bool 
     313FileList::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; 
    310348} 
    311349 
     
    354392 
    355393  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()) 
    358395      throw storage_error("Could not create directory '" + m_rootDir + "': " + std::strerror(errno)); 
    359396   
     
    389426      // it here if necessary. 
    390427 
     428      entry->set_flags_protected(File::flag_active); 
     429 
    391430      if (!open_file(&*entry, lastPath, flags)) { 
    392431        // This needs to check if the error was due to open_no_create 
     
    404443 
    405444  } 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); 
    407447      manager->file_manager()->close(*itr); 
     448    } 
    408449 
    409450    // Set to false here in case we tried to open the FileList for the 
     
    422463 
    423464  for (iterator itr = begin(), last = end(); itr != last; ++itr) { 
     465    (*itr)->unset_flags_protected(File::flag_active); 
    424466    manager->file_manager()->close(*itr); 
    425      
    426     // Keep the progress so the user can see it even though he closes 
    427     // the torrent. 
    428 //     (*itr)->set_completed(0); 
    429467  } 
    430468 
    431469  m_isOpen = false; 
    432470  m_indirectLinks.clear(); 
    433 } 
    434  
    435 bool 
    436 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; 
    447471} 
    448472 
     
    476500bool 
    477501FileList::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  
    489502  rak::error_number::clear_global(); 
    490503 
    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 
    492516    make_directory(path->begin(), path->end(), firstMismatch); 
     517  } 
    493518 
    494519  // Some torrents indicate an empty directory by having a path with 
    495520  // an empty last element. This entry must be zero length. 
    496   if (path->back().empty()) 
     521  if (node->path()->back().empty()) 
    497522    return node->size_bytes() == 0; 
    498523 
     
    596621  std::for_each(firstItr, 
    597622                lastItr == end() ? end() : (lastItr + 1), 
    598                 std::mem_fun(&File::inc_completed)); 
     623                std::mem_fun(&File::inc_completed_protected)); 
    599624 
    600625  return lastItr; 
     
    608633  if (m_bitfield.is_all_set()) { 
    609634    for (iterator itr = begin(), last = end(); itr != last; ++itr) 
    610       (*itr)->set_completed((*itr)->size_chunks()); 
     635      (*itr)->set_completed_protected((*itr)->size_chunks()); 
    611636 
    612637  } else { 
     
    614639    // this on close, etc. 
    615640    for (iterator itr = begin(), last = end(); itr != last; ++itr) 
    616       (*itr)->set_completed(0); 
     641      (*itr)->set_completed_protected(0); 
    617642 
    618643    if (m_bitfield.is_all_unset()) 
     
    627652} 
    628653 
    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}