Logo Search packages:      
Sourcecode: pan version File versions  Download package

void TaskXOver::on_nntp_line ( NNTP nntp,
const StringView line 
) [private, virtual]

Invoked for each line of an NNTP server's list responses, such as a list of headers for an XOVER command or a list of lines for an ARTICLE command.

Reimplemented from pan::NNTP::Listener.

Definition at line 253 of file task-xover.cc.

References pan::NNTP::_group, pan::NNTP::_server, pan::Quark::c_str(), pan::StringView::empty(), pan::Quark::empty(), pan::StringView::front(), pan::StringView::len, pan::StringView::pop_token(), pan::StringView::str, pan::StringView::substr(), pan::Article::time_posted, pan::StringView::trim(), and pan::Data::xover_add().

{
  pan_return_if_fail (nntp != 0);
  pan_return_if_fail (!nntp->_server.empty());
  pan_return_if_fail (!nntp->_group.empty());

  _bytes_so_far += line.len;

  unsigned int lines=0u;
  unsigned long number=0ul, bytes=0ul;
  StringView subj, author, date, mid, ref, tmp, xref, l(line);
  bool ok = !l.empty();
  ok = ok && l.pop_token (tmp, '\t');    if (ok) number = view_to_ul (tmp);
  ok = ok && l.pop_token (subj, '\t');   if (ok) subj.trim ();
  ok = ok && l.pop_token (author, '\t'); if (ok) author.trim ();
  ok = ok && l.pop_token (date, '\t');   if (ok) date.trim ();
  ok = ok && l.pop_token (mid, '\t');    if (ok) mid.trim ();
  ok = ok && l.pop_token (ref, '\t');    if (ok) ref.trim ();
  ok = ok && l.pop_token (tmp, '\t');    if (ok) bytes = view_to_ul (tmp);
  ok = ok && l.pop_token (tmp, '\t');    if (ok) lines = view_to_ul (tmp);
  ok = ok && l.pop_token (xref, '\t');   if (ok) xref.trim ();

  if (xref.len>6 && !strncmp(xref.str,"Xref: ", 6)) {
    xref = xref.substr (xref.str+6, 0);
    xref.trim ();
  }

  // is this header corrupt?
  if (!number // missing number
      || subj.empty() // missing subject
      || author.empty() // missing author
      || date.empty() // missing date
      || mid.empty() // missing mid
      || mid.front()!='<' // corrupt mid
      || (!ref.empty() && ref.front()!='<'))
    return;

  // if news server doesn't provide an xref, fake one
  char * buf (0);
  if (xref.empty())
    xref = buf = g_strdup_printf ("%s %s:%lu",
                       nntp->_server.c_str(), nntp->_group.c_str(), number);

  unsigned long& h (_high[nntp->_server]);
  h = std::max (h, number);

  const char * fallback_charset = NULL; // FIXME

  ++_parts_so_far;

  const Article * article = _data.xover_add (
    nntp->_server, nntp->_group,
    (header_is_nonencoded_utf8(subj) ? subj : header_to_utf8(subj,fallback_charset).c_str()),
    (header_is_nonencoded_utf8(author) ? author : header_to_utf8(author,fallback_charset).c_str()),
    date, mid, ref, bytes, lines, xref);

  if (article)
  {
    ++_articles_so_far;

    // are we done?
    if (_mode==DAYS && article->time_posted<_days_cutoff)
      _server_to_minitasks[nntp->_server].clear ();
  }

  // emit a status update
  int& prev = _last_xover_number[nntp];
  increment_step (number - prev);
  prev = number;
  if (!(_parts_so_far % 500))
    set_status_va (_("%s (%lu parts, %lu articles)"), _short_group_name.c_str(), _parts_so_far, _articles_so_far);

  // cleanup
  g_free (buf);
}


Generated by  Doxygen 1.6.0   Back to index