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