Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

Article Class Reference

#include <Article.h>

List of all members.

Public Types

enum  { Head = 0x1, Body = 0x2 }

Public Member Functions

 Article ()
 Article (Article *a)
 Article (int artnbr)
 Article (int artnbr, const char *text, int textlen=0)
 ~Article ()
void read (std::istream &is)
void setnbr (int nbr)
void clear (void)
void settext (const std::string &text)
int getnbr (void) const
std::string GetText (void)
const char * c_str (void)
int length (void) const
int has_field (const char *ifld)
std::string getfield (const char *ifld, int Full=0) const
void setfield (const char *ifld, const char *field_data)
std::ostream & write (std::ostream &os, int flags=Head|Body)

Protected Attributes

int _nbr
std::string _text
const char * _ctext

Private Member Functions

const char * find_field (const char *ifld) const

Friends

std::ostream & operator<< (std::ostream &os, Article &art)


Detailed Description

Author:
Thomas Gschwind
Handle a Article

Bug:
Method documentation is missing.

Definition at line 36 of file Article.h.


Member Enumeration Documentation

anonymous enum
 

Enumeration values:
Head 
Body 

Definition at line 52 of file Article.h.

00052              {
00053                 Head = 0x1,
00054                 Body = 0x2
00055         };


Constructor & Destructor Documentation

Article::Article  ) 
 

Definition at line 51 of file Article.cc.

00052 {
00053 }

Article::Article Article a  ) 
 

Definition at line 55 of file Article.cc.

References _ctext, _nbr, _text, getnbr(), and GetText().

00056           : _nbr(a->getnbr()), _text(a->GetText()), _ctext(_text.c_str())
00057 {
00058         _nbr = a->getnbr();
00059         _text = a->GetText();
00060         _ctext = _text.c_str();
00061 
00062 }

Article::Article int  artnbr  ) 
 

Definition at line 64 of file Article.cc.

References setnbr().

00065 {
00066         setnbr(artnbr);
00067 }

Article::Article int  artnbr,
const char *  text,
int  textlen = 0
 

Definition at line 69 of file Article.cc.

References _ctext, _text, and setnbr().

00070           : setnbr(artnbr), _text.assign(text, textlen), _ctext = _text.c_str()
00071 {
00072         setnbr(artnbr);
00073         _text.assign(text, textlen);
00074         _ctext = _text.c_str();
00075 }

Article::~Article  ) 
 

Definition at line 77 of file Article.cc.

00078 {
00079 }


Member Function Documentation

const char * Article::c_str void   ) 
 

Definition at line 117 of file Article.cc.

References _ctext.

Referenced by checkArticle(), and NVNewsgroup::setarticle().

00118 {
00119         return _ctext;
00120 }

void Article::clear void   ) 
 

Definition at line 94 of file Article.cc.

References _ctext, _nbr, and _text.

00095 {
00096         _nbr = 0;
00097         _text = "";
00098         _ctext = _text.c_str();
00099 }

const char * Article::find_field const char *  ifld  )  const [private]
 

Return the position of a given field in the article's header.

