⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_list.cc

📁 linux federo 6下的bt软件的类库文件
💻 CC
📖 第 1 页 / 共 2 页
字号:
  if (chunkSize == 0)    throw internal_error("FileList::initialize() chunk_size() == 0.");  m_chunkSize = chunkSize;  m_torrentSize = torrentSize;  m_rootDir = ".";  m_bitfield.set_size_bits((size_bytes() + chunk_size() - 1) / chunk_size());  File* newFile = new File();  newFile->set_offset(0);  newFile->set_size_bytes(torrentSize);  newFile->set_range(m_chunkSize);  base_type::push_back(newFile);}struct file_list_cstr_less {  bool operator () (const char* c1, const char* c2) const {    return std::strcmp(c1, c2) < 0;  }};voidFileList::open() {  typedef std::set<const char*, file_list_cstr_less> path_set;  if (m_rootDir.empty())    throw internal_error("FileList::open() m_rootDir.empty().");  m_indirectLinks.push_back(m_rootDir);  Path lastPath;  path_set pathSet;  iterator itr = begin();  try {    if (::mkdir(m_rootDir.c_str(), 0777) != 0 && errno != EEXIST)      throw storage_error("Could not create directory '" + m_rootDir + "': " + strerror(errno));      while (itr != end()) {      File* entry = *itr++;      if (entry->is_open())        throw internal_error("FileList::open(...) found an already opened file.");      //       manager->file_manager()->insert(entry);      // Update the path during open so that any changes to root dir      // and file paths are properly handled.      if (entry->path()->back().empty())        entry->set_frozen_path(std::string());      else        entry->set_frozen_path(m_rootDir + entry->path()->as_string());      if (!pathSet.insert(entry->frozen_path().c_str()).second)        throw storage_error("Found a duplicate filename.");      if (entry->size_bytes() > m_maxFileSize)        throw storage_error("Found a file exceeding max file size.");      if (entry->path()->empty())        throw storage_error("Found an empty filename.");      if (!open_file(&*entry, lastPath))        throw storage_error("Could not open file \"" + m_rootDir + entry->path()->as_string() + "\": " + rak::error_number::current().c_str());            lastPath = *entry->path();    }  } catch (storage_error& e) {    for (iterator cleanupItr = begin(); cleanupItr != itr; ++cleanupItr)      manager->file_manager()->close(*cleanupItr);    throw e;  }  m_isOpen = true;}voidFileList::close() {  if (!is_open())    return;  for (iterator itr = begin(), last = end(); itr != last; ++itr) {    manager->file_manager()->close(*itr);        // Keep the progress so the user can see it even though he closes    // the torrent.//     (*itr)->set_completed(0);  }  m_isOpen = false;  m_indirectLinks.clear();}boolFileList::resize_all() {  bool success = true;  for (iterator itr = begin(); itr != end(); itr++)    if (!(*itr)->frozen_path().empty() &&        !(*itr)->resize_file())      success = false;  return success;}voidFileList::make_directory(Path::const_iterator pathBegin, Path::const_iterator pathEnd, Path::const_iterator startItr) {  std::string path = m_rootDir;  while (pathBegin != pathEnd) {    path += "/" + *pathBegin;    if (pathBegin++ != startItr)      continue;    startItr++;    rak::file_stat fileStat;    if (fileStat.update_link(path) &&        fileStat.is_link() &&        std::find(m_indirectLinks.begin(), m_indirectLinks.end(), path) == m_indirectLinks.end())      m_indirectLinks.push_back(path);    if (pathBegin == pathEnd)      break;    if (::mkdir(path.c_str(), 0777) != 0 && errno != EEXIST)      throw storage_error("Could not create directory '" + path + "': " + strerror(errno));  }}boolFileList::open_file(File* node, const Path& lastPath) {  const Path* path = node->path();  Path::const_iterator lastItr = lastPath.begin();  Path::const_iterator firstMismatch = path->begin();  // Couldn't find a suitable stl algo, need to write my own.  while (firstMismatch != path->end() && lastItr != lastPath.end() && *firstMismatch == *lastItr) {    lastItr++;    firstMismatch++;  }  rak::error_number::clear_global();  make_directory(path->begin(), path->end(), firstMismatch);  // Some torrents indicate an empty directory by having a path with  // an empty last element. This entry must be zero length.  if (path->back().empty())    return node->size_bytes() == 0;  rak::file_stat fileStat;  if (fileStat.update(node->frozen_path()) &&      !fileStat.is_regular() && !fileStat.is_link()) {    // Might also bork on other kinds of file types, but there's no    // suitable errno for all cases.    rak::error_number::set_global(rak::error_number::e_isdir);    return false;  }  return    node->prepare(MemoryChunk::prot_read | MemoryChunk::prot_write, SocketFile::o_create) ||    node->prepare(MemoryChunk::prot_read, SocketFile::o_create);}MemoryChunkFileList::create_chunk_part(FileList::iterator itr, uint64_t offset, uint32_t length, int prot) {  offset -= (*itr)->offset();  length = std::min<uint64_t>(length, (*itr)->size_bytes() - offset);  if (offset < 0)    throw internal_error("FileList::chunk_part(...) caught a negative offset");  // Check that offset != length of file.  if (!(*itr)->prepare(prot))    return MemoryChunk();  return SocketFile((*itr)->file_descriptor()).create_chunk(offset, length, prot, MemoryChunk::map_shared);}Chunk*FileList::create_chunk(uint64_t offset, uint32_t length, int prot) {  if (offset + length > m_torrentSize)    throw internal_error("Tried to access chunk out of range in FileList");  std::auto_ptr<Chunk> chunk(new Chunk);  for (iterator itr = std::find_if(begin(), end(), std::bind2nd(std::mem_fun(&File::is_valid_position), offset)); length != 0; ++itr) {    if (itr == end())      throw internal_error("FileList could not find a valid file for chunk");    if ((*itr)->size_bytes() == 0)      continue;    MemoryChunk mc = create_chunk_part(itr, offset, length, prot);    if (!mc.is_valid())      return NULL;    if (mc.size() == 0)      throw internal_error("FileList::create_chunk(...) mc.size() == 0.");    if (mc.size() > length)      throw internal_error("FileList::create_chunk(...) mc.size() > length.");    chunk->push_back(ChunkPart::MAPPED_MMAP, mc);    offset += mc.size();    length -= mc.size();  }  if (chunk->empty())    return NULL;  return chunk.release();}Chunk*FileList::create_chunk_index(uint32_t index, int prot) {  return create_chunk((uint64_t)index * chunk_size(), chunk_index_size(index), prot);}voidFileList::mark_completed(uint32_t index) {  if (m_bitfield.get(index))    throw internal_error("FileList::mark_completed(...) received a chunk that has already been finished.");  if (m_bitfield.size_set() >= m_bitfield.size_bits())    throw internal_error("FileList::mark_completed(...) m_bitfield.size_set() >= m_bitfield.size_bits().");  if (index >= size_chunks() || completed_chunks() >= size_chunks())    throw internal_error("FileList::mark_completed(...) received an invalid index.");  m_bitfield.set(index);  DEBUGP_DOWNLOAD("complete download %d\n",index);  inc_completed(begin(), index);}FileList::iteratorFileList::inc_completed(iterator firstItr, uint32_t index) {  firstItr         = std::find_if(firstItr, end(), rak::less(index, std::mem_fun(&File::range_second)));  iterator lastItr = std::find_if(firstItr, end(), rak::less(index + 1, std::mem_fun(&File::range_second)));  if (firstItr == end())    throw internal_error("FileList::inc_completed() first == m_entryList->end().");  std::for_each(firstItr,                lastItr == end() ? end() : (lastItr + 1),                std::mem_fun(&File::inc_completed));  return lastItr;}voidFileList::update_completed() {  if (!m_bitfield.is_tail_cleared())    throw internal_error("Content::update_done() called but m_bitfield's tail isn't cleared.");  if (m_bitfield.is_all_set()) {    for (iterator itr = begin(), last = end(); itr != last; ++itr)      (*itr)->set_completed((*itr)->size_chunks());  } else {    // Clear any old progress data from the entries as we don't clear    // this on close, etc.    for (iterator itr = begin(), last = end(); itr != last; ++itr)      (*itr)->set_completed(0);    if (m_bitfield.is_all_unset())      return;    iterator entryItr = begin();    for (Bitfield::size_type index = 0; index < m_bitfield.size_bits(); ++index)      if (m_bitfield.get(index))        entryItr = inc_completed(entryItr, index);  }}voidFileList::set_match_depth(File* left, File* right) {  uint32_t level = 0;  Path::const_iterator itrLeft = left->path()->begin();  Path::const_iterator itrRight = right->path()->begin();  while (itrLeft != left->path()->end() && itrRight != right->path()->end() && *itrLeft == *itrRight) {    itrLeft++;    itrRight++;    level++;  }  left->set_match_depth_next(level);  right->set_match_depth_prev(level);}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -