* Added file_path_iterator that allows the client to iterate through

FileList in a structured manner. Messed up the file list view to test
it.

* Added operator[] and at(...) to torrent::FileList and torrent::Path.

* Fixed Handshake::fill_read_buffer(...) that was throwing due to a
bad error check. Patch by Josef Drexler.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@830 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2006-12-22 10:54:39 +00:00
parent aab31e5ea5
commit c65b6aa9ff
4 changed files with 127 additions and 51 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ public:
unsigned int rows() const;
unsigned int chunks_per_row() const { return (width() - 6) / 11 * 10; }
unsigned int max_focus() const { return std::max<int>(rows() - height() + 1, 0); }
unsigned int max_focus() const { return std::max<int>(rows() - height() / 2 + 1, 0); }
private:
core::Download* m_download;
+117 -39
View File
@@ -71,6 +71,72 @@ hack_wstring(const std::string& src) {
}
*/
// A special purpose iterator class for iterating through FileList as
// a dired structure.
class file_path_iterator {
public:
typedef torrent::FileList::iterator iterator;
typedef torrent::File& reference;
typedef torrent::File* pointer;
file_path_iterator() {}
explicit file_path_iterator(iterator pos, uint32_t depth = 0) : m_position(pos), m_depth(depth) {}
bool is_file() const { return m_depth >= 0 && m_depth + 1 == (int32_t)(*m_position)->path()->size(); }
bool is_empty() const { return (*m_position)->path()->size() == 0; }
bool is_entering() const { return m_depth >= 0 && m_depth + 1 != (int32_t)(*m_position)->path()->size(); }
bool is_leaving() const { return m_depth < 0; }
uint32_t depth() const { return std::abs(m_depth); }
iterator base() const { return m_position; }
reference operator *() const { return **m_position; }
pointer operator ->() const { return *m_position; }
file_path_iterator operator ++();
friend bool operator == (const file_path_iterator& left, const file_path_iterator& right);
friend bool operator != (const file_path_iterator& left, const file_path_iterator& right);
private:
iterator m_position;
int32_t m_depth;
};
file_path_iterator
file_path_iterator::operator ++() {
int32_t sizePath = (*m_position)->path()->size();
if (sizePath == 0) {
m_position++;
return *this;
}
m_depth++;
if (m_depth == sizePath)
m_depth = -m_depth + 1;
if (-m_depth == (int32_t)(*m_position)->match_depth_next()) {
m_depth = -m_depth;
m_position++;
}
return *this;
}
bool
operator == (const file_path_iterator& left, const file_path_iterator& right) {
return left.m_position == right.m_position && left.m_depth == right.m_depth;
}
bool
operator != (const file_path_iterator& left, const file_path_iterator& right) {
return left.m_position != right.m_position || left.m_depth != right.m_depth;
}
void
WindowFileList::redraw() {
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(10)).round_seconds());
@@ -81,7 +147,7 @@ WindowFileList::redraw() {
if (fl->size_files() == 0 || m_canvas->height() < 2)
return;
int pos = 0;
unsigned int pos = 0;
m_canvas->print( 2, pos, "File");
m_canvas->print(55, pos, "Size");
@@ -95,57 +161,69 @@ WindowFileList::redraw() {
if (*m_focus >= fl->size_files())
throw std::logic_error("WindowFileList::redraw() called on an object with a bad focus value");
Range range = rak::advance_bidirectional<unsigned int>(0, *m_focus, fl->size_files(), m_canvas->height() - pos);
std::pair<unsigned int, unsigned int> range = rak::advance_bidirectional<unsigned int>(0, *m_focus, fl->size_files(), m_canvas->height() - pos);
while (range.first != range.second) {
torrent::File* e = *(fl->begin() + range.first);
file_path_iterator first(fl->begin() + range.first, (*(fl->begin() + range.first))->match_depth_prev());
file_path_iterator last(fl->end());
std::string path = e->path()->as_string();
while (pos != m_canvas->height() && first != last) {
if (first.is_empty()) {
m_canvas->print(0, pos, "EMPTY");
if (path.length() <= 50)
path = path + std::string(50 - path.length(), ' ');
else
path = path.substr(0, 50);
} else if (first.is_entering()) {
m_canvas->print(first.depth(), pos, "\\ %s",
first.depth() < first->path()->size() ? first->path()->at(first.depth()).c_str() : "UNKNOWN");
std::string priority;
} else if (first.is_leaving()) {
m_canvas->print(first.depth(), pos, "/");
switch (e->priority()) {
case torrent::PRIORITY_OFF:
priority = "off";
break;
} else if (first.is_file()) {
torrent::File* e = &*first;
case torrent::PRIORITY_NORMAL:
priority = " ";
break;
std::string priority;
case torrent::PRIORITY_HIGH:
priority = "hig";
break;
switch (e->priority()) {
case torrent::PRIORITY_OFF:
priority = "off";
break;
default:
priority = "BUG";
break;
};
case torrent::PRIORITY_NORMAL:
priority = " ";
break;
m_canvas->print(0, pos, "%c %s %6.1f %s %3d %9s",
range.first == *m_focus ? '*' : ' ',
path.c_str(),
(double)e->size_bytes() / (double)(1 << 20),
priority.c_str(),
done_percentage(e),
e->path()->encoding().c_str());
case torrent::PRIORITY_HIGH:
priority = "hig";
break;
m_canvas->print(84, pos, "%i - %i %c%c %u",
e->range().first,
e->range().first != e->range().second ? (e->range().second - 1) : e->range().second,
e->is_created() ? 'E' : 'M',
e->is_correct_size() ? 'C' : 'W',
e->path_match_depth());
default:
priority = "BUG";
break;
};
++range.first;
m_canvas->print(first.depth(), pos, "| %s",
first.depth() < first->path()->size() ? first->path()->at(first.depth()).c_str() : "UNKNOWN");
// %6.1f %s %3d %9s",
// (double)e->size_bytes() / (double)(1 << 20),
// priority.c_str(),
// done_percentage(e),
// e->path()->encoding().c_str());
m_canvas->print(104, pos, "%i - %i %c%c %u %u",
e->range().first,
e->range().first != e->range().second ? (e->range().second - 1) : e->range().second,
e->is_created() ? 'E' : 'M',
e->is_correct_size() ? 'C' : 'W',
e->match_depth_prev(),
e->match_depth_next());
} else {
m_canvas->print(0, pos, "BORK BORK");
}
++first;
++pos;
}
}
int
-2
View File
@@ -53,8 +53,6 @@ namespace display {
class WindowFileList : public Window {
public:
typedef std::pair<unsigned int, unsigned int> Range;
WindowFileList(core::Download* d, unsigned int* focus);
virtual void redraw();
+9 -9
View File
@@ -54,8 +54,8 @@ ElementChunksSeen::ElementChunksSeen(core::Download* d) :
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementChunksSeen::receive_next);
m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementChunksSeen::receive_prev);
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementChunksSeen::receive_next);
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementChunksSeen::receive_prev);
m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pagenext);
m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pageprev);
}
@@ -137,14 +137,14 @@ ElementChunksSeen::receive_pagenext() {
throw torrent::internal_error("ui::ElementChunksSeen::receive_pagenext(...) called on a disabled object");
unsigned int visible = m_window->height() - 1;
unsigned int scrollable = std::max<int>(m_window->rows() - visible, 0);
unsigned int maxFocus = m_window->max_focus();
if (scrollable == 0 || m_focus == scrollable)
if (maxFocus == 0 || m_focus == maxFocus)
m_focus = 0;
else if (m_focus + visible / 2 < scrollable)
else if (m_focus + visible / 2 < maxFocus)
m_focus += visible / 2;
else
m_focus = scrollable;
m_focus = maxFocus;
m_window->mark_dirty();
}
@@ -155,12 +155,12 @@ ElementChunksSeen::receive_pageprev() {
throw torrent::internal_error("ui::ElementChunksSeen::receive_pageprev(...) called on a disabled object");
unsigned int visible = m_window->height() - 1;
unsigned int scrollable = std::max<int>(m_window->rows() - visible, 0);
unsigned int maxFocus = m_window->max_focus();
if (m_focus > visible / 2)
m_focus -= visible / 2;
else if (scrollable > 0 && m_focus == 0)
m_focus = scrollable;
else if (maxFocus > 0 && m_focus == 0)
m_focus = maxFocus;
else
m_focus = 0;