Parameters:
ifld The name of the field to be searched for including `:'
Exceptions:
InvalidArticleError If a syntactic error is detected.

Definition at line 137 of file Article.cc.

References _ctext, ERROR_LOCATION, slog, and VERB.

Referenced by getfield(), has_field(), and setfield().

00138 {
00139         char hdrbuf[513], *p;
00140         const char *q, *fld;
00141         const char *ifp;
00142         unsigned int i;
00143 
00144         i = 1;
00145         p = hdrbuf;
00146         ifp = ifld;
00147         while (i < sizeof(hdrbuf) && (*p = tolower(*ifp))) {
00148                 i++;
00149                 p++;
00150                 ifp++;
00151         }
00152         if (i == sizeof(hdrbuf)) {
00153                 p--;
00154                 VERB(slog.
00155                      p(Logger::
00156                        Error) <<
00157                      "Article::find_field: field exceeds 512 characters! Contact maintainer!\n");
00158         }
00159         *p = '\0';
00160 
00161         q = _ctext;
00162         for (;;) {
00163                 p = hdrbuf;
00164                 fld = q;
00165                 while (*p && *p == tolower(*q)) {
00166                         p++;
00167                         q++;
00168                 }
00169                 if (*p == '\0')
00170                         return fld;
00171 
00172                 // bad luck find next line
00173                 while (*q && *q != '\r' && *q != '\n')
00174                         q++;
00175                 if (!*q) {
00176                         VERB(slog.
00177                              p(Logger::
00178                                Error) <<
00179                              "Article::find_field: unterminated header, no body\n");
00180                         throw
00181                             InvalidArticleError
00182                             ("unterminated header, no body",
00183                              ERROR_LOCATION);
00184                 }
00185                 // Skip first CRLF
00186                 if (*q == '\r' && *(q + 1) == '\n') {
00187                         q += 2;
00188                 } else if (*q == '\n') {
00189                         ++q;
00190                 } else {
00191                         VERB(slog.
00192                              p(Logger::
00193                                Error) <<
00194                              "Article::find_field: line not terminated with CRLF\n");
00195                         throw
00196                             InvalidArticleError
00197                             ("line not terminated with CRLF/LF",
00198                              ERROR_LOCATION);
00199                 }
00200                 if (*q == '\r' || *q == '\n')
00201                         return q;
00202         }
00203 }

string Article::getfield const char *  ifld,
int  Full = 0
const
 

Definition at line 205 of file Article.cc.

References _text, ERROR_LOCATION, and find_field().

Referenced by checkArticle(), ArtSpooler::extractID(), ns_post(), ns_stat(), nsh_particle(), RServer::post(), CServer::postspooled(), and NVNewsgroup::printheaderdb().

00206 {
00207         string rfld;
00208         const char *p, *fld;
00209 
00210         if (strcasecmp(ifld, "bytes:") == 0) {
00211 #ifdef HAVE_SSTREAM
00212                 stringstream sb;
00213 #else
00214                 strstream sb;
00215 #endif
00216                 sb << _text.length();
00217                 return sb.rdbuf()->str();
00218         }
00219 
00220         fld = find_field(ifld);
00221         if (*fld == '\r' || *fld == '\n') {
00222                 // Bad luck, did not find the header
00223                 throw NoSuchFieldError(ifld, ERROR_LOCATION);
00224         }
00225         // found header
00226         p = fld + strlen(ifld);
00227         while (*p == ' ' || *p == '\t')
00228                 p++;
00229         if (!Full)
00230                 fld = p;
00231         while (*p && *p != '\r' && *p != '\n')
00232                 p++;
00233         rfld.assign(fld, p - fld);
00234 
00235         if (*p == '\n')
00236                 p++;
00237         else if (*p == '\r') {
00238                 if (*(p + 1) != '\n')
00239                         throw
00240                             InvalidArticleError
00241                             ("illegaly terminated line, neither <lf> nor <cr><lf>",
00242                              ERROR_LOCATION);
00243                 p += 2;
00244         }
00245         if (!(*p))
00246                 throw InvalidArticleError("article without body",
00247                                           ERROR_LOCATION);
00248 
00249         // multi-line header?
00250         while (*p == ' ' || *p == '\t') {
00251                 do {
00252                         p++;
00253                 } while (*p == ' ' || *p == '\t');
00254                 fld = p;
00255                 while (*p && *p != '\r' && *p != '\n')
00256                         p++;
00257                 rfld.append(fld, p - fld);
00258 
00259                 if (*p == '\n')
00260                         p++;
00261                 else if (*p == '\r') {
00262                         if (*(p + 1) != '\n')
00263                                 throw
00264                                     InvalidArticleError
00265                                     ("illegaly terminated line, neither <lf> nor <cr><lf>",
00266                                      ERROR_LOCATION);
00267                         p += 2;
00268                 }
00269                 if (!(*p))
00270                         throw
00271                             InvalidArticleError
00272                             ("article without body", ERROR_LOCATION);
00273         }
00274         return rfld;
00275 }

int Article::getnbr void   )  const
 

Definition at line 107 of file Article.cc.

References _nbr.

Referenced by Article(), OverviewFmt::convert(), and NVNewsgroup::setarticle().

00108 {
00109         return _nbr;
00110 }

string Article::GetText void   ) 
 

Definition at line 112 of file Article.cc.

References _text.

Referenced by Article().

00113 {
00114         return _text;
00115 }       

int Article::has_field const char *  ifld  ) 
 

Definition at line 127 of file Article.cc.

References find_field().

Referenced by checkArticle(), and RServer::post().

00128 {
00129         char c;
00130 
00131         c = *find_field(ifld);
00132         if (!c || c == '\r' || c == '\n')
00133                 return 0;
00134         return 1;
00135 }

int Article::length void   )  const
 

Definition at line 122 of file Article.cc.

References _text.

Referenced by checkArticle(), OverviewFmt::convert(), nsh_particle(), and NVNewsgroup::setarticle().

00123 {
00124         return _text.length();
00125 }

void Article::read std::istream &  is  ) 
 

Definition at line 81 of file Article.cc.

References _ctext, _text, DEBUG, Logger::p(), readtext(), and slog.

Referenced by CServer::article(), RServer::article(), checkArticle(), checkConvertArtOver(), NVNewsgroup::getarticle(), ArtSpooler::getSpooledArt(), main(), ns_post(), and NVNewsgroup::printarticle().

00082 {
00083         DEBUG(slog.p(Logger::Debug) << "Article::read(&is)\n");
00084         _text = "";
00085         readtext(is, _text);
00086         _ctext = _text.c_str();
00087 }

void Article::setfield const char *  ifld,
const char *  field_data
 

Definition at line 277 of file Article.cc.

References _ctext, _text, ASSERT, Logger::Error, find_field(), Logger::p(), and slog.

Referenced by checkArticle(), and RServer::post().

00278 {
00279         const char *p, *fld;
00280 
00281         fld = find_field(ifld);
00282         if (*fld == '\r' || *fld == '\n') {
00283                 // Bad luck, did not find the header
00284                 _text.insert(fld - _ctext, field_data);
00285                 _ctext = _text.c_str();
00286                 return;
00287         }
00288         // We have found the header
00289         p = fld + strlen(ifld);
00290         while (isspace(*p))
00291                 p++;
00292         while (*p && *p != '\r' && *p != '\n')
00293                 p++;
00294         ASSERT(if (!(*p)) {
00295                slog.p(Logger::Error) << "Article without body.\n";}
00296                if (*p == '\r' && !(*(p + 1))) {
00297                slog.p(Logger::Error) << "Article ended with <CR><NULL>.\n";}
00298         );
00299         if (*p == '\n')
00300                 p++;
00301         if (*p == '\r' && *(p + 1) == '\n')
00302                 p += 2;
00303 
00304         // Multiline header?
00305         while (isspace(*p) && *p != '\n' && *p != '\r') {
00306                 while (isspace(*p))
00307                         p++;
00308                 while (*p != '\r' && *p != '\n')
00309                         p++;
00310                 ASSERT(if (!(*p)) {
00311                        slog.p(Logger::Error) << "Article without body.\n";}
00312                        if (*p == '\r' && !(*(p + 1))) {
00313                        slog.
00314                        p(Logger::
00315                          Error) << "Article ended with <CR><NULL>.\n";}
00316                 );
00317                 if (*p == '\n')
00318                         p++;
00319                 if (*p == '\r' && *(p + 1) == '\n')
00320                         p += 2;
00321         }
00322         _text.replace(fld - _ctext, p - fld, field_data);
00323         _ctext = _text.c_str();
00324 }

void Article::setnbr int  nbr  ) 
 

Definition at line 89 of file Article.cc.

References _nbr.

Referenced by CServer::article(), RServer::article(), Article(), and checkConvertArtOver().

00090 {
00091         _nbr = nbr;
00092 }

void Article::settext const std::string &  text  ) 
 

Definition at line 101 of file Article.cc.

References _ctext, and _text.

Referenced by checkArticle().

00102 {
00103         _text = text;
00104         _ctext = _text.c_str();
00105 }

ostream & Article::write std::ostream &  os,
int  flags = Head|Body
 

Definition at line 326 of file Article.cc.

References _ctext, _text, Body, Head, slog, and VERB.

Referenced by checkArticle(), nsh_particle(), and CServer::post().

00327 {
00328         const char *p, *q;
00329 
00330         if ((flags & (Head | Body)) == (Head | Body)) {
00331                 os << _text;
00332                 return os;
00333         }
00334 
00335         p = q = _ctext;
00336         for (;;) {
00337                 while (*q && *q != '\r' && *q != '\n')
00338                         q++;
00339                 if (!*q) {
00340                         VERB(slog.
00341                              p(Logger::
00342                                Notice) <<
00343                              "Article::write: Article without body!\n");
00344                         break;
00345                 }
00346                 if (*q == '\r' && *(q + 1) == '\n'
00347                     && *(q + 2) == '\r' && *(q + 3) == '\n') {
00348                         q += 2;
00349                         break;
00350                 }
00351                 if (*q == '\n' && *(q + 1) == '\n') {
00352                         q++;
00353                         break;
00354                 }
00355                 while (*q == '\n' || *q == '\r')
00356                         q++;
00357         }
00358         if (flags & Head) {
00359                 os.write(p, q - p);
00360         } else if (flags & Body) {
00361                 if (*q == '\n')
00362                         p++;
00363                 else if (*q == '\r' && *(q + 1) == '\n')
00364                         q += 2;
00365 
00366                 os.write(q, _text.length() - (q - p));
00367         }
00368         return os;
00369 }


Friends And Related Function Documentation

std::ostream& operator<< std::ostream &  os,
Article art
[friend]
 

Definition at line 371 of file Article.cc.

00372 {
00373         os << art._text;
00374         return os;
00375 }


Member Data Documentation

const char* Article::_ctext [protected]
 

Definition at line 49 of file Article.h.

Referenced by Article(), c_str(), clear(), find_field(), read(), setfield(), settext(), and write().

int Article::_nbr [protected]
 

Definition at line 47 of file Article.h.

Referenced by Article(), clear(), getnbr(), and setnbr().

std::string Article::_text [protected]
 

Definition at line 48 of file Article.h.

Referenced by Article(), clear(), getfield(), GetText(), length(), operator<<(), read(), setfield(), settext(), and write().


The documentation for this class was generated from the following files:
Generated on Fri Aug 20 10:58:09 2004 for NewsCache by doxygen 1.3.6-20040222