1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* 3 * Pan - A Newsreader for Gtk+ 4 * Copyright (C) 2002-2006 Charles Kerr <charles@rebelbase.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 #ifndef __Article_h__ 21 #define __Article_h__ 22 23 #include <ctime> 24 #include <vector> 25 #include <pan/general/sorted-vector.h> 26 #include <pan/general/quark.h> 27 #include <pan/data/parts.h> 28 #include <pan/data/xref.h> 29 30 namespace pan 31 { 32 /** 33 * A Usenet article, either single-part or multipart. 34 * 35 * To lessen the memory footprint of large binaries groups, 36 * Pan folds multipart posts into a single Article object. 37 * Only minimal information for any one part is kept 38 * (message-id, line count, byte count), and the Article object 39 * holds the rest. 40 * 41 * This is a lossy approach: less-important unique fields, 42 * such as the part's xref and time-posted, are not needed 43 * and so we don't keep them. 44 * 45 * @ingroup data 46 */ 47 class Article 48 { 49 public: set_parts(const PartBatch & b)50 void set_parts (const PartBatch& b) { parts.set_parts(b); } add_part(Parts::number_t num,const StringView & mid,Parts::bytes_t bytes)51 bool add_part (Parts::number_t num, const StringView& mid, Parts::bytes_t bytes) { return parts.add_part(num,mid,bytes,message_id); } set_part_count(Parts::number_t num)52 void set_part_count (Parts::number_t num) { parts.set_part_count(num); } get_total_part_count()53 Parts::number_t get_total_part_count () const { return parts.get_total_part_count(); } get_found_part_count()54 Parts::number_t get_found_part_count () const { return parts.get_found_part_count(); } get_part_info(Parts::number_t num,std::string & mid,Parts::bytes_t & bytes)55 bool get_part_info (Parts::number_t num, 56 std::string & mid, 57 Parts::bytes_t & bytes) const { return parts.get_part_info(num,mid,bytes,message_id); } 58 59 typedef Parts::const_iterator part_iterator; pbegin()60 part_iterator pbegin() const { return parts.begin(message_id); } pend()61 part_iterator pend() const { return parts.end(message_id); } 62 63 typedef std::vector<Quark> mid_sequence_t; 64 mid_sequence_t get_part_mids () const; 65 enum PartState { SINGLE, INCOMPLETE, COMPLETE }; 66 PartState get_part_state () const; 67 68 public: 69 Quark message_id; 70 Quark author; 71 Quark subject; 72 time_t time_posted; 73 unsigned int lines; 74 int score; 75 bool is_binary; 76 bool flag; 77 static bool has_reply_leader (const StringView&); 78 79 public: 80 unsigned int get_crosspost_count () const; get_line_count()81 unsigned long get_line_count () const { return lines; } is_line_count_ge(size_t test)82 bool is_line_count_ge (size_t test) const { return lines >= test; } 83 unsigned long get_byte_count () const; 84 bool is_byte_count_ge (unsigned long test) const; 85 86 Xref xref; 87 88 public: Article()89 Article (): time_posted(0), lines(0), score(0), is_binary(false), flag(false) {} 90 void clear (); 91 92 /* Functions to bookmark an article */ toggle_flag()93 void toggle_flag() { flag = !flag; } get_flag()94 bool get_flag() const { return flag; } set_flag(bool setme)95 void set_flag(bool setme) { flag = setme; } 96 97 private: 98 Parts parts; 99 100 }; 101 } 102 103 #endif 104