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

void DataImpl::load_article ( const Quark g,
Article article,
const StringView references 
) [private]

HEADERS 'article' MUST have been allocated by GroupHeaders::alloc_new_article()!!

Definition at line 238 of file headers.cc.

References pan::DataImpl::ArticleNode::_article, pan::DataImpl::ArticleNode::_children, pan::DataImpl::ArticleNode::_mid, pan::DataImpl::ArticleNode::_parent, pan::StringView::empty(), pan::StringView::pop_last_token(), pan::StringView::strstr(), pan::Quark::to_view(), and pan::StringView::trim().

Referenced by xover_add().

{
#if 0
  std::cerr << LINE_ID << " adding article "
            << " subject [" << article->subject << ']'
            << " mid [" << article->message_id <<  ']'
            << " references [" << references << ']'
            << std::endl;
#endif

  GroupHeaders * h (get_group_headers (group));
  pan_return_if_fail (h!=0);

  // populate the current node
  const Quark& mid (article->message_id);
  ArticleNode * node (h->_nodes[mid]);
  if (!node) {
    static const ArticleNode blank_node;
    h->_node_chunk.push_back (blank_node);
    node = h->_nodes[mid] = &h->_node_chunk.back();
    node->_mid = mid;
  }
  assert (!node->_article);
  node->_article = article;
  ArticleNode * article_node = node;

  // build nodes for each of the references
  StringView tok, refs(references);
  //std::cerr << LINE_ID << " references [" << refs << ']' << std::endl;
  while (refs.pop_last_token (tok, ' '))
  {
    tok.trim ();
    if (tok.empty())
      break;

    ArticleNode * old_parent_node (node->_parent);
    const Quark old_parent_mid (old_parent_node ? old_parent_node->_mid : Quark());
    const Quark new_parent_mid (tok);
    //std::cerr << LINE_ID << " now we're working on " << new_parent_mid << std::endl;

    if (new_parent_mid == old_parent_mid)
    {
      //std::cerr << LINE_ID << " our tree agrees with the References header here..." << std::endl;
      node = node->_parent;
      continue;
    }

    if (!old_parent_node)
    {
      //std::cerr << LINE_ID << " haven't mapped " << new_parent_mid << " before..." << std::endl;
      ArticleNode * new_parent_node (h->_nodes[new_parent_mid]);
      const bool found (new_parent_node != 0);
      if (!found) {
        //std::cerr << LINE_ID << " didn't find it; adding new node for " << new_parent_mid << std::endl;
        static const ArticleNode blank_node;
        h->_node_chunk.push_back (blank_node);
        new_parent_node = h->_nodes[new_parent_mid] = &h->_node_chunk.back();
        new_parent_node->_mid = new_parent_mid;
      }
      node->_parent = new_parent_node;
      if (find_ancestor (new_parent_node, new_parent_mid)) {
        node->_parent = 0;
        //std::cerr << LINE_ID << " someone's been munging References headers to cause trouble!" << std::endl;
        break;
      }
      new_parent_node->_children.push_front (node);
      node = new_parent_node;
      continue;
    }

    ArticleNode * tmp;
    if ((tmp = find_ancestor (node, new_parent_mid)))
    {
      //std::cerr << LINE_ID << " this References header has a hole... jumping to " << tmp->_mid << std::endl;
      node = tmp;
      continue;
    }

    const char * cpch;
    if ((cpch = refs.strstr (old_parent_mid.to_view())))
    {
      //std::cerr << LINE_ID << " this References header fills a hole of ours ... " << new_parent_mid << std::endl;

      // unlink from old parent
      old_parent_node->_children.remove (node);
      node->_parent = 0;

      // link to new parent
      ArticleNode * new_parent_node (h->_nodes[new_parent_mid]);
      const bool found (new_parent_node != 0);
      if (!found) {
        //std::cerr << LINE_ID << " didn't find it; adding new node for " << new_parent_mid << std::endl;
        static const ArticleNode blank_node;
        h->_node_chunk.push_back (blank_node);
        new_parent_node = h->_nodes[new_parent_mid] = &h->_node_chunk.back();
        new_parent_node->_mid = new_parent_mid;
      }
      node->_parent = new_parent_node;
      if (find_ancestor (new_parent_node, new_parent_mid) != 0) {
        node->_parent = 0;
        //std::cerr << LINE_ID << " someone's been munging References headers to cause trouble!" << std::endl;
        break;
      }
      new_parent_node->_children.push_front (node);
      node = new_parent_node;
      continue;
    }
  }

  // recursion?
  assert (find_ancestor(article_node, article->message_id) == 0);
}


Generated by  Doxygen 1.6.0   Back to index